Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Records Page to React #10623

Open
wants to merge 52 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
bb687c0
WIP transform rankings page to records page
FinnIckler Jan 14, 2025
a3195c1
port filter changes from other pr
FinnIckler Jan 14, 2025
d781932
fix records API
FinnIckler Jan 14, 2025
bd3ca24
add more show variables
FinnIckler Jan 14, 2025
7625d3f
fix after merge
FinnIckler Jan 14, 2025
7d12e2e
use init function
FinnIckler Jan 14, 2025
743750d
implement slim table
FinnIckler Jan 14, 2025
c4b7cf5
Merge branch 'main' into react/records
FinnIckler Jan 15, 2025
e349987
replace fixed with single line
FinnIckler Jan 15, 2025
85db683
separate view
FinnIckler Jan 15, 2025
d47e8ba
history view
FinnIckler Jan 15, 2025
b3bf9d2
implement mixed History
FinnIckler Jan 15, 2025
a577979
id to query to fix duplicates
FinnIckler Jan 15, 2025
f98cedc
refator Headers and Rows
FinnIckler Jan 15, 2025
ae217b4
create dynamic header
FinnIckler Jan 15, 2025
cbd107c
refactor common cells
FinnIckler Jan 15, 2025
f7ce2ba
Merge branch 'main' into react/records
FinnIckler Jan 15, 2025
525da5a
remove unneeded props
FinnIckler Jan 15, 2025
7cabe81
add back accidental deletion of <CountryCell country={country} />
FinnIckler Jan 15, 2025
9c9fa3c
review changes
FinnIckler Jan 20, 2025
91848c1
Merge branch 'main' into react/records
FinnIckler Jan 20, 2025
a919edc
Create dedicated component per table type
kr-matthews Jan 21, 2025
de9b8ae
Fix default 'show' value
kr-matthews Jan 21, 2025
9ad4b6b
Rename TableWrapper -> RecordsTable
kr-matthews Jan 21, 2025
4f1f346
Add key to SlimRecordsTable
kr-matthews Jan 21, 2025
bfa5c44
Add key to RankingTypeTable
kr-matthews Jan 21, 2025
ab22328
Add key to HistoryRecordsTable
kr-matthews Jan 21, 2025
898b49a
Use filter in table rendering
kr-matthews Jan 21, 2025
50ac182
Create util file
kr-matthews Jan 21, 2025
f345a18
Rename components to reflect mult. tables
kr-matthews Jan 21, 2025
a55c885
Remove unnecessary key
kr-matthews Jan 21, 2025
230480d
Rename/simplify tables
kr-matthews Jan 21, 2025
b39295c
Create and use RecordsTable
kr-matthews Jan 21, 2025
69a8546
Rename to isMixed
kr-matthews Jan 21, 2025
ce63f1b
Formatting
kr-matthews Jan 21, 2025
dc4fa9c
add empty results fallback
FinnIckler Jan 21, 2025
3cf7223
add more linebreaks
FinnIckler Jan 21, 2025
348f6e6
add getRegionIdWithFallback
FinnIckler Jan 21, 2025
2914644
add empty results fallback
FinnIckler Jan 21, 2025
b60f906
add getRegionIdWithFallback
FinnIckler Jan 21, 2025
a11bda1
Merge branch 'kr-matthews-react/records' into react/records
FinnIckler Jan 21, 2025
7ae9c73
lint
FinnIckler Jan 21, 2025
ad8b79e
Merge branch 'main' into react/records
gregorbg Feb 3, 2025
d8b0cc4
Fix import after merging
gregorbg Feb 3, 2025
0e18de3
Combine 'ResultsFilter' after merge
gregorbg Feb 3, 2025
7ebbca1
Styling: Remove line break from 'All' button
gregorbg Feb 3, 2025
9717007
Show filters table while fetching data
gregorbg Feb 3, 2025
e326553
Add cubing icon to sub-table headers
gregorbg Feb 3, 2025
a51dfca
Use shared cell models
gregorbg Feb 3, 2025
92ae2be
Add cache iso2 backwards compatibility
gregorbg Feb 3, 2025
7470bf8
Make sure the iso2 fallback is only used wheen necessary
gregorbg Feb 3, 2025
d32318a
Merge branch 'main' into react/records
gregorbg Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions app/controllers/results_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ def records
DAY(competition.start_date) day,
event.id eventId,
event.name eventName,
result.id id,
result.type type,
result.value value,
result.formatId formatId,
Expand Down Expand Up @@ -241,6 +242,26 @@ def records
`rank`, type DESC, start_date, roundTypeId, personName
SQL
end

@record_timestamp = ComputeAuxiliaryData.successful_start_date || Date.current

respond_to do |format|
format.html {}
format.json do
cached_data = Rails.cache.fetch ["records-page-api", *@cache_params, @record_timestamp] do
rows = DbHelper.execute_cached_query(@cache_params, @record_timestamp, @query)
comp_ids = rows.map { |r| r["competitionId"] }.uniq
if @is_slim || @is_separate
rows = compute_slim_or_separate_records(rows)
end
competitions_by_id = Competition.where(id: comp_ids).index_by(&:id).transform_values { |comp| comp.as_json(methods: %w[country], include: [], only: %w[cellName id]) }
{
rows: rows.as_json, competitionsById: competitions_by_id
}
end
render json: cached_data
end
end
Comment on lines +266 to +284
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This snippet should be merged/extracted to a common function once the Rankings page gets merged.

end

private def current_records_query(value, type)
Expand Down Expand Up @@ -286,6 +307,27 @@ def records
SQL
end

private def compute_slim_or_separate_records(rows)
FinnIckler marked this conversation as resolved.
Show resolved Hide resolved
single_rows = []
average_rows = []
rows
.group_by { |row| row["eventId"] }
.each_value do |event_rows|
singles, averages = event_rows.partition { |row| row["type"] == "single" }
balance = singles.size - averages.size
if balance < 0
singles += Array.new(-balance, nil)
elsif balance > 0
averages += Array.new(balance, nil)
end
single_rows += singles
average_rows += averages
end

slim_rows = single_rows.zip(average_rows)
[slim_rows, single_rows.compact, average_rows.compact]
end

private def shared_constants_and_conditions
@years = Competition.non_future_years
@types = ["single", "average"]
Expand Down
21 changes: 0 additions & 21 deletions app/helpers/results_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,6 @@ def compute_rankings_by_region(rows, continent, country)
[rows_to_display, first_continent_index, first_country_index]
end

def compute_slim_or_separate_records(rows)
single_rows = []
average_rows = []
rows
.group_by { |row| row["eventId"] }
.each_value do |event_rows|
singles, averages = event_rows.partition { |row| row["type"] == "single" }
balance = singles.size - averages.size
if balance < 0
singles += Array.new(-balance, nil)
elsif balance > 0
averages += Array.new(balance, nil)
end
single_rows += singles
average_rows += averages
end

slim_rows = single_rows.zip(average_rows)
[slim_rows, single_rows.compact, average_rows.compact]
end

def pb_type_class_for_result(regional_record, pb_marker)
if pb_marker
record_class = 'pb'
Expand Down
59 changes: 2 additions & 57 deletions app/views/results/records.html.erb
Original file line number Diff line number Diff line change
@@ -1,64 +1,9 @@
<% provide(:title, t(".title")) %>

<% record_timestamp = ComputeAuxiliaryData.successful_start_date || Date.current %>
<% @rows = DbHelper.execute_cached_query(@cache_params, record_timestamp, @query) %>

<div class="container">
<h1><%= yield(:title) %></h1>
<p><%= t("results.last_updated_html", timestamp: wca_local_time(record_timestamp)) %></p>
<p><%= t("results.last_updated_html", timestamp: wca_local_time(@record_timestamp)) %></p>
<p><i><%= t('results.filters_fixes_underway') %></i></p>

<div id="results-selector" class="results-select form-inline">
<%= render 'results_selector', show_records_options: true %>
</div>

<% cache [*@cache_params, record_timestamp, I18n.locale] do %>
<%
comp_ids = @rows.map { |r| r["competitionId"] }.uniq
unless @is_slim
@competitions_by_id = Hash[Competition.where(id: comp_ids).map { |c| [c.id, c] }]
end
%>

<div id="search-results" class="results">
<div id="results-list">
<% if @is_mixed %>
<% @rows.group_by { |row| row["eventId"] }.each do |event_id, rows| %>
<% event = Event.c_find(event_id) %>
<h2>
<%= link_to rankings_path(event.id, "single"), class: "plain" do %>
<%= cubing_icon event.id %>
<%= event.name %>
<% end %>
</h2>
<%= render 'records_mixed_table', rows: rows %>
<% end %>
<% elsif @is_slim || @is_separate %>
<% slim_rows, single_rows, average_rows = compute_slim_or_separate_records(@rows) %>
<% if @is_slim %>
<%= render 'records_slim_table', rows: slim_rows %>
<% else %>
<h2> <%= t("results.table_elements.type_options.single") %> </h2>
<%= render 'records_separate_table', rows: single_rows, type: "single" %>

<h2> <%= t("results.table_elements.type_options.average") %> </h2>
<%= render 'records_separate_table', rows: average_rows, type: "average" %>
<% end %>
<% elsif @is_history %>
<% @rows.group_by { |row| row["eventId"] }.each do |event_id, rows| %>
<% event = Event.c_find(event_id) %>
<h2>
<%= link_to rankings_path(event.id, "single"), class: "plain" do %>
<%= cubing_icon event.id %>
<%= event.name %>
<% end %>
</h2>
<%= render 'records_histories_table', rows: rows %>
<% end %>
<% elsif @is_mixed_history %>
<%= render 'records_histories_table', rows: @rows %>
<% end %>
</div>
</div>
<% end %>
<%= react_component("Results/Records") %>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ function TimeOrderButtonGroup({ filterState, dispatchFilter }) {
return (
<>
<label htmlFor="state">{I18n.t('competitions.index.state')}</label>
<Button.Group id="state" size="small" compact primary>
<Button.Group id="state" size="large" primary>
FinnIckler marked this conversation as resolved.
Show resolved Hide resolved
<Button
name="state"
id="present"
Expand Down
69 changes: 69 additions & 0 deletions app/webpacker/components/Results/Records/RecordsTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useMemo } from 'react';
import { Header, Table } from 'semantic-ui-react';
import _ from 'lodash';
import { countries, events } from '../../../lib/wca-data.js.erb';
import { WCA_EVENT_IDS } from '../../wca/EventSelector';
import { HistoryRow, RecordRow } from '../TableRows';
import { HistoryHeader, MixedHeader } from '../TableHeaders';

export default function RecordsTable({
rows, competitionsById, show,
}) {
const results = useMemo(() => {
const r = rows.map((result) => {
const competition = competitionsById[result.competitionId];
const country = countries.real.find((c) => c.id === result.countryId);

return {
result,
competition,
country,
key: `${result.id}-${show}-${result.type}`,
};
});
if (show !== 'mixed history') {
FinnIckler marked this conversation as resolved.
Show resolved Hide resolved
return _.groupBy(r, 'result.eventId');
}
return r;
FinnIckler marked this conversation as resolved.
Show resolved Hide resolved
}, [competitionsById, rows, show]);
return (
FinnIckler marked this conversation as resolved.
Show resolved Hide resolved
<div style={{ overflowX: 'scroll' }}>
{ show !== 'mixed history' ? WCA_EVENT_IDS.map((id) => Object.keys(results).includes(id)
&& <RecordTable record={results[id]} eventId={id} show={show} />)
: <RecordTable record={results} show={show} />}
</div>
);
}

function RecordTable({ record, eventId, show }) {
return (
<>
{ show !== 'mixed history' && <Header>{events.byId[eventId].name}</Header>}
<Table basic="very" compact="very" striped unstackable singleLine>
{ show === 'mixed' ? <MixedHeader /> : <HistoryHeader mixed={show === 'mixed history'} /> }
<Table.Body>
{record.map((r) => (show === 'mixed' ? (
<RecordRow
country={r.country}
key={r.key}
result={r.result}
competition={r.competition}
rank={r.rank}
tiedPrevious={r.tiedPrevious}
/>
) : (
<HistoryRow
country={r.country}
key={r.key}
result={r.result}
competition={r.competition}
rank={r.rank}
tiedPrevious={r.tiedPrevious}
mixed={show === 'mixed history'}
/>
)))}
</Table.Body>
</Table>
</>
);
}
35 changes: 35 additions & 0 deletions app/webpacker/components/Results/Records/SeparateRecordsTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { Header, Table } from 'semantic-ui-react';
import I18n from '../../../lib/i18n';
import { SeparateHeader } from '../TableHeaders';
import { SeparateRecordsRow } from '../TableRows';

export default function SeparateRecordsTable({ rows, competitionsById }) {
const [, singleRecords, averageRecords] = rows;

return (
<>
<Header>{I18n.t('results.selector_elements.type_selector.single')}</Header>
<RankingTypeTable records={singleRecords} competitionsById={competitionsById} rankingType="single" />
<Header>{I18n.t('results.selector_elements.type_selector.average')}</Header>
<RankingTypeTable records={averageRecords} competitionsById={competitionsById} rankingType="average" />
</>
);
}

function RankingTypeTable({ records, rankingType, competitionsById }) {
return (
<Table basic="very" compact="very" striped unstackable singleLine>
<SeparateHeader isAverage={rankingType === 'average'} />
<Table.Body>
{records.map((row) => (
<SeparateRecordsRow
rankingType={rankingType}
competition={competitionsById[row.competitionId]}
result={row}
/>
))}
</Table.Body>
</Table>
);
}
15 changes: 15 additions & 0 deletions app/webpacker/components/Results/Records/SlimRecordsTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { Table } from 'semantic-ui-react';
import { SlimHeader } from '../TableHeaders';
import { SlimRecordsRow } from '../TableRows';

export default function SlimRecordsTable({ rows }) {
return (
<Table basic="very" compact="very" striped unstackable>
<SlimHeader />
<Table.Body>
{rows.map((row) => <SlimRecordsRow row={row} />)}
</Table.Body>
</Table>
);
}
Loading
Loading