Skip to content

Commit

Permalink
Use Event and Schedule React Component from Registrations (#9262)
Browse files Browse the repository at this point in the history
* add schedule

* use new schedule component

* add events

* use new event component

* Pass only relevant slices of WCIF

* Only allow passing timezone when 'custom' is selected

* Respect timezone setting in the Add To Calendar link

* Hide new-tab icon for Google Calendar link

* Reinstate events picker

* Remove obsolete FullCalendar files

* Localize FullCalendar depending on backend

* Render 'other' activities in gray

* Make ESLint happy

* Hack around FC client-side width computation

* Fix tests

* translate events (except round name)

* remove console.log

* Add roundType information in WCIF events output

* Set selectable and rowSpan for events

* use roundTypeId instead of wcif extension

* localize rest of schedule

* use two dropdowns for timezones

* Localize ActivityCode in calendar view

* Localize ActivityCode in table view

* ignore missing keys for schedule

* testing if updates to show will get test to pass

* correcting test failure

* fixed path

* added anchor to event test

* added missing value

* Make whole room panel clickable

* Source timezones from Rails backend

* Simplify timezone selection

* Render rooms as panel

* Add timezone clicker below room button

* Fix (kinda) menue width issue

* Review i18n changes

* Only show 'follow' checkbox if there is more than one venue

* Fix table view translation interpolation quirk by introducing new key

---------

Co-authored-by: Gregor Billing <[email protected]>
Co-authored-by: Duncan <[email protected]>
  • Loading branch information
3 people authored May 7, 2024
1 parent f5d91ca commit c5237ca
Show file tree
Hide file tree
Showing 140 changed files with 1,200 additions and 700 deletions.
8 changes: 7 additions & 1 deletion app/assets/javascripts/competition_tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@ onPage("competitions#show", function() {
$(window).on('hashchange', showTabFromHash);

function showTabFromHash() {
id = window.location.hash || '#general-info';
var id = window.location.hash || '#general-info';
$('a[href="' + id + '"]').tab('show');
$(id).find("iframe").each(function () {
$iframe = $(this);
if ($iframe.attr("src") === undefined) {
$iframe.attr("src", $iframe.data("src"));
}
});
// The FullCalendar implementation that lives inside React (rendered client-side!)
// does not go well with the Bootstrap Tabs that are rendered server-side :(
// So we "fake" a resize fo React FullCalendar to compute its own dimensions correctly.
if (id === '#competition-schedule') {
window.dispatchEvent(new Event('resize'));
}
}
});

Expand Down
2 changes: 0 additions & 2 deletions app/assets/javascripts/fullcalendar/fullcalendar_wca.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/ca.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/cs.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/da.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/de.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/eo.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/es.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/fi.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/fr.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/hr.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/hu.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/id.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/it.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/ja.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/kk.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/ko.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/nl.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/pl.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/pt-br.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/pt.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/ro.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/ru.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/sk.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/sl.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/sv.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/th.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/uk.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/vi.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/zh-cn.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/fullcalendar/locales/zh-tw.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/stylesheets/fullcalendar_wca.scss

This file was deleted.

8 changes: 0 additions & 8 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,4 @@ def add_to_js_assets(*names)
[@all_js_assets, *names].compact.join(",")
end
end

def add_fullcalendar_to_packs
add_to_js_assets('fullcalendar/fullcalendar_wca')
add_to_css_assets('fullcalendar_wca')
if I18n.locale != :en
add_to_js_assets("fullcalendar/locales/#{I18n.locale.downcase}.js")
end
end
end
2 changes: 1 addition & 1 deletion app/models/round.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def self.wcif_json_schema
"type" => "object",
"properties" => {
"id" => { "type" => "string" },
"format" => { "type" => "string", "enum" => Format.pluck(:id) },
"format" => { "type" => "string", "enum" => Format.ids },
"timeLimit" => TimeLimit.wcif_json_schema,
"cutoff" => Cutoff.wcif_json_schema,
"advancementCondition" => AdvancementConditions::AdvancementCondition.wcif_json_schema,
Expand Down

This file was deleted.

139 changes: 6 additions & 133 deletions app/views/competitions/_competition_schedule_tab.html.erb
Original file line number Diff line number Diff line change
@@ -1,133 +1,6 @@
<%# Generate round informations for the competition %>
<% rounds_by_wcif_id = Hash[competition.rounds.map { |r| [r.wcif_id, r.to_string_map] }] %>
<% add_to_packs("show_schedule") %>
<% add_fullcalendar_to_packs %>

<div class="tab-content" id="schedule-tab">
<ul class="nav nav-pills nav-justified venue-pills">
<% competition.competition_venues.each_with_index do |venue, index| %>
<li class="<%= (index == 0) ? "active" : "" %> venue-pill">
<a href="#schedule-venue-<%= venue.id %>" data-toggle="pill">
<%= venue.name %>
</a>
</li>
<% end %>
</ul>
<% competition.competition_venues.each_with_index do |venue, index| %>
<%
activities = venue.top_level_activities.sort_by(&:start_time)
min_time, max_time = first_and_last_time_from_activities(activities, venue.timezone_id)
activities.map!{ |a| a.to_event(rounds_by_wcif_id) }
%>
<script>
window.wca.registerVenueData("<%= venue.id %>", {
events: <%= raw(activities.to_json) %>,
minTime: "<%= min_time %>",
maxTime: "<%= max_time %>",
});
</script>
<div class="tab-pane <%= (index == 0) ? "active" : "" %>" id="schedule-venue-<%= venue.id %>" data-venue="<%= venue.id %>">
<p>
<%= t("competitions.schedule.venue_information_html", venue_name: link_to_google_maps_place(venue.name, venue.latitude_degrees, venue.longitude_degrees)) %>
<br />
<%= t("competitions.schedule.timezone_message", timezone: venue.timezone_id) %>
<br />
<%= t("competitions.competition_info.add_to_calendar") %>
<%= link_to(ui_icon("calendar plus"), competition_path(competition, format: :ics),
title: t("competitions.competition_info.add_to_calendar"),
data: {
toggle: "tooltip",
placement: "top",
container: "body",
}) %>
<% if competition.competition_venues.size > 1 %>
<br />
<%= t("competitions.schedule.multiple_venues_available") %>
<% end %>
</p>
<% venue_rooms = venue.venue_rooms %>
<div class="row">
<div class="col-xs-12 col-md-6">
<%= t("competitions.schedule.display_as.label") %>
<div class="list-group">
<a class="list-group-item active schedule-table-link" data-venue="<%= venue.id %>" href="#">
<%= t("competitions.schedule.display_as.table") %>
</a>
<a class="list-group-item schedule-calendar-link" data-venue="<%= venue.id %>" href="#">
<%= t("competitions.schedule.display_as.calendar") %>
</a>
</div>
</div>
<%# We want to keep these elements in the html for the event filter. %>
<div class="col-xs-12 col-md-6 <%= "hidden" if venue.venue_rooms.size <= 1 %>">
<%= t("competitions.schedule.display_for_room") %>
<div class="list-group" id="room-list-<%= venue.id %>">
<% venue_rooms.each do |r| %>
<a class="list-group-item room-entry selected toggle-room"
href="#" data-room="<%= r.id %>" data-venue="<%= venue.id %>">
<div class="room-checkbox">
<div class="room-checkbox-bg" style="background-color:<%= r.color %>;"></div>
</div>
<div class="room-name">
<%= r.name %>
</div>
</a>
<% end %>
</div>
</div>
<div class="col-xs-12">
<div class="panel panel-default panel-events-filter">
<div class="panel-body">
<div class="events-filter" data-venue="<%= venue.id %>">
<div class="event-all selected">ALL</div>
<% competition.events.each do |e| %>
<%= cubing_icon(e.id, class: "selected", data: { event: e.id }) %>
<% end %>
</div>
</div>
</div>
</div>
</div>
<div class="schedule_table_container">
<%= render "competition_schedule_for_venue_table", competition: competition, rounds_by_wcif_id: rounds_by_wcif_id, activities: activities %>
</div>
<div class="schedule_calendar_container" style="display: none;">
<div id="calendar-venue-<%= venue.id %>"></div>
</div>
</div>
<% end %>
</div>

<script>
let roundsByWcifId = <%= raw(rounds_by_wcif_id.to_json) %>;
function popoverContentFromData(eventData) {
let roundId = `${eventData.activityDetails.event_id}-r${eventData.activityDetails.round_number}`;
let roundData = roundsByWcifId[roundId];
let content = `<div class="row"><div class="col-xs-12 room-name">${eventData.roomName}</div></div>`;
if (!roundData) {
return null;
}
// If we have round data, format and time limit are mandatory
content += `<div class="row"><div class="col-xs-4"><%= t("competitions.events.format") %></div><div class="col-xs-8"><strong>${roundData.format_name}</strong></div></div>`;
let time_limit_text = roundData.time_limit;
if (roundData.cumulative_round_ids.length == 1) {
time_limit_text += `<%= link_to "*", "#cumulative-time-limit" %>`;
} else if (roundData.cumulative_round_ids.length > 1) {
time_limit_text += `<%= link_to "**", "#cumulative-across-rounds-time-limit" %>`;
}
content += `<div class="row"><div class="col-xs-4"><%= t("competitions.events.time_limit") %></div><div class="col-xs-8"><strong>${time_limit_text}</strong></div></div>`;
if (roundData.cutoff.length > 0) {
content += `<div class="row"><div class="col-xs-4"><%= t("competitions.events.cutoff") %></div><div class="col-xs-8"><strong>${roundData.cutoff}</strong></div></div>`;
}
if (roundData.advancement.length > 0) {
content += `<div class="row"><div class="col-xs-4"><%= t("competitions.events.proceed") %></div><div class="col-xs-8"><strong>${roundData.advancement}</strong></div></div>`;
}
return content;
}

$(() => {
window.wca.setupCalendarAndFilter(popoverContentFromData, "<%= I18n.locale %>",
"<%= competition.start_date %>",
<%= competition.number_of_days %>);
});
</script>
<%= react_component("Schedule", {
wcifSchedule: @competition.schedule_wcif,
wcifEvents: @competition.events_wcif,
competitionName: @competition.name,
calendarLocale: I18n.locale,
}) %>
58 changes: 4 additions & 54 deletions app/views/competitions/_events_tab.html.erb
Original file line number Diff line number Diff line change
@@ -1,54 +1,4 @@
<%= wca_table table_class: "show-events-table" do %>
<thead>
<tr>
<th><%= t("competitions.results_table.event") %></th>
<th><%= t("competitions.results_table.round") %></th>
<th><%= link_to t("competitions.events.format"), "#format" %></th>
<th><%= link_to t("competitions.events.time_limit"), "#time-limit" %></th>
<% if @competition.uses_cutoff? %>
<th><%= link_to t("competitions.events.cutoff"), "#cutoff" %></th>
<% end %>
<th><%= t("competitions.events.proceed") %></th>
<% if @competition.uses_qualification? %>
<th><%= link_to t("competitions.events.qualification"), "#qualification" %></th>
<% end %>
</tr>
<thead>

<tbody>
<% @competition.competition_events.sort_by { |ce| ce.event.rank }.each do |competition_event| %>
<% competition_event.rounds.each do |round| %>
<tr class="<%= round.final_round? ? "last-round" : "" %>">
<td>
<%= competition_event.event.name if round.number == 1 %>
</td>
<td><%= round.round_type.name %></td>
<td>
<%= round.full_format_name(with_short_names: true, with_tooltips: true) %>
</td>
<td>
<%= round.time_limit_to_s %>
<% if competition_event.event.can_change_time_limit? %>
<% if round.time_limit.cumulative_round_ids.length == 1 %>
<%= link_to "*", "#cumulative-time-limit" %>
<% elsif round.time_limit.cumulative_round_ids.length > 1 %>
<%= link_to "**", "#cumulative-across-rounds-time-limit" %>
<% end %>
<% end %>
</td>
<% if @competition.uses_cutoff? %>
<td><%= round.cutoff_to_s %></td>
<% end %>
<td><%= round.advancement_condition_to_s %></td>
<% if @competition.uses_qualification? %>
<% if round.number == 1 %>
<td><%= competition_event.qualification_to_s %></td>
<% else %>
<td></td>
<% end %>
<% end %>
</tr>
<% end %>
<% end %>
</tbody>
<% end %>
<%= react_component("EventsTable", {
wcifEvents: @competition.events_wcif,
competitionInfo: @competition.to_competition_info
}) %>
Loading

0 comments on commit c5237ca

Please sign in to comment.