Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(VCalendar): timed event sorting #7806

Merged
merged 6 commits into from
Jul 30, 2019
Merged

fix(VCalendar): timed event sorting #7806

merged 6 commits into from
Jul 30, 2019

Conversation

ClickerMonkey
Copy link
Contributor

Use cases in #7777 highlighted sorting issues with timed events. Now If something is offset it will be placed over a column, instead of the opposite.

Description

Event ordering is fixed

Motivation and Context

Fix for #7777

How Has This Been Tested?

Visually

Markup:

<template>
  <v-sheet class="v-fullscreen" color="grey lighten-1">
    <v-toolbar fixed flat app color="white">
      <v-btn outline @click="setToday" class="mr-3">
        Today
      </v-btn>
      <v-btn fab text small @click="prev">
        <v-icon small>arrow_back_ios</v-icon>
      </v-btn>
      <v-btn fab text small @click="next">
        <v-icon small>arrow_forward_ios</v-icon>
      </v-btn>
      <v-toolbar-title>{{ title }}</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-menu bottom right>
        <template v-slot:activator="{ on }">
          <v-btn outline v-on="on">
            <span>{{ typeToLabel[type] }}</span>
            <v-icon right>arrow_drop_down</v-icon>
          </v-btn>
        </template>
        <v-list>
          <v-list-item @click="type = 'day'">
            <v-list-item-title>Day</v-list-item-title>
          </v-list-item>
          <v-list-item @click="type = 'week'">
            <v-list-item-title>Week</v-list-item-title>
          </v-list-item>
          <v-list-item @click="type = 'month'">
            <v-list-item-title>Month</v-list-item-title>
          </v-list-item>
          <v-list-item @click="type = '4day'">
            <v-list-item-title>4 days</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </v-toolbar>
    <v-calendar
      ref="calendar"
      color="primary"
      :events="events"
      :event-color="getEventColor"
      :now="today"
      :type="type"
      v-model="focus"
      @click:event="showEvent"
      @click:more="viewDay"
      @click:date="viewDay"
      @change="updateRange"
    ></v-calendar>
    <v-menu
      v-model="selectedOpen"
      :close-on-content-click="false"
      :activator="selectedElement"
      full-width
      offset-x
    >
      <v-card
        color="grey lighten-4"
        min-width="350px"
        flat
      >
        <v-toolbar
          :color="selectedEvent.color"
          dark
        >
          <v-btn icon>
            <v-icon>edit</v-icon>
          </v-btn>
          <v-toolbar-title v-html="selectedEvent.name"></v-toolbar-title>
          <v-spacer></v-spacer>
          <v-btn icon>
            <v-icon>favorite</v-icon>
          </v-btn>
          <v-btn icon>
            <v-icon>more_vert</v-icon>
          </v-btn>
        </v-toolbar>
        <v-card-title primary-title>
          <span v-html="selectedEvent.details"></span>
        </v-card-title>
        <v-card-actions>
          <v-btn
            text
            color="secondary"
          >
            Cancel
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-menu>
  </v-sheet>
</template>

