-
Notifications
You must be signed in to change notification settings - Fork 187
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
Migate Run Validators page to react #10652
base: main
Are you sure you want to change the base?
Conversation
900e926
to
f0412cb
Compare
validators = params.require(:selectedValidators).split(',').map(&:constantize) | ||
apply_fix_when_possible = params.require(:applyFixWhenPossible) | ||
|
||
results_validator = ResultsValidators::CompetitionsResultsValidator.new( | ||
validators, | ||
check_real_results: true, | ||
apply_fixes: apply_fix_when_possible, | ||
) | ||
results_validator.validate(competition_ids) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As useful as constantize
is, you gotta be careful with when and how you use it because it can potentially lead to vulnerabilities. In this context, I'm wondering: Why didn't you use the existing result_validation_form.rb
that is also used in the previous running_validators
hook?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't use the result_validation_form.rb
because it was having too many things. I agree those were good, but I feel that if I forcefully use that model, it may not be so clean. So just took the above two lines from that.
I just now saw couple of validations from the model which are also relevant, I've now implemented those validations in the client side.
I understand the risk of constantize
, I now see how the result_validation_form
is doing it - I have now changed to a similar logic, so no more use of constantize
.
Also, now I think technically result_validation_form.rb
is not needed anymore as it was used to support the rails ERB code, and that code is no longer there. So I've removed result_validation_form.rb
after making necessary changes.
const { | ||
data: competitionList, isLoading, isError, refetch, | ||
} = useQuery({ | ||
queryKey: ['competitionCountInRange'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The startDate
and endDate
need to be included in the queryKey
. Otherwise, the query will never be refetched when the dates change, and the old number will persist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For your basic understanding, you can think of queryKey
as a cache key that controls the "cache" of the network traffic, to make sure that the data is only refetched when needed. (The real implementation is a bit more complex than that, but as a rule of thumb the cache comparison works.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks for the info.
|
||
export default async function getCompetitionList(startDate, endDate, maxLimit) { | ||
const { data } = await fetchJsonOrError( | ||
`${apiV0Urls.competitions.listIndex}?start=${startDate}&end=${endDate}&per_page=${maxLimit}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you not using the admin_validation_competitions_path
URL from the old jQuery form?
Don't get me wrong, I would love it if we can switch to (semi-)public APIs, but I just really want to make sure they return the same results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One advantage of a custom path would be that you can serialize only the names, and avoid sending (or even loading from the DB) any unnecessary extra data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't think of the admin_validation_competitions_path
actually. But as part of one more cleanup, I actually removed ResultValidationForm
, and hence all it's usages which includes admin_validation_competitions_path
as well. But I've now created a new API to fetch the count of competitions. Hope that is fine.
useEffect(() => { | ||
setRange({ startDate, endDate }); | ||
if (enableCompetitionListFetch) { | ||
refetch(); | ||
} | ||
}, [startDate, endDate, setRange, enableCompetitionListFetch, refetch]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hook definitely needs to go. react-query
should only be refetched in rare circumstances, but right here is a basic use-case which should be fixed by adjusting the query key as noted in my comment above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
<div> | ||
{`The checks will run for ${competitionList.length}${ | ||
competitionList.length >= MAX_COMPETITIONS_PER_QUERY ? '+' : '' | ||
} competitions`} | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you really need this wrapping div
? In case of doubt, a <>
fragment should do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed, correct. Removed it. Thanks.
|
||
return ( | ||
<> | ||
<Form onSubmit={runValidators}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! I think what you want are React-Query Mutations: https://tanstack.com/query/latest/docs/framework/react/guides/mutations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(This also explains why you hard-coded enabled: false
above, which definitely still is an anti-pattern.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya looks like useMutation
is the correct use-case here. I've changed to useMutation
now.
<Form.Field | ||
label="Competition ID(s)" | ||
control={IdWcaSearch} | ||
name="competitionIds" | ||
value={selectedCompetitionIds} | ||
onChange={setSelectedCompetitionIds} | ||
model={SEARCH_MODELS.competition} | ||
multiple | ||
required | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation looks a little bit off here? Might just be the GitHub diff though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it was off, fixed it. Thanks for pointing.
label={`Apply fix when possible (List of validators with automated fix: ${ | ||
VALIDATORS_WITH_FIX.map(validatorNameReadable).join(', ') | ||
})`} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit awkward to have such a (potentially) long list as part of the checkbox label. Can you add them as an extra text paragraph below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SemUI Header
as h4
or h5
with only the subheader
and no "real" header should do: https://react.semantic-ui.com/elements/header/#content-subheader
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
[ | ||
<a href={competitionUrl(validationData.competition_id)}> | ||
{validationData.competition_id} | ||
</a> | ||
{'] '} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need the []
? Are they absolutely essential for user communication?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The users are WRT, it will look clean if the competition is added at the beginning of the validation info.
if (isFetching) return <Loading />; | ||
if (isError) return <Errored />; | ||
|
||
if (!isFetching && !isError && !validationOutput) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point, you already know that !isFetching && !isError
will always be true. Otherwise, the code would have returned already. So just checking !validationOutput
should be enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, I missed it for some reason. Changed it.
app/webpacker/components/Panel/pages/RunValidatorsPage/CompetitionRangeSelector.jsx
Outdated
Show resolved
Hide resolved
app/webpacker/components/Panel/pages/RunValidatorsPage/CompetitionRangeSelector.jsx
Outdated
Show resolved
Hide resolved
app/webpacker/components/Panel/pages/RunValidatorsPage/CompetitionRangeSelector.jsx
Outdated
Show resolved
Hide resolved
return ( | ||
<> | ||
{Object.entries(listByGroup).map(([group, list]) => ( | ||
<> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure the console will be warning you that you need a key here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The console was filled with warnings and errors nowadays, so I'm not looking at it nowadays. Thanks for pointing it, I've made the change.
app/webpacker/components/Panel/pages/RunValidatorsPage/ValidationListView.jsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed review, @gregorbg. One of the main change that I did post last commit is that I removed result_validation_form
. I'm not sure if you are against it, but just to strengthen my argument, I like to highlight that the reason I felt to remove result_validation_form
is because this was a helper model for the rails UI, and the rails UI no longer exists, and everything done inside result_validation_form
can now be done in 2-3 lines.
validators = params.require(:selectedValidators).split(',').map(&:constantize) | ||
apply_fix_when_possible = params.require(:applyFixWhenPossible) | ||
|
||
results_validator = ResultsValidators::CompetitionsResultsValidator.new( | ||
validators, | ||
check_real_results: true, | ||
apply_fixes: apply_fix_when_possible, | ||
) | ||
results_validator.validate(competition_ids) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't use the result_validation_form.rb
because it was having too many things. I agree those were good, but I feel that if I forcefully use that model, it may not be so clean. So just took the above two lines from that.
I just now saw couple of validations from the model which are also relevant, I've now implemented those validations in the client side.
I understand the risk of constantize
, I now see how the result_validation_form
is doing it - I have now changed to a similar logic, so no more use of constantize
.
Also, now I think technically result_validation_form.rb
is not needed anymore as it was used to support the rails ERB code, and that code is no longer there. So I've removed result_validation_form.rb
after making necessary changes.
useEffect(() => { | ||
setRange({ startDate, endDate }); | ||
if (enableCompetitionListFetch) { | ||
refetch(); | ||
} | ||
}, [startDate, endDate, setRange, enableCompetitionListFetch, refetch]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
const { | ||
data: competitionList, isLoading, isError, refetch, | ||
} = useQuery({ | ||
queryKey: ['competitionCountInRange'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks for the info.
import runValidatorsForCompetitionsInRange from './api/runValidatorsForCompetitionsInRange'; | ||
import ValidationOutput from './ValidationOutput'; | ||
|
||
const validatorNameReadable = (validatorName) => validatorName.split('::')[1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed the logic for the validator name, so this is no longer there.
[ | ||
<a href={competitionUrl(validationData.competition_id)}> | ||
{validationData.competition_id} | ||
</a> | ||
{'] '} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The users are WRT, it will look clean if the competition is added at the beginning of the validation info.
queryKey: ['competitionCountInRange'], | ||
queryFn: runValidatorsForCompetitions, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya it was a copy-paste, I forgot to change the key. I've anyway changed to useMutation
as you suggested, so no longer relevant.
} = useQuery({ | ||
queryKey: ['competitionCountInRange'], | ||
queryFn: runValidatorsForCompetitions, | ||
enabled: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
<Form.Field | ||
label="Competition ID(s)" | ||
control={IdWcaSearch} | ||
name="competitionIds" | ||
value={selectedCompetitionIds} | ||
onChange={setSelectedCompetitionIds} | ||
model={SEARCH_MODELS.competition} | ||
multiple | ||
required | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it was off, fixed it. Thanks for pointing.
label={`Apply fix when possible (List of validators with automated fix: ${ | ||
VALIDATORS_WITH_FIX.map(validatorNameReadable).join(', ') | ||
})`} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
if (isFetching) return <Loading />; | ||
if (isError) return <Errored />; | ||
|
||
if (!isFetching && !isError && !validationOutput) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, I missed it for some reason. Changed it.
6553fc2
to
0468c2f
Compare
This is part of migrating all panel pages to react