- 1 import {Calendar} from '@fullcalendar/core';
- 2 import resourceTimelinePlugin from '@fullcalendar/resource-timeline';
- 3 import interactionPlugin from '@fullcalendar/interaction';
- 4 import '@fullcalendar/core/main.css';
- 5 import '@fullcalendar/timeline/main.css';
- 6 import '@fullcalendar/resource-timeline/main.css';
- 7
- 8 // import zh_cn from '@fullcalendar/core/locales/zh-cn';
- 9 let option = {
- 10 schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
- 11 plugins: [interactionPlugin, resourceTimelinePlugin],
- 12 defaultView: 'resourceTimeline',
- 13 now: '2019-03-07',
- 14 // locale: zh_cn,
- 15 selectable: true,
- 16 selectHelper: true,
- 17 editable: true, // enable draggable events
- 18 eventResourceEditable: false,
- 19 aspectRatio: 1,
- 20 // height: 440,
- 21 contentHeight: 440,
- 22 resourceAreaWidth: '120px',
- 23 eventOverlap: false,
- 24 selectOverlap: false,
- 25 eventTextColor: '#fff',
- 26 displayEventTime: true,
- 27 displayEventEnd: true,
- 28 slotLabelFormat: {
- 29 hour: 'numeric',
- 30 minute: '2-digit',
- 31 omitZeroMinute: true,
- 32 meridiem: 'short',
- 33 hour12: false,
- 34 },
- 35 eventTimeFormat: {
- 36 hour: 'numeric',
- 37 minute: '2-digit',
- 38 meridiem: 'narrow',
- 39 hour12: false,
- 40 },
- 41 header: {
- 42 left: '',
- 43 center: '',
- 44 right: '',
- 45 },
- 46 resourceLabelText: '姓名',
- 47 resources: [],
- 48 events: [],
- 49 };
- 50 /**
- 51 * {Object} option , onSelect: function onEventClick: function ,
- 52 */
- 53
- 54 class Timeline {
- 55 constructor(el, opt = {}, callBack = () => {}) {
- 56 this.callBack = callBack;
- 57 console.log('timeline -init');
- 58 this._option = Object.assign(
- 59 {
- 60 select: info => this.select(info),
- 61 dateClick: info => this.dateClick(info),
- 62 eventClick: info => this.eventClick(info),
- 63 eventMouseEnter: info => this.eventMouseEnter(info),
- 64 eventMouseLeave: info => this.eventMouseLeave(info),
- 65 eventResize: info => this.eventResize(info),
- 66 eventDrop: info => this.eventDrop(info),
- 67 resourceRender: info => this.resourceRender(info),
- 68 eventRender: info => this.eventRender(info),
- 69 eventDestroy: info => this.eventDestroy(info),
- 70 },
- 71 option,
- 72 opt
- 73 );
- 74 console.log('timeline-option==>>', this._option);
- 75 this.calendar = new Calendar(el, this._option);
- 76 this.render();
- 77
- 78 let currentDate = new Date(this._option.now);
- 79 let end = new Date().setDate(currentDate.getDate());
- 80 if (currentDate.getHours() !== 0) {
- 81 end = new Date().setDate(currentDate.getDate() + 1);
- 82 }
- 83 console.table('start, end', currentDate, new Date(end));
- 84 this.setOption('visibleRange', {
- 85 start: currentDate,
- 86 end: end,
- 87 });
- 88 }
- 89
- 90 /**
- 91 * @param {Object} value
- 92 */
- 93 setOption(key, value) {
- 94 this.calendar.setOption(key, value);
- 95 this._option[key] = value;
- 96 }
- 97
- 98 // methods
- 99 render() {
- 100 this.calendar.render();
- 101 }
- 102 addResource(resource) {
- 103 if (!resource) {
- 104 return;
- 105 }
- 106 this.calendar.addResource(resource);
- 107 }
- 108 removeResource(resource, e) {
- 109 if (!this._option.editable) {
- 110 return;
- 111 }
- 112 this._option.onRemoveResource && this._option.onRemoveResource(resource);
- 113 let events = resource.getEvents();
- 114 events.forEach(event => {
- 115 event.remove();
- 116 });
- 117 resource.remove();
- 118 this.getResult();
- 119
- 120 e.target.removeEventListener('click', this.removeResource);
- 121 }
- 122 addEvent(event) {
- 123 if (!event) {
- 124 return;
- 125 }
- 126 let tmp = this.calendar.getEventById(event.id);
- 127 if (tmp) {
- 128 for (let key in event) {
- 129 if (tmp.extendedProps[key]) {
- 130 tmp.setExtendedProp(key, event[key]);
- 131 continue;
- 132 }
- 133 if (tmp[key]) {
- 134 tmp.setProp(key, event[key]);
- 135 }
- 136 }
- 137 } else {
- 138 this.calendar.addEvent(event);
- 139 console.log('addd', event);
- 140 }
- 141 }
- 142 removeEvent(eventId) {
- 143 let event = this.calendar.getEventById(eventId);
- 144 if (event) {
- 145 event.remove();
- 146 this.getResult();
- 147 }
- 148 }
- 149
- 150 destroy() {
- 151 this.calendar.destroy();
- 152 console.log('timeline destroy >>>>>>>');
- 153 }
- 154 getResult() {
- 155 let resources = this.calendar.getResources();
- 156 let result = [];
- 157 resources.map(item => {
- 158 let tmp = {
- 159 resource: item,
- 160 events: item.getEvents(),
- 161 };
- 162 result.push(tmp);
- 163 });
- 164
- 165 this.callBack && this.callBack(result);
- 166 }
- 167 isValid(event) {
- 168 let now = this._option.now;
- 169 let start = new Date(event.start).getTime();
- 170 let end = new Date(event.end).getTime();
- 171 let startH = new Date(now).getHours();
- 172 let startD = new Date(now).getDate();
- 173 let crossDate = new Date(now);
- 174 crossDate.setDate(startD);
- 175 crossDate.setHours(23);
- 176 let endPoint = crossDate.getTime();
- 177 if (startH !== 0) {
- 178 crossDate.setDate(startD + 1);
- 179 crossDate.setHours(startH);
- 180 endPoint = crossDate.getTime();
- 181 }
- 182 if (start < now || end < now || start > endPoint || end > endPoint) {
- 183 return false;
- 184 }
- 185 return true;
- 186 }
- 187 /**
- 188 callbacks
- 189 */
- 190 select(info) {
- 191 if (!this.isValid({start: info.start, end: info.end})) {
- 192 // info.revert();
- 193 return;
- 194 }
- 195 this._option.onSelect && this._option.onSelect(info);
- 196 }
- 197 dateClick(arg) {
- 198 console.log('dateClick', arg.date, arg.resource ? arg.resource.id : '(no resource)');
- 199 }
- 200 eventClick(info) {
- 201 this._option.onEventClick && this._option.onEventClick(info);
- 202 }
- 203 eventMouseEnter(info) {
- 204 this._option.onEventMouseEnter && this._option.onEventMouseEnter(info);
- 205 }
- 206 eventMouseLeave(info) {
- 207 this._option.onEventMouseLeave && this._option.onEventMouseLeave(info);
- 208 }
- 209 eventResize(info) {
- 210 if (!this.isValid(info.event)) {
- 211 info.revert();
- 212 }
- 213 // this.getResult();
- 214 }
- 215 eventDrop(info) {
- 216 if (!this.isValid(info.event)) {
- 217 info.revert();
- 218 }
- 219 // this.getResult();
- 220 }
- 221 resourceRender(info) {
- 222 let dom = info.el;
- 223 dom.style = dom.style + ';position:relative;';
- 224 let close = document.createElement('i');
- 225 close.classList.add('iconfont', 'icon-c');
- 226 close.style = 'position:absolute;right:10px;top:50%;transform:translateY(-50%);font-size: 10px;';
- 227 close.addEventListener('click', e => this.removeResource(info.resource, e));
- 228 dom.appendChild(close);
- 229 }
- 230 eventRender(info) {
- 231 this.getResult();
- 232 }
- 233
- 234 eventDestroy(info) {
- 235 // this.getResult();
- 236 // console.log('eventDestroy', info);
- 237 }
- 238 }
- 239
- 240 export default Timeline;