Repository navigation
Users and Invitations
' Section editors and managers, by family name
Dim editors = Await ojs.Users.ListAllAsync(New UserQuery With {
.RoleIds = {UserRole.Manager, UserRole.SubEditor},
.OrderBy = UserOrderBy.FamilyName})
For Each u In editors
Dim roles = String.Join(", ", u.Groups.Select(Function(g) g.Name.GetValue("en")))
Console.WriteLine($"{u.FullName} <{u.Email}>: {roles}")
Next
' Everyone assigned to a submission in the review stage
Dim reviewStageUsers = Await ojs.Users.ListAsync(New UserQuery With {
.AssignedToSubmission = 12, .AssignedToSubmissionStage = WorkflowStage.ExternalReview})var editors = await ojs.Users.ListAllAsync(new UserQuery
{
RoleIds = new[] { UserRole.Manager, UserRole.SubEditor },
OrderBy = UserOrderBy.FamilyName
});
foreach (var u in editors)
{
var roles = string.Join(", ", u.Groups.Select(g => g.Name.GetValue("en")));
Console.WriteLine($"{u.FullName} <{u.Email}>: {roles}");
}let! editors =
ojs.Users.ListAllAsync(UserQuery(RoleIds = [| UserRole.Manager; UserRole.SubEditor |], OrderBy = UserOrderBy.FamilyName))
for u in editors do
let roles = u.Groups |> Seq.map (fun g -> g.Name.GetValue "en") |> String.concat ", "
printfn "%s <%s>: %s" u.FullName u.Email rolesRemove a role from a user. The userGroupId comes from the user's Groups:
Await ojs.Users.EndRoleAsync(userId:=7, userGroupId:=14)ListReviewersAsync returns ReviewerSummary items, which are users with their review statistics:
-
ReviewsActive,ReviewsCompleted,ReviewsDeclinedandReviewsCancelled; -
AverageReviewCompletionDays; -
ReviewerRating.
The count filters take a single number, which means a minimum, or a range such as "2-5".
' Experienced reviewers who are not busy
Dim available = Await ojs.Users.ListReviewersAsync(New ReviewerQuery With {
.ReviewsCompleted = "3",
.ReviewsActive = "0-1",
.ReviewerRating = 4,
.SearchPhrase = "linguistics"})
For Each r In available.Items
Console.WriteLine($"{r.FullName}: {r.ReviewsCompleted} done, {r.ReviewsActive} active, ~{r.AverageReviewCompletionDays} days")
Nextvar available = await ojs.Users.ListReviewersAsync(new ReviewerQuery
{
ReviewsCompleted = "3", ReviewsActive = "0-1", ReviewerRating = 4, SearchPhrase = "linguistics"
});
foreach (var r in available.Items)
Console.WriteLine($"{r.FullName}: {r.ReviewsCompleted} done, {r.ReviewsActive} active");Invitations ask someone to take on roles in the journal, for example to become a section editor or a reviewer. The flow has three steps:
-
Create the invitation for an existing user or an email address. Its status is
INITIALIZEDand nothing is sent yet. - Populate it with the roles to add and, optionally, the email text.
-
Invite: OJS sends the email and the status becomes
PENDING. The invitee accepts or declines through the link in that email.
Dim id = Await ojs.Invitations.CreateForUserAsync(InvitationTypes.UserRoleAssignment, userId:=5)
Await ojs.Invitations.PopulateAsync(id, New UserRoleAssignmentData With {
.UserGroupsToAdd = New List(Of InvitationUserGroup) From {
New InvitationUserGroup With {.UserGroupId = 5, .Masthead = True, .DateStart = DateOnly.FromDateTime(Date.Today)}},
.EmailComposer = New InvitationEmail With {
.EmailSubject = "Join our editorial team",
.EmailBody = "<p>We would be glad to have you as a section editor.</p>"}})
Dim preview = Await ojs.Invitations.GetMailableAsync(id) ' what will be sent
Dim sent = Await ojs.Invitations.InviteAsync(id)
Console.WriteLine($"{sent.StatusValue}, expires {sent.ExpiryDate:g}")var id = await ojs.Invitations.CreateForUserAsync(InvitationTypes.UserRoleAssignment, userId: 5);
await ojs.Invitations.PopulateAsync(id, new UserRoleAssignmentData
{
UserGroupsToAdd = new List<InvitationUserGroup>
{
new() { UserGroupId = 5, Masthead = true, DateStart = DateOnly.FromDateTime(DateTime.Today) }
},
EmailComposer = new InvitationEmail
{
EmailSubject = "Join our editorial team",
EmailBody = "<p>We would be glad to have you as a section editor.</p>"
}
});
var sent = await ojs.Invitations.InviteAsync(id);
Console.WriteLine($"{sent.StatusValue}, expires {sent.ExpiryDate:g}");let! id = ojs.Invitations.CreateForUserAsync(InvitationTypes.UserRoleAssignment, userId = 5)
let groups = Collections.Generic.List<InvitationUserGroup>()
groups.Add(InvitationUserGroup(UserGroupId = 5, Masthead = true, DateStart = DateOnly.FromDateTime DateTime.Today))
let! _ = ojs.Invitations.PopulateAsync(id, UserRoleAssignmentData(UserGroupsToAdd = groups))
let! sent = ojs.Invitations.InviteAsync id
printfn "%A" sent.StatusValueTo invite someone who has no account, use CreateForEmailAsync(type, "person@example.com"). When they accept, they
choose a user name and password.
Validation errors (a 422 response) arrive as OjsValidationException. Sending without roles, for example, gives
userGroupsToAdd: This field is required.
Manage invitations:
Dim pending = Await ojs.Invitations.ListAsync(InvitationTypes.UserRoleAssignment,
New InvitationQuery With {.Status = InvitationStatus.Pending})
For Each inv In pending.Items
Console.WriteLine($"{inv.Id}: {inv.ExistingUser?.Email} until {inv.ExpiryDate:d}")
Next
Await ojs.Invitations.CancelAsync(id) ' only pending invitations can be cancelledIn OJS 3.5.0,
GET /invitations/{id}answers 401 even for the inviter, so useListAsyncinstead ofGetAsync. Cancelled invitations disappear from every list. See OJS 3.5 Quirks.