UNPKG

@innovation-system/vuetify-week-scheduler

Version:
1,422 lines (1,285 loc) 40 kB
import { VIcon, VBtn, VHover, VTextField, VListItem, VList, VMenu } from 'vuetify/lib'; // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // var script$1 = { components: { VIcon: VIcon, VBtn: VBtn, VHover: VHover }, name: "vuetify-week-scheduler-period", props: { period: Object, settings: Object, blockHeight: Number, editable: { type: Boolean, default: false } }, computed: { options() { return this.period.options; }, shortPeriod() { return this.period.height <= 30; } } }; function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) { if (typeof shadowMode !== 'boolean') { createInjectorSSR = createInjector; createInjector = shadowMode; shadowMode = false; } // Vue.extend constructor export interop. const options = typeof script === 'function' ? script.options : script; // render functions if (template && template.render) { options.render = template.render; options.staticRenderFns = template.staticRenderFns; options._compiled = true; // functional template if (isFunctionalTemplate) { options.functional = true; } } // scopedId if (scopeId) { options._scopeId = scopeId; } let hook; if (moduleIdentifier) { // server build hook = function (context) { // 2.3 injection context = context || // cached call (this.$vnode && this.$vnode.ssrContext) || // stateful (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional // 2.2 with runInNewContext: true if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { context = __VUE_SSR_CONTEXT__; } // inject component styles if (style) { style.call(this, createInjectorSSR(context)); } // register component module identifier for async chunk inference if (context && context._registeredComponents) { context._registeredComponents.add(moduleIdentifier); } }; // used by ssr in case component is cached and beforeCreate // never gets called options._ssrRegister = hook; } else if (style) { hook = shadowMode ? function (context) { style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot)); } : function (context) { style.call(this, createInjector(context)); }; } if (hook) { if (options.functional) { // register for functional component in vue file const originalRender = options.render; options.render = function renderWithStyleInjection(h, context) { hook.call(context); return originalRender(h, context); }; } else { // inject component registration as beforeCreate hook const existing = options.beforeCreate; options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; } } return script; } /* script */ const __vue_script__$1 = script$1; /* template */ var __vue_render__$1 = function () { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c('v-hover', { scopedSlots: _vm._u([{ key: "default", fn: function (ref) { var hover = ref.hover; return [_c('div', { staticClass: "vws-period", style: { backgroundColor: _vm.options.backgroundColor, outlineColor: _vm.options.borderColor, textColor: _vm.options.textColor, color: _vm.options.textColor, top: _vm.period.top + 'px', height: _vm.period.height + 'px' }, on: { "mousedown": function ($event) { $event.stopPropagation(); return _vm.$emit('period-drag', $event); }, "touchstart": function ($event) { $event.stopPropagation(); return _vm.$emit('period-drag', $event); }, "contextmenu": function ($event) { $event.stopPropagation(); $event.preventDefault(); return _vm.$emit('edit', $event); }, "dblclick": function ($event) { $event.stopPropagation(); $event.preventDefault(); return _vm.$emit('edit', $event); } } }, [_c('div', { staticClass: "vws-period-container" }, [_c('v-icon', { directives: [{ name: "show", rawName: "v-show", value: _vm.editable && hover, expression: "editable && hover" }], staticClass: "vws-handle", attrs: { "small": "" }, on: { "mousedown": function ($event) { $event.stopPropagation(); return _vm.$emit('period-resize', { $event: $event, isUp: true, $el: _vm.$el }); }, "touchstart": function ($event) { $event.stopPropagation(); return _vm.$emit('period-resize', { $event: $event, isUp: true, $el: _vm.$el }); } } }, [_vm._v("\n mdi-chevron-up\n ")]), _vm._v(" "), _c('div', { staticClass: "vws-period-time" }, [_vm._v("\n " + _vm._s(_vm.options.start) + " - " + _vm._s(_vm.options.end) + "\n "), _c('span', { directives: [{ name: "show", rawName: "v-show", value: _vm.shortPeriod, expression: "shortPeriod" }], staticClass: "text--caption ml-2" }, [_vm._v(_vm._s(_vm.options.title))])]), _vm._v(" "), _c('div', { directives: [{ name: "show", rawName: "v-show", value: !_vm.shortPeriod, expression: "!shortPeriod" }], staticClass: "vws-period-title text-truncate" }, [_vm._v("\n " + _vm._s(_vm.options.title) + "\n ")]), _vm._v(" "), _c('div', { directives: [{ name: "show", rawName: "v-show", value: _vm.editable && hover, expression: "editable && hover" }], staticClass: "vws-period-buttons", attrs: { "justify": "end" } }, [_c('v-btn', { attrs: { "icon": "", "x-small": "", "title": _vm.settings.periodRemoveButton }, on: { "click": function ($event) { $event.stopPropagation(); return _vm.$emit('delete'); }, "mousedown": function ($event) { $event.stopPropagation(); }, "touchstart": function ($event) { $event.stopPropagation(); } } }, [_c('v-icon', { attrs: { "x-small": "" } }, [_vm._v("mdi-close")])], 1), _vm._v(" "), _c('v-btn', { attrs: { "icon": "", "x-small": "", "title": _vm.settings.periodDuplicateButton }, on: { "click": function ($event) { $event.stopPropagation(); return _vm.$emit('clone'); }, "mousedown": function ($event) { $event.stopPropagation(); }, "touchstart": function ($event) { $event.stopPropagation(); } } }, [_c('v-icon', { attrs: { "x-small": "" } }, [_vm._v("mdi-content-copy")])], 1)], 1), _vm._v(" "), _c('v-icon', { directives: [{ name: "show", rawName: "v-show", value: _vm.editable && hover, expression: "editable && hover" }], staticClass: "vws-handle", staticStyle: { "bottom": "0" }, attrs: { "small": "" }, on: { "mousedown": function ($event) { $event.stopPropagation(); return _vm.$emit('period-resize', { $event: $event, isUp: false, $el: _vm.$el }); }, "touchstart": function ($event) { $event.stopPropagation(); return _vm.$emit('period-resize', { $event: $event, isUp: false, $el: _vm.$el }); } } }, [_vm._v("\n mdi-chevron-down\n ")])], 1)])]; } }]) }); }; var __vue_staticRenderFns__$1 = []; /* style */ const __vue_inject_styles__$1 = undefined; /* scoped */ const __vue_scope_id__$1 = undefined; /* module identifier */ const __vue_module_identifier__$1 = undefined; /* functional template */ const __vue_is_functional_template__$1 = false; /* style inject */ /* style inject SSR */ /* style inject shadow dom */ const __vue_component__$1 = /*#__PURE__*/normalizeComponent({ render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 }, __vue_inject_styles__$1, __vue_script__$1, __vue_scope_id__$1, __vue_is_functional_template__$1, __vue_module_identifier__$1, false, undefined, undefined, undefined); var script = { name: "vuetify-week-scheduler", // vue component name components: { SchedulerPeriod: __vue_component__$1, VIcon: VIcon, VBtn: VBtn, VHover: VHover, VTextField: VTextField, VListItem: VListItem, VList: VList, VMenu: VMenu }, props: { config: { type: Object, default: () => {} }, value: { type: Array, required: true }, editable: { type: Boolean, default: false } }, data() { return { settings: {}, counter: 0, blocksEachHour: 0, maxBlocks: 0, blockHeight: 0, events: [], // keep track of listeners newPeriod: null, draggingPeriod: null, resizingPeriod: null, showEditMenu: false, x: 0, y: 0, editEvent: null }; }, mounted() { this.settings = { ...this.getDefaults(), ...this.config }; this.init(); this.handleEvents(); }, beforeDestroy() { this.events.forEach(e => { e.element.removeEventListener(e.event, e.callback); }); }, computed: { data: { get() { let toReturn = this.value; // validate data object if (this.value.length !== this.settings.days) { toReturn = []; for (let i = 0; i < this.settings.days; i++) { toReturn.push({ day: i, periods: [] }); } this.$emit("input", toReturn); } return toReturn; }, set(value) { this.$emit("input", value); } }, daysPeriods() { const toReturn = []; for (let d = 0; d < this.settings.days; d++) { const toPush = { day: d, periods: [] }; toReturn.push(toPush); const day = this.data?.[d]; if (day) { for (let i = 0; i < day.periods.length; i++) { const period = day.periods[i]; const start = this.positionFormat(period.start); const end = this.positionFormat(period.end); toPush.periods.push({ options: this.addDefaults(period), index: i, top: start * this.blockHeight, height: (end - start) * this.blockHeight }); } } } return toReturn; }, isMobile() { return this.$vuetify.breakpoint.mdAndDown; } }, methods: { getDefaults() { return { hour: 24, // 12 days: 7, // 7/5 periodDuration: 15, // 15/30/60 periodTitle: "", periodBackgroundColor: "#F44336FF", periodBorderColor: "transparent", periodTextColor: "#000", periodRemoveButton: "Remove", periodDuplicateButton: "Duplicate", periodSelectWholeButton: "Select whole day", inputType: "text", daysList: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], colors: ["#F44336", "#FF9800", "#FFEB3B", "#8BC34A", "#4CAF50", "#00BCD4", "#2196F3"] }; }, /** When clicking on a day */ onDayDown(day, e) { if (!this.editable) return; const rect = e.currentTarget.getBoundingClientRect(); const offset = this.getY(e, true) - rect.top; const blocks = Math.floor(offset / this.blockHeight); const start = this.blocksToTime(blocks); const end = this.blocksToTime(blocks + 2); const height = 2 * this.blockHeight; // show the ghost period this.newPeriod = { dragStart: this.getY(e, true), startHeight: height, maxHeight: e.currentTarget.clientHeight, day, start, end, top: blocks * this.blockHeight, height }; }, /** Add defaults to period */ addDefaults(period) { return { title: this.settings.periodTitle, backgroundColor: this.settings.periodBackgroundColor, borderColor: this.settings.periodBorderColor, textColor: this.settings.periodTextColor, ...period }; }, handleEvents() { const onUp = () => { if (this.newPeriod) { this.addPeriod(this.newPeriod.day, { start: this.newPeriod.start, end: this.newPeriod.end }); this.newPeriod = null; } else if (this.draggingPeriod) { const { el, day, index } = this.draggingPeriod; const top = el.offsetTop; const height = el.clientHeight; this.onPositionChange(day, index, { top, height }); this.draggingPeriod = null; } else if (this.resizingPeriod) { const { el, day, index } = this.resizingPeriod; const top = el.offsetTop; const height = el.clientHeight; this.onPositionChange(day, index, { top, height }); this.resizingPeriod = null; } }; const onMove = e => { if (this.newPeriod) { e.preventDefault(); const dragDelta = this.roundBlock(this.newPeriod.dragStart - this.getY(e, true)); const height = this.roundBlock(this.newPeriod.startHeight - dragDelta); if (height > this.blockHeight && this.newPeriod.top + height <= this.newPeriod.maxHeight) { const { start, end } = this.positionToInterval(this.newPeriod); const { periods } = this.data[this.newPeriod.day]; if (this.isValid({ start, end }, periods)) { Object.assign(this.newPeriod, { height, start, end }); } } } else if (this.draggingPeriod) { e.preventDefault(); const { startDrag, startTop, el, day, index } = this.draggingPeriod; const dragDelta = startDrag - this.getY(e, true); const top = this.roundBlock(startTop - dragDelta); const height = el.clientHeight; const maxHeight = el.parentElement.clientHeight; if (top + height <= maxHeight && top >= 0) { el.style.top = `${top}px`; this.onPositionChange(day, index, { top, height }); } } else if (this.resizingPeriod) { e.preventDefault(); const { startDrag, startTop, startHeight, el, day, index, isUp } = this.resizingPeriod; const dragDelta = this.roundBlock(startDrag - this.getY(e, true)); const top = isUp ? this.roundBlock(startTop - dragDelta) : el.offsetTop; let height = this.roundBlock(startHeight + (isUp ? dragDelta : -dragDelta)); const maxHeight = document.querySelector(".vws-day").clientHeight; height = Math.max(height, this.blockHeight); if (top + height <= maxHeight && top >= 0) { el.style.height = `${height}px`; if (isUp) { el.style.top = `${top}px`; } this.onPositionChange(day, index, { top, height }); } } }; this.addListener(document, "mouseup", onUp); this.addListener(document, "touchend", onUp); this.addListener(document, "mousemove", onMove); this.addListener(document, "touchmove", onMove); }, onPeriodDown(e, day, index) { if (this.editable) { const el = e.currentTarget; this.draggingPeriod = { el, day, index, startDrag: this.getY(e, false), startTop: el.offsetTop }; } }, onPeriodResize(event, day, index) { if (this.editable) { const { $event: e, isUp, $el } = event; this.resizingPeriod = { el: $el, day, index, isUp, startDrag: this.getY(e, false), startTop: $el.offsetTop, startHeight: $el.clientHeight }; } }, addPeriod(day, period) { if (!this.data[day]) { this.data[day] = { day, periods: [] }; } const { periods } = this.data[day]; period = this.addDefaults(period); if (this.isValid(period, periods)) { periods.push(period); } }, init() { try { // duration validation if (![15, 30, 60].includes(this.settings.periodDuration)) { throw new Error("Invalide period duration"); } this.blocksEachHour = 60 / this.settings.periodDuration; // How many blocks there are in an hour this.maxBlocks = 24 * this.blocksEachHour; // Period height in blocks this.blockHeight = 40 / this.blocksEachHour; // Pixel height of each block // periods validation this.data.forEach(d => { d?.periods.forEach((period, i) => { if (!this.isValid(period, d.periods)) { d.periods.splice(i, 1); // eslint-disable-next-line no-console console.error("Invalid period duration", period); } }); }); } catch (error) { this.$emit("error", error); } }, deletePeriod(day, index) { this.data[day].periods.splice(index, 1); }, clonePeriod(day, indexOrPeriod) { const period = typeof indexOrPeriod === "object" ? indexOrPeriod : this.data[day].periods[indexOrPeriod]; for (const d of this.data) { if (d.day !== day && this.isValid(period, d.periods)) { d.periods.push({ ...period }); } } }, clearDayPeriods(day) { if (this.data[day]) { this.data[day].periods = []; } }, cloneDayPeriods(day) { if (this.data[day]) { const { periods } = this.data[day]; for (const d of this.data) { if (d.day !== day) { for (const p of periods) { this.clonePeriod(day, p); } } } } }, async onPositionChange(day, periodIndex, pos) { day = this.data?.[day]; const period = day?.periods[periodIndex]; if (period) { const { start, end } = this.positionToInterval(pos); const oldStart = period.start; const oldEnd = period.end; Object.assign(period, { start, end }); await this.$nextTick(); if (!this.isValid(period, day.periods)) { Object.assign(period, { start: oldStart, end: oldEnd }); } } }, /** Round val to nearest multiple of blockHeight */ roundBlock(val) { return Math.round(val / this.blockHeight) * this.blockHeight; }, /** Returns start/end hours string (hh:mm) from period top/height in pixel */ positionToInterval(pos) { return { start: this.blocksToTime(pos.top / this.blockHeight), end: this.blocksToTime(Math.floor((pos.top + pos.height) / this.blockHeight)) }; }, /** * Return a readable hour from a block position * @param position * @returns {number} */ blocksToTime(nBlocks) { if (nBlocks > this.maxBlocks) { nBlocks = 0; } if (nBlocks < 0) { nBlocks = 0; } let hour = Math.floor(nBlocks / this.blocksEachHour); let mn = (nBlocks / this.blocksEachHour - hour) * 60; if (this.settings.hour === 12) { let time = hour; let ind = ""; if (hour >= 12) { ind = "p"; } if (hour > 12) { time = hour - 12; } if (hour === 0 || hour === 24) { ind = ""; time = 12; } if (mn !== 0) { time += `:${mn}`; } return time + ind; } if (hour < 10) { hour = `0${hour}`; } if (mn < 10) { mn = `0${mn}`; } // back compatibility when period ends on 23:59 if (hour === 23 && mn === 59) { hour = "24"; mn = "00"; } return `${hour}:${mn}`; }, /** Hour to string */ formatHour(hour) { if (this.settings.hour === 12) { switch (hour) { case 0: case 24: hour = "12am"; break; case 12: hour = "12pm"; break; default: if (hour > 12) { hour = `${hour - 12}pm`; } else { hour += "am"; } } } else { if (hour > 24) { hour = 0; } if (hour < 10) { hour = `0${hour}`; } hour += ":00"; } return hour; }, /** * Return blocks from a time string (hh:mm) * @param time * @returns {number} */ positionFormat(time) { const split = time.split(":"); let hour = parseInt(split[0], 10); let mn = parseInt(split[1], 10); if (this.settings.hour === 12) { const matches = time.match(/([0-1]?[0-9]):?([0-5][0-9])?\s?(am|pm|p)?/); let ind = matches[3]; if (!ind) { ind = "am"; } hour = parseInt(matches[1], 10); mn = parseInt(matches[2], 10); if (!mn) { mn = 0; } if (hour === 12 && ind === "am") { hour = 0; } if (hour === 12 && (ind === "pm" || ind === "p")) { ind = "am"; } if (ind === "pm" || ind === "p") { hour += 12; } } let position = 0; position += hour * this.blocksEachHour; position += mn / 60 * this.blocksEachHour; // if (Math.floor(position) !== position) { // return -1 // } return position; }, /** * Check if a period is valid * @param current * @returns {boolean} */ isValid(current, periods) { const currentStart = this.positionFormat(current.start); const currentEnd = this.positionFormat(current.end); let start = 0; let end = 0; let check = true; for (const p of periods) { if (p !== current) { start = this.positionFormat(p.start); end = this.positionFormat(p.end); if (start > currentStart && start < currentEnd) { check = false; } if (end > currentStart && end < currentEnd) { check = false; } if (start < currentStart && end > currentEnd) { check = false; } if (start === currentStart || end === currentEnd) { check = false; } if (!check) { break; } } } return check; }, addListener(element, event, callback, options) { this.events.push({ element, event, callback }); element.addEventListener(event, callback, options); }, async editPeriod(day, index, e) { if (this.editable) { if (this.$listeners.edit) { this.$emit("edit", { day, index }); } else { e.preventDefault(); this.showEditMenu = false; this.x = e.clientX; this.y = e.clientY; const { periods } = this.value[day]; this.editEvent = periods[index]; await this.$nextTick(); this.showEditMenu = true; } } }, getY(e, prevent) { let y = null; if (e.type === "touchstart" || e.type === "touchmove" || e.type === "touchend" || e.type === "touchcancel") { if (prevent) { e.preventDefault(); } const touch = e.touches[0] || e.changedTouches[0]; y = touch.clientY; } else if (e.type === "mousedown" || e.type === "mouseup" || e.type === "mousemove" || e.type === "mouseover" || e.type === "mouseout" || e.type === "mouseenter" || e.type === "mouseleave") { y = e.clientY; } return y; }, selectWholeDay(day) { if (this.data[day]) { const { periods } = this.data[day]; if (periods.length > 0) { periods[0].start = "00:00"; periods[0].end = "24:00"; this.data[day].periods = [periods[0]]; } else { this.data[day].periods = [{ start: "00:00", end: "24:00", title: this.settings.periodTitle, backgroundColor: this.settings.periodBackgroundColor, borderColor: this.settings.periodBorderColor, textColor: this.settings.periodTextColor }]; } } } } }; const isOldIE = typeof navigator !== 'undefined' && /msie [6-9]\\b/.test(navigator.userAgent.toLowerCase()); function createInjector(context) { return (id, style) => addStyle(id, style); } let HEAD; const styles = {}; function addStyle(id, css) { const group = isOldIE ? css.media || 'default' : id; const style = styles[group] || (styles[group] = { ids: new Set(), styles: [] }); if (!style.ids.has(id)) { style.ids.add(id); let code = css.source; if (css.map) { // https://developer.chrome.com/devtools/docs/javascript-debugging // this makes source maps inside style tags work properly in Chrome code += '\n/*# sourceURL=' + css.map.sources[0] + ' */'; // http://stackoverflow.com/a/26603875 code += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) + ' */'; } if (!style.element) { style.element = document.createElement('style'); style.element.type = 'text/css'; if (css.media) style.element.setAttribute('media', css.media); if (HEAD === undefined) { HEAD = document.head || document.getElementsByTagName('head')[0]; } HEAD.appendChild(style.element); } if ('styleSheet' in style.element) { style.styles.push(code); style.element.styleSheet.cssText = style.styles .filter(Boolean) .join('\n'); } else { const index = style.ids.size - 1; const textNode = document.createTextNode(code); const nodes = style.element.childNodes; if (nodes[index]) style.element.removeChild(nodes[index]); if (nodes.length) style.element.insertBefore(textNode, nodes[index]); else style.element.appendChild(textNode); } } } /* script */ const __vue_script__ = script; /* template */ var __vue_render__ = function () { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c('div', { staticClass: "vws vws-mode-edit vws-mode-7" }, [_c('table', { staticClass: "vws-table" }, [_c('tbody', [_c('tr', _vm._l(_vm.daysPeriods, function (day) { return _c('td', { key: 'day-' + day.day }, [_c('div', { ref: "day", refInFor: true, staticClass: "vws-day", on: { "touchstart": function ($event) { return _vm.onDayDown(day.day, $event); }, "mousedown": function ($event) { return _vm.onDayDown(day.day, $event); } } }, [_vm._l(day.periods, function (p, i) { return _c('scheduler-period', { key: i, attrs: { "period": p, "settings": _vm.settings, "blockHeight": _vm.blockHeight, "editable": _vm.editable }, on: { "period-drag": function ($event) { return _vm.onPeriodDown($event, day.day, p.index); }, "period-resize": function ($event) { return _vm.onPeriodResize($event, day.day, p.index); }, "position-change": function ($event) { return _vm.onPositionChange(day.day, p.index, $event); }, "delete": function ($event) { return _vm.deletePeriod(day.day, p.index); }, "clone": function ($event) { return _vm.clonePeriod(day.day, p.index); }, "edit": function ($event) { return _vm.editPeriod(day.day, p.index, $event); } } }); }), _vm._v(" "), _vm.newPeriod && _vm.newPeriod.day === day.day ? _c('div', { staticClass: "vws-period-helper", style: { top: _vm.newPeriod.top + "px", height: _vm.newPeriod.height + "px" } }, [_c('div', { staticClass: "vws-period-helper-time" }, [_vm._v("\n " + _vm._s(_vm.newPeriod.start) + " - " + _vm._s(_vm.newPeriod.end) + "\n ")])]) : _vm._e()], 2)]); }), 0)])]), _vm._v(" "), _c('div', { staticClass: "vws-grid" }, [_c('div', { staticClass: "vws-grid-head" }, _vm._l(_vm.settings.days, function (n) { return _c('div', { key: n, staticClass: "vws-grid-day" }, [_c('v-hover', { scopedSlots: _vm._u([{ key: "default", fn: function (ref) { var hover = ref.hover; return [_c('div', [_c('strong', [_vm._v("\n " + _vm._s(!_vm.isMobile ? _vm.settings.daysList[n - 1] : _vm.settings.daysList[n - 1].slice(0, 3)) + "\n ")]), _vm._v(" "), _c('v-btn', { directives: [{ name: "show", rawName: "v-show", value: _vm.editable && hover, expression: "editable && hover" }], attrs: { "icon": "", "x-small": "", "title": _vm.settings.periodRemoveButton }, on: { "click": function ($event) { return _vm.clearDayPeriods(n - 1); } } }, [_c('v-icon', { attrs: { "x-small": "" } }, [_vm._v("mdi-close")])], 1), _vm._v(" "), _c('v-btn', { directives: [{ name: "show", rawName: "v-show", value: _vm.editable && hover, expression: "editable && hover" }], attrs: { "icon": "", "x-small": "", "title": _vm.settings.periodDuplicateButton }, on: { "click": function ($event) { return _vm.cloneDayPeriods(n - 1); } } }, [_c('v-icon', { attrs: { "x-small": "" } }, [_vm._v("mdi-content-copy")])], 1), _vm._v(" "), _c('v-btn', { directives: [{ name: "show", rawName: "v-show", value: _vm.editable && hover, expression: "editable && hover" }], attrs: { "icon": "", "x-small": "", "title": _vm.settings.periodSelectWholeButton }, on: { "click": function ($event) { return _vm.selectWholeDay(n - 1); } } }, [_c('v-icon', { attrs: { "x-small": "" } }, [_vm._v("mdi-select-all")])], 1)], 1)]; } }], null, true) })], 1); }), 0), _vm._v(" "), _vm._l(25, function (n) { return _c('div', { key: n, staticClass: "vws-grid-line" }, [_c('div', { staticClass: "vws-grid-hour" }, [_vm._v(_vm._s(_vm.formatHour(n - 1)))])]); })], 2), _vm._v(" "), _vm.showEditMenu ? _c('v-menu', { attrs: { "position-x": _vm.x, "position-y": _vm.y, "absolute": "", "offset-y": "", "close-on-content-click": false }, model: { value: _vm.showEditMenu, callback: function ($$v) { _vm.showEditMenu = $$v; }, expression: "showEditMenu" } }, [_c('v-list', { attrs: { "dense": "" } }, [_c('v-list-item', [_c('v-text-field', { attrs: { "label": "Title", "required": "", "type": _vm.settings.inputType }, model: { value: _vm.editEvent.title, callback: function ($$v) { _vm.$set(_vm.editEvent, "title", $$v); }, expression: "editEvent.title" } })], 1), _vm._v(" "), _c('v-list-item', { staticClass: "d-flex", staticStyle: { "max-width": "300px" } }, _vm._l(_vm.settings.colors, function (c) { return _c('v-btn', { key: c, attrs: { "icon": "", "elevation": _vm.editEvent.backgroundColor === c ? 10 : 0 } }, [_c('v-icon', { attrs: { "color": c, "size": "35px" }, on: { "click": function ($event) { _vm.editEvent.backgroundColor = c; } } }, [_vm._v("mdi-circle")])], 1); }), 1)], 1)], 1) : _vm._e()], 1); }; var __vue_staticRenderFns__ = []; /* style */ const __vue_inject_styles__ = function (inject) { if (!inject) return; inject("data-v-6e1cde99_0", { source: ".vws{position:relative;padding:40px 20px 20px 60px;font-family:system,-apple-system,Roboto,Helvetica Neue,Arial,Helvetica,Geneva,sans-serif;box-sizing:border-box;z-index:1}.vws-mode-edit{cursor:pointer}.vws-mode-edit .ui-draggable-dragging{cursor:move}.vws-mode-5 .vws-grid-day,.vws-mode-5 .vws-table td{width:20%}.vws-table{position:relative;z-index:8;width:100%;margin-bottom:20px;border-collapse:collapse;border-spacing:0;box-sizing:content-box}.vws-table td,.vws-table th{padding:0}.vws-table td{position:relative;width:14.28571%;border-left:1px solid #ccc;border-right:1px solid #ccc}.vws-grid{position:absolute;top:40px;left:60px;right:20px;box-sizing:content-box}.vws-grid-head{position:absolute;top:-30px;left:0;right:0;display:flex}.vws-grid-day{position:relative;width:14.28571%;padding:8px 0 4px 0;text-align:center;font-size:12px}.vws-grid-day-buttons .vws-day-duplicate,.vws-grid-day-buttons .vws-day-remove,.vws-grid-day:hover .vws-day-duplicate,.vws-grid-day:hover .vws-day-remove{display:block}.vws-grid-line{border-top:1px solid #ccc;border-bottom:1px solid transparent;position:relative;height:38px;box-sizing:content-box}.vws-grid-line:last-child{height:0;border-bottom:none}.vws-grid-line:before{content:\"\";position:absolute;top:50%;height:1px;width:100%;background:#eee}.vws-grid-hour{position:absolute;top:-7px;left:-50px;display:block;width:42px;font-size:12px;text-align:right}.vws-day{width:100%;height:960px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;touch-action:none}.vws-day-remove{bottom:20px;right:2px}.vws-day-duplicate{bottom:4px;right:2px}.vws-period-helper{position:absolute;width:100%;min-height:10px}.vws-period-helper:after{content:\"\";display:block;position:absolute;top:2px;bottom:2px;left:2px;right:2px;background-color:rgba(204,204,204,.2)}.vws-period-helper-time{padding:2px 0 0 5px;font-size:11px;font-weight:700;line-height:16px;letter-spacing:-.5px;color:#666}.vws-handle{position:absolute!important;left:calc(50% - 8px);cursor:ns-resize}.vws-day-duplicate,.vws-day-remove{display:none;position:absolute;height:10px;width:10px;cursor:pointer;background-size:100% 100%}.vws-period{cursor:pointer;border-radius:5px;touch-action:none;outline:1px solid #ccc}.vws-period{position:absolute;width:100%;min-height:10px}.vws-period:hover .vws-period:hover{display:block}.vws-period-time,.vws-period-title{display:block;line-height:20px;letter-spacing:-.5px;word-break:break-all;overflow:hidden}.vws-period-title{font-size:15px}.vws-period-time{font-size:11px;font-weight:700;line-height:16px}.vws-period-container{position:absolute;top:2px;bottom:2px;left:2px;right:2px;padding:0 3px;border-radius:3px;box-sizing:border-box}.vws-period-buttons{position:absolute;bottom:0;right:0}", map: undefined, media: undefined }); }; /* scoped */ const __vue_scope_id__ = undefined; /* module identifier */ const __vue_module_identifier__ = undefined; /* functional template */ const __vue_is_functional_template__ = false; /* style inject SSR */ /* style inject shadow dom */ const __vue_component__ = /*#__PURE__*/normalizeComponent({ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, false, createInjector, undefined, undefined); // Import vue component // IIFE injects install function into component, allowing component // to be registered via Vue.use() as well as Vue.component(), var entry_esm = /* #__PURE__ */(() => { // Get component instance const installable = __vue_component__; // Attach install function executed by Vue.use() installable.install = Vue => { Vue.component("vuetify-week-scheduler", installable); }; return installable; })(); // It's possible to expose named exports when writing components that can // also be used as directives, etc. - eg. import { RollupDemoDirective } from 'rollup-demo'; // export const RollupDemoDirective = directive; export { entry_esm as default };