import { Initialized , Success } from '@abraham/remotedata' ; import { computed , customElement , observe , property } from '@polymer/decorators' ; import { html , PolymerElement } from '@polymer/polymer' ; import { RouterLocation } from '@vaadin/router' ; import { ReduxMixin } from '../mixins/redux-mixin' ; import { Day } from '../models/day' ; import { Filter } from '../models/filter' ; import { Session } from '../models/session' ; import { Time } from '../models/time' ; import { Timeslot } from '../models/timeslot' ; import { RootState , store } from '../store' ; import { fetchUserFeaturedSessions } from '../store/featured-sessions/actions' ; import { initialFeaturedSessionsState } from '../store/featured-sessions/state' ; import { selectFilters } from '../store/filters/selectors' ; import { initialScheduleState , ScheduleState } from '../store/schedule/state' ; import { initialUserState } from '../store/user/state' ; import { UserState } from '../store/user/types' ; import { generateClassName } from '../utils/functions' ; import './session-element' ; import './shared-styles' ; @ customElement ( 'schedule-day' ) export class ScheduleDay extends ReduxMixin ( PolymerElement ) { static get template ( ) { return html `
      <style include="shared-styles flex flex-alignment positioning">
        :host {
          display: block;
          --tracks-number: 3;
        }

        .start-time {
          margin-top: 16px;
          padding: 8px 16px;
          color: var(--secondary-text-color);
          letter-spacing: -0.04em;
          border-bottom: 1px solid var(--border-light-color);
        }

        .hours {
          font-size: 24px;
          font-weight: 300;
        }

        .minutes {
          font-size: 16px;
        }

        .add-session {
          padding: 8px;
          grid-column-end: -1 !important;
          background-color: var(--primary-background-color);
          border-bottom: 1px solid var(--border-light-color);
          font-size: 14px;
          color: var(--secondary-text-color);
        }

        .add-session:hover {
          background-color: var(--additional-background-color);
        }

        .add-session-icon {
          --iron-icon-width: 14px;
          margin-right: 8px;
        }

        @media (min-width: 812px) {
          :host {
            margin-left: auto;
            display: block;
            max-width: calc(100% - 64px);
          }

          .grid {
            display: grid;
            grid-column-gap: 16px;
            grid-row-gap: 32px;
            grid-template-columns: repeat(var(--tracks-number), 1fr);
          }

          .start-time {
            margin: 0;
            padding: 0;
            text-align: right;
            transform: translateX(calc(-100% - 16px));
            border-bottom: 0;
          }

          .hours {
            font-size: 32px;
          }

          .subsession:not(:last-of-type) {
            margin-bottom: 16px;
          }

          .add-session {
            border: 1px solid var(--border-light-color);
          }
        }
      </style>

      <div class="grid" style$="--tracks-number: [[day.tracks.length]];">
        <template is="dom-repeat" items="[[day.timeslots]]" as="timeslot" index-as="timeslotIndex">
          <div
            id$="[[timeslot.startTime]]"
            class="start-time"
            style$="grid-area: [[_getTimePosition(timeslotIndex)]]"
          >
            <span class="hours">[[_splitText(timeslot.startTime, ':', 0)]]</span>
            <span class="minutes">[[_splitText(timeslot.startTime, ':', 1)]]</span>
          </div>

          <a
            class="add-session"
            href$="/schedule/[[day.date]]#[[timeslot.startTime]]"
            hidden$="[[!_showAddSession(timeslot, onlyFeatured)]]"
            style$="grid-area: [[timeslot.sessions.0.gridArea]]"
            layout
            horizontal
            center-center
          >
            <iron-icon class="add-session-icon" icon="hoverboard:add-circle-outline"></iron-icon>
            <span>{$ mySchedule.browseSession $}</span>
          </a>

          <template
            is="dom-repeat"
            items="[[timeslot.sessions]]"
            as="session"
            index-as="sessionIndex"
            filter="_isNotEmpty"
          >
            <div class="session" style$="grid-area: [[session.gridArea]]" layout vertical>
              <template
                is="dom-repeat"
                items="[[filterSessions(session.items, selectedFilters)]]"
                as="subSession"
              >
                <session-element
                  class="subsession"
                  day-name="[[name]]"
                  session="[[subSession]]"
                ></session-element>
              </template>
            </div>
          </template>
        </template>
      </div>
    ` ; } @ property ( { type : Object } ) schedule : ScheduleState = initialScheduleState ; @ property ( { type : Object } ) location : RouterLocation ; @ property ( { type : Object } ) private day : Day ; @ property ( { type : Object } ) private user = initialUserState ; @ property ( { type : Object } ) private featuredSessions = initialFeaturedSessionsState ; @ property ( { type : Boolean } ) private onlyFeatured = false ; @ property ( { type : Array } ) private selectedFilters : Filter [ ] = [ ] ; onAfterEnter ( location ) { this . location = location ; } override stateChanged ( state ) { this . schedule = state . schedule ; this . user = state . user ; this . selectedFilters = selectFilters ( state ) ; this . featuredSessions = state . featuredSessions ; } @ observe ( 'user' ) _fetchFeaturedSessions ( user ) { if ( user instanceof Success && this . featuredSessions instanceof Initialized ) { store . dispatch ( fetchUserFeaturedSessions ) ; } } _getTimePosition ( timeslotIndex ) { return `${ timeslotIndex + 1 } / 1` ; } _splitText ( text , divider , index ) { return text . split ( divider ) [ index ] ; } _showAddSession ( timeslot , onlyFeatured ) { return ( onlyFeatured && ! timeslot . sessions . reduce ( ( aggregator , sessionBlock ) => aggregator + sessionBlock . items . length , 0 ) ) ; } _isNotEmpty ( sessionBlock ) { return ! ! sessionBlock . items . length ; } filterSessions ( sessions , selectedFilters ) { if ( selectedFilters . length === 0 ) { return sessions ; } return sessions . filter ( ( session ) => { return selectedFilters . every ( ( filter ) => { const values = session [ filter . group ] ; if ( values === undefined ) { return false ; } else if ( typeof values === 'string' ) { return generateClassName ( values ) === generateClassName ( filter . tag ) ; } else { return values . some ( ( value ) => generateClassName ( value ) === generateClassName ( filter . tag ) ) ; } } ) ; } ) ; } @ computed ( 'location' , 'schedule' ) get name ( ) { if ( this . location && this . schedule instanceof Success ) { const { params : { id } , pathname , } = this . location ; if ( pathname . endsWith ( 'my-schedule' ) ) { return 'my-schedule' ; } else { return id || this . schedule . data [ 0 ] . date ; } } else { return undefined ; } } @ observe ( 'name' , 'schedule' ) onNameAndSchedule ( ) { if ( ! this . onlyFeatured && this . name && this . schedule instanceof Success ) { this . day = this . schedule . data . find ( ( day ) => day . date === this . name ) ; } } }