diff --git a/dist/index.js b/dist/index.js index df194c4..e54c225 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("moment"),require("react-sizeme")):"function"==typeof define&&define.amd?define("react-gantt-timeline",["React","moment","ReactDOM"],t):"object"==typeof exports?exports["react-gantt-timeline"]=t(require("react"),require("moment"),require("react-sizeme")):e["react-gantt-timeline"]=t(e.React,e.moment,e.ReactDOM)}(window,function(e,t,n){return function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=8)}([function(t,n){t.exports=e},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n=0&&c.splice(t,1)}function y(e){var t=document.createElement("style");return void 0===e.attrs.type&&(e.attrs.type="text/css"),g(t,e.attrs),h(e,t),t}function g(e,t){Object.keys(t).forEach(function(n){e.setAttribute(n,t[n])})}function v(e,t){var n,o,r,i;if(t.transform&&e.css){if(!(i=t.transform(e.css)))return function(){};e.css=i}if(t.singleton){var a=u++;n=l||(l=y(t)),o=k.bind(null,n,a,!1),r=k.bind(null,n,a,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(e){var t=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",g(t,e.attrs),h(e,t),t}(t),o=function(e,t,n){var o=n.css,r=n.sourceMap,i=void 0===t.convertToAbsoluteUrls&&r;(t.convertToAbsoluteUrls||i)&&(o=d(o));r&&(o+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(r))))+" */");var a=new Blob([o],{type:"text/css"}),s=e.href;e.href=URL.createObjectURL(a),s&&URL.revokeObjectURL(s)}.bind(null,n,t),r=function(){m(n),n.href&&URL.revokeObjectURL(n.href)}):(n=y(t),o=function(e,t){var n=t.css,o=t.media;o&&e.setAttribute("media",o);if(e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}.bind(null,n),r=function(){m(n)});return o(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;o(e=t)}else r()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||"boolean"==typeof t.singleton||(t.singleton=a()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=f(e,t);return p(n,t),function(e){for(var o=[],r=0;rn.props.end.x?(e=n.calcSCoordinates(),"M"+n.props.start.x+" "+n.props.start.y+" "+e.cpt1.x+" "+e.cpt1.y+" "+e.cpt2.x+" "+e.cpt2.y+" "+e.cpt3.x+" "+e.cpt3.y+" "+e.cpt4.x+" "+e.cpt4.y+" "+n.props.end.x+" "+n.props.end.y):(e=n.calcNormCoordinates(),"M"+n.props.start.x+" "+n.props.start.y+" "+e.cpt1.x+" "+e.cpt1.y+" "+e.cpt2.x+" "+e.cpt2.y+" "+n.props.end.x+" "+n.props.end.y)},n.onSelect=function(e){n.props.onSelectItem&&n.props.onSelectItem(n.props.item)},n}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,r.Component),o(t,[{key:"render",value:function(){var e=this.props.isSelected?a.default.values.links.selectedColor:a.default.values.links.color;return i.default.createElement("g",{className:"timeline-link"},i.default.createElement("path",{pointerEvents:"stroke",onMouseDown:this.onSelect,stroke:"white",d:this.getPath(),strokeLinejoin:"round",fill:"transparent",strokeWidth:"4",cursor:"pointer"}),i.default.createElement("path",{pointerEvents:"stroke",onMouseDown:this.onSelect,stroke:e,d:this.getPath(),strokeLinejoin:"round",fill:"transparent",strokeWidth:"1",cursor:"pointer",markerEnd:"url(#arrow)"}))}}]),t}();t.default=u},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=Object.assign||function(e){for(var t=1;t=t.length?t.length:r+e}},n.setStartEnd=function(){n.dc.setStartEnd(n.state.scrollLeft,n.state.scrollLeft+n.state.size.width,n.state.nowposition,n.state.dayWidth)},n.horizontalChange=function(e){var t=n.state.nowposition,o=-1,r=n.state.headerData,i=n.state.startRow,a=n.state.endRow;e>n.pxToScroll?(t=n.state.nowposition-n.pxToScroll,o=0):e<=0?(t=n.state.nowposition+n.pxToScroll,o=n.pxToScroll):o=e;var s=Math.trunc((e-n.state.nowposition)/n.state.dayWidth);a=(i=Math.trunc(n.state.scrollTop/n.props.itemheight))+n.state.numVisibleRows>=n.props.data.length?n.props.data.length-1:i+n.state.numVisibleRows,n.setStartEnd(),n.setState(n.state={currentday:s,nowposition:t,headerData:r,scrollLeft:o,startRow:i,endRow:a})},n.calculateVerticalScrollVariables=function(e){n.pxToScroll=(1-e.width/h.DATA_CONTAINER_WIDTH)*h.DATA_CONTAINER_WIDTH-1},n.onHorizonChange=function(e,t){n.props.onHorizonChange&&n.props.onHorizonChange(e,t)},n.doMouseDown=function(e){n.dragging=!0,n.draggingPosition=e.clientX},n.doMouseMove=function(e){if(n.dragging){var t=n.draggingPosition-e.clientX;0!==t&&(n.draggingPosition=e.clientX,n.horizontalChange(n.state.scrollLeft+t))}},n.doMouseUp=function(e){n.dragging=!1},n.doMouseLeave=function(e){n.dragging=!1},n.doTouchStart=function(e){n.dragging=!0,n.draggingPosition=e.touches[0].clientX},n.doTouchEnd=function(e){n.dragging=!1},n.doTouchMove=function(e){if(n.dragging){var t=n.draggingPosition-e.touches[0].clientX;0!==t&&(n.draggingPosition=e.touches[0].clientX,n.horizontalChange(n.state.scrollLeft+t))}},n.doTouchCancel=function(e){n.dragging=!1},n.doMouseLeave=function(e){n.dragging=!1},n.onTaskListSizing=function(e){n.setState(function(t){var n=o({},t);return n.sideStyle={width:n.sideStyle.width-e},n})},n.onSelectItem=function(e){n.props.onSelectItem&&e!=n.props.selectedItem&&n.props.onSelectItem(e)},n.onStartCreateLink=function(e,t){n.setState({interactiveMode:!0,taskToCreate:{task:e,position:t}})},n.onFinishCreateLink=function(e,t){n.props.onCreateLink&&e&&n.props.onCreateLink({start:n.state.taskToCreate,end:{task:e,position:t}}),n.setState({interactiveMode:!1,taskToCreate:null})},n.onTaskChanging=function(e){n.setState({changingTask:e})},n.calcNumVisibleDays=function(e){return Math.ceil(e.width/n.state.dayWidth)+h.BUFFER_DAYS},n.checkNeeeData=function(){if(n.props.data!=n.state.data){n.state.data=n.props.data;var e=n.calculateStartEndRows(n.state.numVisibleRows,n.props.data,n.state.scrollTop);n.state.startRow=e.start,n.state.endRow=e.end,f.default.registerData(n.state.data)}n.props.links!=n.state.links&&(n.state.links=n.props.links,f.default.registerLinks(n.props.links))},n.dragging=!1,n.draggingPosition=0,n.dc=new m.default,n.dc.onHorizonChange=n.onHorizonChange,n.initialise=!1,n.pxToScroll=1900;var r=n.getDayWidth(n.props.mode);return y.default.load(n.props.config),n.state={currentday:0,nowposition:0,startRow:0,endRow:10,sideStyle:{width:200},scrollLeft:0,scrollTop:0,numVisibleRows:40,numVisibleDays:60,dayWidth:r,interactiveMode:!1,taskToCreate:null,links:[],mode:n.props.mode?n.props.mode:h.VIEW_MODE_MONTH,size:{width:1,height:1},changingTask:null},n}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,i.Component),r(t,[{key:"getDayWidth",value:function(e){switch(e){case h.VIEW_MODE_DAY:return h.DAY_DAY_MODE;case h.VIEW_MODE_WEEK:return h.DAY_WEEK_MODE;case h.VIEW_MODE_MONTH:return h.DAY_MONTH_MODE;case h.VIEW_MODE_YEAR:return h.DAY_YEAR_MODE;default:return h.DAY_MONTH_MODE}}},{key:"checkMode",value:function(){if(this.props.mode!=this.state.mode&&this.props.mode){this.state.mode=this.props.mode;var e=this.getDayWidth(this.state.mode);this.state.dayWidth=e,this.state.numVisibleDays=this.calcNumVisibleDays(this.state.size);var t=Math.ceil(-this.state.currentday*this.state.dayWidth/this.pxToScroll);this.state.nowposition=t*this.pxToScroll;var n=(this.state.currentday*this.state.dayWidth+this.state.nowposition)%this.pxToScroll;this.state.scrollLeft=n}}},{key:"render",value:function(){var e;return this.checkMode(),this.checkNeeeData(),a.default.createElement("div",{className:"timeLine"},a.default.createElement("div",{className:"timeLine-side-main",style:this.state.sideStyle},a.default.createElement(p.default,{ref:"taskViewPort",itemheight:this.props.itemheight,startRow:this.state.startRow,endRow:this.state.endRow,data:this.props.data,selectedItem:this.props.selectedItem,onSelectItem:this.onSelectItem,onUpdateTask:this.props.onUpdateTask,onScroll:this.verticalChange}),a.default.createElement(l.default,{onTaskListSizing:this.onTaskListSizing})),a.default.createElement("div",{className:"timeLine-main"},a.default.createElement(u.default,{headerData:this.state.headerData,numVisibleDays:this.state.numVisibleDays,currentday:this.state.currentday,nowposition:this.state.nowposition,dayWidth:this.state.dayWidth,mode:this.state.mode,scrollLeft:this.state.scrollLeft}),a.default.createElement(c.default,{ref:"dataViewPort",scrollLeft:this.state.scrollLeft,scrollTop:this.state.scrollTop,itemheight:this.props.itemheight,nowposition:this.state.nowposition,startRow:this.state.startRow,endRow:this.state.endRow,data:this.props.data,selectedItem:this.props.selectedItem,dayWidth:this.state.dayWidth,onScroll:this.scrollData,onMouseDown:this.doMouseDown,onMouseMove:this.doMouseMove,onMouseUp:this.doMouseUp,onMouseLeave:this.doMouseLeave,onTouchStart:this.doTouchStart,onTouchMove:this.doTouchMove,onTouchEnd:this.doTouchEnd,onTouchCancel:this.doTouchCancel,onSelectItem:this.onSelectItem,onUpdateTask:this.props.onUpdateTask,onTaskChanging:this.onTaskChanging,onStartCreateLink:this.onStartCreateLink,onFinishCreateLink:this.onFinishCreateLink,boundaries:{lower:this.state.scrollLeft,upper:this.state.scrollLeft+this.state.size.width},onSize:this.onSize}),a.default.createElement(d.default,(v(e={scrollLeft:this.state.scrollLeft,scrollTop:this.state.scrollTop,startRow:this.state.startRow,endRow:this.state.endRow,data:this.props.data,nowposition:this.state.nowposition,dayWidth:this.state.dayWidth,interactiveMode:this.state.interactiveMode,taskToCreate:this.state.taskToCreate,onFinishCreateLink:this.onFinishCreateLink,changingTask:this.state.changingTask,selectedItem:this.props.selectedItem,onSelectItem:this.onSelectItem,itemheight:this.props.itemheight},"onSelectItem",this.onSelectItem),v(e,"links",this.props.links),e))))}}]),t}();b.propTypes={itemheight:s.default.number.isRequired,dayWidth:s.default.number.isRequired},b.defaultProps={itemheight:20,dayWidth:24},t.default=b},function(e,t,n){e.exports=n(10)()},function(e,t,n){"use strict";var o=n(11);function r(){}e.exports=function(){function e(e,t,n,r,i,a){if(a!==o){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return n.checkPropTypes=r,n.PropTypes=n,n}},function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;nn.end},n.setBoundaries(),n}return h(t,i.PureComponent),r(t,[{key:"getFormat",value:function(e,t){switch(e){case"year":return"YYYY";case"month":return"top"==t?"MMMM YYYY":"MMMM";case"week":return"top"==t?"ww MMMM YYYY":"ww";case"dayweek":return"dd";case"daymonth":return"D"}}},{key:"getModeIncrement",value:function(e,t){switch(t){case"year":return c.default.daysInYear(e.year());case"month":return e.daysInMonth();case"week":return 7;default:return 1}}},{key:"getBox",value:function(e,t,n){var o=this.getModeIncrement(e,t)*this.props.dayWidth;if(!n){var r=this.getStartDate(e,t);r=r.startOf("day");var i=(0,s.default)().startOf("day"),a=r.diff(i,"days");n=c.default.dayToPosition(a,this.props.nowposition,this.props.dayWidth)}return{left:n,width:o}}},{key:"render",value:function(){return this.refs.Header&&(this.refs.Header.scrollLeft=this.props.scrollLeft),a.default.createElement("div",{id:"timeline-header",ref:"Header",className:"timeLine-main-header-viewPort"},this.renderHeader())}}]),t}();t.default=y},function(e,n){e.exports=t},function(e,t,n){var o=n(16);"string"==typeof o&&(o=[[e.i,o,""]]);var r={hmr:!0,transform:void 0,insertInto:void 0};n(5)(o,r);o.locals&&(e.exports=o.locals)},function(e,t,n){(e.exports=n(4)(!1)).push([e.i,".header-top{\n height: 20px;\n\n border-bottom: solid 0.5px silver;\n}\n\n.header-middle{\n height: 20px;\n background-color: chocolate;\n color: white;\n font-size:10px;\n border-bottom: solid 0.5px silver;\n \n}\n.header-bottom{\n height: 20px;\n font-size:10px;\n border-bottom: solid 0.5px silver;\n}\n",""])},function(e,t){e.exports=function(e){var t="undefined"!=typeof window&&window.location;if(!t)throw new Error("fixUrls requires window.location");if(!e||"string"!=typeof e)return e;var n=t.protocol+"//"+t.host,o=n+t.pathname.replace(/\/[^\/]*$/,"/");return e.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi,function(e,t){var r,i=t.trim().replace(/^"(.*)"$/,function(e,t){return t}).replace(/^'(.*)'$/,function(e,t){return t});return/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(i)?e:(r=0===i.indexOf("//")?i:0===i.indexOf("/")?n+i:o+i.replace(/^\.\//,""),"url("+JSON.stringify(r)+")")})}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.DataViewPort=t.DataRow=void 0;var o=Object.assign||function(e){for(var t=1;t0?e*this.props.itemheight:10}},{key:"componentDidMount",value:function(){this.refs.dataViewPort.scrollLeft=0}},{key:"render",value:function(){this.refs.dataViewPort&&(this.refs.dataViewPort.scrollLeft=this.props.scrollLeft,this.refs.dataViewPort.scrollTop=this.props.scrollTop);var e=this.getContainerHeight(this.props.data.length);return a.default.createElement("div",{ref:"dataViewPort",id:"timeLinedataViewPort",className:"timeLine-main-data-viewPort",onMouseDown:this.doMouseDown,onMouseMove:this.doMouseMove,onMouseUp:this.props.onMouseUp,onMouseLeave:this.props.onMouseLeave,onTouchStart:this.doTouchStart,onTouchMove:this.doTouchMove,onTouchEnd:this.props.onTouchEnd,onTouchCancel:this.props.onTouchCancel},a.default.createElement("div",{className:"timeLine-main-data-container",style:{height:e,width:s.DATA_CONTAINER_WIDTH,maxWidth:s.DATA_CONTAINER_WIDTH}},this.renderRows()))}}]),t}();t.default=(0,c.default)({monitorWidth:!0,monitorHeight:!0})(g)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=Object.assign||function(e){for(var t=1;t0?e*this.props.itemheight:10}}},{key:"renderTaskRow",value:function(e){for(var t=[],n=this.props.startRow;nt.upper_data_limit},this.setLimits=function(e,n){t.lower_limit=e-1e3,t.lower_data_limit=e-750,t.upper_limit=n+1e3,t.upper_data_limit=n+750},this.loadDataHorizon=function(){var e=i.default.pixelToDate(t.lower_limit,t.nowposition,t.daywidth),n=i.default.pixelToDate(t.upper_limit,t.nowposition,t.daywidth);t.onHorizonChange(e,n)},this.lower_limit=0,this.upper_limit=0,this._dataToRender=[]}},function(e,t,n){var o=n(27);"string"==typeof o&&(o=[[e.i,o,""]]);var r={hmr:!0,transform:void 0,insertInto:void 0};n(5)(o,r);o.locals&&(e.exports=o.locals)},function(e,t,n){(e.exports=n(4)(!1)).push([e.i,".timeLine{\n display: flex;\n flex-direction: row;\n width:100%;\n height: 100%;\n border:solid 1px rgb(207, 207, 205);\n font-size: 12px;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n}\n\n/* Main Area */\n\n.timeLine-main{\n flex: 1 1 100%;\n position: relative;\n display: flex;\n flex-direction: column;\n overflow-y: hidden;\n}\n/* Main Area Header*/\n\n.timeLine-main-header-viewPort{\n flex: 0 0 60px;\n position: relative;\n height: 60px ;\n width: 100%;\n background-color: rgb(112, 112, 112);\n overflow: hidden;\n \n}\n\n.timeLine-main-header-container{\n flex: 0 0 60px;\n position: relative;\n top:0;\n left:0;\n height: 100% ;\n display:flex;\n flex-direction: column;\n background-color: #333333;\n overflow: hidden;\n user-select: none;\n}\n\n.timeLine-main-header-day-item{\n position: absolute;\n display: flex;\n flex-direction: column;\n justify-content: center;\n background-color:rgb(112, 112, 112);\n font-size: 10px;\n text-align: center;\n border-right:solid 1px;\n border-top:solid 1px;\n border-bottom:solid 1px;\n top:20px;\n height:40px;\n color: white;\n text-align: center;\n}\n\n\n.timeLine-main-header-top-item{\n position: absolute;\n display: flex;\n flex-direction: column;\n justify-content: center;\n border-right:solid 1px white;\n height:20px;\n z-index: 91;\n}\n\n.timeLine-main-header-day-week{\n flex:0 0 12px;\n padding: 4px;\n z-index: 90;\n}\n\n.timeLine-main-header-day-month{\n top:0px;\n position: sticky;\n flex:0 0 15px;\n padding: 5px;\n z-index: 90;\n}\n\n.timeLine-main-header-time{\n display: flex;\n flex-direction: row;\n align-items: stretch;\n height: 22px;\n justify-content: stretch;\n}\n\n.timeLine-main-header-time-item{\n border-left: solid 1px silver;\n border-bottom: solid 1px silver;\n border-top: solid 1px silver;\n text-align: center;\n padding-top: 5px;\n}\n/* Main Area Data*/\n\n.timeLine-main-data-viewPort{\n flex: 1 1 auto;\n position: relative;\n overflow: hidden;\n background-color:#fbf9f9;;\n \n \n}\n.timeLine-main-data-container{\n position: relative;\n top:0;\n left:0;\n height: 100% ;\n background-color: rgb(255, 255, 255);\n}\n\n.timeLine-main-data-row{\n position: absolute;\n width: 100%;\n height: 50px;\n \n}\n\n.timeLine-main-data-task{\n position: absolute;\n background-color:darkorchid;\n border-radius: 14px;\n color: white;\n text-align: center;\n}\n\n.timeLine-main-data-task-side{\n position: absolute;\n width: 10px;\n cursor: col-resize;\n display:flex;\n flex-direction: column;\n justify-content: center;\n}\n.timeLine-main-data-task-side-linker{\n width:8px;\n height: 8px;\n border-radius: 4px;\n cursor: default;\n z-index: 100;\n \n}\n.timeLine-main-data-task-side-linker:hover{\n background-color: black;\n border: solid 0.5px grey\n}\n/* .timeLine-main-data-task:hover {\n background-color:chocolate;\n border:solid 2px darkorchid;\n cursor: move;\n} */\n\n\n\n.timeLine-main-data-verticalLine{\n flex:1 1 auto;\n height: 100%;\n width: 24px;\n background-color:white;\n border-left-width: 0.5px;\n border-left-color: rgb(207, 207, 205);\n border-left-style: dashed;\n}\n\n/* Side Area */\n\n.timeLine-side-main{\n flex: 0 0 auto;\n width:108px;\n min-width: 108px;\n display: flex;\n flex-direction: row;\n \n}\n\n.timeLine-side{\n flex: 1 0 100px;\n display: flex;\n flex-direction: column;\n border-right:solid 1px rgb(207, 207, 205);\n}\n\n.verticalResizer{\n flex: 0 0 8px;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n cursor: col-resize;\n border-right:solid 1px rgb(207, 207, 205);\n height: 100%;\n\n}\n.squareGrip{\n flex: 0 0 auto;\n \n border-radius: 50%;\n height: 5px;\n width: 5px;\n margin: 3px 0;\n}\n\n.timeLine-side-title{\n flex: 0 0 60px;\n display: flex;\n justify-content: center;\n align-items: center;\n \n}\n\n.timeLine-side-task-viewPort{\n position: relative;\n flex: 1 1 auto;\n height:100% ;\n background-color:#fbf9f9;\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.timeLine-side-task-container{\n position: relative;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.timeLine-side-task-row{\n position: absolute;\n width: 100%;\n background-color: rgb(112, 112, 112);\n border-bottom-width: 0.5px;\n border-bottom-color: rgb(207, 207, 205);\n border-bottom-style: solid;\n height: 30px;\n color: grey;\n text-align: center;\n overflow: hidden;\n text-overflow: ellipsis; \n outline: none;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n",""])}])}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("moment"),require("react-sizeme")):"function"==typeof define&&define.amd?define("react-gantt-timeline",["React","moment","ReactDOM"],t):"object"==typeof exports?exports["react-gantt-timeline"]=t(require("react"),require("moment"),require("react-sizeme")):e["react-gantt-timeline"]=t(e.React,e.moment,e.ReactDOM)}(window,function(e,t,n){return function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=8)}([function(t,n){t.exports=e},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n=0&&c.splice(t,1)}function y(e){var t=document.createElement("style");return void 0===e.attrs.type&&(e.attrs.type="text/css"),g(t,e.attrs),h(e,t),t}function g(e,t){Object.keys(t).forEach(function(n){e.setAttribute(n,t[n])})}function v(e,t){var n,o,r,i;if(t.transform&&e.css){if(!(i=t.transform(e.css)))return function(){};e.css=i}if(t.singleton){var a=u++;n=l||(l=y(t)),o=k.bind(null,n,a,!1),r=k.bind(null,n,a,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(e){var t=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",g(t,e.attrs),h(e,t),t}(t),o=function(e,t,n){var o=n.css,r=n.sourceMap,i=void 0===t.convertToAbsoluteUrls&&r;(t.convertToAbsoluteUrls||i)&&(o=d(o));r&&(o+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(r))))+" */");var a=new Blob([o],{type:"text/css"}),s=e.href;e.href=URL.createObjectURL(a),s&&URL.revokeObjectURL(s)}.bind(null,n,t),r=function(){m(n),n.href&&URL.revokeObjectURL(n.href)}):(n=y(t),o=function(e,t){var n=t.css,o=t.media;o&&e.setAttribute("media",o);if(e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}.bind(null,n),r=function(){m(n)});return o(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;o(e=t)}else r()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||"boolean"==typeof t.singleton||(t.singleton=a()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=f(e,t);return p(n,t),function(e){for(var o=[],r=0;rn.props.end.x?(e=n.calcSCoordinates(),"M"+n.props.start.x+" "+n.props.start.y+" "+e.cpt1.x+" "+e.cpt1.y+" "+e.cpt2.x+" "+e.cpt2.y+" "+e.cpt3.x+" "+e.cpt3.y+" "+e.cpt4.x+" "+e.cpt4.y+" "+n.props.end.x+" "+n.props.end.y):(e=n.calcNormCoordinates(),"M"+n.props.start.x+" "+n.props.start.y+" "+e.cpt1.x+" "+e.cpt1.y+" "+e.cpt2.x+" "+e.cpt2.y+" "+n.props.end.x+" "+n.props.end.y)},n.onSelect=function(e){n.props.onSelectItem&&n.props.onSelectItem(n.props.item)},n}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,r.Component),o(t,[{key:"render",value:function(){var e=this.props.isSelected?a.default.values.links.selectedColor:a.default.values.links.color;return i.default.createElement("g",{className:"timeline-link"},i.default.createElement("path",{pointerEvents:"stroke",onMouseDown:this.onSelect,stroke:"white",d:this.getPath(),strokeLinejoin:"round",fill:"transparent",strokeWidth:"4",cursor:"pointer"}),i.default.createElement("path",{pointerEvents:"stroke",onMouseDown:this.onSelect,stroke:e,d:this.getPath(),strokeLinejoin:"round",fill:"transparent",strokeWidth:"1",cursor:"pointer",markerEnd:"url(#arrow)"}))}}]),t}();t.default=u},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=Object.assign||function(e){for(var t=1;t=t.length?t.length:r+e}},n.setStartEnd=function(){n.dc.setStartEnd(n.state.scrollLeft,n.state.scrollLeft+n.state.size.width,n.state.nowposition,n.state.dayWidth)},n.horizontalChange=function(e){var t=n.state.nowposition,o=-1,r=n.state.headerData,i=n.state.startRow,a=n.state.endRow;e>n.pxToScroll?(t=n.state.nowposition-n.pxToScroll,o=0):e<=0?(t=n.state.nowposition+n.pxToScroll,o=n.pxToScroll):o=e;var s=Math.trunc((e-n.state.nowposition)/n.state.dayWidth);a=(i=Math.trunc(n.state.scrollTop/n.props.itemheight))+n.state.numVisibleRows>=n.props.data.length?n.props.data.length-1:i+n.state.numVisibleRows,n.setStartEnd(),n.setState(n.state={currentday:s,nowposition:t,headerData:r,scrollLeft:o,startRow:i,endRow:a})},n.calculateVerticalScrollVariables=function(e){n.pxToScroll=(1-e.width/h.DATA_CONTAINER_WIDTH)*h.DATA_CONTAINER_WIDTH-1},n.onHorizonChange=function(e,t){n.props.onHorizonChange&&n.props.onHorizonChange(e,t)},n.doMouseDown=function(e){n.dragging=!0,n.draggingPosition=e.clientX},n.doMouseMove=function(e){if(n.dragging){var t=n.draggingPosition-e.clientX;0!==t&&(n.draggingPosition=e.clientX,n.horizontalChange(n.state.scrollLeft+t))}},n.doMouseUp=function(e){n.dragging=!1},n.doMouseLeave=function(e){n.dragging=!1},n.doTouchStart=function(e){n.dragging=!0,n.draggingPosition=e.touches[0].clientX},n.doTouchEnd=function(e){n.dragging=!1},n.doTouchMove=function(e){if(n.dragging){var t=n.draggingPosition-e.touches[0].clientX;0!==t&&(n.draggingPosition=e.touches[0].clientX,n.horizontalChange(n.state.scrollLeft+t))}},n.doTouchCancel=function(e){n.dragging=!1},n.doMouseLeave=function(e){n.dragging=!1},n.onTaskListSizing=function(e){n.setState(function(t){var n=o({},t);return n.sideStyle={width:n.sideStyle.width-e},n})},n.onSelectItem=function(e){n.props.onSelectItem&&e!=n.props.selectedItem&&n.props.onSelectItem(e)},n.onStartCreateLink=function(e,t){n.setState({interactiveMode:!0,taskToCreate:{task:e,position:t}})},n.onFinishCreateLink=function(e,t){n.props.onCreateLink&&e&&n.props.onCreateLink({start:n.state.taskToCreate,end:{task:e,position:t}}),n.setState({interactiveMode:!1,taskToCreate:null})},n.onTaskChanging=function(e){n.setState({changingTask:e})},n.calcNumVisibleDays=function(e){return Math.ceil(e.width/n.state.dayWidth)+h.BUFFER_DAYS},n.checkNeeeData=function(){if(n.props.data!=n.state.data){n.state.data=n.props.data;var e=n.calculateStartEndRows(n.state.numVisibleRows,n.props.data,n.state.scrollTop);n.state.startRow=e.start,n.state.endRow=e.end,f.default.registerData(n.state.data)}n.props.links!=n.state.links&&(n.state.links=n.props.links,f.default.registerLinks(n.props.links))},n.dragging=!1,n.draggingPosition=0,n.dc=new m.default,n.dc.onHorizonChange=n.onHorizonChange,n.initialise=!1,n.pxToScroll=1900;var r=n.getDayWidth(n.props.mode);return y.default.load(n.props.config),n.state={currentday:0,nowposition:0,startRow:0,endRow:10,sideStyle:{width:200},scrollLeft:0,scrollTop:0,numVisibleRows:40,numVisibleDays:60,dayWidth:r,interactiveMode:!1,taskToCreate:null,links:[],mode:n.props.mode?n.props.mode:h.VIEW_MODE_MONTH,size:{width:1,height:1},changingTask:null},n}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,i.Component),r(t,[{key:"getDayWidth",value:function(e){switch(e){case h.VIEW_MODE_DAY:return h.DAY_DAY_MODE;case h.VIEW_MODE_WEEK:return h.DAY_WEEK_MODE;case h.VIEW_MODE_MONTH:return h.DAY_MONTH_MODE;case h.VIEW_MODE_YEAR:return h.DAY_YEAR_MODE;default:return h.DAY_MONTH_MODE}}},{key:"checkMode",value:function(){if(this.props.mode!=this.state.mode&&this.props.mode){this.state.mode=this.props.mode;var e=this.getDayWidth(this.state.mode);this.state.dayWidth=e,this.state.numVisibleDays=this.calcNumVisibleDays(this.state.size);var t=Math.ceil(-this.state.currentday*this.state.dayWidth/this.pxToScroll);this.state.nowposition=t*this.pxToScroll;var n=(this.state.currentday*this.state.dayWidth+this.state.nowposition)%this.pxToScroll;this.state.scrollLeft=n}}},{key:"render",value:function(){var e,t=this;return this.checkMode(),this.checkNeeeData(),a.default.createElement("div",{className:"timeLine"},a.default.createElement("div",{className:"timeLine-side-main",style:this.state.sideStyle},a.default.createElement(p.default,{ref:function(e){return t.taskViewPort=e},itemheight:this.props.itemheight,startRow:this.state.startRow,endRow:this.state.endRow,data:this.props.data,selectedItem:this.props.selectedItem,onSelectItem:this.onSelectItem,onUpdateTask:this.props.onUpdateTask,onScroll:this.verticalChange}),a.default.createElement(l.default,{onTaskListSizing:this.onTaskListSizing})),a.default.createElement("div",{className:"timeLine-main"},a.default.createElement(u.default,{headerData:this.state.headerData,numVisibleDays:this.state.numVisibleDays,currentday:this.state.currentday,nowposition:this.state.nowposition,dayWidth:this.state.dayWidth,mode:this.state.mode,scrollLeft:this.state.scrollLeft}),a.default.createElement(c.default,{ref:function(e){return t.taskViedataViewPortwPort=e},scrollLeft:this.state.scrollLeft,scrollTop:this.state.scrollTop,itemheight:this.props.itemheight,nowposition:this.state.nowposition,startRow:this.state.startRow,endRow:this.state.endRow,data:this.props.data,selectedItem:this.props.selectedItem,dayWidth:this.state.dayWidth,onScroll:this.scrollData,onMouseDown:this.doMouseDown,onMouseMove:this.doMouseMove,onMouseUp:this.doMouseUp,onMouseLeave:this.doMouseLeave,onTouchStart:this.doTouchStart,onTouchMove:this.doTouchMove,onTouchEnd:this.doTouchEnd,onTouchCancel:this.doTouchCancel,onSelectItem:this.onSelectItem,onUpdateTask:this.props.onUpdateTask,onTaskChanging:this.onTaskChanging,onStartCreateLink:this.onStartCreateLink,onFinishCreateLink:this.onFinishCreateLink,boundaries:{lower:this.state.scrollLeft,upper:this.state.scrollLeft+this.state.size.width},onSize:this.onSize}),a.default.createElement(d.default,(v(e={scrollLeft:this.state.scrollLeft,scrollTop:this.state.scrollTop,startRow:this.state.startRow,endRow:this.state.endRow,data:this.props.data,nowposition:this.state.nowposition,dayWidth:this.state.dayWidth,interactiveMode:this.state.interactiveMode,taskToCreate:this.state.taskToCreate,onFinishCreateLink:this.onFinishCreateLink,changingTask:this.state.changingTask,selectedItem:this.props.selectedItem,onSelectItem:this.onSelectItem,itemheight:this.props.itemheight},"onSelectItem",this.onSelectItem),v(e,"links",this.props.links),e))))}}]),t}();b.propTypes={itemheight:s.default.number.isRequired,dayWidth:s.default.number.isRequired},b.defaultProps={itemheight:20,dayWidth:24},t.default=b},function(e,t,n){e.exports=n(10)()},function(e,t,n){"use strict";var o=n(11);function r(){}e.exports=function(){function e(e,t,n,r,i,a){if(a!==o){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return n.checkPropTypes=r,n.PropTypes=n,n}},function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;nn.end},n.setBoundaries(),n}return h(t,i.PureComponent),r(t,[{key:"getFormat",value:function(e,t){switch(e){case"year":return"YYYY";case"month":return"top"==t?"MMMM YYYY":"MMMM";case"week":return"top"==t?"ww MMMM YYYY":"ww";case"dayweek":return"dd";case"daymonth":return"D"}}},{key:"getModeIncrement",value:function(e,t){switch(t){case"year":return c.default.daysInYear(e.year());case"month":return e.daysInMonth();case"week":return 7;default:return 1}}},{key:"getBox",value:function(e,t,n){var o=this.getModeIncrement(e,t)*this.props.dayWidth;if(!n){var r=this.getStartDate(e,t);r=r.startOf("day");var i=(0,s.default)().startOf("day"),a=r.diff(i,"days");n=c.default.dayToPosition(a,this.props.nowposition,this.props.dayWidth)}return{left:n,width:o}}},{key:"render",value:function(){var e=this;return this.Header&&(this.Header.scrollLeft=this.props.scrollLeft),a.default.createElement("div",{id:"timeline-header",ref:function(t){return e.Header=t},className:"timeLine-main-header-viewPort"},this.renderHeader())}}]),t}();t.default=y},function(e,n){e.exports=t},function(e,t,n){var o=n(16);"string"==typeof o&&(o=[[e.i,o,""]]);var r={hmr:!0,transform:void 0,insertInto:void 0};n(5)(o,r);o.locals&&(e.exports=o.locals)},function(e,t,n){(e.exports=n(4)(!1)).push([e.i,".header-top{\n height: 20px;\n\n border-bottom: solid 0.5px silver;\n}\n\n.header-middle{\n height: 20px;\n background-color: chocolate;\n color: white;\n font-size:10px;\n border-bottom: solid 0.5px silver;\n \n}\n.header-bottom{\n height: 20px;\n font-size:10px;\n border-bottom: solid 0.5px silver;\n}\n",""])},function(e,t){e.exports=function(e){var t="undefined"!=typeof window&&window.location;if(!t)throw new Error("fixUrls requires window.location");if(!e||"string"!=typeof e)return e;var n=t.protocol+"//"+t.host,o=n+t.pathname.replace(/\/[^\/]*$/,"/");return e.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi,function(e,t){var r,i=t.trim().replace(/^"(.*)"$/,function(e,t){return t}).replace(/^'(.*)'$/,function(e,t){return t});return/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(i)?e:(r=0===i.indexOf("//")?i:0===i.indexOf("/")?n+i:o+i.replace(/^\.\//,""),"url("+JSON.stringify(r)+")")})}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.DataViewPort=t.DataRow=void 0;var o=Object.assign||function(e){for(var t=1;t0?e*this.props.itemheight:10}},{key:"componentDidMount",value:function(){this.dataViewPort.scrollLeft=0}},{key:"render",value:function(){var e=this;this.dataViewPort&&(this.dataViewPort.scrollLeft=this.props.scrollLeft,this.dataViewPort.scrollTop=this.props.scrollTop);var t=this.getContainerHeight(this.props.data.length);return a.default.createElement("div",{ref:function(t){return e.dataViewPort=t},id:"timeLinedataViewPort",className:"timeLine-main-data-viewPort",onMouseDown:this.doMouseDown,onMouseMove:this.doMouseMove,onMouseUp:this.props.onMouseUp,onMouseLeave:this.props.onMouseLeave,onTouchStart:this.doTouchStart,onTouchMove:this.doTouchMove,onTouchEnd:this.props.onTouchEnd,onTouchCancel:this.props.onTouchCancel},a.default.createElement("div",{className:"timeLine-main-data-container",style:{height:t,width:s.DATA_CONTAINER_WIDTH,maxWidth:s.DATA_CONTAINER_WIDTH}},this.renderRows()))}}]),t}();t.default=(0,c.default)({monitorWidth:!0,monitorHeight:!0})(g)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=Object.assign||function(e){for(var t=1;t0?e*this.props.itemheight:10}}},{key:"renderTaskRow",value:function(e){for(var t=[],n=this.props.startRow;nt.upper_data_limit},this.setLimits=function(e,n){t.lower_limit=e-1e3,t.lower_data_limit=e-750,t.upper_limit=n+1e3,t.upper_data_limit=n+750},this.loadDataHorizon=function(){var e=i.default.pixelToDate(t.lower_limit,t.nowposition,t.daywidth),n=i.default.pixelToDate(t.upper_limit,t.nowposition,t.daywidth);t.onHorizonChange(e,n)},this.lower_limit=0,this.upper_limit=0,this._dataToRender=[]}},function(e,t,n){var o=n(27);"string"==typeof o&&(o=[[e.i,o,""]]);var r={hmr:!0,transform:void 0,insertInto:void 0};n(5)(o,r);o.locals&&(e.exports=o.locals)},function(e,t,n){(e.exports=n(4)(!1)).push([e.i,".timeLine{\n display: flex;\n flex-direction: row;\n width:100%;\n height: 100%;\n border:solid 1px rgb(207, 207, 205);\n font-size: 12px;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n}\n\n/* Main Area */\n\n.timeLine-main{\n flex: 1 1 100%;\n position: relative;\n display: flex;\n flex-direction: column;\n overflow-y: hidden;\n}\n/* Main Area Header*/\n\n.timeLine-main-header-viewPort{\n flex: 0 0 60px;\n position: relative;\n height: 60px ;\n width: 100%;\n background-color: rgb(112, 112, 112);\n overflow: hidden;\n \n}\n\n.timeLine-main-header-container{\n flex: 0 0 60px;\n position: relative;\n top:0;\n left:0;\n height: 100% ;\n display:flex;\n flex-direction: column;\n background-color: #333333;\n overflow: hidden;\n user-select: none;\n}\n\n.timeLine-main-header-day-item{\n position: absolute;\n display: flex;\n flex-direction: column;\n justify-content: center;\n background-color:rgb(112, 112, 112);\n font-size: 10px;\n text-align: center;\n border-right:solid 1px;\n border-top:solid 1px;\n border-bottom:solid 1px;\n top:20px;\n height:40px;\n color: white;\n text-align: center;\n}\n\n\n.timeLine-main-header-top-item{\n position: absolute;\n display: flex;\n flex-direction: column;\n justify-content: center;\n border-right:solid 1px white;\n height:20px;\n z-index: 91;\n}\n\n.timeLine-main-header-day-week{\n flex:0 0 12px;\n padding: 4px;\n z-index: 90;\n}\n\n.timeLine-main-header-day-month{\n top:0px;\n position: sticky;\n flex:0 0 15px;\n padding: 5px;\n z-index: 90;\n}\n\n.timeLine-main-header-time{\n display: flex;\n flex-direction: row;\n align-items: stretch;\n height: 22px;\n justify-content: stretch;\n}\n\n.timeLine-main-header-time-item{\n border-left: solid 1px silver;\n border-bottom: solid 1px silver;\n border-top: solid 1px silver;\n text-align: center;\n padding-top: 5px;\n}\n/* Main Area Data*/\n\n.timeLine-main-data-viewPort{\n flex: 1 1 auto;\n position: relative;\n overflow: hidden;\n background-color:#fbf9f9;;\n \n \n}\n.timeLine-main-data-container{\n position: relative;\n top:0;\n left:0;\n height: 100% ;\n background-color: rgb(255, 255, 255);\n}\n\n.timeLine-main-data-row{\n position: absolute;\n width: 100%;\n height: 50px;\n \n}\n\n.timeLine-main-data-task{\n position: absolute;\n background-color:darkorchid;\n border-radius: 14px;\n color: white;\n text-align: center;\n}\n\n.timeLine-main-data-task-side{\n position: absolute;\n width: 10px;\n cursor: col-resize;\n display:flex;\n flex-direction: column;\n justify-content: center;\n}\n.timeLine-main-data-task-side-linker{\n width:8px;\n height: 8px;\n border-radius: 4px;\n cursor: default;\n z-index: 100;\n \n}\n.timeLine-main-data-task-side-linker:hover{\n background-color: black;\n border: solid 0.5px grey\n}\n/* .timeLine-main-data-task:hover {\n background-color:chocolate;\n border:solid 2px darkorchid;\n cursor: move;\n} */\n\n\n\n.timeLine-main-data-verticalLine{\n flex:1 1 auto;\n height: 100%;\n width: 24px;\n background-color:white;\n border-left-width: 0.5px;\n border-left-color: rgb(207, 207, 205);\n border-left-style: dashed;\n}\n\n/* Side Area */\n\n.timeLine-side-main{\n flex: 0 0 auto;\n width:108px;\n min-width: 108px;\n display: flex;\n flex-direction: row;\n \n}\n\n.timeLine-side{\n flex: 1 0 100px;\n display: flex;\n flex-direction: column;\n border-right:solid 1px rgb(207, 207, 205);\n}\n\n.verticalResizer{\n flex: 0 0 8px;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n cursor: col-resize;\n border-right:solid 1px rgb(207, 207, 205);\n height: 100%;\n\n}\n.squareGrip{\n flex: 0 0 auto;\n \n border-radius: 50%;\n height: 5px;\n width: 5px;\n margin: 3px 0;\n}\n\n.timeLine-side-title{\n flex: 0 0 60px;\n display: flex;\n justify-content: center;\n align-items: center;\n \n}\n\n.timeLine-side-task-viewPort{\n position: relative;\n flex: 1 1 auto;\n height:100% ;\n background-color:#fbf9f9;\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.timeLine-side-task-container{\n position: relative;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.timeLine-side-task-row{\n position: absolute;\n width: 100%;\n background-color: rgb(112, 112, 112);\n border-bottom-width: 0.5px;\n border-bottom-color: rgb(207, 207, 205);\n border-bottom-style: solid;\n height: 30px;\n color: grey;\n text-align: center;\n overflow: hidden;\n text-overflow: ellipsis; \n outline: none;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n",""])}])}); \ No newline at end of file diff --git a/package.json b/package.json index ceb845e..a6c51d1 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "jest-fetch-mock": "^1.6.4", "jest-junit": "^5.0.0", "json-loader": "^0.5.7", + "merge": ">=1.2.1", "react": "^16.3.2", "react-dom": "^16.3.2", "react-test-renderer": "^16.4.0", @@ -49,8 +50,7 @@ "url-loader": "^1.0.1", "webpack": "^4.20.2", "webpack-cli": "^3.1.1", - "webpack-dev-server": "^3.1.4", - "merge": ">=1.2.1" + "webpack-dev-server": "^3.1.4" }, "author": "Guillermo Quiros", "license": "MIT", @@ -67,8 +67,10 @@ ], "homepage": "https://github.com/guiqui/react-timeline-gantt", "dependencies": { + "moment": "^2.23.0", "opencollective": "^1.0.3", - "opencollective-postinstall": "^2.0.1" + "opencollective-postinstall": "^2.0.1", + "react-sizeme": "^2.5.2" }, "collective": { "type": "opencollective", diff --git a/src/lib/TimeLine.js b/src/lib/TimeLine.js index 212edd7..dd20c7f 100644 --- a/src/lib/TimeLine.js +++ b/src/lib/TimeLine.js @@ -1,426 +1,410 @@ -import React,{Component} from 'react' -import PropTypes from 'prop-types' -import VerticalSpliter from 'libs/components/taskList/VerticalSpliter' -import Header from 'libs/components/header/Headers' -import DataViewPort from 'libs/components/viewport/DataViewPort' -import LinkViewPort from 'libs/components/links/LinkViewPort' -import TaskList from 'libs/components/taskList/TaskList' -import Registry from 'libs/helpers/registry/Registry' -import {BUFFER_DAYS,DATA_CONTAINER_WIDTH} from 'libs/Const' -import {VIEW_MODE_DAY,VIEW_MODE_WEEK,VIEW_MODE_MONTH,VIEW_MODE_YEAR}from 'libs/Const' -import {DAY_MONTH_MODE,DAY_WEEK_MODE,DAY_DAY_MODE,DAY_YEAR_MODE} from 'libs/Const' -import DataController from 'libs/controller/DataController' -import Config from 'libs/helpers/config/Config' -import DateHelper from 'libs/helpers/DateHelper' -import './TimeLine.css' - - - - - - -class TimeLine extends Component{ - constructor(props){ - super(props); - this.dragging=false; - this.draggingPosition=0; - this.dc=new DataController(); - this.dc.onHorizonChange=this.onHorizonChange; - this.initialise=false; - //This variable define the number of pixels the viewport can scroll till arrive to the end of the context - this.pxToScroll=1900; - - let dayWidth=this.getDayWidth(this.props.mode); - Config.load(this.props.config) - //Initialising state - this.state={ - currentday:0,//Day that is in the 0px horizontal - //nowposition is the reference position, this variable support the infinit scrolling by accumulatning scroll times and redefining the 0 position - // if we accumulat 2 scroll to the left nowposition will be 2* DATA_CONTAINER_WIDTH - nowposition:0, - startRow:0,// - endRow:10, - sideStyle:{width:200}, - scrollLeft:0, - scrollTop:0, - numVisibleRows:40, - numVisibleDays:60, - dayWidth:dayWidth, - interactiveMode:false, - taskToCreate:null, - links:[], - mode:this.props.mode?this.props.mode:VIEW_MODE_MONTH, - size:{width:1,height:1}, - changingTask:null - - } +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import VerticalSpliter from 'libs/components/taskList/VerticalSpliter'; +import Header from 'libs/components/header/Headers'; +import DataViewPort from 'libs/components/viewport/DataViewPort'; +import LinkViewPort from 'libs/components/links/LinkViewPort'; +import TaskList from 'libs/components/taskList/TaskList'; +import Registry from 'libs/helpers/registry/Registry'; +import { BUFFER_DAYS, DATA_CONTAINER_WIDTH } from 'libs/Const'; +import { VIEW_MODE_DAY, VIEW_MODE_WEEK, VIEW_MODE_MONTH, VIEW_MODE_YEAR } from 'libs/Const'; +import { DAY_MONTH_MODE, DAY_WEEK_MODE, DAY_DAY_MODE, DAY_YEAR_MODE } from 'libs/Const'; +import DataController from 'libs/controller/DataController'; +import Config from 'libs/helpers/config/Config'; +import DateHelper from 'libs/helpers/DateHelper'; +import './TimeLine.css'; + +class TimeLine extends Component { + constructor(props) { + super(props); + this.dragging = false; + this.draggingPosition = 0; + this.dc = new DataController(); + this.dc.onHorizonChange = this.onHorizonChange; + this.initialise = false; + //This variable define the number of pixels the viewport can scroll till arrive to the end of the context + this.pxToScroll = 1900; + + let dayWidth = this.getDayWidth(this.props.mode); + Config.load(this.props.config); + //Initialising state + this.state = { + currentday: 0, //Day that is in the 0px horizontal + //nowposition is the reference position, this variable support the infinit scrolling by accumulatning scroll times and redefining the 0 position + // if we accumulat 2 scroll to the left nowposition will be 2* DATA_CONTAINER_WIDTH + nowposition: 0, + startRow: 0, // + endRow: 10, + sideStyle: { width: 200 }, + scrollLeft: 0, + scrollTop: 0, + numVisibleRows: 40, + numVisibleDays: 60, + dayWidth: dayWidth, + interactiveMode: false, + taskToCreate: null, + links: [], + mode: this.props.mode ? this.props.mode : VIEW_MODE_MONTH, + size: { width: 1, height: 1 }, + changingTask: null, + }; + } + + //////////////////// + // ON MODE // + //////////////////// + + getDayWidth(mode) { + switch (mode) { + case VIEW_MODE_DAY: + return DAY_DAY_MODE; + case VIEW_MODE_WEEK: + return DAY_WEEK_MODE; + case VIEW_MODE_MONTH: + return DAY_MONTH_MODE; + case VIEW_MODE_YEAR: + return DAY_YEAR_MODE; + default: + return DAY_MONTH_MODE; } - - //////////////////// - // ON MODE // - //////////////////// - - - - - getDayWidth(mode){ - switch(mode){ - - case VIEW_MODE_DAY: - return DAY_DAY_MODE; - case VIEW_MODE_WEEK: - return DAY_WEEK_MODE; - case VIEW_MODE_MONTH: - return DAY_MONTH_MODE; - case VIEW_MODE_YEAR: - return DAY_YEAR_MODE; - default: - return DAY_MONTH_MODE; - } + } + + //////////////////// + // ON SIZE // + //////////////////// + + onSize = size => { + //If size has changed + this.calculateVerticalScrollVariables(size); + if (!this.initialise) { + this.dc.initialise( + this.state.scrollLeft + this.state.nowposition, + this.state.scrollLeft + this.state.nowposition + size.width, + this.state.nowposition, + this.state.dayWidth + ); + this.initialise = true; } + this.setStartEnd(); + let newNumVisibleRows = Math.ceil(size.height / this.props.itemheight); + let newNumVisibleDays = this.calcNumVisibleDays(size); + let rowInfo = this.calculateStartEndRows(newNumVisibleRows, this.props.data, this.state.scrollTop); + this.setState({ + numVisibleRows: newNumVisibleRows, + numVisibleDays: newNumVisibleDays, + startRow: rowInfo.start, + endRow: rowInfo.end, + size: size, + }); + }; - - //////////////////// - // ON SIZE // - //////////////////// - - - onSize = size => { - //If size has changed - this.calculateVerticalScrollVariables(size); - if (!this.initialise){ - this.dc.initialise(this.state.scrollLeft+this.state.nowposition, - this.state.scrollLeft+this.state.nowposition+size.width, - this.state.nowposition,this.state.dayWidth - ) - this.initialise=true; - - } - this.setStartEnd(); - let newNumVisibleRows=Math.ceil(size.height / this.props.itemheight); - let newNumVisibleDays=this.calcNumVisibleDays(size) - let rowInfo=this.calculateStartEndRows(newNumVisibleRows,this.props.data,this.state.scrollTop); - this.setState({ - numVisibleRows:newNumVisibleRows, - numVisibleDays:newNumVisibleDays, - startRow:rowInfo.start, - endRow:rowInfo.end, - size:size + ///////////////////////// + // VIEWPORT CHANGES // + ///////////////////////// + + verticalChange = scrollTop => { + if (scrollTop == this.state.scrollTop) return; + //Check if we have scrolling rows + let rowInfo = this.calculateStartEndRows(this.state.numVisibleRows, this.props.data, scrollTop); + if (rowInfo.start !== this.state.start) { + this.setState( + (this.state = { + scrollTop: scrollTop, + startRow: rowInfo.start, + endRow: rowInfo.end, }) + ); } - - ///////////////////////// - // VIEWPORT CHANGES // - ///////////////////////// - - verticalChange=(scrollTop)=>{ - if (scrollTop==this.state.scrollTop) - return; - //Check if we have scrolling rows - let rowInfo=this.calculateStartEndRows(this.state.numVisibleRows,this.props.data,scrollTop); - if (rowInfo.start!==this.state.start){ - this.setState( - this.state={ - scrollTop:scrollTop, - startRow:rowInfo.start, - endRow:rowInfo.end, - }) - } - } - - calculateStartEndRows=(numVisibleRows,data,scrollTop)=>{ - let new_start=Math.trunc(scrollTop/this.props.itemheight) - let new_end =new_start+numVisibleRows>=data.length?data.length:new_start+numVisibleRows; - return {start:new_start,end:new_end} - } + }; - - setStartEnd=()=>{ - this.dc.setStartEnd(this.state.scrollLeft, - this.state.scrollLeft+this.state.size.width, - this.state.nowposition, - this.state.dayWidth) - } + calculateStartEndRows = (numVisibleRows, data, scrollTop) => { + let new_start = Math.trunc(scrollTop / this.props.itemheight); + let new_end = new_start + numVisibleRows >= data.length ? data.length : new_start + numVisibleRows; + return { start: new_start, end: new_end }; + }; + setStartEnd = () => { + this.dc.setStartEnd( + this.state.scrollLeft, + this.state.scrollLeft + this.state.size.width, + this.state.nowposition, + this.state.dayWidth + ); + }; - horizontalChange=(newScrollLeft)=>{ - let new_nowposition=this.state.nowposition; - let new_left=-1; - let headerData=this.state.headerData; - let new_startRow=this.state.startRow; - let new_endRow=this.state.endRow; - - //Calculating if we need to roll up the scroll - if (newScrollLeft>this.pxToScroll){//ContenLegnth-viewportLengt - new_nowposition=this.state.nowposition-this.pxToScroll - new_left=0; - } else{ - if (newScrollLeft<=0){//ContenLegnth-viewportLengt - new_nowposition=this.state.nowposition+this.pxToScroll - new_left=this.pxToScroll; - }else{ - new_left=newScrollLeft; - } - } - - //Get the day of the left position - let currentIndx=Math.trunc((newScrollLeft-this.state.nowposition) /this.state.dayWidth) - - - //Calculate rows to render - new_startRow=Math.trunc(this.state.scrollTop/this.props.itemheight) - new_endRow =new_startRow+this.state.numVisibleRows>=this.props.data.length?this.props.data.length-1:new_startRow+this.state.numVisibleRows; - //If we need updates then change the state and the scroll position - //Got you - this.setStartEnd(); - this.setState( - this.state={ - currentday:currentIndx, - nowposition:new_nowposition, - headerData:headerData, - scrollLeft: new_left, - startRow:new_startRow, - endRow:new_endRow, - }) - + horizontalChange = newScrollLeft => { + let new_nowposition = this.state.nowposition; + let new_left = -1; + let headerData = this.state.headerData; + let new_startRow = this.state.startRow; + let new_endRow = this.state.endRow; + + //Calculating if we need to roll up the scroll + if (newScrollLeft > this.pxToScroll) { + //ContenLegnth-viewportLengt + new_nowposition = this.state.nowposition - this.pxToScroll; + new_left = 0; + } else { + if (newScrollLeft <= 0) { + //ContenLegnth-viewportLengt + new_nowposition = this.state.nowposition + this.pxToScroll; + new_left = this.pxToScroll; + } else { + new_left = newScrollLeft; + } } + //Get the day of the left position + let currentIndx = Math.trunc((newScrollLeft - this.state.nowposition) / this.state.dayWidth); + + //Calculate rows to render + new_startRow = Math.trunc(this.state.scrollTop / this.props.itemheight); + new_endRow = + new_startRow + this.state.numVisibleRows >= this.props.data.length + ? this.props.data.length - 1 + : new_startRow + this.state.numVisibleRows; + //If we need updates then change the state and the scroll position + //Got you + this.setStartEnd(); + this.setState( + (this.state = { + currentday: currentIndx, + nowposition: new_nowposition, + headerData: headerData, + scrollLeft: new_left, + startRow: new_startRow, + endRow: new_endRow, + }) + ); + }; - + calculateVerticalScrollVariables = size => { + //The pixel to scroll verically is equal to the pecentage of what the viewport represent in the context multiply by the context width + this.pxToScroll = (1 - size.width / DATA_CONTAINER_WIDTH) * DATA_CONTAINER_WIDTH - 1; + }; - calculateVerticalScrollVariables=(size)=>{ - //The pixel to scroll verically is equal to the pecentage of what the viewport represent in the context multiply by the context width - this.pxToScroll=(1-(size.width/DATA_CONTAINER_WIDTH)) * DATA_CONTAINER_WIDTH -1; - } + onHorizonChange = (lowerLimit, upLimit) => { + if (this.props.onHorizonChange) this.props.onHorizonChange(lowerLimit, upLimit); + }; - onHorizonChange=(lowerLimit,upLimit)=>{ - if (this.props.onHorizonChange) - this.props.onHorizonChange(lowerLimit,upLimit) - } - - ///////////////////// - // MOUSE EVENTS // - ///////////////////// - - doMouseDown=(e)=>{ - this.dragging=true; - this.draggingPosition=e.clientX; - } - doMouseMove=(e)=>{ - if(this.dragging){ - let delta=this.draggingPosition-e.clientX; - - if (delta!==0){ - this.draggingPosition=e.clientX; - this.horizontalChange(this.state.scrollLeft+delta); - } - } - } - doMouseUp=(e)=>{ - this.dragging=false; - } - doMouseLeave=(e)=>{ - // if (!e.relatedTarget.nodeName) - // this.dragging=false; - this.dragging=false; - } - - doTouchStart=(e)=>{ - this.dragging=true; - this.draggingPosition=e.touches[0].clientX; - } - doTouchEnd=(e)=>{ - this.dragging=false; - } - doTouchMove=(e)=>{ - if(this.dragging){ - let delta=this.draggingPosition-e.touches[0].clientX; - - if (delta!==0){ - this.draggingPosition=e.touches[0].clientX; - this.horizontalChange(this.state.scrollLeft+delta); - } - } - } - doTouchCancel=(e)=>{ - this.dragging=false; - } + ///////////////////// + // MOUSE EVENTS // + ///////////////////// - doMouseLeave=(e)=>{ - // if (!e.relatedTarget.nodeName) - // this.dragging=false; - this.dragging=false; + doMouseDown = e => { + this.dragging = true; + this.draggingPosition = e.clientX; + }; + doMouseMove = e => { + if (this.dragging) { + let delta = this.draggingPosition - e.clientX; + + if (delta !== 0) { + this.draggingPosition = e.clientX; + this.horizontalChange(this.state.scrollLeft + delta); + } } + }; + doMouseUp = e => { + this.dragging = false; + }; + doMouseLeave = e => { + // if (!e.relatedTarget.nodeName) + // this.dragging=false; + this.dragging = false; + }; - //Child communicating states - onTaskListSizing=(delta)=>{ - this.setState((prevState) => { - let result={...prevState}; - result.sideStyle={width:result.sideStyle.width-delta}; - return result; - }) + doTouchStart = e => { + this.dragging = true; + this.draggingPosition = e.touches[0].clientX; + }; + doTouchEnd = e => { + this.dragging = false; + }; + doTouchMove = e => { + if (this.dragging) { + let delta = this.draggingPosition - e.touches[0].clientX; + + if (delta !== 0) { + this.draggingPosition = e.touches[0].clientX; + this.horizontalChange(this.state.scrollLeft + delta); + } } + }; + doTouchCancel = e => { + this.dragging = false; + }; - ///////////////////// - // ITEMS EVENTS // - ///////////////////// - - onSelectItem=(item)=>{ - if (this.props.onSelectItem && item!=this.props.selectedItem) - this.props.onSelectItem(item) - } + doMouseLeave = e => { + // if (!e.relatedTarget.nodeName) + // this.dragging=false; + this.dragging = false; + }; - - onStartCreateLink=(task,position)=>{ - console.log(`Start Link ${task}`) - this.setState({ - interactiveMode:true, - taskToCreate:{task:task,position:position} - }) - - } + //Child communicating states + onTaskListSizing = delta => { + this.setState(prevState => { + let result = { ...prevState }; + result.sideStyle = { width: result.sideStyle.width - delta }; + return result; + }); + }; - - onFinishCreateLink=(task,position)=>{ - console.log(`End Link ${task}`) - if (this.props.onCreateLink && task){ - this.props.onCreateLink({start:this.state.taskToCreate,end:{task:task,position:position}}) - } - this.setState({ - interactiveMode:false, - taskToCreate:null - }) + ///////////////////// + // ITEMS EVENTS // + ///////////////////// - - } + onSelectItem = item => { + if (this.props.onSelectItem && item != this.props.selectedItem) this.props.onSelectItem(item); + }; - onTaskChanging=(changingTask)=>{ - this.setState({ - changingTask:changingTask - }) + onStartCreateLink = (task, position) => { + console.log(`Start Link ${task}`); + this.setState({ + interactiveMode: true, + taskToCreate: { task: task, position: position }, + }); + }; + onFinishCreateLink = (task, position) => { + console.log(`End Link ${task}`); + if (this.props.onCreateLink && task) { + this.props.onCreateLink({ start: this.state.taskToCreate, end: { task: task, position: position } }); } + this.setState({ + interactiveMode: false, + taskToCreate: null, + }); + }; - calcNumVisibleDays=(size)=>{ - return Math.ceil(size.width / this.state.dayWidth)+BUFFER_DAYS - } - checkMode(){ - if(this.props.mode!=this.state.mode && this.props.mode){ - this.state.mode=this.props.mode - let newDayWidth=this.getDayWidth(this.state.mode); - this.state.dayWidth=newDayWidth; - this.state.numVisibleDays=this.calcNumVisibleDays(this.state.size) - //to recalculate the now position we have to see how mwny scroll has happen - //to do so we calculate the diff of days between current day and now - //And we calculate how many times we have scroll - let scrollTime=Math.ceil(-this.state.currentday*this.state.dayWidth/this.pxToScroll) - //We readjust now postion to the new number of scrolls - this.state.nowposition=scrollTime*this.pxToScroll; - let scrollLeft=(this.state.currentday*this.state.dayWidth+this.state.nowposition)%this.pxToScroll - // we recalculate the new scroll Left value - this.state.scrollLeft=scrollLeft; - } + onTaskChanging = changingTask => { + this.setState({ + changingTask: changingTask, + }); + }; + + calcNumVisibleDays = size => { + return Math.ceil(size.width / this.state.dayWidth) + BUFFER_DAYS; + }; + checkMode() { + if (this.props.mode != this.state.mode && this.props.mode) { + this.state.mode = this.props.mode; + let newDayWidth = this.getDayWidth(this.state.mode); + this.state.dayWidth = newDayWidth; + this.state.numVisibleDays = this.calcNumVisibleDays(this.state.size); + //to recalculate the now position we have to see how mwny scroll has happen + //to do so we calculate the diff of days between current day and now + //And we calculate how many times we have scroll + let scrollTime = Math.ceil((-this.state.currentday * this.state.dayWidth) / this.pxToScroll); + //We readjust now postion to the new number of scrolls + this.state.nowposition = scrollTime * this.pxToScroll; + let scrollLeft = (this.state.currentday * this.state.dayWidth + this.state.nowposition) % this.pxToScroll; + // we recalculate the new scroll Left value + this.state.scrollLeft = scrollLeft; } - checkNeeeData=()=>{ - if (this.props.data!=this.state.data){ - this.state.data=this.props.data; - let rowInfo=this.calculateStartEndRows(this.state.numVisibleRows,this.props.data,this.state.scrollTop); - this.state.startRow=rowInfo.start; - this.state.endRow=rowInfo.end; - Registry.registerData(this.state.data) - } - if (this.props.links!=this.state.links){ - this.state.links=this.props.links; - Registry.registerLinks(this.props.links) - } - + } + checkNeeeData = () => { + if (this.props.data != this.state.data) { + this.state.data = this.props.data; + let rowInfo = this.calculateStartEndRows(this.state.numVisibleRows, this.props.data, this.state.scrollTop); + this.state.startRow = rowInfo.start; + this.state.endRow = rowInfo.end; + Registry.registerData(this.state.data); } - render(){ - this.checkMode(); - this.checkNeeeData(); - return ( -
-
- - -
-
-
- - -
-
) + if (this.props.links != this.state.links) { + this.state.links = this.props.links; + Registry.registerLinks(this.props.links); } - + }; + render() { + this.checkMode(); + this.checkNeeeData(); + return ( +
+
+ (this.taskViewPort = ref)} + itemheight={this.props.itemheight} + startRow={this.state.startRow} + endRow={this.state.endRow} + data={this.props.data} + selectedItem={this.props.selectedItem} + onSelectItem={this.onSelectItem} + onUpdateTask={this.props.onUpdateTask} + onScroll={this.verticalChange} + /> + +
+
+
+ (this.taskViedataViewPortwPort = ref)} + scrollLeft={this.state.scrollLeft} + scrollTop={this.state.scrollTop} + itemheight={this.props.itemheight} + nowposition={this.state.nowposition} + startRow={this.state.startRow} + endRow={this.state.endRow} + data={this.props.data} + selectedItem={this.props.selectedItem} + dayWidth={this.state.dayWidth} + onScroll={this.scrollData} + onMouseDown={this.doMouseDown} + onMouseMove={this.doMouseMove} + onMouseUp={this.doMouseUp} + onMouseLeave={this.doMouseLeave} + onTouchStart={this.doTouchStart} + onTouchMove={this.doTouchMove} + onTouchEnd={this.doTouchEnd} + onTouchCancel={this.doTouchCancel} + onSelectItem={this.onSelectItem} + onUpdateTask={this.props.onUpdateTask} + onTaskChanging={this.onTaskChanging} + onStartCreateLink={this.onStartCreateLink} + onFinishCreateLink={this.onFinishCreateLink} + boundaries={{ lower: this.state.scrollLeft, upper: this.state.scrollLeft + this.state.size.width }} + onSize={this.onSize} + /> + +
+
+ ); + } } TimeLine.propTypes = { - itemheight: PropTypes.number.isRequired, - dayWidth:PropTypes.number.isRequired - }; + itemheight: PropTypes.number.isRequired, + dayWidth: PropTypes.number.isRequired, +}; TimeLine.defaultProps = { - itemheight:20, - dayWidth:24 - }; - - + itemheight: 20, + dayWidth: 24, +}; -export default TimeLine \ No newline at end of file +export default TimeLine; diff --git a/src/lib/components/common/ContentEditable.js b/src/lib/components/common/ContentEditable.js index 8b6d5ca..a7fd060 100644 --- a/src/lib/components/common/ContentEditable.js +++ b/src/lib/components/common/ContentEditable.js @@ -1,73 +1,77 @@ -import React,{Component} from 'react' -export default class ContentEditable extends Component{ - constructor(props){ - super(props) - this.isFocus=false; - this.state={ - editing:false, - value:this.props.value, - } - } +import React, { Component } from 'react'; +export default class ContentEditable extends Component { + constructor(props) { + super(props); + this.isFocus = false; + this.state = { + editing: false, + value: this.props.value, + }; + } - componentDidUpdate(prevProps, prevState) { - if (this.refs.textInput && !this.isFocus){ - this.refs.textInput.focus(); - this.isFocus=true; - } + componentDidUpdate(prevProps, prevState) { + if (this.textInput && !this.isFocus) { + this.textInput.focus(); + this.isFocus = true; } + } - onFocus=()=>{ - this.setState({editing:true}) - } - - onBlur=()=>{ - this.finishEditing() - } - - handleKey=(e)=>{ - const keyCode = e.keyCode || e.which; - if (keyCode === 13) { - this.finishEditing() - } - } + onFocus = () => { + this.setState({ editing: true }); + }; - finishEditing=()=>{ - this.isFocus=false; - this.setState({editing:false}) - if(this.props.onChange) - this.props.onChange(this.state.value) - } + onBlur = () => { + this.finishEditing(); + }; - handleChange=(e)=> { - this.setState({value: e.target.value}); + handleKey = e => { + const keyCode = e.keyCode || e.which; + if (keyCode === 13) { + this.finishEditing(); } + }; - renderDiv=()=>{ - return
{this.state.value}
- } - shouldComponentUpdate(nextProps, nextState){ - if (nextProps.value!=this.props.value){ - this.state.value=nextProps.value; - } - return true; - } + finishEditing = () => { + this.isFocus = false; + this.setState({ editing: false }); + if (this.props.onChange) this.props.onChange(this.state.value); + }; - renderEditor=()=>{ + handleChange = e => { + this.setState({ value: e.target.value }); + }; - return + renderDiv = () => { + return ( +
+ {' '} + {this.state.value} +
+ ); + }; + shouldComponentUpdate(nextProps, nextState) { + if (nextProps.value != this.props.value) { + this.state.value = nextProps.value; } + return true; + } - render(){ - return this.state.editing?this.renderEditor():this.renderDiv(); + renderEditor = () => { + return ( + (this.textInput = ref)} + onBlur={this.onBlur} + style={{ width: '100%', outlineColor: 'black', outlineStyle: 'oinset' }} + type="text" + name="name" + value={this.state.value} + onKeyUp={this.handleKey} + onChange={this.handleChange} + /> + ); + }; - } + render() { + return this.state.editing ? this.renderEditor() : this.renderDiv(); + } } diff --git a/src/lib/components/header/Headers.js b/src/lib/components/header/Headers.js index 97293b3..9233978 100644 --- a/src/lib/components/header/Headers.js +++ b/src/lib/components/header/Headers.js @@ -1,215 +1,206 @@ -import React,{PureComponent} from 'react' -import moment from 'moment' -import {BUFFER_DAYS,DATA_CONTAINER_WIDTH} from 'libs/Const' -import {VIEW_MODE_DAY,VIEW_MODE_WEEK,VIEW_MODE_MONTH,VIEW_MODE_YEAR}from 'libs/Const' -import Config from 'libs/helpers/config/Config' -import DateHelper from 'libs/helpers/DateHelper' -import './Header.css' - - -export class HeaderItem extends PureComponent{ - constructor(props){ - super(props); - - } - render(){ - return ( -
-
- {this.props.label} -
-
) - } +import React, { PureComponent } from 'react'; +import moment from 'moment'; +import { BUFFER_DAYS, DATA_CONTAINER_WIDTH } from 'libs/Const'; +import { VIEW_MODE_DAY, VIEW_MODE_WEEK, VIEW_MODE_MONTH, VIEW_MODE_YEAR } from 'libs/Const'; +import Config from 'libs/helpers/config/Config'; +import DateHelper from 'libs/helpers/DateHelper'; +import './Header.css'; + +export class HeaderItem extends PureComponent { + constructor(props) { + super(props); + } + render() { + return ( +
+
{this.props.label}
+
+ ); + } } - export default class Header extends PureComponent { - constructor (props){ - super(props) - this.setBoundaries(); - + constructor(props) { + super(props); + this.setBoundaries(); + } + + getFormat(mode, position) { + switch (mode) { + case 'year': + return 'YYYY'; + case 'month': + if (position == 'top') return 'MMMM YYYY'; + else return 'MMMM'; + case 'week': + if (position == 'top') return 'ww MMMM YYYY'; + else return 'ww'; + case 'dayweek': + return 'dd'; + case 'daymonth': + return 'D'; } - - getFormat(mode,position){ - - switch (mode){ - case 'year': - return 'YYYY' - case 'month': - if (position =='top') - return 'MMMM YYYY' - else - return 'MMMM' - case 'week': - if (position =='top') - return 'ww MMMM YYYY' - else - return 'ww' - case 'dayweek': - return 'dd' - case 'daymonth': - return 'D' - - } - - - + } + + getModeIncrement(date, mode) { + switch (mode) { + case 'year': + return DateHelper.daysInYear(date.year()); + case 'month': + return date.daysInMonth(); + case 'week': + return 7; + default: + return 1; } - - getModeIncrement(date,mode){ - switch (mode){ - case 'year': - return DateHelper.daysInYear(date.year()) - case 'month': - return date.daysInMonth() - case 'week': - return 7; - default: - return 1; - } + } + + getStartDate = (date, mode) => { + let year = null; + switch (mode) { + case 'year': + year = date.year(); + return moment([year, 0, 1]); + case 'month': + year = date.year(); + let month = date.month(); + return moment([year, month, 1]); + case 'week': + return date.subtract(date.day(), 'days'); + default: + return date; } - - - getStartDate=(date,mode)=>{ - let year=null; - switch (mode){ - case 'year': - year=date.year(); - return moment([year, 0, 1]); - case 'month': - year=date.year(); - let month=date.month(); - return moment([year, month, 1]); - case 'week': - - return date.subtract(date.day(), 'days') - default: - return date - - } + }; + + renderTime = (left, width, mode, key) => { + let result = []; + let hourWidth = width / 24; + let iterLeft = 0; + for (let i = 0; i < 24; i++) { + result.push(); + iterLeft = iterLeft + hourWidth; } - - - renderTime=(left,width,mode,key)=>{ - let result=[] - let hourWidth=width/24; - let iterLeft=0; - for(let i=0;i<24;i++){ - - result.push() - iterLeft=iterLeft+hourWidth; - } - return
{result}
; - } - getBox(date,mode,lastLeft){ - let increment=this.getModeIncrement(date,mode)*this.props.dayWidth - if(!lastLeft){ - let starDate=this.getStartDate(date,mode) - starDate=starDate.startOf('day') - let now =moment().startOf('day') - let daysInBetween=starDate.diff(now,'days'); - lastLeft=DateHelper.dayToPosition(daysInBetween,this.props.nowposition,this.props.dayWidth); - - - } - - return {left:lastLeft,width:increment} + return ( +
+ {' '} + {result} +
+ ); + }; + getBox(date, mode, lastLeft) { + let increment = this.getModeIncrement(date, mode) * this.props.dayWidth; + if (!lastLeft) { + let starDate = this.getStartDate(date, mode); + starDate = starDate.startOf('day'); + let now = moment().startOf('day'); + let daysInBetween = starDate.diff(now, 'days'); + lastLeft = DateHelper.dayToPosition(daysInBetween, this.props.nowposition, this.props.dayWidth); } - renderHeaderRows=(top,middle,bottom)=>{ - let result ={"top":[],"middle":[],"bottom":[]} - let lastLeft ={} - let currentTop="" - let currentMiddle="" - let currentBottom="" - let currentDate=null; - let box=null - - let start=this.props.currentday; - let end=this.props.currentday+this.props.numVisibleDays; - - for (let i=start-BUFFER_DAYS;i) - } - - if (currentMiddle!=currentDate.format(this.getFormat(middle))){ - currentMiddle=currentDate.format(this.getFormat(middle)); - box=this.getBox(currentDate,middle,lastLeft.middle) - lastLeft.middle=box.left+box.width; - result.middle.push() - } - - if (currentBottom!=currentDate.format(this.getFormat(bottom))){ - currentBottom=currentDate.format(this.getFormat(bottom)); - box=this.getBox(currentDate,bottom,lastLeft.bottom) - lastLeft.bottom=box.left+box.width; - if (bottom == 'shorttime' ||bottom == 'fulltime'){ - result.bottom.push(this.renderTime(box.left,box.width,bottom,i)) - }else{ - result.bottom.push() - } - - } - + return { left: lastLeft, width: increment }; + } + + renderHeaderRows = (top, middle, bottom) => { + let result = { top: [], middle: [], bottom: [] }; + let lastLeft = {}; + let currentTop = ''; + let currentMiddle = ''; + let currentBottom = ''; + let currentDate = null; + let box = null; + + let start = this.props.currentday; + let end = this.props.currentday + this.props.numVisibleDays; + + for (let i = start - BUFFER_DAYS; i < end + BUFFER_DAYS; i++) { + //The unit of iteration is day + currentDate = moment().add(i, 'days'); + if (currentTop != currentDate.format(this.getFormat(top, 'top'))) { + currentTop = currentDate.format(this.getFormat(top, 'top')); + box = this.getBox(currentDate, top, lastLeft.top); + lastLeft.top = box.left + box.width; + result.top.push(); + } + + if (currentMiddle != currentDate.format(this.getFormat(middle))) { + currentMiddle = currentDate.format(this.getFormat(middle)); + box = this.getBox(currentDate, middle, lastLeft.middle); + lastLeft.middle = box.left + box.width; + result.middle.push(); + } + + if (currentBottom != currentDate.format(this.getFormat(bottom))) { + currentBottom = currentDate.format(this.getFormat(bottom)); + box = this.getBox(currentDate, bottom, lastLeft.bottom); + lastLeft.bottom = box.left + box.width; + if (bottom == 'shorttime' || bottom == 'fulltime') { + result.bottom.push(this.renderTime(box.left, box.width, bottom, i)); + } else { + result.bottom.push(); } - - return (
-
- {result.top} -
-
- {result.middle} -
-
- {result.bottom} -
-
- ) - - - + } } - renderHeader=()=>{ - switch (this.props.mode){ - case VIEW_MODE_DAY: - return this.renderHeaderRows('week','dayweek','fulltime') - case VIEW_MODE_WEEK: - return this.renderHeaderRows('week','dayweek','shorttime') - case VIEW_MODE_MONTH: - return this.renderHeaderRows('month','dayweek','daymonth') - case VIEW_MODE_YEAR: - return this.renderHeaderRows('year','month','week') - } - - } - - setBoundaries=()=>{ - this.start=this.props.currentday-BUFFER_DAYS; - this.end=this.props.currentday+this.props.numVisibleDays+BUFFER_DAYS - } - - needToRender=()=>{ - return (this.props.currentday this.end) - } - - render(){ - if (this.refs.Header) - this.refs.Header.scrollLeft=this.props.scrollLeft; - //Check boundaries to see if wee need to recalcualte header - // if (this.needToRender()|| !this.cache){ - // this.cache=this.renderHeader(); - // this.setBoundaries(); - // } - return
- {this.renderHeader()} -
+ return ( +
+
+ {result.top} +
+
+ {result.middle} +
+
+ {result.bottom} +
+
+ ); + }; + + renderHeader = () => { + switch (this.props.mode) { + case VIEW_MODE_DAY: + return this.renderHeaderRows('week', 'dayweek', 'fulltime'); + case VIEW_MODE_WEEK: + return this.renderHeaderRows('week', 'dayweek', 'shorttime'); + case VIEW_MODE_MONTH: + return this.renderHeaderRows('month', 'dayweek', 'daymonth'); + case VIEW_MODE_YEAR: + return this.renderHeaderRows('year', 'month', 'week'); } + }; + + setBoundaries = () => { + this.start = this.props.currentday - BUFFER_DAYS; + this.end = this.props.currentday + this.props.numVisibleDays + BUFFER_DAYS; + }; + + needToRender = () => { + return this.props.currentday < this.start || this.props.currentday + this.props.numVisibleDays > this.end; + }; + + render() { + if (this.Header) this.Header.scrollLeft = this.props.scrollLeft; + //Check boundaries to see if wee need to recalcualte header + // if (this.needToRender()|| !this.cache){ + // this.cache=this.renderHeader(); + // this.setBoundaries(); + // } + return ( +
(this.Header = ref)} className="timeLine-main-header-viewPort"> + {this.renderHeader()} +
+ ); + } } - diff --git a/src/lib/components/taskList/TaskList.js b/src/lib/components/taskList/TaskList.js index bb8956f..3fbc144 100644 --- a/src/lib/components/taskList/TaskList.js +++ b/src/lib/components/taskList/TaskList.js @@ -1,91 +1,84 @@ -import React,{Component} from 'react' -import Config from 'libs/helpers/config/Config' -import ContentEditable from 'libs/components/common/ContentEditable' - -export class VerticalLine extends Component{ - constructor(props){ - super(props); - } - render(){ - return (
-
) - } +import React, { Component } from 'react'; +import Config from 'libs/helpers/config/Config'; +import ContentEditable from 'libs/components/common/ContentEditable'; +export class VerticalLine extends Component { + constructor(props) { + super(props); + } + render() { + return
; + } } -export class TaskRow extends Component{ - constructor(props){ - super(props); +export class TaskRow extends Component { + constructor(props) { + super(props); + } + onChange = value => { + if (this.props.onUpdateTask) { + this.props.onUpdateTask(this.props.item, { name: value }); } - onChange=(value)=>{ - if (this.props.onUpdateTask){ - this.props.onUpdateTask(this.props.item,{name:value}) - } + }; - } - - render(){ - - return ( -
this.props.onSelectItem(this.props.item)}> - - - - -
) - } + render() { + return ( +
this.props.onSelectItem(this.props.item)}> + +
+ ); + } } -export default class TaskList extends Component{ - constructor(props){ - super(props) +export default class TaskList extends Component { + constructor(props) { + super(props); + } + getContainerStyle(rows) { + let new_height = rows > 0 ? rows * this.props.itemheight : 10; + return { height: new_height }; + } + renderTaskRow(data) { + let result = []; + for (let i = this.props.startRow; i < this.props.endRow + 1; i++) { + let item = data[i]; + if (!item) break; + result.push( + + ); } - getContainerStyle(rows){ - let new_height=rows>0?rows * this.props.itemheight:10; - return {height:new_height} - } - renderTaskRow(data){ - let result=[]; - for (let i=this.props.startRow;i); - - } - return result; - } - doScroll=()=>{ - this.props.onScroll(this.refs.taskViewPort.scrollTop) - } - render(){ - let data =this.props.data?this.props.data:[]; - this.containerStyle=this.getContainerStyle(data.length) - return( -
-
-
- {Config.values.taskList.title.label} -
-
-
-
- { this.renderTaskRow(data) } -
-
-
- ) - - } -} \ No newline at end of file + return result; + } + doScroll = () => { + this.props.onScroll(this.taskViewPort.scrollTop); + }; + render() { + let data = this.props.data ? this.props.data : []; + this.containerStyle = this.getContainerStyle(data.length); + return ( +
+
+
{Config.values.taskList.title.label}
+
+
(this.taskViewPort = ref)} className="timeLine-side-task-viewPort" onScroll={this.doScroll}> +
+ {this.renderTaskRow(data)} +
+
+
+ ); + } +} diff --git a/src/lib/components/viewport/DataViewPort.js b/src/lib/components/viewport/DataViewPort.js index 1c583ef..1c1068d 100644 --- a/src/lib/components/viewport/DataViewPort.js +++ b/src/lib/components/viewport/DataViewPort.js @@ -1,135 +1,145 @@ -import React,{Component} from 'react' -import {DATA_CONTAINER_WIDTH} from 'libs/Const' -import DataTask from 'libs/components/viewport/DataTask' -import DateHelper from 'libs/helpers/DateHelper' -import sizeMe from 'react-sizeme' -import Config from 'libs/helpers/config/Config' +import React, { Component } from 'react'; +import { DATA_CONTAINER_WIDTH } from 'libs/Const'; +import DataTask from 'libs/components/viewport/DataTask'; +import DateHelper from 'libs/helpers/DateHelper'; +import sizeMe from 'react-sizeme'; +import Config from 'libs/helpers/config/Config'; -export class DataRow extends Component{ - constructor(props){ - super(props); - - } - render(){ - return ( -
+export class DataRow extends Component { + constructor(props) { + super(props); + } + render() { + return ( +
{this.props.children} -
) - } +
+ ); + } } -export class DataViewPort extends Component{ - constructor(props){ - super(props) - this.childDragging=false - } - getContainerHeight(rows){ - let new_height=rows>0?rows * this.props.itemheight:10; - return new_height - } - onChildDrag=(dragging)=>{ - this.childDragging=dragging; - } +export class DataViewPort extends Component { + constructor(props) { + super(props); + this.childDragging = false; + } + getContainerHeight(rows) { + let new_height = rows > 0 ? rows * this.props.itemheight : 10; + return new_height; + } + onChildDrag = dragging => { + this.childDragging = dragging; + }; - // calculatePosition=(item)=>{ - // let new_position=DateHelper.dateToPixel(item.start,this.props.nowposition,this.props.dayWidth); - // let new_width=DateHelper.dateToPixel(item.end,this.props.nowposition,this.props.dayWidth)-new_position; - // //Checking start - // if (new_positionthis.props.boundaries.upper){ - // return({left:0,width:0}) - // } - // if (new_position>this.props.boundaries.upper){ - // return({left:0,width:0}) - // }else{ - // } - // } + // calculatePosition=(item)=>{ + // let new_position=DateHelper.dateToPixel(item.start,this.props.nowposition,this.props.dayWidth); + // let new_width=DateHelper.dateToPixel(item.end,this.props.nowposition,this.props.dayWidth)-new_position; + // //Checking start + // if (new_positionthis.props.boundaries.upper){ + // return({left:0,width:0}) + // } + // if (new_position>this.props.boundaries.upper){ + // return({left:0,width:0}) + // }else{ + // } + // } - renderRows=()=>{ - let result=[]; - for (let i=this.props.startRow;i - - ); - - } - return result; - } + renderRows = () => { + let result = []; + for (let i = this.props.startRow; i < this.props.endRow + 1; i++) { + let item = this.props.data[i]; + if (!item) break; + //FIXME PAINT IN BOUNDARIES - doMouseDown=(e)=>{ - if ((e.button === 0) && (!this.childDragging)) { - this.props.onMouseDown(e) - } - } - doMouseMove=(e)=>{ - this.props.onMouseMove(e,this.refs.dataViewPort) + let new_position = DateHelper.dateToPixel(item.start, this.props.nowposition, this.props.dayWidth); + let new_width = DateHelper.dateToPixel(item.end, this.props.nowposition, this.props.dayWidth) - new_position; + result.push( + + + {' '} + + + ); } + return result; + }; - doTouchStart=(e)=>{ - if (!this.childDragging) { - this.props.onTouchStart(e) - } - } - doTouchMove=(e)=>{ - this.props.onTouchMove(e,this.refs.dataViewPort) + doMouseDown = e => { + if (e.button === 0 && !this.childDragging) { + this.props.onMouseDown(e); } + }; + doMouseMove = e => { + this.props.onMouseMove(e, this.dataViewPort); + }; - componentDidMount(){ - this.refs.dataViewPort.scrollLeft=0; + doTouchStart = e => { + if (!this.childDragging) { + this.props.onTouchStart(e); } + }; + doTouchMove = e => { + this.props.onTouchMove(e, this.dataViewPort); + }; - render(){ - if (this.refs.dataViewPort){ - this.refs.dataViewPort.scrollLeft=this.props.scrollLeft; - this.refs.dataViewPort.scrollTop=this.props.scrollTop; - } - - let height=this.getContainerHeight(this.props.data.length) - return ( -
- -
- {this.renderRows()} -
-
) + componentDidMount() { + this.dataViewPort.scrollLeft = 0; + } + + render() { + if (this.dataViewPort) { + this.dataViewPort.scrollLeft = this.props.scrollLeft; + this.dataViewPort.scrollTop = this.props.scrollTop; } + + let height = this.getContainerHeight(this.props.data.length); + return ( +
(this.dataViewPort = ref)} + id="timeLinedataViewPort" + className="timeLine-main-data-viewPort" + onMouseDown={this.doMouseDown} + onMouseMove={this.doMouseMove} + onMouseUp={this.props.onMouseUp} + onMouseLeave={this.props.onMouseLeave} + onTouchStart={this.doTouchStart} + onTouchMove={this.doTouchMove} + onTouchEnd={this.props.onTouchEnd} + onTouchCancel={this.props.onTouchCancel}> +
+ {this.renderRows()} +
+
+ ); + } } -export default sizeMe({monitorWidth:true,monitorHeight:true})(DataViewPort) +export default sizeMe({ monitorWidth: true, monitorHeight: true })(DataViewPort);