diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index db8b9855e5c..13a3686a90e 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -418,22 +418,17 @@ def do_anonymize_person render 'anonymize_person' end - def finish_unfinished_persons - @finish_persons = FinishPersonsForm.new( - competition_ids: params[:competition_ids] || nil, - ) + private def competition_list_from_string(competition_ids_string) + competition_ids_string.split(',').uniq.compact end def complete_persons - action_params = params.require(:finish_persons_form) - .permit(:competition_ids) - - @finish_persons = FinishPersonsForm.new(action_params) - @persons_to_finish = @finish_persons.search_persons + @competition_ids = competition_list_from_string(params.fetch(:competition_ids, "")) + @persons_to_finish = FinishUnfinishedPersons.search_persons(@competition_ids) if @persons_to_finish.empty? flash[:warning] = "There are no persons to complete for the selected competition" - redirect_to action: :finish_unfinished_persons + redirect_to panel_page_path(id: User.panel_pages[:createNewComers], competition_ids: @competition_ids) end end @@ -488,15 +483,14 @@ def do_complete_persons competition_ids = params.dig(:person_completions, :competition_ids) if continue_batch - finish_persons = FinishPersonsForm.new(competition_ids: competition_ids) - can_continue = FinishUnfinishedPersons.unfinished_results_scope(finish_persons.competitions).any? + can_continue = FinishUnfinishedPersons.unfinished_results_scope(competition_list_from_string(competition_ids)).any? if can_continue - return redirect_to action: :complete_persons, finish_persons_form: { competition_ids: competition_ids } + return redirect_to action: :complete_persons, competition_ids: competition_ids end end - redirect_to action: :finish_unfinished_persons, competition_ids: competition_ids + redirect_to panel_page_path(id: User.panel_pages[:createNewComers], competition_ids: competition_ids) end def peek_unfinished_results diff --git a/app/controllers/panel_controller.rb b/app/controllers/panel_controller.rb index 92ed2271cbf..5d121961c50 100644 --- a/app/controllers/panel_controller.rb +++ b/app/controllers/panel_controller.rb @@ -55,6 +55,8 @@ def panel_page panel_with_panel_page = current_user.panels_with_access&.find { |panel| User.panel_list[panel][:pages].include?(panel_page_id) } return head :unauthorized if panel_with_panel_page.nil? - redirect_to panel_index_path(panel_id: panel_with_panel_page, anchor: panel_page_id) + + query_params = request.query_parameters.except(:id) + redirect_to panel_index_path(panel_id: panel_with_panel_page, anchor: panel_page_id, **query_params) end end diff --git a/app/models/finish_persons_form.rb b/app/models/finish_persons_form.rb deleted file mode 100644 index 89f01814130..00000000000 --- a/app/models/finish_persons_form.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -class FinishPersonsForm - include ActiveModel::Model - - attr_accessor :competition_ids - - def competitions - competition_ids.split(',').uniq.compact - end - - def search_persons - FinishUnfinishedPersons.search_persons competitions - end -end diff --git a/app/views/admin/_import_inbox_step.erb b/app/views/admin/_import_inbox_step.erb index bcb39fbb33e..96747bbe850 100644 --- a/app/views/admin/_import_inbox_step.erb +++ b/app/views/admin/_import_inbox_step.erb @@ -49,7 +49,7 @@ All newcomers seem to have been assigned WCA IDs. Please <%= link_to "delete the inbox rows", competition_admin_delete_inbox_data_path(@competition, model: :inbox_person), class: 'inbox-trigger btn btn-primary', data: { jquery_method: :delete } %>. <% else %> - Please <%= link_to "assign WCA IDs to newcomers", admin_complete_persons_path(finish_persons_form: { competition_ids: @competition.id }), target: '_blank', class: 'btn btn-primary' %> + Please <%= link_to "assign WCA IDs to newcomers", admin_complete_persons_path(competition_ids: [@competition.id]), target: '_blank', class: 'btn btn-primary' %> to proceed to the next step. <% end %>

diff --git a/app/views/admin/complete_persons.html.erb b/app/views/admin/complete_persons.html.erb index 52fd53ae3b6..e69f9ad55d2 100644 --- a/app/views/admin/complete_persons.html.erb +++ b/app/views/admin/complete_persons.html.erb @@ -1,25 +1,23 @@ <% provide(:title, 'Finish unfinished persons') %>
- <% competition_ids = @finish_persons.competition_ids %> -

<%= yield(:title) %> - <%= link_to "Go back", admin_finish_unfinished_persons_path(competition_ids: competition_ids), class: "btn btn-default" %> + <%= link_to "Go back", panel_page_path(id: User.panel_pages[:createNewComers], competition_ids: @competition_ids.join(',')), class: "btn btn-default" %>

- <% if competition_ids.present? %> + <% if @competition_ids.present? %>

For competition(s):

