Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Conversation

@duartegalvao
Copy link
Member

This PR adds the ability to preview emails sent in regform invitations. To achieve this, a full refactoring to React was necessary, otherwise it would require adding legacy code to handle obtaining placeholder data for indico user + import invites.

In this refactoring, all three actions (Invite new user, invite existing users, import) are merged into a single dialog:
image

image

On top we can select the desired action. By default, invite existing users is selected.
image
image
image

All of the functionality was ported to the new React version.
When importing CSVs, since they are now immediately uploaded, they are verified immediately and show an upload error if there are any CSV format errors. When an upload is successful, the delimiter field is locked and can only be changed if the file is removed.

Future work:
Since pretty much every interactive thing on the invitations page has been reactified now, it seems that the whole page could just become a React component and would simplify things a lot. The only concern is supporting the registration-invite-options template hook...

Copy link
Member

@tomasr8 tomasr8 left a comment

Choose a reason for hiding this comment

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

Looks good overall! I still want to have a deeper look at the InviteDialog but I already left some comments.

One comment for the CSV upload: when it fails (i.e. the CSV is not in a valid format), you can still choose the separator but it has no effect. I'd either disable it or revalidate the file with the new separator.

I'm also not a big fan of the new onPrincipalsResolved logic because now there are two different ways of getting data from that PrincipalList field - one from the final form state and one via this new callback, which seems a bit awkward to me. Maybe instead of onPrincipalsResolved we could have a boolean prop like includeNames or such that would include more details in the field value. So instead of

['User:1', 'User:2']

you'd have

[{identifier: 'User:1', firstName: 'John', lastName: 'Doe'}]

And then you wouldn't need the callbacks and also getPreviewPayload could also operate only on the values.

indico/modules/events/persons/client/js/EmailDialog.jsx Outdated Show resolved Hide resolved
indico/modules/events/registration/notifications.py Outdated Show resolved Hide resolved
indico/modules/events/registration/schemas.py Outdated Show resolved Hide resolved
indico/modules/events/registration/schemas.py Outdated Show resolved Hide resolved
indico/modules/events/registration/util.py Outdated Show resolved Hide resolved
@duartegalvao
Copy link
Member Author

duartegalvao commented Nov 20, 2025

One comment for the CSV upload: when it fails (i.e. the CSV is not in a valid format), you can still choose the separator but it has no effect. I'd either disable it or revalidate the file with the new separator.

my reasoning for that was that, if the upload fails, there's no point in "locking" the separator. why stop the user from changing the separator before reuploading it? it just seems like an unnecessary barrier

indeed the ideal behavior would be to revalidate the file, but I don't see a straightforward way to implement that... there's no way to trigger a reupload in FinalSingleFileManager.. the only solution I can think of is to make the upload always successful, and have a separate endpoint to verify that the uploaded file is a valid csv. do we want that extra complexity?

EDIT: another solution could be to clear the field when changing the delimiter, but I could also see some users finding that annoying

@duartegalvao
Copy link
Member Author

I'm also not a big fan of the new onPrincipalsResolved logic because now there are two different ways of getting data from that PrincipalList field - one from the final form state and one via this new callback, which seems a bit awkward to me. Maybe instead of onPrincipalsResolved we could have a boolean prop like includeNames or such that would include more details in the field value. So instead of

['User:1', 'User:2']

you'd have

[{identifier: 'User:1', firstName: 'John', lastName: 'Doe'}]

And then you wouldn't need the callbacks and also getPreviewPayload could also operate only on the values.

I've been trying to implement this but it really requires reworking the whole principallistfield component... all the handlers, all the subcomponents that provide new principals...
I don't mind doing it that way but this PR is huge already 😅 so I just wanna confirm that this is something you really want

@ThiefMaster
Copy link
Member

on the phone atm while in a meeting but I really prefer to not make the value of this field heavier... it's identifiers-only on purpose

@duartegalvao
Copy link
Member Author

@tomasr8 @ThiefMaster I've made some improvements as requested

  1. removed all changes to the principalslistfield and now just directly pass the list of principals to the preview controller (shaved off ~50 lines of code)
  2. made it so that the changing the delimiter resets the file field (when an upload fails)

Thank you again for all the effort looking through this, and I will await further comments 😄

@duartegalvao duartegalvao force-pushed the invite-email-preview branch 3 times, most recently from 4a4f443 to 32217ee Compare December 8, 2025 15:33
Otherwise it may be hard to see why sending the emails failed, in cases
like inviting someone who's already invited/registered...
reader = csv.reader(ftxt.read().splitlines(), delimiter=delimiter)
content = ftxt.read().splitlines()
if not delimiter and content:
delimiters = [d.delimiter for d in CSVFieldDelimiter]
Copy link
Member

Choose a reason for hiding this comment

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

Is this actually needed? The only thing this avoids is allowing : as a delimiter, but I don't see any reason where this would be an issue here.

webargs_errors?: UploadErrorMessages;
}

function ImportedInvitesMessage({name}: {name: string}) {
Copy link
Member

Choose a reason for hiding this comment

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

I think this would be a perfect place to actually show the data from the CSV at some point (not now) instead of just the number.

Otherwise weird data in the first line could result in wrong data
@ThiefMaster ThiefMaster added the build-wheel Build a Python wheel for this PR label Dec 9, 2025
@ThiefMaster ThiefMaster merged commit b0c2328 into indico:master Dec 10, 2025
11 checks passed
@ThiefMaster ThiefMaster deleted the invite-email-preview branch December 10, 2025 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build-wheel Build a Python wheel for this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.