vue-scheduler-lite
Version:
A support drag and drop scheduler on vue.js
989 lines (975 loc) • 35.2 kB
JavaScript
/**
* vue-scheduler-lite
*
* A support drag and drop scheduler on vue.js
*
* @date 2020/04/18
* @author Lin Masahiro(k80092@hotmail.com)
* @see https://github.com/linmasahiro/vue-scheduler-lite
*
* (c) 2020 Lin masahiro
* Released under the MIT License.
*/
const unitDiv = {
props: {
rowIndex: Number,
keyIndex: Number,
width: String,
rowData: Object,
isBusiness: Boolean,
isSelecting: Boolean,
isSelectingRowIndex: Number
},
data: function () {
return {}
},
methods: {
mousedown() {
if (!this.isBusiness) {
return false
}
this.$emit('mouse-down', this.rowIndex, this.keyIndex)
},
mouseenter() {
if (!this.isSelecting || this.rowIndex != this.isSelectingRowIndex || !this.isBusiness) {
return false
}
this.$emit('mouse-enter', this.keyIndex)
},
mouseup() {
this.$emit('mouse-up')
},
setDragenterRowAndIndex() {
if (!this.isBusiness) {
return false
}
this.$emit('set-dragenter-row-and-index', this.rowIndex, this.keyIndex)
}
},
template: `
<div
:class="['tl', isBusiness ? 'can-res' : 'cant-res']"
:style="{width: width}"
="mousedown"
="mouseenter"
="mouseup"
="setDragenterRowAndIndex"
>
</div>
`
}
const reservedDiv = {
props: {
rowIndex: Number,
keyNo: Number,
unitWidth: Number,
unitHeight: Number,
titleDivWidth: Number,
borderWidth: Number,
startText: String,
endText: String,
contentText: String,
minDate: String,
maxDate: String,
unit: Number,
clearSwitch: Boolean,
dragenterRowIndex: Number,
dragenterKeyIndex: Number,
isSelecting: Boolean,
isSelectingRowIndex: Number,
isSelectingIndex: Number
},
data: function () {
return {
styleObject: {
"Opacity": 1,
"left": "0px",
"width": "0px",
"height": "130px"
},
isShow: false,
mouseXStarted: null,
startLineNo: null,
endLineNo: null,
isMe: false,
isEdit: false,
isMove: false
}
},
created() {
if ((new Date(this.startText) - new Date(this.minDate)) < 0 && (new Date(this.endText) - new Date(this.minDate)) < 0) {
return
}
this.setLeftPosition()
this.setWidth()
this.isShow = true
},
watch: {
startText(newVal, oldVal) {
if (newVal != oldVal) {
this.startDate = newVal
this.setLeftPosition()
}
},
endText(newVal, oldVal) {
if (newVal != oldVal) {
this.endDate = newVal
this.setWidth()
if (this.isSelecting &&
this.mouseXStarted &&
this.rowIndex == this.isSelectingRowIndex &&
this.keyNo == this.isSelectingIndex
) {
let diff = this.getMinutesDiff(new Date(oldVal), new Date(newVal))
let cnt = parseInt(diff / this.unit)
this.mouseXStarted += this.unitWidth * cnt
}
}
},
dragenterKeyIndex(newVal, oldVal) {
if (newVal != oldVal && this.dragenterRowIndex == this.rowIndex && this.isEdit) {
this.editting()
}
},
clearSwitch(newVal, oldVal) {
if (newVal != oldVal) {
this.editEnd()
}
}
},
methods: {
/**
* Set the Block left pixel
*
* @returns void
*/
setLeftPosition() {
let leftDiff = this.getMinutesDiff(new Date(this.minDate), new Date(this.startText))
let shiftCnt = parseInt(leftDiff / this.unit)
this.startLineNo = shiftCnt
let shiftLeft = this.unitWidth * shiftCnt + (shiftCnt * this.borderWidth)
this.styleObject.left = shiftLeft + "px"
},
/**
* Set the Block width pixel
*
* @returns void
*/
setWidth() {
let rightDiff = this.getMinutesDiff(new Date(this.startText), new Date(this.endText))
let widthCnt = parseInt(rightDiff / this.unit)
this.endLineNo = this.startLineNo + widthCnt
let width = this.unitWidth * widthCnt + (widthCnt * this.borderWidth)
this.styleObject.width = width + "px"
},
/**
* Set the Block to edit status
*
* @param Object e Event
*
* @returns void
*/
editStart(e) {
if (this.isSelecting) {
e.preventDefault()
return
}
this.isEdit = true
this.mouseXStarted = e.clientX
this.styleObject.Opacity = 0.5
},
/**
* Adjust time event
*
* @param Obejct e Event
*
* @returns void
*/
editting(e) {
if (this.isSelecting) {
e.preventDefault()
return
}
if (this.isEdit) {
if (e) {
let width = e.x + e.layerX
if (this.mouseXStarted > width) {
this.mouseXStarted = width
return
}
// adjust by Mouse X-axio
let movePx = e.clientX - this.mouseXStarted
let unitCnt = parseInt(movePx / this.unitWidth)
if (unitCnt != 0) {
this.mouseXStarted = e.clientX
this.$emit("edit-schedule-data", this.rowIndex, this.keyNo, unitCnt)
}
} else {
// adjust by current unit-div number
if (this.dragenterKeyIndex > this.startLineNo) {
this.mouseXStarted += this.unitWidth
let unitCnt = parseInt(this.dragenterKeyIndex - this.endLineNo)
this.$emit("edit-schedule-data", this.rowIndex, this.keyNo, unitCnt)
}
}
}
},
/**
* End edit and set new data
*
* @returns void
*/
editEnd() {
if (this.isEdit) {
this.$emit('edit-event', this.startText, this.endText)
}
this.isEdit = false
this.styleObject.Opacity = 1
this.mouseXStarted = null
},
/**
* Set the block to move status
*
* @param Object e
*/
moveStart(e) {
if (this.isSelecting) {
e.preventDefault()
return
}
if (!this.isEdit) {
this.styleObject.Opacity = 0.5
this.isMove = true
this.mouseXStarted = e.clientX
this.$emit('set-dragenter-row-and-index', this.rowIndex, null)
}
},
/**
* End move and set new data
*
* @returns void
*/
moveEnd(e) {
let mouseXEnd = e.clientX
// Check move status and move block
if (this.isMove && (mouseXEnd != this.mouseXStarted || this.dragenterRowIndex != this.rowIndex)) {
// get x-axis moved count
let moveXPx = mouseXEnd - this.mouseXStarted
let unitCnt = parseInt(moveXPx / this.unitWidth)
let halfWidth = parseInt(this.unitWidth / 2)
let modXPx = parseInt(moveXPx % this.unitWidth)
if (moveXPx < 0 && Math.abs(modXPx) >= halfWidth) {
unitCnt--
}
this.mouseXStarted = null
if (unitCnt != 0 || this.dragenterRowIndex != this.rowIndex) {
// result pass to father component's method
this.$emit("move-schedule-data", this.rowIndex, this.keyNo, unitCnt)
}
}
// Return block all status and opacity
this.isEdit = false
this.isMove = false
this.styleObject.Opacity = 1
},
/**
* Delete this event
*/
deleteEvent() {
this.$emit("delete-schedule-data", this.rowIndex, this.keyNo)
},
/**
* Mouse move event for Add new schedule
*/
mousemove(e) {
if (
this.rowIndex == this.isSelectingRowIndex &&
this.keyNo == this.isSelectingIndex
) {
if (this.isSelecting && this.mouseXStarted) {
let movePx = e.clientX - this.mouseXStarted
let unitCnt = parseInt(movePx / this.unitWidth)
if (unitCnt != 0 && unitCnt < 0) {
this.mouseXStarted = e.clientX + this.unitWidth
this.$emit("edit-schedule-data", this.rowIndex, this.keyNo, unitCnt)
}
}
if (this.isSelecting && !this.mouseXStarted) {
this.mouseXStarted = e.clientX
this.styleObject.Opacity = 0.5
}
}
},
/**
* Mouse up event for Add new schedule
*/
mouseup() {
this.$emit('mouse-up', this.startText, this.endText)
},
/**
* Get minutes diff between date1 and date2
*
* @param Object date1 DateObject1
* @param Object date2 DateObject2
*
* @returns Int
*/
getMinutesDiff(date1, date2) {
const diffTime = date2 - date1;
return Math.ceil(diffTime / (1000 * 60));
}
},
template: `
<div
v-if="isShow"
:class="['sc-bar', isMe ? 'isMe' : 'notMe']"
:style="styleObject"
:draggable="'true'"
="moveStart"
="moveEnd"
="editting($event)"
="mouseup"
="mousemove"
="$emit('click-event')"
>
<span style="float: right; padding: 5px" ="deleteEvent">✖</span><span class="head">
<span class="startTime time">{{ startText }}</span>~<span class="endTime time">{{ endText }}</span>
</span>
<span class="text">{{ contentText }}</span>
<div
class="resizable-e"
:draggable="'true'"
="editStart"
="editEnd"
></div>
</div>
`
}
const vueSchedulerLite = {
components: {
'unit-div': unitDiv,
'reserved-div': reservedDiv
},
props: {
scheduleData: Array,
setting: Object,
},
data() {
return {
settingData: {
startDate: '2020/04/20',
endDate: '2020/04/26',
weekdayText: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
unit: 60,
borderW: 1,
dateDivH: 25,
timeDivH: 25,
unitDivW: 25,
titleDivW: 200,
rowH: 135,
},
padding: 0,
timeDivW: 0,
dateDivW: 0,
contentH: 0,
contentW: 0,
dateCnt: 0,
unitCnt: 0,
isSelecting: false,
isSelectingRowIndex: null,
isSelectingIndex: null,
dragenterRowIndex: null,
dragenterKeyIndex: null,
clearSwitch: false
}
},
created() {
this.settingData = Object.assign(this.settingData, this.setting);
this.dateCnt = this.getDateDiff(new Date(this.settingData.startDate), new Date(this.settingData.endDate)) + 1
let oneDayCnt = parseInt(1440 / this.settingData.unit)
this.unitCnt = oneDayCnt * this.dateCnt
this.padding = this.settingData.dateDivH + this.settingData.timeDivH + (this.settingData.borderW * 4)
this.dateDivW = this.settingData.unitDivW * oneDayCnt + (oneDayCnt - this.settingData.borderW)
this.contentH = this.padding + ((this.settingData.rowH + this.settingData.borderW * 2) * this.scheduleData.length)
this.contentW = this.dateDivW * this.dateCnt + (this.dateCnt * this.settingData.borderW)
this.timeDivW = 60 / this.settingData.unit * (this.settingData.unitDivW + this.settingData.borderW) - 1
},
methods: {
/**
* Draggable Enter Event
*
* @param int rowIndex Row Index
*
* @returns void
*/
setDragenterRow(rowIndex) {
this.dragenterRowIndex = rowIndex
},
/**
* Draggable Enter Event
*
* @param int rowIndex Row Index
* @param int currentIndex Current Index
*
* @returns void
*/
setDragenterRowAndIndex(rowIndex, currentIndex) {
this.dragenterRowIndex = rowIndex
this.dragenterKeyIndex = currentIndex
},
/**
* Disable HTML5 DragEnd animation and Set mouse position
*
* @param Obejct e Event
*/
disableDragendAnimation(e) {
e.preventDefault();
},
/**
* Get header area date-text
*
* @param Int n Col index
*
* @returns String
*/
getHeaderDate(n) {
let startDate = this.addDays(new Date(this.settingData.startDate), n)
return this.dateFormatter(startDate, true)
},
/**
* Get header area time-text
*
* @param {*} n Col index
*/
getHeaderTime(n) {
return n % 24
},
/**
* Get diff day between date1 and date2
*
* @param Object date1 DateObejct1
* @param Object date2 DateObejct2
*
* @returns Int
*/
getDateDiff(date1, date2) {
const diffTime = Math.abs(date2 - date1);
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
},
/**
* Custom date formatter
*
* @param Obejct dateObj DateObejct
* @param Boolean withWeekDay If u need weekday, set True
*
* @returns String
*/
dateFormatter(dateObj, withWeekDay) {
let year = dateObj.getFullYear()
let month = dateObj.getMonth() + 1
if (month < 10) {
month = '0' + month
}
let date = dateObj.getDate()
if (withWeekDay) {
let day = dateObj.getDay()
let dayText = this.settingData.weekdayText[day]
return year + '/' + month + '/' + date + '(' + dayText + ')'
}
return year + '/' + month + '/' + date
},
/**
* Custom datetime formatter
*
* @param Obejct dateObj DateObejct
*
* @returns String
*/
datetimeFormatter(dateObj) {
let year = dateObj.getFullYear()
let month = dateObj.getMonth() + 1
if (month < 10) {
month = '0' + month
}
let date = dateObj.getDate()
let hours = dateObj.getHours()
if (hours < 10) {
hours = '0' + hours
}
let minutes = dateObj.getMinutes()
if (minutes < 10) {
minutes = '0' + minutes
}
return year + '/' + month + '/' + date + ' ' + hours + ':' + minutes
},
/**
* Add days to object
*
* @param Obejct dateObj DateObject
* @param Int n Add number
*
* @returns Object
*/
addDays(dateObj, n) {
dateObj.setTime(dateObj.getTime() + (n * 60 * 60 * 24 * 1000))
return dateObj
},
/**
* Add minutes to date object
*
* @param Obejct dateObj DateObject
* @param Int n Add number
*
* @returns Object
*/
addMinutes(dateObj, n) {
dateObj.setTime(dateObj.getTime() + (n * 60 * 1000))
return dateObj
},
/**
* Check this div is business or not
*
* @param Int rowIndex Row index
* @param Int n Col index
*
* @returns Boolean
*/
isBusiness: function (rowIndex, n) {
// first check this div business day
let startDate = new Date(this.settingData.startDate)
let oneDayCnt = parseInt(1440 / this.settingData.unit)
let thisDate = this.addDays(startDate, parseInt(n / oneDayCnt))
let noBusinessDate = this.scheduleData[rowIndex].noBusinessDate
if (noBusinessDate.indexOf(this.dateFormatter(thisDate)) >= 0) {
// today not business day
return false
}
// and check this div time bussiness hour
let weekDay = thisDate.getDay()
let businessHour = this.scheduleData[rowIndex].businessHours[weekDay]
if (businessHour.start == '00:00' && businessHour.end == '24:00') {
// alltime
return true
}
// has bussiness hour
let businessStartTime = businessHour.start.replace(":", "")
let businessEndTime = businessHour.end.replace(":", "")
let dateMod = n % oneDayCnt
let divStartCnt = dateMod * this.settingData.unit
let divStartHour = parseInt(divStartCnt / 60)
if (divStartHour < 10) {
divStartHour = "0" + divStartHour
}
let divStartMin = parseInt(divStartCnt % 60)
if (divStartMin < 10) {
divStartMin = "0" + divStartMin
}
let divStartTime = divStartHour + "" + divStartMin
if (divStartTime >= businessStartTime && divStartTime < businessEndTime) {
return true
}
return false
},
/**
* Check this range is business or not
*
* @param Int rowIndex Row index
* @param String startDateText StartDate text
* @param String endDateText EndDate text
*
* @returns Boolean
*/
isBusinessOnRange(rowIndex, startDateText, endDateText) {
let startDiff = this.getMinutesDiff(new Date(this.settingData.startDate), new Date(startDateText))
let startCnt = parseInt(startDiff / this.settingData.unit)
let endDiff = this.getMinutesDiff(new Date(this.settingData.startDate), new Date(endDateText))
let endCnt = parseInt(endDiff / this.settingData.unit)
let result = true
for (var i = startCnt; i < endCnt; i++) {
if (!this.isBusiness(rowIndex, i)) {
result = false
}
}
return result
},
/**
* Check this range has other event
*
* @param Int index Data index
* @param Int oldRowIndex Old row index
* @param Int newRowIndex New row index
* @param String startDateText StartDate text
* @param String endDateText EndDate text
*
* @returns Boolean
*/
hasOtherEvent(index, oldRowIndex, newRowIndex, startDateText, endDateText) {
for (var n = 0; n < this.scheduleData[newRowIndex].schedule.length; n++) {
if (n != index || oldRowIndex != newRowIndex) {
let diffData = this.scheduleData[newRowIndex].schedule[n];
if (
new Date(diffData.start) - new Date(startDateText) >= 0 &&
new Date(diffData.end) - new Date(endDateText) <= 0
) {
return true;
}
if (
new Date(diffData.start) - new Date(startDateText) >= 0 &&
new Date(diffData.start) - new Date(endDateText) < 0
) {
return true;
}
if (
new Date(diffData.start) - new Date(startDateText) <= 0 &&
new Date(diffData.end) - new Date(startDateText) > 0
) {
return true;
}
}
}
return false;
},
/**
* The column are click start event
*
* @param Object e Event
*
* @returns void
*/
selectStartTime(rowIndex, keyIndex) {
this.isSelecting = true
this.isSelectingRowIndex = rowIndex
let addMinutes = (keyIndex - 1) * this.settingData.unit
let addMinutes2 = keyIndex * this.settingData.unit
let newStartDateObj = this.addMinutes(new Date(this.settingData.startDate), addMinutes)
let newEndDateObj = this.addMinutes(new Date(this.settingData.startDate), addMinutes2)
this.scheduleData[rowIndex].schedule.push({
text: 'New',
start: this.datetimeFormatter(newStartDateObj),
end: this.datetimeFormatter(newEndDateObj)
})
this.isSelectingIndex = (this.scheduleData[this.isSelectingRowIndex].schedule.length - 1)
},
/**
* New event adjust event
*
* @param int keyIndex
*/
adjustTimeRange(keyIndex) {
let targetIndex =
this.scheduleData[this.isSelectingRowIndex].schedule.length - 1;
let targetData = this.scheduleData[this.isSelectingRowIndex].schedule[
targetIndex
];
if (targetData) {
let addMinutes = keyIndex * this.settingData.unit;
let newEndDateObj = this.addMinutes(
new Date(this.settingData.startDate),
addMinutes
);
let newEndDateText = this.datetimeFormatter(newEndDateObj);
let isPermission = true;
// Check other event
if (
this.hasOtherEvent(
targetIndex,
this.isSelectingRowIndex,
this.isSelectingRowIndex,
targetData.start,
newEndDateText
)
) {
isPermission = false;
}
// Check Businessday
if (isPermission) {
isPermission = this.isBusinessOnRange(
this.isSelectingRowIndex,
targetData.start,
newEndDateText
);
}
if (isPermission) {
targetData.end = newEndDateText;
}
}
},
/**
* Add new block event
*
* @param Boolean isAdd Is add event action
* @param String startDate StartDate text
* @param String endDate EndDate text
*
* @returns void
*/
selectEndTime(startDate, endDate) {
if (this.isSelecting) {
if (startDate == undefined) {
let targetData = this.scheduleData[this.isSelectingRowIndex].schedule[this.scheduleData[this.isSelectingRowIndex].schedule.length - 1]
startDate = targetData.start
endDate = targetData.end
}
this.$emit('add-event', this.isSelectingRowIndex, startDate, endDate)
}
this.isSelecting = false
this.isSelectingRowIndex = null
this.isSelectingIndex = null
this.clearSwitch = !this.clearSwitch
},
/**
* Edit Schedule Datetime Text
*
* @param int rowIndex Row Index
* @param int keyNo Key
* @param int unitCnt Moved unit count
*
* @returns void
*/
moveScheduleData(rowIndex, keyNo, unitCnt) {
let targetData = this.scheduleData[rowIndex].schedule[keyNo];
if (targetData) {
let status = 0;
let isBusinessFlag = true;
let isBusinessChecked = false;
let changeDatetimeText = datetimeText => {
let addMinutes = unitCnt * this.settingData.unit;
let dateObj = new Date(datetimeText);
let newDateObj = this.addMinutes(dateObj, addMinutes);
return this.datetimeFormatter(newDateObj);
};
let newStartDatetime = changeDatetimeText(targetData.start);
let newEndDatetime = changeDatetimeText(targetData.end);
if (unitCnt != 0) {
if (
this.hasOtherEvent(
keyNo,
rowIndex,
this.dragenterRowIndex,
newStartDatetime,
newEndDatetime
)
) {
status = 2;
} else {
isBusinessFlag = this.isBusinessOnRange(
this.dragenterRowIndex,
newStartDatetime,
newEndDatetime
);
if (isBusinessFlag) {
targetData.start = newStartDatetime;
targetData.end = newEndDatetime;
status = 1;
}
isBusinessChecked = true;
}
}
if (
rowIndex != this.dragenterRowIndex &&
this.scheduleData[this.dragenterRowIndex]
) {
if (isBusinessChecked && !isBusinessFlag) {
this.$emit("move-event", status);
return;
}
if (!isBusinessChecked && isBusinessFlag) {
if (
this.hasOtherEvent(
keyNo,
rowIndex,
this.dragenterRowIndex,
newStartDatetime,
newEndDatetime
)
) {
status = 2;
this.$emit("move-event", status);
return;
}
isBusinessFlag = this.isBusinessOnRange(
this.dragenterRowIndex,
targetData.start,
targetData.end
);
isBusinessChecked = true;
}
if (isBusinessChecked && isBusinessFlag) {
this.scheduleData[this.dragenterRowIndex].schedule.push(targetData);
this.scheduleData[rowIndex].schedule.splice(keyNo, 1);
status = 1;
}
}
this.$emit("move-event", status, targetData.start, targetData.end);
}
},
/**
* Edit Schedule Datetime Text
*
* @param int rowIndex Row
* @param int keyNo Key
* @param int unitCnt Moved unit count
*
* @returns void
*/
editScheduleData(rowIndex, keyNo, unitCnt) {
let targetData = this.scheduleData[rowIndex].schedule[keyNo]
if (targetData) {
let changeDatetimeText = (datetimeText) => {
let addMinutes = unitCnt * this.settingData.unit
let dateObj = new Date(datetimeText)
let newDateObj = this.addMinutes(dateObj, addMinutes)
return this.datetimeFormatter(newDateObj)
}
let newEndText = changeDatetimeText(targetData.end)
if (this.hasOtherEvent(keyNo, rowIndex, rowIndex, targetData.start, newEndText)) {
return
}
targetData.end = newEndText
}
},
/**
* Delete Schedule
*
* @param int rowIndex Row
* @param int keyNo Key
*
* @returns void
*/
deleteScheduleData(rowIndex, keyNo) {
this.scheduleData[rowIndex].schedule.splice(keyNo, 1)
this.$emit('delete-event', rowIndex, keyNo)
},
/**
* Get minutes diff between date1 and date2
*
* @param Object date1 DateObject1
* @param Object date2 DateObject2
*
* @returns Int
*/
getMinutesDiff(date1, date2) {
const diffTime = Math.abs(date2 - date1);
return Math.ceil(diffTime / (1000 * 60));
}
},
template: `
<div
class="schedule"
="disableDragendAnimation"
>
<div>
<div
class="sc-rows"
:style="{width: settingData.titleDivW + '%', height: contentH + 'px'}"
>
<div
class="sc-rows-scroll"
:style="{width: '100%'}"
>
<div
v-for="(row, index) in scheduleData"
:key="index"
:class="'timeline title'"
:style="{'height': settingData.rowH + 'px', 'padding-top': (index == 0) ? padding + 'px' : '0px'}"
="$emit('row-click-event', index, row.title)"
>
<span style="cursor: pointer;">{{ row.title }}</span>
</div>
</div>
</div>
<div class="sc-main-box" :style="{width: (100 - settingData.titleDivW) + '%'}">
<div
class="sc-main-scroll"
:style="{width: contentW + 'px'}"
>
<div class="sc-main">
<div
class="timeline"
:style="{height: settingData.dateDivH + 'px', background: 'black'}"
>
<div
v-for="n in dateCnt"
:key="n"
class="sc-time"
:style="{width: dateDivW + 'px', cursor: 'pointer'}"
="$emit('date-click-event', getHeaderDate(n-1))"
>
{{ getHeaderDate(n-1) }}
</div>
</div>
<div
class="timeline"
:style="{height: settingData.timeDivH + 'px', background: '#6187AE'}"
>
<div
v-for="n in (dateCnt * 24)"
:key="n"
class="sc-time"
:style="{width: timeDivW + 'px'}"
>
{{ getHeaderTime(n - 1) }}
</div>
</div>
<div
v-for="(row, index) in scheduleData"
:key="index"
:class="'timeline'"
:style="{'height': settingData.rowH + 'px'}"
="setDragenterRow(index)"
>
<unit-div
v-for="n in unitCnt"
:key="'unit' + n"
:row-index="index"
:key-index="n"
:row-data="row"
:is-business="isBusiness(index, (n - 1))"
:is-selecting="isSelecting"
:is-selecting-row-index="isSelectingRowIndex"
:width="settingData.unitDivW + 'px'"
-down="selectStartTime"
-enter="adjustTimeRange"
-up="selectEndTime"
-dragenter-row-and-index="setDragenterRowAndIndex"
></unit-div>
<reserved-div
v-for="(detail, keyNo) in row.schedule"
:key="'res' + keyNo"
:schedule-detail="detail"
:row-index="index"
:key-no="keyNo"
:start-text="detail.start"
:end-text="detail.end"
:content-text="detail.text"
:unit-width="settingData.unitDivW"
:unit-height="settingData.rowH"
:title-div-width="settingData.titleDivW"
:border-width="settingData.borderW"
:min-date="settingData.startDate"
:max-date="settingData.endDate"
:unit="settingData.unit"
:clear-switch="clearSwitch"
:dragenter-row-index="dragenterRowIndex"
:dragenter-key-index="dragenterKeyIndex"
:is-selecting="isSelecting"
:is-selecting-row-index="isSelectingRowIndex"
:is-selecting-index="isSelectingIndex"
-dragenter-row-and-index="setDragenterRowAndIndex"
-schedule-data="moveScheduleData"
-schedule-data="editScheduleData"
-schedule-data="deleteScheduleData"
-up="selectEndTime"
-event="$emit('move-event')"
-event="$emit('edit-event', detail.start, detail.end)"
-event="$emit('click-event', detail.start, detail.end, detail.text, detail.data)"
></reserved-div>
</div>
</div>
</div>
</div>
<br class="clear">
</div>
</div>
`
}