<% end %> <%= simple_form_for :person_completions, url: admin_complete_persons_path do |f| %> - <%= f.hidden_field :competition_ids, value: competition_ids %> + <%= f.hidden_field :competition_ids, value: @competition_ids %> <%= wca_table table_class: 'wca-persons', striped: false, greedy: false do %> @@ -42,7 +40,7 @@ - <% if competition_ids.present? && @finish_persons.competitions.length == 1 %> + <% if @competition_ids.present? && @competition_ids.length == 1 %> <%= p[:person_name] %> (ID <%= p[:person_id] %>) <% else %> <%= p[:person_name] %> (ID <%= p[:person_id] %>, Competition <%= p[:competition_id] %>) @@ -114,9 +112,9 @@ <% end %> <% end %> - <%= f.input :continue_batch, as: :boolean, label: "Continue with the next batch of newcomers if there are more pending entries", hint: "If you are redirected to the 'Create Newcomers' entry point, it means that there are no more pending entries.", input_html: { checked: competition_ids.present? } %> + <%= f.input :continue_batch, as: :boolean, label: "Continue with the next batch of newcomers if there are more pending entries", hint: "If you are redirected to the 'Create Newcomers' entry point, it means that there are no more pending entries.", input_html: { checked: @competition_ids.present? } %> <%= f.button :submit, value: "Submit changes!", class: "btn-primary" %> - <%= link_to "Go back", admin_finish_unfinished_persons_path(competition_ids: competition_ids), class: "btn btn-default" %> + <%= link_to "Go back", panel_page_path(id: User.panel_pages[:createNewComers], competition_ids: @competition_ids), class: "btn btn-default" %> <% end %>
diff --git a/app/views/admin/finish_unfinished_persons.html.erb b/app/views/admin/finish_unfinished_persons.html.erb deleted file mode 100644 index 2932aeb8707..00000000000 --- a/app/views/admin/finish_unfinished_persons.html.erb +++ /dev/null @@ -1,35 +0,0 @@ -<% provide(:title, 'Finish unfinished persons') %> - -
-

Create newcomers

-
-

In this script, a "person" always means a triple of (id,name,countryId) and "similar" always means just name - similarity. A person is called "finished" if it has a non-empty personId. A "semi-id" is the id without the - running number at the end.

- -

For each unfinished person in the Results table, I show you the few most similar persons. Then you make choices - and click "update" at the bottom of the page to show and execute your choices. You can:

- - - -
-
- - <%= simple_form_for @finish_persons, url: admin_complete_persons_path, method: :get do |f| %> - <%= f.input :competition_ids, as: :competition_id, label: "Competition(s)", hint: "Leave blank to check for all competitions" %> - <%= f.button :submit, value: "Check now!", class: "btn-primary" %> - <% end %> -
diff --git a/app/webpacker/components/Panel/PanelPages.jsx b/app/webpacker/components/Panel/PanelPages.jsx index 369264676ff..377c38c1ef4 100644 --- a/app/webpacker/components/Panel/PanelPages.jsx +++ b/app/webpacker/components/Panel/PanelPages.jsx @@ -6,7 +6,6 @@ import { generateDbTokenUrl, serverStatusPageUrl, runValidatorsUrl, - createNewComersUrl, checkRecordsUrl, computeAuxiliaryDataUrl, generateDataExportsUrl, @@ -39,6 +38,7 @@ import DownloadVoters from './pages/DownloadVoters'; import ApprovePictures from './pages/ApprovePictures'; import EditPersonRequestsPage from './pages/EditPersonRequestsPage'; import AnonymizationScriptPage from './pages/AnonymizationScriptPage'; +import CreateNewcomersPage from './pages/CreateNewcomersPage'; const DELEGATE_HANDBOOK_LINK = 'https://documents.worldcubeassociation.org/edudoc/delegate-handbook/delegate-handbook.pdf'; @@ -168,8 +168,8 @@ export default { link: runValidatorsUrl, }, [PANEL_PAGES.createNewComers]: { - name: 'Create New Comers', - link: createNewComersUrl, + name: 'Create Newcomers', + component: CreateNewcomersPage, }, [PANEL_PAGES.checkRecords]: { name: 'Check Records', diff --git a/app/webpacker/components/Panel/pages/CreateNewcomersPage/CompetitionsInput.jsx b/app/webpacker/components/Panel/pages/CreateNewcomersPage/CompetitionsInput.jsx new file mode 100644 index 00000000000..365e297996c --- /dev/null +++ b/app/webpacker/components/Panel/pages/CreateNewcomersPage/CompetitionsInput.jsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { + Button, Form, Header, HeaderSubheader, +} from 'semantic-ui-react'; +import { IdWcaSearch } from '../../../SearchWidget/WcaSearch'; +import SEARCH_MODELS from '../../../SearchWidget/SearchModel'; +import { viewUrls } from '../../../../lib/requests/routes.js.erb'; +import useQueryParams from '../../../../lib/hooks/useQueryParams'; +import useInputState from '../../../../lib/hooks/useInputState'; + +export default function CompetitionsInput() { + const [queryParams] = useQueryParams(); + const competitionIdsFromQuery = queryParams?.competition_ids?.split(','); + const [competitionIds, setCompetitionIds] = useInputState(competitionIdsFromQuery || []); + + return ( +
+ +
+ + Leave blank to check for all competitions + +
+ + + ); +} diff --git a/app/webpacker/components/Panel/pages/CreateNewcomersPage/index.jsx b/app/webpacker/components/Panel/pages/CreateNewcomersPage/index.jsx new file mode 100644 index 00000000000..2a5cf006f44 --- /dev/null +++ b/app/webpacker/components/Panel/pages/CreateNewcomersPage/index.jsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { Header, List, ListItem } from 'semantic-ui-react'; +import CompetitionsInput from './CompetitionsInput'; + +export default function CreateNewcomersPage() { + return ( + <> +
Create Newcomers
+ + + + ); +} + +function Information() { + return ( + <> +

+ In this script, a "person" always means a triple of (id,name,countryId) and + "similar" always means just name similarity. A person is called + "finished" if it has a non-empty personId. A "semi-id" is the id + without the running number at the end. +

+

+ For each unfinished person in the Results table, I show you the few most similar + persons. Then you make choices and click "update" at the bottom of the page + to show and execute your choices. You can: +

+ + + Choose the person as "new", optionally modifying name, country and + semi-id. This will add the person to the Persons table (with appropriately + extended id) and change its Results accordingly. If this person has both roman and + local names, the syntax for the names to be inserted correctly is + "romanName (localName)". + + + Choose another person. This will overwrite the person's (id,name,countryId) + triple in the Results table with those of the other person. + + + Skip it if you're not sure yet. + + + + ); +} diff --git a/app/webpacker/lib/requests/routes.js.erb b/app/webpacker/lib/requests/routes.js.erb index 170118c7a3e..af7530ed9cc 100644 --- a/app/webpacker/lib/requests/routes.js.erb +++ b/app/webpacker/lib/requests/routes.js.erb @@ -266,7 +266,10 @@ export const viewUrls = { tickets: { list: (type, status, sort) => `<%= CGI.unescape(Rails.application.routes.url_helpers.tickets_path) %>?${jsonToQueryString({ type, status, sort })}`, show: (ticketId) => `<%= CGI.unescape(Rails.application.routes.url_helpers.ticket_path("${ticketId}")) %>`, - } + }, + admin: { + completePersons: (competitionIds) => `<%= CGI.unescape(Rails.application.routes.url_helpers.admin_complete_persons_path) %>?${jsonToQueryString({ competition_ids: competitionIds })}`, + }, } export const actionUrls = { @@ -312,8 +315,6 @@ export const serverStatusPageUrl = `<%= CGI.unescape(Rails.application.routes.ur export const runValidatorsUrl = `<%= CGI.unescape(Rails.application.routes.url_helpers.admin_check_results_path) %>`; -export const createNewComersUrl = `<%= CGI.unescape(Rails.application.routes.url_helpers.admin_finish_unfinished_persons_path) %>`; - export const checkRecordsUrl = `<%= CGI.unescape(Rails.application.routes.url_helpers.admin_check_regional_records_path) %>`; export const computeAuxiliaryDataUrl = `<%= CGI.unescape(Rails.application.routes.url_helpers.admin_compute_auxiliary_data_path) %>`; diff --git a/config/routes.rb b/config/routes.rb index 75d54e32923..9945a558351 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -194,7 +194,6 @@ get 'panel/:panel_id' => 'panel#index', as: :panel_index scope 'panel-page' do get 'run-validators' => 'admin#check_results', as: :admin_check_results - get 'create-new-comers' => 'admin#finish_unfinished_persons', as: :admin_finish_unfinished_persons get 'check-records' => 'admin#check_regional_records', as: :admin_check_regional_records get 'compute-auxiliary-data' => 'admin#compute_auxiliary_data', as: :admin_compute_auxiliary_data get 'generate-data-exports' => 'admin#generate_exports', as: :admin_generate_exports @@ -291,8 +290,6 @@ get '/admin/do_generate_public_export' => 'admin#do_generate_public_export' get '/admin/override_regional_records' => 'admin#override_regional_records' post '/admin/override_regional_records' => 'admin#do_override_regional_records' - get '/admin/finish_persons' => 'admin#finish_persons' - post '/admin/finish_persons' => 'admin#do_finish_persons' get '/admin/complete_persons' => 'admin#complete_persons' post '/admin/complete_persons' => 'admin#do_complete_persons' get '/admin/peek_unfinished_results' => 'admin#peek_unfinished_results'