<script>
export default {
  data: () => ({
    today: '2019-01-08',
    focus: '2019-01-08',
    type: 'month',
    typeToLabel: {
      'month': 'Month',
      'week': 'Week',
      'day': 'Day',
      '4day': '4 Days'
    },
    start: null,
    end: null,
    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'
      },
      {
        name: 'Mash Potatoes 1',
        start: '2019-01-09 12:30',
        end: '2019-01-09 15:30',
        color: '#000000'
      },
      {
        name: 'Mash Potatoes 2',
        start: '2019-01-09 11:30',
        end: '2019-01-09 15:30',
        color: '#000000'
      },
      {
        name: 'Mash Potatoes 3',
        start: '2019-01-09 10:30',
        end: '2019-01-09 15:30',
        color: '#000000'
      },
      {
        name: 'Mash Potatoes 4',
        start: '2019-01-09 11:30',
        end: '2019-01-09 15:30',
        color: '#000000'
      }
    ]
  }),
  computed: {
    title () {
      const { start, end } = this
      if (!start || !end) {
        return ''
      }

      const startMonth = this.monthFormatter(start)
      const endMonth = this.monthFormatter(end)
      const suffixMonth = startMonth === endMonth ? '' : endMonth

      const startYear = start.year
      const endYear = end.year
      const suffixYear = startYear === endYear ? '' : endYear

      const startDay = start.day + this.nth(start.day)
      const endDay = end.day + this.nth(end.day)

      switch (this.type) {
        case 'month':
          return `${startMonth} ${startYear}`
        case 'week':
        case '4day':
          return `${startMonth} ${startDay} ${startYear} - ${suffixMonth} ${endDay} ${suffixYear}`
        case 'day':
          return `${startMonth} ${startDay} ${startYear}`
      }
      return ''
    },
    monthFormatter () {
      return this.$refs.calendar.getFormatter({
        timeZone: 'UTC', month: 'long'
      })
    }
  },
  methods: {
    viewDay ({date}) {
      this.focus = date
      this.type = 'day'
    },
    getEventColor (event) {
      return event.color
    },
    setToday () {
      this.focus = this.today
    },
    prev () {
      this.$refs.calendar.prev()
    },
    next () {
      this.$refs.calendar.next()
    },
    showEvent ({ nativeEvent, event }) {
      const open = () => {
        this.selectedEvent = event
        this.selectedElement = nativeEvent.target
        this.selectedOpen = true
      }

      if (this.selectedOpen) {
        this.selectedOpen = false
        setTimeout(open, 10)
      } else {
        open()
      }

      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
      this.start = start
      this.end = end
    },
    nth(d) {
      return d > 3 && d < 21
        ? 'th'
        : ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'][d % 10]
    }
  }
}
</script>

<style scoped>
  .v-fullscreen {
    position: absolute;
    padding-top: 1px;
    top: 0px;
    left: 0px;
    right: 0px;
    bottom: 0px;
  }
</style>

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Improvement/refactoring (non-breaking change that doesn't add any feature but make things better)

Checklist:

  • The PR title is no longer than 64 characters.
  • The PR is submitted to the correct branch (master for bug fixes and documentation updates, dev for new features and breaking changes).
  • My code follows the code style of this project.
  • I've added relevant changes to the documentation (applies to new features and breaking changes in core library)

Use cases in #7777 highlighted sorting issues with timed events. Now If something is offset it will be placed over a column, instead of the opposite.
@codecov
Copy link

codecov bot commented Jul 11, 2019

Codecov Report

Merging #7806 into master will increase coverage by 0.01%.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #7806      +/-   ##
=========================================
+ Coverage   85.79%   85.8%   +0.01%     
=========================================
  Files         334     334              
  Lines        9095    9095              
  Branches     2418    2418              
=========================================
+ Hits         7803    7804       +1     
+ Misses       1204    1203       -1     
  Partials       88      88
Impacted Files Coverage Δ
...omponents/VCalendar/mixins/calendar-with-events.ts 37.86% <0%> (ø) ⬆️
packages/vuetify/src/components/VSelect/VSelect.ts 94.13% <0%> (+0.36%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2de4e72...f41a040. Read the comment docs.

@jacekkarczmarczyk jacekkarczmarczyk added the T: bug Functionality that does not work as intended/expected label Jul 11, 2019
@ElijahKotyluk ElijahKotyluk self-requested a review July 20, 2019 12:38
ElijahKotyluk
ElijahKotyluk previously approved these changes Jul 20, 2019
Copy link
Contributor

@ElijahKotyluk ElijahKotyluk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen Shot 2019-07-19 at 10 08 12 AM

@ClickerMonkey ClickerMonkey removed the request for review from dsseng July 30, 2019 16:26
@johnleider johnleider merged commit e38a763 into master Jul 30, 2019
@johnleider johnleider deleted the fix/vcalendar branch July 30, 2019 16:36
@lock lock bot locked as resolved and limited conversation to collaborators Aug 29, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
T: bug Functionality that does not work as intended/expected
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants