Schedule divisions and workshops table
This commit is contained in:
		
							parent
							
								
									c1f9b5db82
								
							
						
					
					
						commit
						ad3136a5cb
					
				
							
								
								
									
										1
									
								
								app/assets/images/admin/workshops.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								app/assets/images/admin/workshops.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 26.25"><path d="M0 21h24V0H0v21zM19 1h4v3h-4V1zm0 4h4v3h-4V5zm0 4h4v3h-4V9zm0 4h4v3h-4v-3zm0 4h4v3h-4v-3zM14 1h4v3h-4V1zm0 4h4v3h-4V5zm0 4h4v3h-4V9zm0 4h4v3h-4v-3zm0 4h4v3h-4v-3zM9 1h4v3H9V1zm0 4h4v3H9V5zm0 4h4v3H9V9zm0 4h4v3H9v-3zm0 4h4v3H9v-3zM1 1h7v3H1V1zm0 4h7v3H1V5zm0 4h7v3H1V9zm0 4h7v3H1v-3zm0 4h7v3H1v-3z"/></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 377 B  | 
@ -58,10 +58,8 @@
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  document.body.addEventListener('click', function (event) {
 | 
					  document.body.addEventListener('click', function (event) {
 | 
				
			||||||
		//console.log(event.target);
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (selectorMatches(event.target, 'td.workshop.open, td.workshop.open *')) {
 | 
					    if (selectorMatches(event.target, 'td.workshop.open, td.workshop.open *')) {
 | 
				
			||||||
			//event.stopPropagation();
 | 
					 | 
				
			||||||
      var button = event.target;
 | 
					      var button = event.target;
 | 
				
			||||||
      while (button && button.tagName && button.tagName !== 'TD') {
 | 
					      while (button && button.tagName && button.tagName !== 'TD') {
 | 
				
			||||||
        button = button.parentElement;
 | 
					        button = button.parentElement;
 | 
				
			||||||
@ -75,6 +73,7 @@
 | 
				
			|||||||
      var block = button.getAttribute('data-block');
 | 
					      var block = button.getAttribute('data-block');
 | 
				
			||||||
      var day = button.getAttribute('data-day');
 | 
					      var day = button.getAttribute('data-day');
 | 
				
			||||||
      var location = button.getAttribute('data-location');
 | 
					      var location = button.getAttribute('data-location');
 | 
				
			||||||
 | 
					      var division = button.getAttribute('data-division');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      _post(
 | 
					      _post(
 | 
				
			||||||
          document.getElementById('workshop-table-form'),
 | 
					          document.getElementById('workshop-table-form'),
 | 
				
			||||||
@ -82,6 +81,7 @@
 | 
				
			|||||||
            block: block,
 | 
					            block: block,
 | 
				
			||||||
            day: day,
 | 
					            day: day,
 | 
				
			||||||
            location: location,
 | 
					            location: location,
 | 
				
			||||||
 | 
					            division: division,
 | 
				
			||||||
            button: 'get-workshop-list'
 | 
					            button: 'get-workshop-list'
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          function (response) {
 | 
					          function (response) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1370,7 +1370,6 @@ nav.sub-menu {
 | 
				
			|||||||
            .event-detail-link {
 | 
					            .event-detail-link {
 | 
				
			||||||
                width: auto;
 | 
					                width: auto;
 | 
				
			||||||
                font-size: 1.25em;
 | 
					                font-size: 1.25em;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            .event-detail-link, .details, .title {
 | 
					            .event-detail-link, .details, .title {
 | 
				
			||||||
                display: inline;
 | 
					                display: inline;
 | 
				
			||||||
@ -1403,6 +1402,10 @@ nav.sub-menu {
 | 
				
			|||||||
                width: 15em;
 | 
					                width: 15em;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            li {
 | 
				
			||||||
 | 
					                white-space: normal;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            + .event-detail-link {
 | 
					            + .event-detail-link {
 | 
				
			||||||
                padding-right: 1em;
 | 
					                padding-right: 1em;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
class ApplicationController < BaseController
 | 
					class ApplicationController < BaseController
 | 
				
			||||||
  protect_from_forgery with: :exception, :except => [:do_confirm, :js_error, :admin_update]
 | 
					  protect_from_forgery with: :exception, except: [:do_confirm, :js_error, :admin_update]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before_filter :application_setup
 | 
					  before_filter :application_setup
 | 
				
			||||||
  after_filter  :capture_page_info
 | 
					  after_filter  :capture_page_info
 | 
				
			||||||
@ -392,13 +392,13 @@ class ApplicationController < BaseController
 | 
				
			|||||||
  def get_scheule_data(do_analyze = true)
 | 
					  def get_scheule_data(do_analyze = true)
 | 
				
			||||||
    conference = @this_conference || @conference
 | 
					    conference = @this_conference || @conference
 | 
				
			||||||
    @meals = Hash[(conference.meals || {}).map{ |k, v| [k.to_i, v] }].sort.to_h
 | 
					    @meals = Hash[(conference.meals || {}).map{ |k, v| [k.to_i, v] }].sort.to_h
 | 
				
			||||||
    @events = Event.where(:conference_id => conference.id).order(start_time: :asc)
 | 
					    @events = Event.where(conference_id: conference.id).order(start_time: :asc)
 | 
				
			||||||
    @workshops = Workshop.where(:conference_id => conference.id).order(start_time: :asc)
 | 
					    @workshops = Workshop.where(conference_id: conference.id).order(start_time: :asc)
 | 
				
			||||||
    @locations = {}
 | 
					    @locations = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    get_block_data
 | 
					    get_block_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @schedule = {}
 | 
					    schedule = {}
 | 
				
			||||||
    day_1 = conference.start_date.wday
 | 
					    day_1 = conference.start_date.wday
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @workshop_blocks.each_with_index do |info, block|
 | 
					    @workshop_blocks.each_with_index do |info, block|
 | 
				
			||||||
@ -407,11 +407,11 @@ class ApplicationController < BaseController
 | 
				
			|||||||
        day_diff += 7 if day_diff < 0
 | 
					        day_diff += 7 if day_diff < 0
 | 
				
			||||||
        day = (conference.start_date + day_diff.days).to_date
 | 
					        day = (conference.start_date + day_diff.days).to_date
 | 
				
			||||||
        time = info['time'].to_f
 | 
					        time = info['time'].to_f
 | 
				
			||||||
        @schedule[day] ||= { times: {}, locations: {} }
 | 
					        schedule[day] ||= { times: {}, locations: {} }
 | 
				
			||||||
        @schedule[day][:times][time] ||= {}
 | 
					        schedule[day][:times][time] ||= {}
 | 
				
			||||||
        @schedule[day][:times][time][:type] = :workshop
 | 
					        schedule[day][:times][time][:type] = :workshop
 | 
				
			||||||
        @schedule[day][:times][time][:length] = info['length'].to_f
 | 
					        schedule[day][:times][time][:length] = info['length'].to_f
 | 
				
			||||||
        @schedule[day][:times][time][:item] = { block: block, workshops: {} }
 | 
					        schedule[day][:times][time][:item] = { block: block, workshops: {} }
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -423,9 +423,9 @@ class ApplicationController < BaseController
 | 
				
			|||||||
        day_diff += 7 if day_diff < 0
 | 
					        day_diff += 7 if day_diff < 0
 | 
				
			||||||
        day = (conference.start_date + day_diff.days).to_date
 | 
					        day = (conference.start_date + day_diff.days).to_date
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if block.present? && @schedule[day].present? && @schedule[day][:times].present? && @schedule[day][:times][block['time'].to_f].present?
 | 
					        if block.present? && schedule[day].present? && schedule[day][:times].present? && schedule[day][:times][block['time'].to_f].present?
 | 
				
			||||||
          @schedule[day][:times][block['time'].to_f][:item][:workshops][workshop.event_location_id] = { workshop: workshop, status: { errors: [], warnings: [], conflict_score: nil } }
 | 
					          schedule[day][:times][block['time'].to_f][:item][:workshops][workshop.event_location_id] = { workshop: workshop, status: { errors: [], warnings: [], conflict_score: nil } }
 | 
				
			||||||
          @schedule[day][:locations][workshop.event_location_id] ||= workshop.event_location if workshop.event_location.present?
 | 
					          schedule[day][:locations][workshop.event_location_id] ||= workshop.event_location if workshop.event_location.present?
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
@ -433,50 +433,50 @@ class ApplicationController < BaseController
 | 
				
			|||||||
    @meals.each do |time, meal|
 | 
					    @meals.each do |time, meal|
 | 
				
			||||||
      day = meal['day'].to_date
 | 
					      day = meal['day'].to_date
 | 
				
			||||||
      time = meal['time'].to_f
 | 
					      time = meal['time'].to_f
 | 
				
			||||||
      @schedule[day] ||= {}
 | 
					      schedule[day] ||= {}
 | 
				
			||||||
      @schedule[day][:times] ||= {}
 | 
					      schedule[day][:times] ||= {}
 | 
				
			||||||
      @schedule[day][:times][time] ||= {}
 | 
					      schedule[day][:times][time] ||= {}
 | 
				
			||||||
      @schedule[day][:times][time][:type] = :meal
 | 
					      schedule[day][:times][time][:type] = :meal
 | 
				
			||||||
      @schedule[day][:times][time][:length] = (meal['length'] || 1.0).to_f
 | 
					      schedule[day][:times][time][:length] = (meal['length'] || 1.0).to_f
 | 
				
			||||||
      @schedule[day][:times][time][:item] = meal
 | 
					      schedule[day][:times][time][:item] = meal
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @events.each do |event|
 | 
					    @events.each do |event|
 | 
				
			||||||
      if event.present? && event.start_time.present? && event.end_time.present?
 | 
					      if event.present? && event.start_time.present? && event.end_time.present?
 | 
				
			||||||
        day = event.start_time.midnight.to_date
 | 
					        day = event.start_time.midnight.to_date
 | 
				
			||||||
        time = event.start_time.hour.to_f + (event.start_time.min / 60.0)
 | 
					        time = event.start_time.hour.to_f + (event.start_time.min / 60.0)
 | 
				
			||||||
        @schedule[day] ||= {}
 | 
					        schedule[day] ||= {}
 | 
				
			||||||
        @schedule[day][:times] ||= {}
 | 
					        schedule[day][:times] ||= {}
 | 
				
			||||||
        @schedule[day][:times][time] ||= {}
 | 
					        schedule[day][:times][time] ||= {}
 | 
				
			||||||
        @schedule[day][:times][time][:type] = :event
 | 
					        schedule[day][:times][time][:type] = :event
 | 
				
			||||||
        @schedule[day][:times][time][:length] = (event.end_time - event.start_time) / 3600.0
 | 
					        schedule[day][:times][time][:length] = (event.end_time - event.start_time) / 3600.0
 | 
				
			||||||
        @schedule[day][:times][time][:item] = event
 | 
					        schedule[day][:times][time][:item] = event
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @schedule = @schedule.sort.to_h
 | 
					    schedule = schedule.sort.to_h
 | 
				
			||||||
    @schedule.each do |day, data|
 | 
					    schedule.each do |day, data|
 | 
				
			||||||
      @schedule[day][:times] = data[:times].sort.to_h
 | 
					      schedule[day][:times] = data[:times].sort.to_h
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @schedule.each do |day, data|
 | 
					    schedule.each do |day, data|
 | 
				
			||||||
      last_event = nil
 | 
					      last_event = nil
 | 
				
			||||||
      data[:times].each do |time, time_data|
 | 
					      data[:times].each do |time, time_data|
 | 
				
			||||||
        if last_event.present?
 | 
					        if last_event.present?
 | 
				
			||||||
          @schedule[day][:times][last_event][:next_event] = time
 | 
					          schedule[day][:times][last_event][:next_event] = time
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
        last_event = time
 | 
					        last_event = time
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      @schedule[day][:num_locations] = (data[:locations] || []).size
 | 
					      schedule[day][:num_locations] = (data[:locations] || []).size
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @schedule.deep_dup.each do |day, data|
 | 
					    schedule.deep_dup.each do |day, data|
 | 
				
			||||||
      data[:times].each do |time, time_data|
 | 
					      data[:times].each do |time, time_data|
 | 
				
			||||||
        if time_data[:next_event].present? || time_data[:length] > @this_conference.schedule_interval
 | 
					        if time_data[:next_event].present? || time_data[:length] > @this_conference.schedule_interval
 | 
				
			||||||
          span = @this_conference.schedule_interval
 | 
					          span = @this_conference.schedule_interval
 | 
				
			||||||
          length = time_data[:next_event].present? ? time_data[:next_event] - time : time_data[:length]
 | 
					          length = time_data[:next_event].present? ? time_data[:next_event] - time : time_data[:length]
 | 
				
			||||||
          while span < length
 | 
					          while span < length
 | 
				
			||||||
            @schedule[day][:times][time + span] ||= {
 | 
					            schedule[day][:times][time + span] ||= {
 | 
				
			||||||
              type: (span >= time_data[:length] ? :empty : :nil),
 | 
					              type: (span >= time_data[:length] ? :empty : :nil),
 | 
				
			||||||
              length: @this_conference.schedule_interval
 | 
					              length: @this_conference.schedule_interval
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -486,16 +486,20 @@ class ApplicationController < BaseController
 | 
				
			|||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @schedule = @schedule.sort.to_h
 | 
					    # schedule = schedule.sort.to_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @schedule.each do |day, data|
 | 
					    schedule.each do |day, data|
 | 
				
			||||||
      @schedule[day][:times] = data[:times].sort.to_h
 | 
					      # @schedule[day] = [{}]
 | 
				
			||||||
      @schedule[day][:locations] ||= {}
 | 
					      # division = 0
 | 
				
			||||||
 | 
					      # schedule[day][:num_locations] = schedule[day][:num_locations]
 | 
				
			||||||
 | 
					      # schedule[day][:times] = data[:times].sort.to_h
 | 
				
			||||||
 | 
					      schedule[day][:times] = data[:times].sort.to_h
 | 
				
			||||||
 | 
					      schedule[day][:locations] ||= {}
 | 
				
			||||||
 | 
					      # # sort the locations by name
 | 
				
			||||||
 | 
					      schedule[day][:locations] = schedule[day][:locations].sort_by { |event_id, event| event.present? ? event.title.downcase   : '' }.to_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # sort the locations by name      
 | 
					      # # add an empty block if no workshops are scheduled on this day yet
 | 
				
			||||||
      @schedule[day][:locations] = @schedule[day][:locations].sort_by { |event_id, event| event.present? ? event.title.downcase   : '' }.to_h
 | 
					      # schedule[day][:locations][0] = :add if do_analyze || schedule[day][:locations].empty?
 | 
				
			||||||
      # add an empty block if no workshops are scheduled on this day yet
 | 
					 | 
				
			||||||
      @schedule[day][:locations][0] = :add if do_analyze || @schedule[day][:locations].empty?
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if do_analyze
 | 
					      if do_analyze
 | 
				
			||||||
        data[:times].each do |time, time_data|
 | 
					        data[:times].each do |time, time_data|
 | 
				
			||||||
@ -512,8 +516,8 @@ class ApplicationController < BaseController
 | 
				
			|||||||
                    workshop_i.active_facilitators.each do |facilitator_i|
 | 
					                    workshop_i.active_facilitators.each do |facilitator_i|
 | 
				
			||||||
                      workshop_j.active_facilitators.each do |facilitator_j|
 | 
					                      workshop_j.active_facilitators.each do |facilitator_j|
 | 
				
			||||||
                        if facilitator_i.id == facilitator_j.id
 | 
					                        if facilitator_i.id == facilitator_j.id
 | 
				
			||||||
                          @schedule[day][:times][time][:status] ||= {}
 | 
					                          schedule[day][:times][time][:status] ||= {}
 | 
				
			||||||
                          @schedule[day][:times][time][:item][:workshops][ids[j]][:status][:errors] << {
 | 
					                          schedule[day][:times][time][:item][:workshops][ids[j]][:status][:errors] << {
 | 
				
			||||||
                              name: :common_facilitator,
 | 
					                              name: :common_facilitator,
 | 
				
			||||||
                              facilitator: facilitator_i,
 | 
					                              facilitator: facilitator_i,
 | 
				
			||||||
                              workshop: workshop_i,
 | 
					                              workshop: workshop_i,
 | 
				
			||||||
@ -533,7 +537,7 @@ class ApplicationController < BaseController
 | 
				
			|||||||
                amenities = JSON.parse(location.amenities || '[]').map &:to_sym
 | 
					                amenities = JSON.parse(location.amenities || '[]').map &:to_sym
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                needs.each do |need|
 | 
					                needs.each do |need|
 | 
				
			||||||
                  @schedule[day][:times][time][:item][:workshops][ids[i]][:status][:errors] << {
 | 
					                  schedule[day][:times][time][:item][:workshops][ids[i]][:status][:errors] << {
 | 
				
			||||||
                      name: :need_not_available,
 | 
					                      name: :need_not_available,
 | 
				
			||||||
                      need: need,
 | 
					                      need: need,
 | 
				
			||||||
                      location: location,
 | 
					                      location: location,
 | 
				
			||||||
@ -555,13 +559,55 @@ class ApplicationController < BaseController
 | 
				
			|||||||
                  end
 | 
					                  end
 | 
				
			||||||
                end
 | 
					                end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                @schedule[day][:times][time][:item][:workshops][ids[i]][:status][:conflict_score] = (interests & (workshop_i.interested.map { | u | u.user_id })).length
 | 
					                schedule[day][:times][time][:item][:workshops][ids[i]][:status][:conflict_score] = (interests & (workshop_i.interested.map { | u | u.user_id })).length
 | 
				
			||||||
              end
 | 
					              end
 | 
				
			||||||
            end
 | 
					            end
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @schedule = {}
 | 
				
			||||||
 | 
					    schedule.sort.to_h.each do |day, data|
 | 
				
			||||||
 | 
					      @schedule[day] = []
 | 
				
			||||||
 | 
					      division = 0
 | 
				
			||||||
 | 
					      # @schedule[day][division] = data
 | 
				
			||||||
 | 
					      locations = nil
 | 
				
			||||||
 | 
					      @schedule[day][division] = {}
 | 
				
			||||||
 | 
					      @schedule[day][division][:times] = {}
 | 
				
			||||||
 | 
					      # @schedule[day][division][:times] = data[:times]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # # sort the locations by name
 | 
				
			||||||
 | 
					      # @schedule[day][:locations] = schedule[day][:locations].sort_by { |event_id, event| event.present? ? event.title.downcase   : '' }.to_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # # add an empty block if no workshops are scheduled on this day yet
 | 
				
			||||||
 | 
					      # schedule[day][:locations][0] = :add if do_analyze || schedule[day][:locations].empty?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # last_time_data = nil
 | 
				
			||||||
 | 
					      data[:times].each do |time, time_data|
 | 
				
			||||||
 | 
					        if time_data[:type] == :workshop && time_data[:item].present? && time_data[:item][:workshops].present?
 | 
				
			||||||
 | 
					          if !locations.nil? && ((locations.keys - time_data[:item][:workshops].keys) | (time_data[:item][:workshops].keys - locations.keys)).length > 0
 | 
				
			||||||
 | 
					            # data[:locations]
 | 
				
			||||||
 | 
					            # xxx
 | 
				
			||||||
 | 
					            @schedule[day][division][:locations] = locations.deep_dup
 | 
				
			||||||
 | 
					            @schedule[day][division][:locations][0] = :add if do_analyze || locations.empty?
 | 
				
			||||||
 | 
					            locations = data[:locations].select { |id, l| time_data[:item][:workshops][id].present? }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            division += 1
 | 
				
			||||||
 | 
					            @schedule[day][division] = {}
 | 
				
			||||||
 | 
					            @schedule[day][division][:times] = {}
 | 
				
			||||||
 | 
					          else
 | 
				
			||||||
 | 
					            locations = data[:locations].select { |id, l| time_data[:item][:workshops][id].present? }
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					        # last_time_data = time_data
 | 
				
			||||||
 | 
					        @schedule[day][division][:times][time] = time_data
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      locations ||= data[:locations]
 | 
				
			||||||
 | 
					      @schedule[day][division][:locations] = locations
 | 
				
			||||||
 | 
					      @schedule[day][division][:locations][0] = :add if do_analyze || locations.empty?
 | 
				
			||||||
 | 
					      @schedule[day][division][:num_locations] = locations.length
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected
 | 
					  protected
 | 
				
			||||||
 | 
				
			|||||||
@ -253,46 +253,7 @@ class ConferenceAdministrationController < ApplicationController
 | 
				
			|||||||
          format.xlsx { render xlsx: '../conferences/stats', filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" }
 | 
					          format.xlsx { render xlsx: '../conferences/stats', filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" }
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        if params[:sort_column]
 | 
					        sort_data(params[:sort_column], params[:sort_dir], :name)
 | 
				
			||||||
          col = params[:sort_column].to_sym
 | 
					 | 
				
			||||||
          @excel_data[:data].sort_by! do |row|
 | 
					 | 
				
			||||||
            value = row[col]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if row[:raw_values].key?(col)
 | 
					 | 
				
			||||||
              value = if row[:raw_values][col].is_a?(TrueClass)
 | 
					 | 
				
			||||||
                        't'
 | 
					 | 
				
			||||||
                      elsif row[:raw_values][col].is_a?(FalseClass)
 | 
					 | 
				
			||||||
                        ''
 | 
					 | 
				
			||||||
                      else
 | 
					 | 
				
			||||||
                        row[:raw_values][col]
 | 
					 | 
				
			||||||
                      end
 | 
					 | 
				
			||||||
            elsif value.is_a?(City)
 | 
					 | 
				
			||||||
              value = value.sortable_string
 | 
					 | 
				
			||||||
            end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if value.nil?
 | 
					 | 
				
			||||||
              case @excel_data[:column_types][col]
 | 
					 | 
				
			||||||
              when :datetime, [:date, :day]
 | 
					 | 
				
			||||||
                value = Date.new
 | 
					 | 
				
			||||||
              when :money
 | 
					 | 
				
			||||||
                value = 0
 | 
					 | 
				
			||||||
              else
 | 
					 | 
				
			||||||
                value = ''
 | 
					 | 
				
			||||||
              end
 | 
					 | 
				
			||||||
            end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            value
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          if params[:sort_dir] == 'up'
 | 
					 | 
				
			||||||
            @sort_dir = :up
 | 
					 | 
				
			||||||
            @excel_data[:data].reverse!
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          @sort_column = col
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          @sort_column = :name
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      @registration_count = @registrations.size
 | 
					      @registration_count = @registrations.size
 | 
				
			||||||
@ -324,6 +285,22 @@ class ConferenceAdministrationController < ApplicationController
 | 
				
			|||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def administrate_workshops
 | 
				
			||||||
 | 
					      get_workshops(true)
 | 
				
			||||||
 | 
					      if request.format.xlsx?
 | 
				
			||||||
 | 
					        logger.info "Generating stats.xls"
 | 
				
			||||||
 | 
					        return respond_to do |format|
 | 
				
			||||||
 | 
					          format.xlsx { render xlsx: '../conferences/stats', filename: "workshops-#{DateTime.now.strftime('%Y-%m-%d')}" }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        sort_data(params[:sort_column], params[:sort_dir], :name)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if request.xhr?
 | 
				
			||||||
 | 
					        render html: view_context.html_table(@excel_data, view_context.registrations_table_options)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def administrate_check_in
 | 
					    def administrate_check_in
 | 
				
			||||||
      sort_weight = {
 | 
					      sort_weight = {
 | 
				
			||||||
        checked_in: 5,
 | 
					        checked_in: 5,
 | 
				
			||||||
@ -769,6 +746,179 @@ class ConferenceAdministrationController < ApplicationController
 | 
				
			|||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_workshops(html_format = false, id = nil, conference = @this_conference)
 | 
				
			||||||
 | 
					      @workshops = conference.workshops.sort_by { |w| w.title.downcase }
 | 
				
			||||||
 | 
					      @excel_data = {
 | 
				
			||||||
 | 
					        columns: [
 | 
				
			||||||
 | 
					            :title,
 | 
				
			||||||
 | 
					            :owner,
 | 
				
			||||||
 | 
					            :locale,
 | 
				
			||||||
 | 
					            :date,
 | 
				
			||||||
 | 
					            :info,
 | 
				
			||||||
 | 
					            :notes,
 | 
				
			||||||
 | 
					            :facilitators
 | 
				
			||||||
 | 
					          ] + User.AVAILABLE_LANGUAGES.map { |l| "language_#{l}".to_sym } +
 | 
				
			||||||
 | 
					          Workshop.all_needs.map { |n| "need_#{n}".to_sym } + [
 | 
				
			||||||
 | 
					            :theme,
 | 
				
			||||||
 | 
					            :space
 | 
				
			||||||
 | 
					          ] + (User.AVAILABLE_LANGUAGES - [I18n.locale]).map { |l| "title_#{l}".to_sym } +
 | 
				
			||||||
 | 
					          (User.AVAILABLE_LANGUAGES - [I18n.locale]).map { |l| "info_#{l}".to_sym },
 | 
				
			||||||
 | 
					        column_types: {
 | 
				
			||||||
 | 
					            title: :bold,
 | 
				
			||||||
 | 
					            date: :datetime,
 | 
				
			||||||
 | 
					            info: :text,
 | 
				
			||||||
 | 
					            notes: :text,
 | 
				
			||||||
 | 
					            owner: :email
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        keys: {
 | 
				
			||||||
 | 
					            title: 'forms.labels.generic.title',
 | 
				
			||||||
 | 
					            owner: 'roles.workshops.facilitator.creator',
 | 
				
			||||||
 | 
					            locale: 'articles.conference_registration.terms.Preferred_Languages',
 | 
				
			||||||
 | 
					            info: 'forms.labels.generic.info',
 | 
				
			||||||
 | 
					            date: 'workshop.created_at',
 | 
				
			||||||
 | 
					            notes: 'forms.labels.generic.notes',
 | 
				
			||||||
 | 
					            facilitators: 'roles.workshops.facilitator.facilitator',
 | 
				
			||||||
 | 
					            theme: 'articles.workshops.headings.theme',
 | 
				
			||||||
 | 
					            space: 'articles.workshops.headings.space'
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        data: []
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      @excel_data[:key_vars] = {}
 | 
				
			||||||
 | 
					      User.AVAILABLE_LANGUAGES.each do |l|
 | 
				
			||||||
 | 
					        @excel_data[:keys]["language_#{l}".to_sym] = "languages.#{l}"
 | 
				
			||||||
 | 
					        if l != I18n.locale
 | 
				
			||||||
 | 
					          @excel_data[:keys]["title_#{l}".to_sym] = 'translate.content.item_translation'
 | 
				
			||||||
 | 
					          @excel_data[:key_vars]["title_#{l}".to_sym] = { language: view_context.language_name(l), item: I18n.t('forms.labels.generic.title') }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          @excel_data[:keys]["info_#{l}".to_sym] = 'translate.content.item_translation'
 | 
				
			||||||
 | 
					          @excel_data[:key_vars]["info_#{l}".to_sym] = { language: view_context.language_name(l), item: I18n.t('forms.labels.generic.info') }
 | 
				
			||||||
 | 
					          @excel_data[:column_types]["info_#{l}".to_sym] = :text
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Workshop.all_needs.each do |n|
 | 
				
			||||||
 | 
					        @excel_data[:keys]["need_#{n}".to_sym] = "workshop.options.needs.#{n}"
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @workshops.each do |w|
 | 
				
			||||||
 | 
					        if w.present?
 | 
				
			||||||
 | 
					          if id.nil? || id == w.id
 | 
				
			||||||
 | 
					            owner = User.find(w.creator)
 | 
				
			||||||
 | 
					            facilitators = w.collaborators.map { |f| User.find(f) }
 | 
				
			||||||
 | 
					            data = {
 | 
				
			||||||
 | 
					              id: w.id,
 | 
				
			||||||
 | 
					              title: w.title,
 | 
				
			||||||
 | 
					              info: view_context.strip_tags(w.info),
 | 
				
			||||||
 | 
					              notes: view_context.strip_tags(w.notes),
 | 
				
			||||||
 | 
					              owner: owner.name,
 | 
				
			||||||
 | 
					              locale: w.locale.present? ? (view_context.language_name w.locale) : '',
 | 
				
			||||||
 | 
					              date: w.created_at ? w.created_at.strftime("%F %T") : '',
 | 
				
			||||||
 | 
					              facilitators: facilitators.map { |f| f.name }.join(', '),
 | 
				
			||||||
 | 
					              theme: w.theme && Workshop.all_themes.include?(w.theme.to_sym) ? I18n.t("workshop.options.theme.#{w.theme}") : w.theme,
 | 
				
			||||||
 | 
					              space: w.space && Workshop.all_spaces.include?(w.space.to_sym) ? I18n.t("workshop.options.space.#{w.space}") : '',
 | 
				
			||||||
 | 
					              raw_values: {
 | 
				
			||||||
 | 
					                info: w.info,
 | 
				
			||||||
 | 
					                owner: owner.email,
 | 
				
			||||||
 | 
					                notes: w.notes,
 | 
				
			||||||
 | 
					                locale: w.locale,
 | 
				
			||||||
 | 
					                facilitators: facilitators.map { |f| f.email }.join(', '),
 | 
				
			||||||
 | 
					                theme: w.theme,
 | 
				
			||||||
 | 
					                space: w.space
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              html_values: {
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            languages = JSON.parse(w.languages || '[]').map &:to_sym
 | 
				
			||||||
 | 
					            User.AVAILABLE_LANGUAGES.each do |l|
 | 
				
			||||||
 | 
					              in_language = ((languages || []).include? l.to_sym)
 | 
				
			||||||
 | 
					              data["language_#{l}".to_sym] = (in_language ? I18n.t('articles.conference_registration.questions.bike.yes') : '')
 | 
				
			||||||
 | 
					              data[:raw_values]["language_#{l}".to_sym] = in_language
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if l != I18n.locale
 | 
				
			||||||
 | 
					                data["title_#{l}".to_sym] = w.get_column_for_locale!(:title, l, false)
 | 
				
			||||||
 | 
					                data["info_#{l}".to_sym] = view_context.strip_tags(w.get_column_for_locale!(:info, l, false))
 | 
				
			||||||
 | 
					                data[:raw_values]["info_#{l}".to_sym] = w.get_column_for_locale!(:info, l, false)
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            needs = JSON.parse(w.needs || '[]').map &:to_sym
 | 
				
			||||||
 | 
					            Workshop.all_needs.each do |n|
 | 
				
			||||||
 | 
					              in_need = ((needs || []).include? n.to_sym)
 | 
				
			||||||
 | 
					              data["need_#{n}".to_sym] = (in_need ? I18n.t('articles.conference_registration.questions.bike.yes') : '')
 | 
				
			||||||
 | 
					              data[:raw_values]["need_#{n}".to_sym] = in_need
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @excel_data[:data] << data
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if html_format
 | 
				
			||||||
 | 
					        @column_options = {
 | 
				
			||||||
 | 
					          locale: I18n.backend.enabled_locales.map { |l| [(view_context.language_name l), l] },
 | 
				
			||||||
 | 
					          theme: Workshop.all_themes.map { |t| [I18n.t("workshop.options.theme.#{t}"), t] },
 | 
				
			||||||
 | 
					          space: Workshop.all_spaces.map { |s| [I18n.t("workshop.options.space.#{s}"), s] }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @column_options[:theme] += ((conference.workshops.map { |w| w.theme }) - Workshop.all_themes.map(&:to_s)).uniq.map { |t| [t, t] }
 | 
				
			||||||
 | 
					        User.AVAILABLE_LANGUAGES.each do |l|
 | 
				
			||||||
 | 
					          @column_options["language_#{l}".to_sym] = [
 | 
				
			||||||
 | 
					              [I18n.t("articles.conference_registration.questions.bike.yes"), true]
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					        Workshop.all_needs.each do |n|
 | 
				
			||||||
 | 
					          @column_options["need_#{n}".to_sym] = [
 | 
				
			||||||
 | 
					              [I18n.t("articles.conference_registration.questions.bike.yes"), true]
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def sort_data(col, sort_dir, default_col)
 | 
				
			||||||
 | 
					      if col
 | 
				
			||||||
 | 
					        col = col.to_sym
 | 
				
			||||||
 | 
					        @excel_data[:data].sort_by! do |row|
 | 
				
			||||||
 | 
					          value = row[col]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if row[:raw_values].key?(col)
 | 
				
			||||||
 | 
					            value = if row[:raw_values][col].is_a?(TrueClass)
 | 
				
			||||||
 | 
					                      't'
 | 
				
			||||||
 | 
					                    elsif row[:raw_values][col].is_a?(FalseClass)
 | 
				
			||||||
 | 
					                      ''
 | 
				
			||||||
 | 
					                    elsif @excel_data[:column_types][col] == :text
 | 
				
			||||||
 | 
					                      view_context.strip_tags(row[:raw_values][col] || '').downcase
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                      row[:raw_values][col]
 | 
				
			||||||
 | 
					                    end
 | 
				
			||||||
 | 
					          elsif value.is_a?(City)
 | 
				
			||||||
 | 
					            value = value.sortable_string
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if value.nil?
 | 
				
			||||||
 | 
					            case @excel_data[:column_types][col]
 | 
				
			||||||
 | 
					            when :datetime, [:date, :day]
 | 
				
			||||||
 | 
					              value = Date.new
 | 
				
			||||||
 | 
					            when :money
 | 
				
			||||||
 | 
					              value = 0
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              value = ''
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          value
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if sort_dir == 'up'
 | 
				
			||||||
 | 
					          @sort_dir = :up
 | 
				
			||||||
 | 
					          @excel_data[:data].reverse!
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @sort_column = col
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        @sort_column = default_col
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_housing_data
 | 
					    def get_housing_data
 | 
				
			||||||
      @hosts = {}
 | 
					      @hosts = {}
 | 
				
			||||||
      @guests = {}
 | 
					      @guests = {}
 | 
				
			||||||
@ -1255,6 +1405,85 @@ class ConferenceAdministrationController < ApplicationController
 | 
				
			|||||||
      return nil
 | 
					      return nil
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def admin_update_workshops
 | 
				
			||||||
 | 
					      if params[:button] == 'update'
 | 
				
			||||||
 | 
					        workshop = Workshop.where(
 | 
				
			||||||
 | 
					              id: params[:key].to_i,
 | 
				
			||||||
 | 
					              conference_id: @this_conference.id
 | 
				
			||||||
 | 
					            ).limit(1).first
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params.each do |key, value|
 | 
				
			||||||
 | 
					          case key.to_sym
 | 
				
			||||||
 | 
					          when :owner
 | 
				
			||||||
 | 
					            user = User.get(value.strip)
 | 
				
			||||||
 | 
					            user_role = WorkshopFacilitator.where(user_id: user.id, workshop_id: workshop.id).first || WorkshopFacilitator.new(user_id: user.id, workshop_id: workshop.id)
 | 
				
			||||||
 | 
					            owner_role = WorkshopFacilitator.where(role: :creator, workshop_id: workshop.id).first
 | 
				
			||||||
 | 
					            if !owner_role || owner_role.user_id != user.id
 | 
				
			||||||
 | 
					              owner_role.role = :collaborator
 | 
				
			||||||
 | 
					              user_role.role = :creator
 | 
				
			||||||
 | 
					              owner_role.save!
 | 
				
			||||||
 | 
					              user_role.save!
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          when :facilitators
 | 
				
			||||||
 | 
					            ids = []
 | 
				
			||||||
 | 
					            value.split(/[\s,;]+/).each do |email|
 | 
				
			||||||
 | 
					              user = User.get(email)
 | 
				
			||||||
 | 
					              ids << user.id
 | 
				
			||||||
 | 
					              user_role = WorkshopFacilitator.where(user_id: user.id, workshop_id: workshop.id).first || WorkshopFacilitator.new(user_id: user.id, workshop_id: workshop.id)
 | 
				
			||||||
 | 
					              unless user_role.role == 'creator' || user_role.role == 'collaborator'
 | 
				
			||||||
 | 
					                user_role.role = 'collaborator'
 | 
				
			||||||
 | 
					                user_role.save
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					            WorkshopFacilitator.where("workshop_id = ? AND role = ? AND user_id NOT IN (?)", workshop.id, 'collaborator', ids).destroy_all
 | 
				
			||||||
 | 
					          when :title, :locale, :date, :info, :notes, :theme, :space
 | 
				
			||||||
 | 
					            workshop.send("#{key}=", value.present? ? value : nil)
 | 
				
			||||||
 | 
					          else
 | 
				
			||||||
 | 
					            if key.start_with?('language_')
 | 
				
			||||||
 | 
					              l = key.split('_').last.to_sym
 | 
				
			||||||
 | 
					              languages = JSON.parse(workshop.languages || '[]').map &:to_sym
 | 
				
			||||||
 | 
					              if User.AVAILABLE_LANGUAGES.include? l
 | 
				
			||||||
 | 
					                if value.present?
 | 
				
			||||||
 | 
					                  languages |= [l]
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                  languages -= [l]
 | 
				
			||||||
 | 
					                end
 | 
				
			||||||
 | 
					                workshop.languages = languages.to_json
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
 | 
					            elsif key.start_with?('need_')
 | 
				
			||||||
 | 
					              n = key.split('_').last.to_sym
 | 
				
			||||||
 | 
					              needs = JSON.parse(workshop.needs || '[]').map &:to_sym
 | 
				
			||||||
 | 
					              if Workshop.all_needs.include? n
 | 
				
			||||||
 | 
					                if value.present?
 | 
				
			||||||
 | 
					                  needs |= [n]
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                  needs -= [n]
 | 
				
			||||||
 | 
					                end
 | 
				
			||||||
 | 
					                workshop.needs = needs.to_json
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
 | 
					            elsif key.start_with?('title_')
 | 
				
			||||||
 | 
					              l = key.split('_').last.to_sym
 | 
				
			||||||
 | 
					              workshop.set_column_for_locale(:title, l, value)
 | 
				
			||||||
 | 
					            elsif key.start_with?('info_')
 | 
				
			||||||
 | 
					              l = key.split('_').last.to_sym
 | 
				
			||||||
 | 
					              workshop.set_column_for_locale(:info, l, value)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					        workshop.save!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        get_workshops(true, params[:key].to_i) 
 | 
				
			||||||
 | 
					        options = view_context.workshops_table_options
 | 
				
			||||||
 | 
					        options[:html] = true
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        render html: view_context.excel_rows(@excel_data, {}, options)
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        do_404
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return nil
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def admin_update_check_in
 | 
					    def admin_update_check_in
 | 
				
			||||||
      unless params[:button] == 'cancel'
 | 
					      unless params[:button] == 'cancel'
 | 
				
			||||||
        user_id = params[:user_id]
 | 
					        user_id = params[:user_id]
 | 
				
			||||||
@ -1478,7 +1707,7 @@ class ConferenceAdministrationController < ApplicationController
 | 
				
			|||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        (params[:title] || {}).each do |locale, value|
 | 
					        (params[:title] || {}).each do |locale, value|
 | 
				
			||||||
          event.set_column_for_locale(:title, locale, html_value(value), current_user.id) if value != event._title(locale) && view_context.strip_tags(value).strip.present?
 | 
					          event.set_column_for_locale(:title, locale, html_value(value), current_user.id) if value != event._title(locale) && view_context.strip.present?
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event.save
 | 
					        event.save
 | 
				
			||||||
@ -1555,8 +1784,18 @@ class ConferenceAdministrationController < ApplicationController
 | 
				
			|||||||
        @time = @workshop_blocks[@block]['time'].to_f
 | 
					        @time = @workshop_blocks[@block]['time'].to_f
 | 
				
			||||||
        @day = (Date.parse params[:day])
 | 
					        @day = (Date.parse params[:day])
 | 
				
			||||||
        @location = params[:location]
 | 
					        @location = params[:location]
 | 
				
			||||||
 | 
					        @division = params[:division].to_i
 | 
				
			||||||
        @event_location = @location.present? && @location.to_i > 0 ? EventLocation.find(@location.to_i) : nil
 | 
					        @event_location = @location.present? && @location.to_i > 0 ? EventLocation.find(@location.to_i) : nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @schedule ||= {}
 | 
				
			||||||
 | 
					        @schedule[@day] ||= {}
 | 
				
			||||||
 | 
					        @schedule[@day][@division] ||= []
 | 
				
			||||||
 | 
					        @schedule[@day][@division][:times] ||= {}
 | 
				
			||||||
 | 
					        @schedule[@day][@division][:times][@time] ||= {}
 | 
				
			||||||
 | 
					        @schedule[@day][@division][:times][@time][:item] ||= {}
 | 
				
			||||||
 | 
					        @schedule[@day][@division][:times][@time][:item][:workshops] || {}
 | 
				
			||||||
 | 
					        @invalid_locations = @schedule[@day][@division.to_i][:times][@time][:item][:workshops].keys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @workshops.sort { |a, b| a.title.downcase <=> b.title.downcase }.each do |workshop|
 | 
					        @workshops.sort { |a, b| a.title.downcase <=> b.title.downcase }.each do |workshop|
 | 
				
			||||||
          @ordered_workshops[workshop.id] = workshop
 | 
					          @ordered_workshops[workshop.id] = workshop
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,8 @@ module AdminHelper
 | 
				
			|||||||
      events: [
 | 
					      events: [
 | 
				
			||||||
          :locations,
 | 
					          :locations,
 | 
				
			||||||
          :meals,
 | 
					          :meals,
 | 
				
			||||||
          :events
 | 
					          :events,
 | 
				
			||||||
 | 
					          :workshops
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      schedule: [
 | 
					      schedule: [
 | 
				
			||||||
          :workshop_times,
 | 
					          :workshop_times,
 | 
				
			||||||
@ -177,8 +178,8 @@ module AdminHelper
 | 
				
			|||||||
  def available_dates_match?(host, guest)
 | 
					  def available_dates_match?(host, guest)
 | 
				
			||||||
    return false unless host.housing_data['availability'].present? && host.housing_data['availability'][1].present?
 | 
					    return false unless host.housing_data['availability'].present? && host.housing_data['availability'][1].present?
 | 
				
			||||||
    return false unless guest.arrival.present? && guest.departure.present?
 | 
					    return false unless guest.arrival.present? && guest.departure.present?
 | 
				
			||||||
    if host.housing_data['availability'][0] <= guest.arrival &&
 | 
					    if host.housing_data['availability'][0].to_date <= guest.arrival.to_date &&
 | 
				
			||||||
      host.housing_data['availability'][1] >= guest.departure
 | 
					      host.housing_data['availability'][1].to_date >= guest.departure.to_date
 | 
				
			||||||
      return true
 | 
					      return true
 | 
				
			||||||
     end
 | 
					     end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,13 +11,15 @@ module FormHelper
 | 
				
			|||||||
    # set the selected locale
 | 
					    # set the selected locale
 | 
				
			||||||
    selected_locale = (options[:locale] || object.locale || I18n.locale).to_sym
 | 
					    selected_locale = (options[:locale] || object.locale || I18n.locale).to_sym
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    I18n.backend.enabled_locales.each do |locale|
 | 
					    locales = I18n.backend.enabled_locales.map { |l| [l, _("languages.#{l}")] }.sort_by { |l| l.last.downcase }.to_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    locales.each do |locale, locale_name|
 | 
				
			||||||
      # ses if this should b the selected field
 | 
					      # ses if this should b the selected field
 | 
				
			||||||
      class_name = selected_locale == locale.to_sym ? 'selected' : nil
 | 
					      class_name = selected_locale == locale.to_sym ? 'selected' : nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # add the locale to the nav
 | 
					      # add the locale to the nav
 | 
				
			||||||
      nav += content_tag(:li,
 | 
					      nav += content_tag(:li,
 | 
				
			||||||
          content_tag(:a, _("languages.#{locale}"), href: 'javascript:void(0)'),
 | 
					          content_tag(:a, locale_name, href: 'javascript:void(0)'),
 | 
				
			||||||
        class: class_name, data: { locale: locale }).html_safe
 | 
					        class: class_name, data: { locale: locale }).html_safe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      fields = ''
 | 
					      fields = ''
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@ module TableHelper
 | 
				
			|||||||
          headers = ''
 | 
					          headers = ''
 | 
				
			||||||
          options[:column_names].each do |header_name, columns|
 | 
					          options[:column_names].each do |header_name, columns|
 | 
				
			||||||
            column_names[header_name] ||= []
 | 
					            column_names[header_name] ||= []
 | 
				
			||||||
            headers += content_tag(:th, excel_data[:keys][header_name].present? ? _(excel_data[:keys][header_name]) : '', colspan: 2)
 | 
					            headers += content_tag(:th, excel_data[:keys][header_name].present? ? I18n.t(excel_data[:keys][header_name], (excel_data[:key_vars] || {})[header_name]) : '', colspan: 2)
 | 
				
			||||||
            row_count = columns.size
 | 
					            row_count = columns.size
 | 
				
			||||||
            columns.each do |column|
 | 
					            columns.each do |column|
 | 
				
			||||||
              column_names[header_name] << column
 | 
					              column_names[header_name] << column
 | 
				
			||||||
@ -43,7 +43,7 @@ module TableHelper
 | 
				
			|||||||
                  attributes[:rowspan] = options[:row_spans][column]
 | 
					                  attributes[:rowspan] = options[:row_spans][column]
 | 
				
			||||||
                end
 | 
					                end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                column_text = excel_data[:keys][column].present? ? _(excel_data[:keys][column]) : ''
 | 
					                column_text = excel_data[:keys][column].present? ? I18n.t(excel_data[:keys][column], (excel_data[:key_vars] || {})[header_name]) : ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                columns_html += content_tag(:th, column_text.html_safe, rowspan: attributes[:rowspan]) + 
 | 
					                columns_html += content_tag(:th, column_text.html_safe, rowspan: attributes[:rowspan]) + 
 | 
				
			||||||
                                edit_column(nil, column, nil, attributes, excel_data, options)
 | 
					                                edit_column(nil, column, nil, attributes, excel_data, options)
 | 
				
			||||||
@ -64,7 +64,7 @@ module TableHelper
 | 
				
			|||||||
            if (excel_data[:column_types] || {})[column] != :table && ((options[:column_names] || []).include? column)
 | 
					            if (excel_data[:column_types] || {})[column] != :table && ((options[:column_names] || []).include? column)
 | 
				
			||||||
              rows += content_tag(:tr, { class: 'always-edit', data: { key: '' } }) do
 | 
					              rows += content_tag(:tr, { class: 'always-edit', data: { key: '' } }) do
 | 
				
			||||||
                attributes = { class: [excel_data[:column_types][column]], data: { 'column-id' => column } }
 | 
					                attributes = { class: [excel_data[:column_types][column]], data: { 'column-id' => column } }
 | 
				
			||||||
                column_text = excel_data[:keys][column].present? ? _(excel_data[:keys][column]) : ''
 | 
					                column_text = excel_data[:keys][column].present? ? I18n.t(excel_data[:keys][column], (excel_data[:key_vars] || {})[header_name]) : ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                columns = content_tag(:th, column_text.html_safe) + edit_column(nil, column, nil, attributes, excel_data, options)
 | 
					                columns = content_tag(:th, column_text.html_safe) + edit_column(nil, column, nil, attributes, excel_data, options)
 | 
				
			||||||
              end
 | 
					              end
 | 
				
			||||||
@ -124,7 +124,7 @@ module TableHelper
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    data[:columns].each do |column|
 | 
					    data[:columns].each do |column|
 | 
				
			||||||
      unless data[:column_types].present? && data[:column_types][column] == :table
 | 
					      unless data[:column_types].present? && data[:column_types][column] == :table
 | 
				
			||||||
        column_text = data[:keys][column].present? ? _(data[:keys][column]) : ''
 | 
					        column_text = data[:keys][column].present? ? I18n.t(data[:keys][column], (data[:key_vars] || {})[column]) : ''
 | 
				
			||||||
        attrs = { class: class_name }
 | 
					        attrs = { class: class_name }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unless @sort_column.nil?
 | 
					        unless @sort_column.nil?
 | 
				
			||||||
@ -400,4 +400,29 @@ module TableHelper
 | 
				
			|||||||
      column_options: @column_options
 | 
					      column_options: @column_options
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def workshops_table_options
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      id: 'search-table',
 | 
				
			||||||
 | 
					      class: ['registrations', 'admin-edit'],
 | 
				
			||||||
 | 
					      primary_key: :id,
 | 
				
			||||||
 | 
					      column_names: [
 | 
				
			||||||
 | 
					          :title,
 | 
				
			||||||
 | 
					          :owner,
 | 
				
			||||||
 | 
					          :info,
 | 
				
			||||||
 | 
					          :notes,
 | 
				
			||||||
 | 
					          :locale,
 | 
				
			||||||
 | 
					          :facilitators
 | 
				
			||||||
 | 
					        ] +
 | 
				
			||||||
 | 
					        User.AVAILABLE_LANGUAGES.map { |l| "language_#{l}".to_sym } +
 | 
				
			||||||
 | 
					        (User.AVAILABLE_LANGUAGES - [I18n.locale]).map { |l| "title_#{l}".to_sym } +
 | 
				
			||||||
 | 
					        Workshop.all_needs.map { |n| "need_#{n}".to_sym } + [
 | 
				
			||||||
 | 
					          :theme,
 | 
				
			||||||
 | 
					          :space
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      editable: administration_update_path(@this_conference.slug, @admin_step),
 | 
				
			||||||
 | 
					      sortable: administration_step_path(@this_conference.slug, @admin_step),
 | 
				
			||||||
 | 
					      column_options: @column_options
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
				
			|||||||
@ -35,7 +35,7 @@
 | 
				
			|||||||
        = day_select @day, small: true, format: :weekday
 | 
					        = day_select @day, small: true, format: :weekday
 | 
				
			||||||
        = hour_select @time, small: true
 | 
					        = hour_select @time, small: true
 | 
				
			||||||
        = length_select @length, small: true
 | 
					        = length_select @length, small: true
 | 
				
			||||||
      = translate_fields @event, { title: { type: :textfield, big: true, label: 'forms.labels.generic.title' }, info: { type: :textarea, label: 'forms.labels.generic.info', edit_on: :focus } }
 | 
					      = translate_fields @event, { title: { type: :textfield, big: true }, info: { type: :textarea, label: 'forms.labels.generic.info', edit_on: :focus } }
 | 
				
			||||||
      .actions.next-prev
 | 
					      .actions.next-prev
 | 
				
			||||||
        = button :save, value: :save
 | 
					        = button :save, value: :save
 | 
				
			||||||
        = button :cancel, value: :cancel, class: :subdued, formnovalidate: true if @event.id.present?
 | 
					        = button :cancel, value: :cancel, class: :subdued, formnovalidate: true if @event.id.present?
 | 
				
			||||||
 | 
				
			|||||||
@ -6,8 +6,9 @@
 | 
				
			|||||||
    - else
 | 
					    - else
 | 
				
			||||||
      - add_inline_script :schedule if @entire_page
 | 
					      - add_inline_script :schedule if @entire_page
 | 
				
			||||||
      #schedule-preview
 | 
					      #schedule-preview
 | 
				
			||||||
        - @schedule.each do |day, data|
 | 
					        - @schedule.each do |day, data_array|
 | 
				
			||||||
          %h4=date(day, :weekday).html_safe
 | 
					          %h4=date(day, :weekday).html_safe
 | 
				
			||||||
 | 
					          - data_array.each_with_index do |data, division|
 | 
				
			||||||
            %table.schedule{class: [data[:locations].present? ? 'has-locations' : 'no-locations', "locations-#{data[:num_locations]}"]}
 | 
					            %table.schedule{class: [data[:locations].present? ? 'has-locations' : 'no-locations', "locations-#{data[:num_locations]}"]}
 | 
				
			||||||
              - if data[:locations].present? && data[:locations].values.first != :add
 | 
					              - if data[:locations].present? && data[:locations].values.first != :add
 | 
				
			||||||
                %thead
 | 
					                %thead
 | 
				
			||||||
@ -27,14 +28,14 @@
 | 
				
			|||||||
                          - status = time_data[:item][:workshops][id][:status]
 | 
					                          - status = time_data[:item][:workshops][id][:status]
 | 
				
			||||||
                        - else
 | 
					                        - else
 | 
				
			||||||
                          - workshop = status = nil
 | 
					                          - workshop = status = nil
 | 
				
			||||||
                      %td{class: [time_data[:type], workshop.present? ? :filled : :open], rowspan: rowspan, data: workshop.present? ? nil : { block: time_data[:item][:block], day: day, location: id }}
 | 
					                        %td{class: [time_data[:type], workshop.present? ? :filled : :open], rowspan: rowspan, data: workshop.present? ? nil : { block: time_data[:item][:block], day: day, location: id, division: division }}
 | 
				
			||||||
                          - if workshop.present? && workshop.event_location.present?
 | 
					                          - if workshop.present? && workshop.event_location.present?
 | 
				
			||||||
                            .workshop-container
 | 
					                            .workshop-container
 | 
				
			||||||
                              - if @can_edit
 | 
					                              - if @can_edit
 | 
				
			||||||
                                -if strip_tags(workshop.notes).strip.present?
 | 
					                                -if strip_tags(workshop.notes).strip.present?
 | 
				
			||||||
                                  = admin_notes(workshop.notes)
 | 
					                                  = admin_notes(workshop.notes)
 | 
				
			||||||
                                - if status[:errors].present?
 | 
					                                - if status[:errors].present?
 | 
				
			||||||
                                = admin_status content_tag(:ul, (status[:errors].collect { |error| (_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars])}.join).html_safe).html_safe
 | 
					                                  = admin_status content_tag(:ul, (status[:errors].collect { |error| "<li>#{(_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars])}</li>"}.join).html_safe).html_safe
 | 
				
			||||||
                              = link_to view_workshop_path(@conference.slug, workshop.id), class: 'event-detail-link' do
 | 
					                              = link_to view_workshop_path(@conference.slug, workshop.id), class: 'event-detail-link' do
 | 
				
			||||||
                                .details
 | 
					                                .details
 | 
				
			||||||
                                  .title=_!workshop.title
 | 
					                                  .title=_!workshop.title
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@
 | 
				
			|||||||
			= @event_location.title
 | 
								= @event_location.title
 | 
				
			||||||
			= hidden_field_tag :event_location, @location
 | 
								= hidden_field_tag :event_location, @location
 | 
				
			||||||
	- else
 | 
						- else
 | 
				
			||||||
		= location_select(nil, inline_label: true, small: true, invalid_locations: (((((@schedule[@day] || {})[:times] || {})[@time] || {})[:item] || {})[:workshops] || {}).keys, label: false)
 | 
							= location_select(nil, inline_label: true, small: true, invalid_locations: @invalid_locations, label: false)
 | 
				
			||||||
- if @event_location.present?
 | 
					- if @event_location.present?
 | 
				
			||||||
	.host-field
 | 
						.host-field
 | 
				
			||||||
		%h4.inline=_'articles.admin.locations.headings.amenities'
 | 
							%h4.inline=_'articles.admin.locations.headings.amenities'
 | 
				
			||||||
@ -38,7 +38,7 @@
 | 
				
			|||||||
			%td=(workshop.active_facilitators.map { |x| x.named_email }).join(', ')
 | 
								%td=(workshop.active_facilitators.map { |x| x.named_email }).join(', ')
 | 
				
			||||||
			%td=workshop.interested_count
 | 
								%td=workshop.interested_count
 | 
				
			||||||
			%td
 | 
								%td
 | 
				
			||||||
				.text=workshop.notes
 | 
									.text=strip_tags(workshop.notes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.legend
 | 
					.legend
 | 
				
			||||||
	%h4 Legend
 | 
						%h4 Legend
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								app/views/conference_administration/_workshops.html.haml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/views/conference_administration/_workshops.html.haml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					- add_inline_script :registrations
 | 
				
			||||||
 | 
					= columns(medium: 12) do
 | 
				
			||||||
 | 
					  .goes-fullscreen#registrations-table
 | 
				
			||||||
 | 
					    .flex-column
 | 
				
			||||||
 | 
					      = searchfield :search, nil, big: true, stretch: true
 | 
				
			||||||
 | 
					      %a.button{data: { expands: 'registrations-table' }}='expand'
 | 
				
			||||||
 | 
					      %a.button.delete{data: { contracts: 'registrations-table' }}='close'
 | 
				
			||||||
 | 
					    .table-scroller#registrations
 | 
				
			||||||
 | 
					      = html_table(@excel_data, workshops_table_options)
 | 
				
			||||||
 | 
					= columns(medium: 12) do
 | 
				
			||||||
 | 
					  .actions.center
 | 
				
			||||||
 | 
					    = link_to (_'links.download.Excel'), administration_step_path(@this_conference.slug, :workshops, format: :xlsx), class: [:button, :download]
 | 
				
			||||||
@ -1427,6 +1427,7 @@ en:
 | 
				
			|||||||
          locations: Locations
 | 
					          locations: Locations
 | 
				
			||||||
          meals: Meals
 | 
					          meals: Meals
 | 
				
			||||||
          events: Events
 | 
					          events: Events
 | 
				
			||||||
 | 
					          workshops: Workshops
 | 
				
			||||||
        descriptions:
 | 
					        descriptions:
 | 
				
			||||||
          locations: Create the list of locations that you will be using for events,
 | 
					          locations: Create the list of locations that you will be using for events,
 | 
				
			||||||
            meals, and workshops.
 | 
					            meals, and workshops.
 | 
				
			||||||
@ -1435,6 +1436,7 @@ en:
 | 
				
			|||||||
          events: Create event details. These events should be any type of event other
 | 
					          events: Create event details. These events should be any type of event other
 | 
				
			||||||
            than meals and workshops such as meeting, rides, and parties. The events
 | 
					            than meals and workshops such as meeting, rides, and parties. The events
 | 
				
			||||||
            will be added to your schedule.
 | 
					            will be added to your schedule.
 | 
				
			||||||
 | 
					          workshops: View and modify all workshops created by registered users.
 | 
				
			||||||
      schedule:
 | 
					      schedule:
 | 
				
			||||||
        description: On this page you can schedule workshops and publish your schedule
 | 
					        description: On this page you can schedule workshops and publish your schedule
 | 
				
			||||||
          to the front page.
 | 
					          to the front page.
 | 
				
			||||||
@ -2625,6 +2627,7 @@ en:
 | 
				
			|||||||
        unregistered: Unregistered
 | 
					        unregistered: Unregistered
 | 
				
			||||||
        facilitator: Facilitator
 | 
					        facilitator: Facilitator
 | 
				
			||||||
  workshop:
 | 
					  workshop:
 | 
				
			||||||
 | 
					    created_at: Creation Date
 | 
				
			||||||
    options:
 | 
					    options:
 | 
				
			||||||
      needs:
 | 
					      needs:
 | 
				
			||||||
        projector: Projector
 | 
					        projector: Projector
 | 
				
			||||||
@ -2718,6 +2721,7 @@ en:
 | 
				
			|||||||
    content:
 | 
					    content:
 | 
				
			||||||
      change_locale: Read in %{language}
 | 
					      change_locale: Read in %{language}
 | 
				
			||||||
      Translation_of: Translation of
 | 
					      Translation_of: Translation of
 | 
				
			||||||
 | 
					      item_translation: "%{item} in %{language}"
 | 
				
			||||||
  number:
 | 
					  number:
 | 
				
			||||||
    currency:
 | 
					    currency:
 | 
				
			||||||
      format:
 | 
					      format:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user