Browse Source

Admin: Create UserPicker component

pull/53/head
Engincan VESKE 5 years ago
parent
commit
4dcf9f2a52
  1. 10
      src/EventHub.Admin.Application.Contracts/Events/Registrations/GetEventRegistrationListInput.cs
  2. 4
      src/EventHub.Admin.Application.Contracts/Events/Registrations/IEventRegistrationAppService.cs
  3. 15
      src/EventHub.Admin.Application.Contracts/Users/GetUnregisteredUserEventInput.cs
  4. 9
      src/EventHub.Admin.Application.Contracts/Users/GetUserListInput.cs
  5. 2
      src/EventHub.Admin.Application.Contracts/Users/IUserAppService.cs
  6. 26
      src/EventHub.Admin.Application/Events/Registrations/EventRegistrationAppService.cs
  7. 25
      src/EventHub.Admin.Application/Users/UserAppService.cs
  8. 12
      src/EventHub.Admin.HttpApi.Host/Controllers/Events/Registrations/EventRegistrationController.cs
  9. 4
      src/EventHub.Admin.HttpApi.Host/Controllers/Users/UserController.cs
  10. 71
      src/EventHub.Admin.Web/Components/UserPicker/UserPicker.razor
  11. 117
      src/EventHub.Admin.Web/Components/UserPicker/UserPicker.razor.cs
  12. 92
      src/EventHub.Admin.Web/Pages/AttendeeDetail.razor
  13. 99
      src/EventHub.Admin.Web/Pages/AttendeeDetail.razor.cs
  14. 4
      src/EventHub.Domain.Shared/Localization/EventHub/en.json

10
src/EventHub.Admin.Application.Contracts/Events/Registrations/GetEventRegistrationListInput.cs

@ -0,0 +1,10 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EventHub.Admin.Events.Registrations
{
public class GetEventRegistrationListInput : PagedAndSortedResultRequestDto
{
public Guid EventId { get; set; }
}
}

4
src/EventHub.Admin.Application.Contracts/Events/Registrations/IEventRegistrationAppService.cs

@ -8,10 +8,12 @@ namespace EventHub.Admin.Events.Registrations
{
public interface IEventRegistrationAppService : IApplicationService
{
Task<PagedResultDto<EventAttendeeDto>> GetAttendeesAsync(Guid eventId);
Task<PagedResultDto<EventAttendeeDto>> GetAttendeesAsync(GetEventRegistrationListInput input);
Task RemoveAttendeeAsync(Guid eventId, Guid attendeeId);
Task RegisterUsersAsync(Guid eventId, List<Guid> userIds);
Task<List<Guid>> GetAllAttendeeIdsAsync(Guid eventId);
}
}

15
src/EventHub.Admin.Application.Contracts/Users/GetUnregisteredUserEventInput.cs

