@innovation-system/vuetify-week-scheduler
Version:
Vuetify week scheduler for Vue 2
1,422 lines (1,285 loc) • 40 kB
JavaScript
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 };