Class: CalendarizeHelper::WeeklyCalendarBuilder

Inherits:
AbstractCalendarBuilder show all
Defined in:
app/helpers/calendarize_helper.rb

Instance Attribute Summary

Attributes inherited from AbstractCalendarBuilder

#event, #is_all_day

Instance Method Summary collapse

Constructor Details

#initialize(view_context, *args) ⇒ WeeklyCalendarBuilder

Returns a new instance of WeeklyCalendarBuilder.



446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'app/helpers/calendarize_helper.rb', line 446

def initialize(view_context, *args)

  opts = {
    id: "weekly_calendar_#{@@uuid}",
    week_start: :monday,
    week_end: :sunday,
    scope: 'weekly'
  }.merge!(args.extract_options!)

  opts[:week_start] = opts[:week_start].to_sym
  opts[:week_end] = opts[:week_end].to_sym

  args << opts

  super(view_context, *args)

  # We calculate the number of days between :week_start and :week_end
  ws = Date::DAYS_INTO_WEEK[@options[:week_start]]
  we = Date::DAYS_INTO_WEEK[@options[:week_end]]
  we += 7 if we <= ws

  @day_start = @day.beginning_of_week(@options[:week_start]).to_date
  @day_end = @day_start + (we - ws)

end

Instance Method Details

#computeObject



473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
# File 'app/helpers/calendarize_helper.rb', line 473

def compute

  super

  # We put events in rows
  @_rows_events = {}

  @events.each do |e|
    row_unit = row_unit(e.start_time)

    if !@_rows_events.has_key?(row_unit)
      @_rows_events[row_unit] = [e]
    else
      @_rows_events[row_unit] << e
    end
  end

  # We remove the events that:
  # - start or end before the :starting_row
  # - start or end after the :ending_row
  @_rows_events.each_value { |r| r.reject! { |e| row_unit(e.start_time) >= @_ending_row || row_unit(e.start_time) < @_starting_row } }
  @_rows_events.each_value { |r| r.reject! { |e| row_unit(e.end_time)   >= @_ending_row || row_unit(e.end_time)   < @_starting_row } }

  # Sort each row (that now contains events) by the duration of the event
  @_rows_events.each_value { |r| r.sort! { |e1, e2| e2.end_time - e2.start_time <=> e1.end_time - e1.start_time } }

  # We remove the events that are outside the days watched
  @_rows_events.each_value { |r| r.reject! { |e| e.start_time.to_date < @day_start || e.start_time.to_date > @day_end } }

  @days_shown = (@day_start..@day_end).to_a

  # Put the events in columns, which give a tuple '[[row, column, index], event]' for the event
  # that will be used to output the calendar. The :index is used to identify an event on a same
  # :row and :column
  @placed_events = []

  @_rows_events.each do |i, v|
    columns = {}
    v.each { |e| columns[column(e.start_time)] = 0 }

    v.each do |e|
      column = column(e.start_time)

      @placed_events << [[i, column, columns[column]], e]

      columns[column] += 1
    end
  end

  # We make a list of all the rows to render
  # If we set the option :verbose to false, we only show the rows that have events
  occupied_rows = []
  @placed_events.each { |tuple| occupied_rows << tuple[0][0] }
  occupied_rows.uniq!

  @rows_to_render_indexes = @options[:verbose] ? @rows.map.with_index { |x, i| i } : occupied_rows.map { |r| @rows.index(r) }

  self
end

#render(&block) ⇒ Object



534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
# File 'app/helpers/calendarize_helper.rb', line 534

def render(&block)
  (:div, class: 'weekly_calendar', id: @options[:id], style: 'position: relative;') do

    tables = ''.html_safe

    # controls
    tables << (:table, id: 'controls', class: 'styled', style: 'width: 100%;') do
      (:thead) do
        (:tr) do
          content = ''.html_safe
          content << (:th, style: 'width: 33%;') { link_to(@options[:verbose] ? I18n.t('calendarize.weekly_calendar.options.verbose', default: 'Compact') : I18n.t('calendarize.weekly_calendar.options.not_verbose', default: 'Full'), @options[:url] + '?' + to_query_params({ date: @day.to_date, verbose: !@options[:verbose] })) }
          content << (:th, style: 'width: 33%;') { "#{I18n.t('calendarize.weekly_calendar.week_of', default: 'Week of')} #{ I18n.l(@day_start.to_date, format: @options[:date_format]) }" }
          content << (:th, style: 'width: 33%;') do
            options = ''.html_safe
            options << link_to(I18n.t('calendarize.weekly_calendar.options.previous_week', default: 'Previous week'), @options[:url] + '?' +  to_query_params({ date: @day_start.prev_week(@options[:week_start]).to_date }))
            options << ' | '
            options << link_to(I18n.t('calendarize.weekly_calendar.options.current_week', default: 'This week'), @options[:url] + '?' + to_query_params)
            options << ' | '
            options << link_to(I18n.t('calendarize.weekly_calendar.options.next_week', default: 'Next week'), @options[:url] + '?' + to_query_params({ date: @day_end.next_week(@options[:week_start]).to_date }))
            options
          end
          content
        end
      end
    end

    # normal events
    tables << (:table, id: 'not_all_day', class: 'styled', style: 'width: 100%;') do
      content = ''.html_safe
      content << (:thead) do
        (:tr) do
          header = ''.html_safe

          header << (:th, style: 'width: 40px;') { I18n.t('calendarize.weekly_calendar.hours', default: 'Hours') }

          @days_shown.each do |d|
            header << (:th) {
              link_to(I18n.l(d, format: @options[:date_format]), @options[:url] + '?' + to_query_params({ date: d, verbose: @options[:verbose], scope: CalendarizeHelper::Scopes::DAILY }))
            }
          end

          header
        end
      end

      content << (:tbody) do

        trs = ''.html_safe

        @rows_to_render_indexes.each do |i|
          trs << (:tr, class: 'row_unit', data: { events_count: @_rows_events.include?(@rows[i]) ? @_rows_events[@rows[i]].map{ |e| column(e.start_time) }.group_by{ |i| i }.map{ |k, v| v.count }.max : 0 }) do
            tds = ''.html_safe

            tds << (:td, class: 'row_header', id: "row_header_#{@rows[i]}", style: 'width: 40px') { @rows_hours[i].strftime('%H:%M') }

            @days_shown.each_index do |j|
              tds << (:td, class: ["row_#{@rows[i]}", "column_#{j}"]) { }
            end

            tds
          end
        end

        trs
      end

      content
    end

    # place the events at the end of the calendar
    # they will be placed at the right place on the calendar with some javascript magic
    @placed_events.each do |e|
      @event = e[1]
      @is_all_day = false
      tables << (:div, class: 'calendar_event', data: { row: e[0][0], column: e[0][1], index: e[0][2] }, style: 'z-index: 1;') do
        (:div, class: 'content') { @view_context.capture(self, &block) }
      end
    end

    tables
  end
end