@ -1,15 +0,0 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EventHub.Admin.Users
{
public class GetUnregisteredUserEventInput : PagedResultRequestDto
{
public Guid EventId { get; set; }
public string Username { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
public string Sorting { get; set; }
}
}

9
src/EventHub.Admin.Application.Contracts/Users/GetUserListInput.cs

@ -0,0 +1,9 @@
using Volo.Abp.Application.Dtos;
namespace EventHub.Admin.Users
{
public class GetUserListInput : PagedAndSortedResultRequestDto
{
public string Username { get; set; }
}
}

2
src/EventHub.Admin.Application.Contracts/Users/IUserAppService.cs

@ -7,6 +7,6 @@ namespace EventHub.Admin.Users
{
public interface IUserAppService : IApplicationService
{
Task<PagedResultDto<UserDto>> GetUnregisteredUsersOfEventAsync(GetUnregisteredUserEventInput input);
Task<PagedResultDto<UserDto>> GetListAsync(GetUserListInput input);
}
}

26
src/EventHub.Admin.Application/Events/Registrations/EventRegistrationAppService.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using EventHub.Admin.Permissions;
using Volo.Abp.Application.Dtos;
@ -33,18 +34,25 @@ namespace EventHub.Admin.Events.Registrations
_eventRegistrationManager = eventRegistrationManager;
}
public async Task<PagedResultDto<EventAttendeeDto>> GetAttendeesAsync(Guid eventId)
public async Task<PagedResultDto<EventAttendeeDto>> GetAttendeesAsync(GetEventRegistrationListInput input)
{
var eventRegistrationQueryable = await _eventRegistrationRepository.GetQueryableAsync();
var userQueryable = await _userRepository.GetQueryableAsync();
var query = from eventRegistration in eventRegistrationQueryable
join user in userQueryable on eventRegistration.UserId equals user.Id
where eventRegistration.EventId == eventId
where eventRegistration.EventId == input.EventId
orderby eventRegistration.CreationTime descending
select user;
var totalCount = await AsyncExecuter.CountAsync(query);
if (!string.IsNullOrWhiteSpace(input.Sorting))
{
query = query.OrderBy(input.Sorting);
}
query = query.PageBy(input);
var users = await AsyncExecuter.ToListAsync(query.Take(10));
return new PagedResultDto<EventAttendeeDto>(
@ -82,5 +90,19 @@ namespace EventHub.Admin.Events.Registrations
await _eventRegistrationManager.RegisterAsync(@event, user);
}
}
public async Task<List<Guid>> GetAllAttendeeIdsAsync(Guid eventId)
{
var eventRegistrationQueryable = await _eventRegistrationRepository.GetQueryableAsync();
var userQueryable = await _userRepository.GetQueryableAsync();
var query = from eventRegistration in eventRegistrationQueryable
join user in userQueryable on eventRegistration.UserId equals user.Id
where eventRegistration.EventId == eventId
orderby eventRegistration.CreationTime descending
select user.Id;
return await AsyncExecuter.ToListAsync(query);
}
}
}

25
src/EventHub.Admin.Application/Users/UserAppService.cs

@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using EventHub.Events.Registrations;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
@ -12,33 +12,26 @@ namespace EventHub.Admin.Users
public class UserAppService : EventHubAdminAppService, IUserAppService
{
private readonly IRepository<IdentityUser, Guid> _identityUserRepository;
private readonly IRepository<EventRegistration, Guid> _eventRegistrationRepository;
public UserAppService(IRepository<IdentityUser, Guid> identityUserRepository, IRepository<EventRegistration, Guid> eventRegistrationRepository)
public UserAppService(IRepository<IdentityUser, Guid> identityUserRepository)
{
_identityUserRepository = identityUserRepository;
_eventRegistrationRepository = eventRegistrationRepository;
}
public async Task<PagedResultDto<UserDto>> GetUnregisteredUsersOfEventAsync(GetUnregisteredUserEventInput input)
public async Task<PagedResultDto<UserDto>> GetListAsync(GetUserListInput input)
{
var identityUserQueryable = await _identityUserRepository.GetQueryableAsync();
var eventRegistrationQuery = (await _eventRegistrationRepository.GetQueryableAsync())
.Where(x => x.EventId == input.EventId)
.Select(x => x.UserId);
var userIds = await AsyncExecuter.ToListAsync(eventRegistrationQuery);
var query = identityUserQueryable
.Where(x => !userIds.Contains(x.Id))
.WhereIf(!string.IsNullOrWhiteSpace(input.Username), user => user.UserName.ToLower().Contains(input.Username.ToLower()))
.WhereIf(!string.IsNullOrWhiteSpace(input.Name), user => user.Name.ToLower().Contains(input.Name.ToLower()))
.WhereIf(!string.IsNullOrWhiteSpace(input.Surname), user => user.Surname.ToLower().Contains(input.Surname.ToLower()))
.WhereIf(!string.IsNullOrWhiteSpace(input.Email), user => user.Email.ToLower().Contains(input.Email.ToLower()));
.WhereIf(!string.IsNullOrWhiteSpace(input.Username), user => user.UserName.ToLower().Contains(input.Username.ToLower()));
var totalCount = await AsyncExecuter.CountAsync(query);
if (!string.IsNullOrWhiteSpace(input.Sorting))
{
query = query.OrderBy(input.Sorting);
}
query = query.PageBy(input);
var users = await AsyncExecuter.ToListAsync(query);

12
src/EventHub.Admin.HttpApi.Host/Controllers/Events/Registrations/EventRegistrationController.cs

@ -25,9 +25,15 @@ namespace EventHub.Admin.Controllers.Events.Registrations
}
[HttpGet("{eventId}")]
public Task<PagedResultDto<EventAttendeeDto>> GetAttendeesAsync(Guid eventId)
public Task<List<Guid>> GetAllAttendeeIdsAsync(Guid eventId)
{
return _eventRegistrationAppService.GetAttendeesAsync(eventId);
return _eventRegistrationAppService.GetAllAttendeeIdsAsync(eventId);
}
[HttpGet]
public Task<PagedResultDto<EventAttendeeDto>> GetAttendeesAsync(GetEventRegistrationListInput input)
{
return _eventRegistrationAppService.GetAttendeesAsync(input);
}
[HttpPost]
@ -36,7 +42,7 @@ namespace EventHub.Admin.Controllers.Events.Registrations
return _eventRegistrationAppService.RegisterUsersAsync(eventId, userIds);
}
[HttpGet]
[HttpDelete]
public Task RemoveAttendeeAsync(Guid eventId, Guid attendeeId)
{
return _eventRegistrationAppService.RemoveAttendeeAsync(eventId, attendeeId);

4
src/EventHub.Admin.HttpApi.Host/Controllers/Users/UserController.cs

@ -22,9 +22,9 @@ namespace EventHub.Admin.Controllers.Users
}
[HttpGet]
public Task<PagedResultDto<UserDto>> GetUnregisteredUsersOfEventAsync(GetUnregisteredUserEventInput input)
public Task<PagedResultDto<UserDto>> GetListAsync(GetUserListInput input)
{
return _userAppService.GetUnregisteredUsersOfEventAsync(input);
return _userAppService.GetListAsync(input);
}
}
}

71
src/EventHub.Admin.Web/Components/UserPicker/UserPicker.razor

@ -1 +1,70 @@
@inherits EventHubComponentBase
@using EventHub.Admin.Users
@inherits EventHubComponentBase
@inject IUserAppService UserAppService
<ModalContent Centered="true">
<ModalHeader>
<ModalTitle>@L["AddUser"]</ModalTitle>
<CloseButton Clicked="CloseUserPickerModalAsync" />
</ModalHeader>
<ModalBody>
<div id="UserFilterSection" class="row mt-3">
<Column ColumnSize="ColumnSize.Is12">
<Field>
<FieldLabel>@L["UserName"]</FieldLabel>
<TextEdit TValue="string" KeyPress="OnKeyPressed" @bind-Text="@Filter.Username" />
</Field>
</Column>
</div>
<DataGrid TItem="UserDto"
Data="UserList"
ReadData="OnDataGridReadAsync"
TotalItems="TotalCount"
ShowPager="true"
PageSize="PageSize"
Responsive="true">
<DataGridColumns>
<DataGridColumn Sortable="false" TItem="UserDto" Field="@nameof(UserDto.Id)">
<CaptionTemplate>
<Check TValue="bool" @bind-Checked="@AllUserSelected"></Check>
</CaptionTemplate>
<DisplayTemplate>
@if (SelectAllUsers.ContainsKey(context.Id))
{
<Check TValue="bool" @bind-Checked="@SelectAllUsers[context.Id]"></Check>
}
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="UserDto" Field="@nameof(UserDto.Username)" Caption="@L["UserName"].Value">
<DisplayTemplate>
@(context.Username)
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="UserDto" Field="@nameof(UserDto.Name)" Caption="@L["Name"].Value">
<DisplayTemplate>
@(context.Name)
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="UserDto" Field="@nameof(UserDto.Surname)" Caption="@L["Surname"].Value">
<DisplayTemplate>
@(context.Surname)
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="UserDto" Field="@nameof(UserDto.Email)" Caption="@L["Email"].Value">
<DisplayTemplate>
@(context.Email)
</DisplayTemplate>
</DataGridColumn>
</DataGridColumns>
</DataGrid>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary" Clicked="CloseUserPickerModalAsync">@L["Cancel"]</Button>
<Button Color="Color.Primary" Clicked="SaveUserPickerFormAsync">@L["Save"]</Button>
</ModalFooter>
</ModalContent>

117
src/EventHub.Admin.Web/Components/UserPicker/UserPicker.razor.cs

@ -0,0 +1,117 @@
using Blazorise;
using EventHub.Admin.Users;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components.Web;
using Volo.Abp.Application.Dtos;
namespace EventHub.Admin.Web.Components.UserPicker
{
public partial class UserPicker
{
[Parameter]
public Modal UserPickerModal { get; set; }
[Parameter]
public EventCallback SaveFormAsync { get; set; }
[Parameter]
public List<Guid> SelectedUserIds { get; set; } = new List<Guid>();
private GetUserListInput Filter { get; set; }
private IReadOnlyList<UserDto> UserList { get; set; }
private int CurrentPage { get; set; }
private string CurrentSorting { get; set; }
private int TotalCount { get; set; }
private int PageSize { get; }
public Dictionary<Guid, bool> SelectAllUsers = new();
private bool AllUserSelected
{
get => SelectAllUsers.All(x => x.Value);
set
{
foreach (var key in SelectAllUsers.Keys)
{
SelectAllUsers[key] = value;
}
}
}
public UserPicker()
{
Filter = new GetUserListInput();
PageSize = LimitedResultRequestDto.DefaultMaxResultCount;
}
protected override async Task OnInitializedAsync()
{
await GetUsersAsync();
}
protected override async Task OnParametersSetAsync()
{
await GetUsersAsync();
}
private async Task GetUsersAsync()
{
Filter.MaxResultCount = PageSize;
Filter.SkipCount = CurrentPage * PageSize;
Filter.Sorting = CurrentSorting;
var result = await UserAppService.GetListAsync(Filter);
UserList = result.Items;
TotalCount = (int)result.TotalCount;
FillSelectedUserList();
}
private void FillSelectedUserList()
{
SelectAllUsers = new Dictionary<Guid, bool>();
foreach (var user in UserList)
{
SelectAllUsers.Add(user.Id, SelectedUserIds.Contains(user.Id));
}
}
private async Task OnKeyPressed(KeyboardEventArgs e)
{
if (e.Code is "Enter" or "NumpadEnter")
{
await GetUsersAsync();
}
}
private async Task OnDataGridReadAsync(DataGridReadDataEventArgs<UserDto> e)
{
CurrentSorting = e.Columns
.Where(c => c.Direction != SortDirection.None)
.Select(c => c.Field + (c.Direction == SortDirection.Descending ? " DESC" : ""))
.JoinAsString(",");
CurrentPage = e.Page - 1;
await GetUsersAsync();
await InvokeAsync(StateHasChanged);
}
public Task CloseUserPickerModalAsync()
{
UserPickerModal.Hide();
return Task.CompletedTask;
}
private async Task SaveUserPickerFormAsync()
{
await SaveFormAsync.InvokeAsync();
}
}
}

92
src/EventHub.Admin.Web/Pages/AttendeeDetail.razor

