Skip to content
Snippets Groups Projects
Schedules.vue 4.06 KiB
Newer Older
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
  <div
    v-if="relevantSchedules.length > 0"
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
    :class="{
      'show-schedules': true,
      expandable: isExpandable,
      collapsed: isExpandable && isCollapsed,
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
    }"
    @click="isCollapsed = !isCollapsed"
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
  >
    <table class="table b-table table-striped border">
      <thead>
        <tr>
          <th class="top-header">
            {{ uppercaseFirst(t('showSchedules.schedule')) }}
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
          </th>
          <th class="top-header text-right font-weight-normal">
            {{ relevantSchedules.length }}
              relevantSchedules.length === 1
                ? t('showSchedules.schedule')
                : t('showSchedules.schedules')
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
            }}
          </th>
        </tr>
      </thead>

      <tbody>
        <tr v-for="schedule in relevantSchedules" :key="schedule.id">
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
          <td>
            {{ renderRruleForSchedule(schedule) }}
          </td>
          <td class="text-right">
            <template v-if="schedule.firstDate === schedule.lastDate">
              {{ prettyDate(parseISO(schedule.firstDate)) }} <br />
            {{ prettyHours(schedule.startTime) }} - {{ prettyHours(schedule.endTime) }}
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
          </td>
        </tr>
      </tbody>
    </table>

    <div v-if="isExpandable" class="collapser">
      {{ t('showSchedules.collapse') }}
    </div>
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
  </div>
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
  <div v-else class="border p-4 mb-4">
    {{ t('showSchedules.noSchedulesAvailable') }}
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
  </div>
import { useStore } from 'vuex'
import { useRRule } from '@/mixins/rrules'
import { usePretty } from '@/mixins/prettyDate'
import { lowercaseFirst, uppercaseFirst, useSelectedShow } from '@/utilities'
import { computed, ref, watch } from 'vue'
import { useI18n } from '@/i18n'

const { t } = useI18n()
const { rruleRender } = useRRule()
const { prettyWeekday, prettyDate, prettyHours } = usePretty()
const store = useStore()
const selectedShow = useSelectedShow()
const schedules = computed(() => store.state.shows.schedules)
const relevantSchedules = computed(() => schedules.value.filter((s) => !isPossiblyPastSchedule(s)))
const isExpandable = computed(() => relevantSchedules.value.length > 2)
function isPossiblyPastSchedule(schedule) {
  // Recurrence rules get very complex very fast, so we only give
  // a definitive answer if a lastDate is set for this schedule.
  if (!schedule.lastDate) {
  const lastDate = parseISO(schedule.lastDate)
  const [hours, minutes, seconds] = (schedule.endTime ?? '00:00:00').split(':')
  lastDate.setHours(parseInt(hours ?? '0'), parseInt(minutes ?? '0'), parseInt(seconds ?? '0'))
  return new Date() > lastDate
}

function updateSchedules() {
  if (selectedShow.value) {
    store.dispatch('shows/fetchSchedules', { showId: selectedShow.value.id })
function renderRruleForSchedule(schedule) {
  if (schedule.rruleId < 3) {
    return uppercaseFirst(rruleRender(schedule.rruleId))
  const rrule = uppercaseFirst(rruleRender(schedule.rruleId))
  const weekday = lowercaseFirst(prettyWeekday(schedule.byWeekday))
// TODO[#127]: this belongs in the store
watch(selectedShow, updateSchedules, { immediate: true })
</script>
<script>
export default {
  compatConfig: {
    MODE: 3,
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
  },
}
</script>
Konrad Mohrfeldt's avatar
Konrad Mohrfeldt committed
<style scoped>
.show-schedules {
  box-sizing: border-box;
  width: 100%;
  margin-bottom: 0.5rem;
  position: relative;
  overflow-y: hidden;
}

.show-schedules:hover {
  cursor: pointer;
}

.show-schedules.expandable {
  margin-bottom: 1rem;
}

.show-schedules.collapsed {
  height: 10rem;
}

.show-schedules.collapsed::after {
  content: 'click to expand';
  display: flex;
  justify-content: center;
  align-items: center;
  background: linear-gradient(rgba(255, 255, 255, 0), rgba(255, 255, 255, 9) 66%);
  height: 4rem;
  width: 100%;
  z-index: 1;
  bottom: 0;
  position: absolute;
}

.show-schedules.collapsed::after,
.collapser {
  text-align: center;
  color: var(--info);
}

.show-schedules:hover:after,
.show-schedules:hover .collapser {
  text-decoration: underline;
}