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

Migate Run Validators page to react #10652

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

danieljames-dj
Copy link
Member

This is part of migrating all panel pages to react

Comment on lines +54 to +62
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)
Copy link
Member

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?

Copy link
Member Author

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'],
Copy link
Member

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.

Copy link
Member

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.)

Copy link
Member Author

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}`,
Copy link
Member

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.

Copy link
Member

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.

Copy link
Member Author

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.

Comment on lines 26 to 31
useEffect(() => {
setRange({ startDate, endDate });
if (enableCompetitionListFetch) {
refetch();
}
}, [startDate, endDate, setRange, enableCompetitionListFetch, refetch]);
Copy link
Member

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Comment on lines 58 to 62
<div>
{`The checks will run for ${competitionList.length}${
competitionList.length >= MAX_COMPETITIONS_PER_QUERY ? '+' : ''
} competitions`}
</div>
Copy link
Member

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

Copy link
Member Author

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}>
Copy link
Member

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

Copy link
Member

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.)

Copy link
Member Author

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.

Comment on lines 110 to 119
<Form.Field
label="Competition ID(s)"
control={IdWcaSearch}
name="competitionIds"
value={selectedCompetitionIds}
onChange={setSelectedCompetitionIds}
model={SEARCH_MODELS.competition}
multiple
required
/>
Copy link
Member

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.

Copy link
Member Author

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.

Comment on lines 142 to 144
label={`Apply fix when possible (List of validators with automated fix: ${
VALIDATORS_WITH_FIX.map(validatorNameReadable).join(', ')
})`}
Copy link
Member

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?

Copy link
Member

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Comment on lines +46 to +50
[
<a href={competitionUrl(validationData.competition_id)}>
{validationData.competition_id}
</a>
{'] '}
Copy link
Member

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?

Copy link
Member Author

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) {
Copy link
Member

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.

Copy link
Member Author

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.

return (
<>
{Object.entries(listByGroup).map(([group, list]) => (
<>
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Member Author

@danieljames-dj danieljames-dj left a 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.

Comment on lines +54 to +62
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)
Copy link
Member Author

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.

Comment on lines 26 to 31
useEffect(() => {
setRange({ startDate, endDate });
if (enableCompetitionListFetch) {
refetch();
}
}, [startDate, endDate, setRange, enableCompetitionListFetch, refetch]);
Copy link
Member Author

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'],
Copy link
Member Author

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];
Copy link
Member Author

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.

Comment on lines +46 to +50
[
<a href={competitionUrl(validationData.competition_id)}>
{validationData.competition_id}
</a>
{'] '}
Copy link
Member Author

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.

Comment on lines 72 to 73
queryKey: ['competitionCountInRange'],
queryFn: runValidatorsForCompetitions,
Copy link
Member Author

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,
Copy link
Member Author

Choose a reason for hiding this comment

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

Changed.

Comment on lines 110 to 119
<Form.Field
label="Competition ID(s)"
control={IdWcaSearch}
name="competitionIds"
value={selectedCompetitionIds}
onChange={setSelectedCompetitionIds}
model={SEARCH_MODELS.competition}
multiple
required
/>
Copy link
Member Author

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.

Comment on lines 142 to 144
label={`Apply fix when possible (List of validators with automated fix: ${
VALIDATORS_WITH_FIX.map(validatorNameReadable).join(', ')
})`}
Copy link
Member Author

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) {
Copy link
Member Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants