Skip to content

Commit

Permalink
feat(VCalendar): redo event overlap logic (#9974)
Browse files Browse the repository at this point in the history
resolves #8826
resolves #8928
resolves #8620
resolves #8396
resolves #8792
resolves #8937
resolves #8565
resolves #8400

* refactor(VCalendar): redo event overlap logic

* refactor(VCalendar): clean up code and add remaining styling variables

* refactor(VCalendar): use getSlot where applicable

* refactor(VCalendar): improve getSlot

* refactor(VCalendar): fix test
  • Loading branch information
ClickerMonkey authored and johnleider committed Dec 17, 2019
1 parent 5c0a67c commit 20a7a1a
Show file tree
Hide file tree
Showing 38 changed files with 3,442 additions and 2,756 deletions.
32 changes: 32 additions & 0 deletions packages/api-generator/src/helpers/variables.js
Expand Up @@ -271,6 +271,34 @@ const VTimestamp = {
future: 'boolean',
}

const VCalendarDay = {
outside: 'boolean',
index: 'number',
week: [VTimestamp],
date: 'string',
time: 'string',
year: 'number',
month: 'number',
day: 'number',
hour: 'number',
minute: 'number',
weekday: 'number',
hasDay: 'boolean',
hasTime: 'boolean',
past: 'boolean',
present: 'boolean',
future: 'boolean',
}

const VCalendarEventSlot = {
event: 'any',
day: VCalendarDay,
outside: 'boolean',
start: 'boolean',
end: 'boolean',
timed: 'boolean',
}

const VTimestampWithTime = {
date: 'string',
time: 'string',
Expand All @@ -286,6 +314,8 @@ const VTimestampWithTime = {
present: 'boolean',
future: 'boolean',
timeToY: '(time: string | number | {hour: number, minute: number}, clamp: boolean = false): number',
minutesToPixels: '(minutes: number): number',
week: [VTimestamp],
}

const VSlider = {
Expand Down Expand Up @@ -339,6 +369,8 @@ module.exports = {
VSlider,
VTimestamp,
VTimestampWithTime,
VCalendarDay,
VCalendarEventSlot,
inputSlots,
inputEvents,
sharedGridProps,
Expand Down
18 changes: 15 additions & 3 deletions packages/api-generator/src/maps/v-calendar.js
@@ -1,19 +1,23 @@
const { VTimestamp, VTimestampWithTime } = require('../helpers/variables')
const { VTimestamp, VTimestampWithTime, VCalendarDay, VCalendarEventSlot } = require('../helpers/variables')

module.exports = {
'v-calendar': {
slots: [
{
name: 'event',
props: VCalendarEventSlot,
},
{
name: 'day',
props: VTimestamp,
props: VCalendarDay,
},
{
name: 'day-body',
props: VTimestampWithTime,
},
{
name: 'day-header',
props: VTimestamp,
props: VTimestampWithTime,
},
{
name: 'day-label',
Expand Down Expand Up @@ -61,6 +65,10 @@ module.exports = {
name: 'scrollToTime',
signature: '(time: number | string | { hour: number, minute: number }): boolean',
},
{
name: 'getVisibleEvents',
signature: '(): CalendarEventParsed[]',
},
],
events: [
{
Expand All @@ -83,6 +91,10 @@ module.exports = {
name: 'contextmenu:date',
value: VTimestampWithTime,
},
{
name: 'click:more',
value: VTimestamp,
},
{
name: 'click:day',
value: VTimestampWithTime,
Expand Down
173 changes: 39 additions & 134 deletions packages/docs/src/examples/calendars/complex/events.vue
Expand Up @@ -3,13 +3,13 @@
<v-col>
<v-sheet height="64">
<v-toolbar flat color="white">
<v-btn outlined class="mr-4" @click="setToday">
<v-btn outlined class="mr-4" color="grey darken-2" @click="setToday">
Today
</v-btn>
<v-btn fab text small @click="prev">
<v-btn fab text small color="grey darken-2" @click="prev">
<v-icon small>mdi-chevron-left</v-icon>
</v-btn>
<v-btn fab text small @click="next">
<v-btn fab text small color="grey darken-2" @click="next">
<v-icon small>mdi-chevron-right</v-icon>
</v-btn>
<v-toolbar-title>{{ title }}</v-toolbar-title>
Expand All @@ -18,6 +18,7 @@
<template v-slot:activator="{ on }">
<v-btn
outlined
color="grey darken-2"
v-on="on"
>
<span>{{ typeToLabel[type] }}</span>
Expand Down Expand Up @@ -48,7 +49,6 @@
color="primary"
:events="events"
:event-color="getEventColor"
:event-margin-bottom="3"
:now="today"
:type="type"
@click:event="showEvent"
Expand All @@ -60,7 +60,6 @@
v-model="selectedOpen"
:close-on-content-click="false"
:activator="selectedElement"
full-width
offset-x
>
<v-card
Expand Down Expand Up @@ -106,8 +105,7 @@
<script>
export default {
data: () => ({
today: '2019-01-01',
focus: '2019-01-01',
focus: '',
type: 'month',
typeToLabel: {
month: 'Month',
Expand All @@ -120,132 +118,9 @@
selectedEvent: {},
selectedElement: null,
selectedOpen: false,
events: [
{
name: 'Vacation',
details: 'Going to the beach!',
start: '2018-12-29',
end: '2019-01-01',
color: 'blue',
},
{
name: 'Meeting',
details: 'Spending time on how we do not have enough time',
start: '2019-01-07 09:00',
end: '2019-01-07 09:30',
color: 'indigo',
},
{
name: 'Large Event',
details: 'This starts in the middle of an event and spans over multiple events',
start: '2018-12-31',
end: '2019-01-04',
color: 'deep-purple',
},
{
name: '3rd to 7th',
details: 'Testing',
start: '2019-01-03',
end: '2019-01-07',
color: 'cyan',
},
{
name: 'Big Meeting',
details: 'A very important meeting about nothing',
start: '2019-01-07 08:00',
end: '2019-01-07 11:30',
color: 'red',
},
{
name: 'Another Meeting',
details: 'Another important meeting about nothing',
start: '2019-01-07 10:00',
end: '2019-01-07 13:30',
color: 'brown',
},
{
name: '7th to 8th',
start: '2019-01-07',
end: '2019-01-08',
color: 'blue',
},
{
name: 'Lunch',
details: 'Time to feed',
start: '2019-01-07 12:00',
end: '2019-01-07 15:00',
color: 'deep-orange',
},
{
name: '30th Birthday',
details: 'Celebrate responsibly',
start: '2019-01-03',
color: 'teal',
},
{
name: 'New Year',
details: 'Eat chocolate until you pass out',
start: '2019-01-01',
end: '2019-01-02',
color: 'green',
},
{
name: 'Conference',
details: 'The best time of my life',
start: '2019-01-21',
end: '2019-01-28',
color: 'grey darken-1',
},
{
name: 'Hackathon',
details: 'Code like there is no tommorrow',
start: '2019-01-30 23:00',
end: '2019-02-01 08:00',
color: 'black',
},
{
name: 'event 1',
start: '2019-01-14 18:00',
end: '2019-01-14 19:00',
color: '#4285F4',
},
{
name: 'event 2',
start: '2019-01-14 18:00',
end: '2019-01-14 19:00',
color: '#4285F4',
},
{
name: 'event 5',
start: '2019-01-14 18:00',
end: '2019-01-14 19:00',
color: '#4285F4',
},
{
name: 'event 3',
start: '2019-01-14 18:30',
end: '2019-01-14 20:30',
color: '#4285F4',
},
{
name: 'event 4',
start: '2019-01-14 19:00',
end: '2019-01-14 20:00',
color: '#4285F4',
},
{
name: 'event 6',
start: '2019-01-14 21:00',
end: '2019-01-14 23:00',
color: '#4285F4',
},
{
name: 'event 7',
start: '2019-01-14 22:00',
end: '2019-01-14 23:00',
color: '#4285F4',
},
],
events: [],
colors: ['blue', 'indigo', 'deep-purple', 'cyan', 'green', 'orange', 'grey darken-1'],
names: ['Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party'],
}),
computed: {
title () {
Expand Down Expand Up @@ -319,15 +194,45 @@
nativeEvent.stopPropagation()
},
updateRange ({ start, end }) {
// You could load events from an outside source (like database) now that we have the start and end dates on the calendar
const events = []
const min = new Date(`${start.date}T00:00:00`)
const max = new Date(`${end.date}T23:59:59`)
const days = (max.getTime() - min.getTime()) / 86400000
const eventCount = this.rnd(days, days + 20)
for (let i = 0; i < eventCount; i++) {
const allDay = this.rnd(0, 3) === 0
const firstTimestamp = this.rnd(min.getTime(), max.getTime())
const first = new Date(firstTimestamp - (firstTimestamp % 900000))
const secondTimestamp = this.rnd(2, allDay ? 288 : 8) * 900000
const second = new Date(first.getTime() + secondTimestamp)
events.push({
name: this.names[this.rnd(0, this.names.length - 1)],
start: this.formatDate(first, !allDay),
end: this.formatDate(second, !allDay),
color: this.colors[this.rnd(0, this.colors.length - 1)],
})
}
this.start = start
this.end = end
this.events = events
},
nth (d) {
return d > 3 && d < 21
? 'th'
: ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'][d % 10]
},
rnd (a, b) {
return Math.floor((b - a + 1) * Math.random()) + a
},
formatDate (a, withTime) {
return withTime
? `${a.getFullYear()}-${a.getMonth() + 1}-${a.getDate()} ${a.getHours()}:${a.getMinutes()}`
: `${a.getFullYear()}-${a.getMonth() + 1}-${a.getDate()}`
},
},
}
</script>

0 comments on commit 20a7a1a

Please sign in to comment.