@ -17,7 +17,7 @@
@if (CanAddAttendee)
{
<Button Color="Color.Primary"
Clicked="OpenAddAttendeeModal">
Clicked="() => AddAttendeeModal.Show()">
@L["AddNewUser"]
</Button>
}
@ -69,92 +69,6 @@
</Card>
<Modal @ref="@AddAttendeeModal" Closing="@ClosingAddAttendeeModal">
<ModalContent Centered="true">
<ModalHeader>
<ModalTitle>@L["AddAttendee"]</ModalTitle>
<CloseButton Clicked="CloseAddAttendeeModalAsync" />
</ModalHeader>
<ModalBody>
<Form>
<div id="UserFilterSection" class="row mt-3">
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel>@L["Username"]</FieldLabel>
<TextEdit TValue="string" KeyPress="OnKeyPressed" @bind-Text="@Filter.Username" />
</Field>
</Column>
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel>@L["Name"]</FieldLabel>
<TextEdit TValue="string" KeyPress="OnKeyPressed" @bind-Text="@Filter.Name" />
</Field>
</Column>
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel>@L["Surname"]</FieldLabel>
<TextEdit TValue="string" KeyPress="OnKeyPressed" @bind-Text="@Filter.Surname" />
</Field>
</Column>
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel>@L["Email"]</FieldLabel>
<TextEdit TValue="string" KeyPress="OnKeyPressed" @bind-Text="@Filter.Email" />
</Field>
</Column>
</div>
</Form>
<DataGrid TItem="UserDto"
Data="UserList"
ReadData="OnDataGridReadForUsersAsync"
TotalItems="UserListTotalCount"
ShowPager="true"
PageSize="PageSize"
Responsive="true">
<DataGridColumns>
<DataGridColumn Sortable="false" TItem="UserDto" Field="@nameof(UserDto.Id)">
<CaptionTemplate>
<Check TValue="bool" @bind-Checked="@AllUserSelected"></Check>
</CaptionTemplate>
<DisplayTemplate>
@if (SelectAllUsers.ContainsKey(context.Id))
{
<Check TValue="bool" @bind-Checked="@SelectAllUsers[context.Id]"></Check>
}
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="UserDto" Field="@nameof(UserDto.Username)" Caption="@L["UserName"].Value">
<DisplayTemplate>
@(context.Username)
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="UserDto" Field="@nameof(UserDto.Name)" Caption="@L["Name"].Value">
<DisplayTemplate>
@(context.Name)
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="UserDto" Field="@nameof(UserDto.Surname)" Caption="@L["Surname"].Value">
<DisplayTemplate>
@(context.Surname)
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="UserDto" Field="@nameof(UserDto.Email)" Caption="@L["Email"].Value">
<DisplayTemplate>
@(context.Email)
</DisplayTemplate>
</DataGridColumn>
</DataGridColumns>
</DataGrid>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary" Clicked="CloseAddAttendeeModalAsync">@L["Cancel"]</Button>
<Button Color="Color.Primary" Clicked="AddSelectedUsersToEventAsync">@L["Save"]</Button>
</ModalFooter>
</ModalContent>
<Modal @ref="@AddAttendeeModal" Closing="@ClosingUserPickerModal">
<UserPicker @ref="UserPickerModalRef" UserPickerModal="AddAttendeeModal" SelectedUserIds="SelectedUserIds" SaveFormAsync="AddSelectedUsersToEventAsync"></UserPicker>
</Modal>

99
src/EventHub.Admin.Web/Pages/AttendeeDetail.razor.cs

@ -8,9 +8,8 @@ using Blazorise;
using Volo.Abp.Application.Dtos;
using Blazorise.DataGrid;
using EventHub.Admin.Permissions;
using EventHub.Admin.Users;
using EventHub.Admin.Web.Components.UserPicker;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Web;
namespace EventHub.Admin.Web.Pages
{
@ -25,28 +24,15 @@ namespace EventHub.Admin.Web.Pages
private int PageSize { get; }
private bool CanAddAttendee { get; set; }
private Modal AddAttendeeModal { get; set; }
private GetUnregisteredUserEventInput Filter { get; set; }
private IReadOnlyList<UserDto> UserList { get; set; }
private int UserListTotalCount { get; set; }
private Dictionary<Guid, bool> SelectAllUsers = new();
private bool AllUserSelected
{
get => SelectAllUsers.All(x => x.Value);
set
{
foreach (var key in SelectAllUsers.Keys)
{
SelectAllUsers[key] = value;
}
}
}
private GetEventRegistrationListInput Filter { get; set; }
public UserPicker UserPickerModalRef { get; set; }
private List<Guid> SelectedUserIds { get; set; }
public AttendeeDetail()
{
PageSize = LimitedResultRequestDto.DefaultMaxResultCount;
Filter = new GetUnregisteredUserEventInput();
Filter = new GetEventRegistrationListInput();
SelectedUserIds = new List<Guid>();
}
protected override async Task OnInitializedAsync()
@ -57,10 +43,17 @@ namespace EventHub.Admin.Web.Pages
private async Task GetAttendeesAsync()
{
var result = await EventRegistrationAppService.GetAttendeesAsync(EventId);
Filter.EventId = EventId;
Filter.MaxResultCount = PageSize;
Filter.SkipCount = CurrentPage * PageSize;
Filter.Sorting = CurrentSorting;
var result = await EventRegistrationAppService.GetAttendeesAsync(Filter);
AttendeeList = result.Items;
TotalCount = (int)result.TotalCount;
SelectedUserIds = await EventRegistrationAppService.GetAllAttendeeIdsAsync(EventId);
}
private async Task SetPermissionsAsync()
@ -85,67 +78,19 @@ namespace EventHub.Admin.Web.Pages
await GetAttendeesAsync();
}
private async Task OpenAddAttendeeModal()
{
AddAttendeeModal.Show();
await GetUsersAsync();
}
private async Task GetUsersAsync()
{
Filter.EventId = EventId;
Filter.MaxResultCount = PageSize;
Filter.SkipCount = CurrentPage * PageSize;
Filter.Sorting = CurrentSorting;
var result = await UserAppService.GetUnregisteredUsersOfEventAsync(Filter);
UserList = result.Items;
UserListTotalCount = (int)result.TotalCount;
FillSelectedUserList();
}
private void FillSelectedUserList()
{
SelectAllUsers = new Dictionary<Guid, bool>();
foreach (var user in UserList)
{
SelectAllUsers.Add(user.Id, false);
}
}
private async Task OnKeyPressed(KeyboardEventArgs e)
{
if (e.Code is "Enter" or "NumpadEnter")
{
await GetUsersAsync();
}
}
private async Task OnDataGridReadForUsersAsync(DataGridReadDataEventArgs<UserDto> e)
{
CurrentSorting = e.Columns
.Where(c => c.Direction != SortDirection.None)
.Select(c => c.Field + (c.Direction == SortDirection.Descending ? " DESC" : ""))
.JoinAsString(",");
CurrentPage = e.Page - 1;
await GetUsersAsync();
await InvokeAsync(StateHasChanged);
}
private async Task AddSelectedUsersToEventAsync()
{
try
{
var selectedUserIds= SelectAllUsers
var selectedUserIds = UserPickerModalRef
.SelectAllUsers
.Where(x => x.Value)
.Select(x => x.Key)
.ToList();
await EventRegistrationAppService.RegisterUsersAsync(EventId, selectedUserIds);
await CloseAddAttendeeModalAsync();
AddAttendeeModal.Hide();
await GetAttendeesAsync();
await InvokeAsync(StateHasChanged);
@ -156,15 +101,9 @@ namespace EventHub.Admin.Web.Pages
}
}
private void ClosingAddAttendeeModal(ModalClosingEventArgs eventArgs)
private void ClosingUserPickerModal(ModalClosingEventArgs eventArgs)
{
eventArgs.Cancel = eventArgs.CloseReason == CloseReason.FocusLostClosing;
}
private Task CloseAddAttendeeModalAsync()
{
AddAttendeeModal.Hide();
return Task.CompletedTask;
}
}
}

4
src/EventHub.Domain.Shared/Localization/EventHub/en.json

@ -141,6 +141,8 @@
"AddNewUser": "Add New User",
"AttendeeRemoveConfirmationMessage": "Are you sure you want to remove this item?",
"RemoveUser": "Remove User",
"AddAttendee": "Add Attendee"
"AddAttendee": "Add Attendee",
"AddUser": "Add User",
}
}

Loading…
Cancel
Save