Browse Source

Merge pull request #53 from volosoft/EngincanV/admin-events

Admin: Manage Events
pull/55/head
Halil İbrahim Kalkan 5 years ago
committed by GitHub
parent
commit
7d15a92e14
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      src/EventHub.Admin.Application.Contracts/Events/CountryLookupDto.cs
  2. 30
      src/EventHub.Admin.Application.Contracts/Events/EventDetailDto.cs
  3. 16
      src/EventHub.Admin.Application.Contracts/Events/EventInListDto.cs
  4. 15
      src/EventHub.Admin.Application.Contracts/Events/EventListFilterDto.cs
  5. 21
      src/EventHub.Admin.Application.Contracts/Events/IEventAppService.cs
  6. 17
      src/EventHub.Admin.Application.Contracts/Events/Registrations/EventAttendeeDto.cs
  7. 10
      src/EventHub.Admin.Application.Contracts/Events/Registrations/GetEventRegistrationListInput.cs
  8. 19
      src/EventHub.Admin.Application.Contracts/Events/Registrations/IEventRegistrationAppService.cs
  9. 47
      src/EventHub.Admin.Application.Contracts/Events/UpdateEventDto.cs
  10. 9
      src/EventHub.Admin.Application.Contracts/Permissions/EventHubPermissionDefinitionProvider.cs
  11. 18
      src/EventHub.Admin.Application.Contracts/Permissions/EventHubPermissions.cs
  12. 9
      src/EventHub.Admin.Application.Contracts/Users/GetUserListInput.cs
  13. 12
      src/EventHub.Admin.Application.Contracts/Users/IUserAppService.cs
  14. 19
      src/EventHub.Admin.Application.Contracts/Users/UserDto.cs
  15. 24
      src/EventHub.Admin.Application/EventHubApplicationAutoMapperProfile.cs
  16. 102
      src/EventHub.Admin.Application/Events/EventAppService.cs
  17. 84
      src/EventHub.Admin.Application/Events/Registrations/EventRegistrationAppService.cs
  18. 7
      src/EventHub.Admin.Application/Organizations/Memberships/OrganizationMembershipAppService.cs
  19. 5
      src/EventHub.Admin.Application/Organizations/OrganizationAppService.cs
  20. 30
      src/EventHub.Admin.Application/Users/UserAppService.cs
  21. 56
      src/EventHub.Admin.HttpApi.Host/Controllers/Events/EventController.cs
  22. 51
      src/EventHub.Admin.HttpApi.Host/Controllers/Events/Registrations/EventRegistrationController.cs
  23. 30
      src/EventHub.Admin.HttpApi.Host/Controllers/Users/UserController.cs
  24. 72
      src/EventHub.Admin.Web/Components/UserPicker/UserPicker.razor
  25. 128
      src/EventHub.Admin.Web/Components/UserPicker/UserPicker.razor.cs
  26. 3
      src/EventHub.Admin.Web/EventHubBlazorAutoMapperProfile.cs
  27. 17
      src/EventHub.Admin.Web/Menus/EventHubMenuContributor.cs
  28. 6
      src/EventHub.Admin.Web/Menus/EventHubMenus.cs
  29. 69
      src/EventHub.Admin.Web/Pages/AttendeeDetail.razor
  30. 113
      src/EventHub.Admin.Web/Pages/AttendeeDetail.razor.cs
  31. 293
      src/EventHub.Admin.Web/Pages/EventManagement.razor
  32. 202
      src/EventHub.Admin.Web/Pages/EventManagement.razor.cs
  33. 12
      src/EventHub.Application/Events/EventAppService.cs
  34. 14
      src/EventHub.Application/Events/Registrations/EventRegistrationAppService.cs
  35. 13
      src/EventHub.Application/Organizations/Memberships/OrganizationMembershipAppService.cs
  36. 10
      src/EventHub.Application/Organizations/OrganizationAppService.cs
  37. 4
      src/EventHub.Application/Users/UserAppService.cs
  38. 4
      src/EventHub.Domain.Shared/Events/EventConsts.cs
  39. 37
      src/EventHub.Domain.Shared/Localization/EventHub/en.json
  40. 17
      src/EventHub.Domain/Events/EventWithDetails.cs
  41. 34
      src/EventHub.Domain/Events/IEventRepository.cs
  42. 20
      src/EventHub.Domain/Events/Registrations/EventRegistrationWithDetails.cs
  43. 21
      src/EventHub.Domain/Events/Registrations/IEventRegistrationRepository.cs
  44. 25
      src/EventHub.Domain/Users/IUserRepository.cs
  45. 102
      src/EventHub.EntityFrameworkCore/EntityFrameworkCore/Events/EventRepository.cs
  46. 61
      src/EventHub.EntityFrameworkCore/EntityFrameworkCore/Events/Registrations/EventRegistrationRepository.cs
  47. 43
      src/EventHub.EntityFrameworkCore/EntityFrameworkCore/Users/UserRepository.cs

10
src/EventHub.Admin.Application.Contracts/Events/CountryLookupDto.cs

@ -0,0 +1,10 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EventHub.Admin.Events
{
public class CountryLookupDto : EntityDto<Guid>
{
public string Name { get; set; }
}
}

30
src/EventHub.Admin.Application.Contracts/Events/EventDetailDto.cs

@ -0,0 +1,30 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EventHub.Admin.Events
{
public class EventDetailDto : EntityDto<Guid>
{
public string Title { get; set; }
public string Description { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public byte[] CoverImageContent { get; set; }
public bool IsOnline { get; set; }
public string OnlineLink { get; set; }
public Guid? CountryId { get; set; }
public string City { get; set; }
public string Language { get; set; }
public int? Capacity { get; set; }
}
}

16
src/EventHub.Admin.Application.Contracts/Events/EventInListDto.cs

@ -0,0 +1,16 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EventHub.Admin.Events
{
public class EventInListDto : EntityDto<Guid>
{
public string Title { get; set; }
public string OrganizationDisplayName { get; set; }
public int AttendeeCount { get; set; }
public DateTime StartTime { get; set; }
}
}

15
src/EventHub.Admin.Application.Contracts/Events/EventListFilterDto.cs

@ -0,0 +1,15 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EventHub.Admin.Events
{
public class EventListFilterDto : PagedAndSortedResultRequestDto
{
public DateTime? MinStartTime { get; set; }
public DateTime? MaxStartTime { get; set; }
public string Title { get; set; }
public string OrganizationDisplayName { get; set; }
public int? MinAttendeeCount { get; set; }
public int? MaxAttendeeCount { get; set; }
}
}

21
src/EventHub.Admin.Application.Contracts/Events/IEventAppService.cs

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace EventHub.Admin.Events
{
public interface IEventAppService : IApplicationService
{
Task<PagedResultDto<EventInListDto>> GetListAsync(EventListFilterDto input);
Task<EventDetailDto> GetAsync(Guid id);
Task UpdateAsync(Guid id, UpdateEventDto input);
Task<List<CountryLookupDto>> GetCountriesLookupAsync();
Task<byte[]> GetCoverImageAsync(Guid id);
}
}

17
src/EventHub.Admin.Application.Contracts/Events/Registrations/EventAttendeeDto.cs

@ -0,0 +1,17 @@
using System;
namespace EventHub.Admin.Events.Registrations
{
public class EventAttendeeDto
{
public Guid UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
}

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; }
}
}

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

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace EventHub.Admin.Events.Registrations
{
public interface IEventRegistrationAppService : IApplicationService
{
Task<PagedResultDto<EventAttendeeDto>> GetAttendeesAsync(GetEventRegistrationListInput input);
Task UnRegisterAttendeeAsync(Guid eventId, Guid attendeeId);
Task RegisterUsersAsync(Guid eventId, List<Guid> userIds);
Task<List<Guid>> GetAllAttendeeIdsAsync(Guid eventId);
}
}

47
src/EventHub.Admin.Application.Contracts/Events/UpdateEventDto.cs

@ -0,0 +1,47 @@
using System;
using System.ComponentModel.DataAnnotations;
using EventHub.Events;
using JetBrains.Annotations;
namespace EventHub.Admin.Events
{
public class UpdateEventDto
{
[Required]
[StringLength(EventConsts.MaxTitleLength, MinimumLength = EventConsts.MinTitleLength)]
public string Title { get; set; }
[Required]
[StringLength(EventConsts.MaxDescriptionLength, MinimumLength = EventConsts.MinDescriptionLength)]
public string Description { get; set; }
[Required]
[DataType(DataType.DateTime)]
public DateTime StartTime { get; set; }
[Required]
[DataType(DataType.DateTime)]
public DateTime EndTime { get; set; }
[CanBeNull]
public byte[] CoverImageContent { get; set; }
public bool IsOnline { get; set; }
[CanBeNull]
[StringLength(EventConsts.MaxOnlineLinkLength, MinimumLength = EventConsts.MinOnlineLinkLength)]
public string OnlineLink { get; set; }
public Guid? CountryId { get; set; }
[CanBeNull]
[StringLength(EventConsts.MaxCityLength, MinimumLength = EventConsts.MinCityLength)]
public string City { get; set; }
[CanBeNull]
[StringLength(EventConsts.MaxLanguageLength, MinimumLength = EventConsts.MinLanguageLength)]
public string Language { get; set; }
[Range(1, int.MaxValue)]
public int? Capacity { get; set; }
}
}

9
src/EventHub.Admin.Application.Contracts/Permissions/EventHubPermissionDefinitionProvider.cs

@ -15,6 +15,15 @@ namespace EventHub.Admin.Permissions
organizationsPermission.AddChild(EventHubPermissions.Organizations.Update, L("Permission:Edit"));
organizationsPermission.AddChild(EventHubPermissions.Organizations.Delete, L("Permission:Delete"));
organizationsPermission.AddChild(EventHubPermissions.Organizations.Memberships.Default, L("Permission:MembershipManagement"));
var eventPermissions = eventHubGroup.AddPermission(EventHubPermissions.Events.Default, L("Permission:EventManagement"));
eventPermissions.AddChild(EventHubPermissions.Events.Update, L("Permission:Edit"));
var eventRegistrationPermissions = eventHubGroup.AddPermission(EventHubPermissions.Events.Registrations.Default, L("Permission:RegistrationManagement"));
eventRegistrationPermissions.AddChild(EventHubPermissions.Events.Registrations.AddAttendee, L("Permission:AddAttendee"));
eventRegistrationPermissions.AddChild(EventHubPermissions.Events.Registrations.RemoveAttendee, L("Permission:RemoveAttendee"));
var userPermissions = eventHubGroup.AddPermission(EventHubPermissions.Users.Default, L("Permission:UserManagement"));
}
private static LocalizableString L(string name)

18
src/EventHub.Admin.Application.Contracts/Permissions/EventHubPermissions.cs

@ -16,5 +16,23 @@
public const string Default = Organizations.Default + ".Memberships";
}
}
public static class Events
{
public const string Default = GroupName + ".Events";
public const string Update = Default + ".Update";
public class Registrations
{
public const string Default = Events.Default + ".Registrations";
public const string AddAttendee = Default + ".AddAttendee";
public const string RemoveAttendee = Default + ".RemoveAttendee";
}
}
public static class Users
{
public const string Default = GroupName + ".Users";
}
}
}

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; }
}
}

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

@ -0,0 +1,12 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace EventHub.Admin.Users
{
public interface IUserAppService : IApplicationService
{
Task<PagedResultDto<UserDto>> GetListAsync(GetUserListInput input);
}
}

19
src/EventHub.Admin.Application.Contracts/Users/UserDto.cs

@ -0,0 +1,19 @@
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Auditing;
namespace EventHub.Admin.Users
{
public class UserDto : EntityDto<Guid>, IHasCreationTime
{
public string Username { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public DateTime CreationTime { get; set; }
}
}

24
src/EventHub.Admin.Application/EventHubApplicationAutoMapperProfile.cs

@ -1,13 +1,20 @@
using AutoMapper;
using EventHub.Admin.Events;
using EventHub.Admin.Events.Registrations;
using EventHub.Admin.Organizations;
using EventHub.Admin.Organizations.Memberships;
using EventHub.Admin.Users;
using EventHub.Countries;
using EventHub.Events;
using EventHub.Events.Registrations;
using EventHub.Organizations;
using EventHub.Organizations.Memberships;
using Volo.Abp.AutoMapper;
using Volo.Abp.Identity;
namespace EventHub.Admin
{
public class EventHubAdminApplicationAutoMapperProfile : Profile
public class EventHubAdminApplicationAutoMapperProfile : Profile
{
public EventHubAdminApplicationAutoMapperProfile()
{
@ -19,6 +26,21 @@ namespace EventHub.Admin
.Ignore(x => x.ProfilePictureContent);
CreateMap<OrganizationMemberWithDetails, OrganizationMemberDto>();
CreateMap<Event, EventDetailDto>()
.Ignore(x => x.CoverImageContent);
CreateMap<Country, CountryLookupDto>();
CreateMap<IdentityUser, EventAttendeeDto>()
.ForMember(eventAttendee => eventAttendee.UserId,
opt => opt.MapFrom(user => user.Id));
CreateMap<IdentityUser, UserDto>();
CreateMap<EventWithDetails, EventInListDto>();
CreateMap<EventRegistrationWithDetails, EventAttendeeDto>();
}
}
}

102
src/EventHub.Admin.Application/Events/EventAppService.cs

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using EventHub.Admin.Permissions;
using EventHub.Countries;
using EventHub.Events;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.BlobStoring;
using Volo.Abp.Domain.Repositories;
namespace EventHub.Admin.Events
{
[Authorize(EventHubPermissions.Events.Default)]
public class EventAppService : EventHubAdminAppService, IEventAppService
{
private readonly IEventRepository _eventRepository;
private readonly IBlobContainer<EventCoverImageContainer> _eventBlobContainer;
private readonly EventManager _eventManager;
private readonly IRepository<Country, Guid> _countryRepository;
public EventAppService(
IEventRepository eventRepository,
IBlobContainer<EventCoverImageContainer> eventBlobContainer,
EventManager eventManager,
IRepository<Country, Guid> countryRepository)
{
_eventRepository = eventRepository;
_eventBlobContainer = eventBlobContainer;
_eventManager = eventManager;
_countryRepository = countryRepository;
}
public async Task<EventDetailDto> GetAsync(Guid id)
{
var @event = await _eventRepository.GetAsync(id);
var eventDetailDto = ObjectMapper.Map<Event, EventDetailDto>(@event);
eventDetailDto.CoverImageContent = await GetCoverImageAsync(id);
return eventDetailDto;
}
public async Task<PagedResultDto<EventInListDto>> GetListAsync(EventListFilterDto input)
{
var totalCount = await _eventRepository.GetCountAsync(input.Title, input.OrganizationDisplayName, input.MinAttendeeCount,
input.MaxAttendeeCount, input.MinStartTime, input.MaxStartTime);
var items = await _eventRepository.GetListAsync(input.Sorting, input.SkipCount, input.MaxResultCount,
input.Title, input.OrganizationDisplayName, input.MinAttendeeCount, input.MaxAttendeeCount,
input.MinStartTime, input.MaxStartTime);
var events = ObjectMapper.Map<List<EventWithDetails>, List<EventInListDto>>(items);
return new PagedResultDto<EventInListDto>(totalCount, events);
}
[Authorize(EventHubPermissions.Events.Update)]
public async Task UpdateAsync(Guid id, UpdateEventDto input)
{
var @event = await _eventRepository.GetAsync(id);
await _eventManager.SetLocationAsync(@event, input.IsOnline, input.OnlineLink, input.CountryId, input.City);
@event.SetTitle(input.Title);
@event.SetDescription(input.Description);
@event.Language = input.Language;
@event.SetTime(input.StartTime, @event.EndTime);
await _eventManager.SetCapacityAsync(@event, input.Capacity);
await SetCoverImageAsync(blobName: id.ToString(), input.CoverImageContent);
await _eventRepository.UpdateAsync(@event);
}
public async Task<byte[]> GetCoverImageAsync(Guid id)
{
var blobName = id.ToString();
return await _eventBlobContainer.GetAllBytesOrNullAsync(blobName);
}
public async Task<List<CountryLookupDto>> GetCountriesLookupAsync()
{
var countriesQueryable = await _countryRepository.GetQueryableAsync();
var query = from country in countriesQueryable
orderby country.Name
select country;
var countries = await AsyncExecuter.ToListAsync(query);
return ObjectMapper.Map<List<Country>, List<CountryLookupDto>>(countries);
}
private async Task SetCoverImageAsync(string blobName, byte[] coverImageContent, bool overrideExisting = true)
{
await _eventBlobContainer.SaveAsync(blobName, coverImageContent, overrideExisting);
}
}
}

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

@ -0,0 +1,84 @@
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;
using EventHub.Events.Registrations;
using Microsoft.AspNetCore.Authorization;
using EventHub.Events;
using EventHub.Users;
namespace EventHub.Admin.Events.Registrations
{
[Authorize(EventHubPermissions.Events.Registrations.Default)]
public class EventRegistrationAppService : EventHubAdminAppService, IEventRegistrationAppService
{
private readonly IUserRepository _userRepository;
private readonly IEventRegistrationRepository _eventRegistrationRepository;
private readonly IEventRepository _eventRepository;
private readonly EventRegistrationManager _eventRegistrationManager;
public EventRegistrationAppService(
IUserRepository userRepository,
IEventRegistrationRepository eventRegistrationRepository,
IEventRepository eventRepository,
EventRegistrationManager eventRegistrationManager)
{
_userRepository = userRepository;
_eventRegistrationRepository = eventRegistrationRepository;
_eventRepository = eventRepository;
_eventRegistrationManager = eventRegistrationManager;
}
public async Task<PagedResultDto<EventAttendeeDto>> GetAttendeesAsync(GetEventRegistrationListInput input)
{
var totalCount = await _eventRegistrationRepository.GetCountAsync(input.EventId);
var items = await _eventRegistrationRepository.GetListAsync(input.EventId, input.Sorting, input.SkipCount, input.MaxResultCount);
var users = ObjectMapper.Map<List<EventRegistrationWithDetails>, List<EventAttendeeDto>>(items);
return new PagedResultDto<EventAttendeeDto>(totalCount, users);
}
[Authorize(EventHubPermissions.Events.Registrations.RemoveAttendee)]
public async Task UnRegisterAttendeeAsync(Guid eventId, Guid attendeeId)
{
await _eventRegistrationRepository.DeleteAsync(x => x.EventId == eventId && x.UserId == attendeeId);
}
[Authorize(EventHubPermissions.Events.Registrations.AddAttendee)]
public async Task RegisterUsersAsync(Guid eventId, List<Guid> userIds)
{
if (userIds == null || !userIds.Any())
{
return;
}
var @event = await _eventRepository.GetAsync(eventId);
var userQueryable = await _userRepository.GetQueryableAsync();
var query = userQueryable.Where(user => userIds.Contains(user.Id));
var users = await AsyncExecuter.ToListAsync(query);
foreach (var user in users)
{
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);
}
}
}

7
src/EventHub.Admin.Application/Organizations/Memberships/OrganizationMembershipAppService.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using EventHub.Admin.Permissions;
using EventHub.Organizations.Memberships;
using EventHub.Users;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
@ -17,11 +18,11 @@ namespace EventHub.Admin.Organizations.Memberships
public class OrganizationMembershipAppService : ApplicationService, IOrganizationMembershipAppService
{
private readonly IOrganizationMembershipRepository _organizationMembershipRepository;
private readonly IRepository<IdentityUser, Guid> _userRepository;
private readonly IUserRepository _userRepository;
public OrganizationMembershipAppService(
IOrganizationMembershipRepository organizationMembershipRepository,
IRepository<IdentityUser, Guid> userRepository)
IOrganizationMembershipRepository organizationMembershipRepository,
IUserRepository userRepository)
{
_organizationMembershipRepository = organizationMembershipRepository;
_userRepository = userRepository;

5
src/EventHub.Admin.Application/Organizations/OrganizationAppService.cs

@ -5,6 +5,7 @@ using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using EventHub.Admin.Permissions;
using EventHub.Organizations;
using EventHub.Users;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
@ -18,12 +19,12 @@ namespace EventHub.Admin.Organizations
public class OrganizationAppService : EventHubAdminAppService, IOrganizationAppService
{
private readonly IRepository<Organization, Guid> _organizationRepository;
private readonly IRepository<IdentityUser, Guid> _identityUserRepository;
private readonly IUserRepository _identityUserRepository;
private readonly IBlobContainer<OrganizationProfilePictureContainer> _organizationBlobContainer;
public OrganizationAppService(
IRepository<Organization, Guid> organizationRepository,
IRepository<IdentityUser, Guid> identityUserRepository,
IUserRepository identityUserRepository,
IBlobContainer<OrganizationProfilePictureContainer> organizationBlobContainer)
{
_organizationRepository = organizationRepository;

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

@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using EventHub.Admin.Permissions;
using EventHub.Users;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Identity;
namespace EventHub.Admin.Users
{
[Authorize(EventHubPermissions.Users.Default)]
public class UserAppService : EventHubAdminAppService, IUserAppService
{
private readonly IUserRepository _userRepository;
public UserAppService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public async Task<PagedResultDto<UserDto>> GetListAsync(GetUserListInput input)
{
var totalCount = await _userRepository.GetCountAsync(input.Username);
var items = await _userRepository.GetListAsync(input.Sorting, input.SkipCount, input.MaxResultCount, input.Username);
var users = ObjectMapper.Map<List<IdentityUser>, List<UserDto>>(items);
return new PagedResultDto<UserDto>(totalCount, users);
}
}
}

56
src/EventHub.Admin.HttpApi.Host/Controllers/Events/EventController.cs

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EventHub.Admin.Events;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
namespace EventHub.Admin.Controllers.Events
{
[RemoteService(Name = EventHubAdminRemoteServiceConsts.RemoteServiceName)]
[Controller]
[Area("eventhub-admin")]
[ControllerName("Event")]
[Route("/api/eventhub/admin/event")]
public class EventController : AbpController, IEventAppService
{
private readonly IEventAppService _eventAppService;
public EventController(IEventAppService eventAppService)
{
_eventAppService = eventAppService;
}
[HttpGet("{id}")]
public Task<EventDetailDto> GetAsync(Guid id)
{
return _eventAppService.GetAsync(id);
}
[HttpGet("countries")]
public Task<List<CountryLookupDto>> GetCountriesLookupAsync()
{
return _eventAppService.GetCountriesLookupAsync();
}
[HttpGet("cover-image/{id}")]
public Task<byte[]> GetCoverImageAsync(Guid id)
{
return _eventAppService.GetCoverImageAsync(id);
}
[HttpGet]
public Task<PagedResultDto<EventInListDto>> GetListAsync(EventListFilterDto input)
{
return _eventAppService.GetListAsync(input);
}
[HttpPut]
public Task UpdateAsync(Guid id, UpdateEventDto input)
{
return _eventAppService.UpdateAsync(id, input);
}
}
}

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

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EventHub.Admin.Events.Registrations;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
namespace EventHub.Admin.Controllers.Events.Registrations
{
[RemoteService(Name = EventHubAdminRemoteServiceConsts.RemoteServiceName)]
[Controller]
[Area("eventhub-admin")]
[ControllerName("EventRegistration")]
[Route("/api/eventhub/admin/event-registration")]
public class EventRegistrationController : AbpController, IEventRegistrationAppService
{
private readonly IEventRegistrationAppService _eventRegistrationAppService;
public EventRegistrationController(IEventRegistrationAppService eventRegistrationAppService)
{
_eventRegistrationAppService = eventRegistrationAppService;
}
[HttpGet("{eventId}")]
public Task<List<Guid>> GetAllAttendeeIdsAsync(Guid eventId)
{
return _eventRegistrationAppService.GetAllAttendeeIdsAsync(eventId);
}
[HttpGet]
public Task<PagedResultDto<EventAttendeeDto>> GetAttendeesAsync(GetEventRegistrationListInput input)
{
return _eventRegistrationAppService.GetAttendeesAsync(input);
}
[HttpPost]
public Task RegisterUsersAsync(Guid eventId, List<Guid> userIds)
{
return _eventRegistrationAppService.RegisterUsersAsync(eventId, userIds);
}
[HttpDelete]
public Task UnRegisterAttendeeAsync(Guid eventId, Guid attendeeId)
{
return _eventRegistrationAppService.UnRegisterAttendeeAsync(eventId, attendeeId);
}
}
}

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

@ -0,0 +1,30 @@
using EventHub.Admin.Users;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
namespace EventHub.Admin.Controllers.Users
{
[RemoteService(Name = EventHubAdminRemoteServiceConsts.RemoteServiceName)]
[Controller]
[Area("eventhub-admin")]
[ControllerName("User")]
[Route("/api/eventhub/admin/user")]
public class UserController : AbpController, IUserAppService
{
private readonly IUserAppService _userAppService;
public UserController(IUserAppService userAppService)
{
_userAppService = userAppService;
}
[HttpGet]
public Task<PagedResultDto<UserDto>> GetListAsync(GetUserListInput input)
{
return _userAppService.GetListAsync(input);
}
}
}

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

@ -0,0 +1,72 @@
@using EventHub.Admin.Users
@inherits EventHubComponentBase
@inject IUserAppService UserAppService
<Modal @ref="@UserPickerModal" Closing="@ClosingUserPickerModal">
<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>
</Modal>

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

@ -0,0 +1,128 @@
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
{
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 OpenUserPickerModalAsync()
{
UserPickerModal.Show();
return Task.CompletedTask;
}
public Task CloseUserPickerModalAsync()
{
UserPickerModal.Hide();
return Task.CompletedTask;
}
private async Task SaveUserPickerFormAsync()
{
await SaveFormAsync.InvokeAsync();
}
private void ClosingUserPickerModal(ModalClosingEventArgs eventArgs)
{
eventArgs.Cancel = eventArgs.CloseReason == CloseReason.FocusLostClosing;
}
}
}

3
src/EventHub.Admin.Web/EventHubBlazorAutoMapperProfile.cs

@ -1,4 +1,5 @@
using AutoMapper;
using EventHub.Admin.Events;
using EventHub.Admin.Organizations;
namespace EventHub.Admin.Web
@ -8,6 +9,8 @@ namespace EventHub.Admin.Web
public EventHubBlazorAutoMapperProfile()
{
CreateMap<OrganizationProfileDto, UpdateOrganizationDto>();
CreateMap<EventDetailDto, UpdateEventDto>();
}
}
}

17
src/EventHub.Admin.Web/Menus/EventHubMenuContributor.cs

@ -48,6 +48,7 @@ namespace EventHub.Admin.Web.Menus
);
await AddOrganizationMenu(context, l);
await AddEventMenu(context, l);
}
private Task ConfigureUserMenuAsync(MenuConfigurationContext context)
@ -87,5 +88,21 @@ namespace EventHub.Admin.Web.Menus
return Task.CompletedTask;
}
private Task AddEventMenu(MenuConfigurationContext context, IStringLocalizer l)
{
var eventMenu = new ApplicationMenuItem(
EventHubMenus.EventManagement.GroupName,
l["Menu:EventManagement"],
icon: "fas fa-calendar-minus"
);
context.Menu.Items.Insert(3, eventMenu);
eventMenu.AddItem(new ApplicationMenuItem(EventHubMenus.EventManagement.Events, displayName: l["Menu:Events"], url: "/events"))
.RequirePermissions(EventHubPermissions.Events.Default);
return Task.CompletedTask;
}
}
}

6
src/EventHub.Admin.Web/Menus/EventHubMenus.cs

@ -11,5 +11,11 @@
public const string Organizations = GroupName + ".Organizations";
public const string OrganizationMemberships = GroupName + ".OrganizationMemberships";
}
public static class EventManagement
{
public const string GroupName = Prefix + ".EventManagement";
public const string Events = GroupName + ".Events";
}
}
}

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

@ -0,0 +1,69 @@
@page "/event/{EventId:guid}/attendees"
@using EventHub.Admin.Web.Components.UserPicker
@using EventHub.Admin.Events.Registrations
@using EventHub.Admin.Permissions
@using EventHub.Admin.Users
@inherits EventHubComponentBase
@inject IEventRegistrationAppService EventRegistrationAppService
@inject IUserAppService UserAppService
<Card>
<CardHeader>
<h2>@L["Attendees"]</h2>
<Paragraph Alignment="TextAlignment.Right">
@if (CanAddAttendee)
{
<Button Color="Color.Primary"
Clicked="OpenUserPickerModal">
@L["AddNewUser"]
</Button>
}
</Paragraph>
</CardHeader>
<CardBody>
<DataGrid TItem="EventAttendeeDto"
Data="AttendeeList"
ReadData="OnDataGridReadAsync"
TotalItems="TotalCount"
ShowPager="true"
PageSize="PageSize"
Responsive="true">
<DataGridColumns>
<DataGridEntityActionsColumn TItem="EventAttendeeDto">
<DisplayTemplate>
<EntityActions TItem="EventAttendeeDto">
<EntityAction TItem="EventAttendeeDto"
RequiredPolicy="@EventHubPermissions.Events.Registrations.RemoveAttendee"
Clicked="() => RemoveAttendeeAsync(context)"
ConfirmationMessage="@(() => L["AttendeeRemoveConfirmationMessage"])"
Text="@L["RemoveUser"]">
</EntityAction>
</EntityActions>
</DisplayTemplate>
</DataGridEntityActionsColumn>
<DataGridColumn TItem="EventAttendeeDto"
Field="UserName"
Caption="@L["UserName"]">
</DataGridColumn>
<DataGridColumn TItem="EventAttendeeDto"
Field="Name"
Caption="@L["Name"]">
</DataGridColumn>
<DataGridColumn TItem="EventAttendeeDto"
Field="Surname"
Caption="@L["Surname"]">
</DataGridColumn>
<DataGridColumn TItem="EventAttendeeDto"
Field="Email"
Caption="@L["Email"]">
</DataGridColumn>
</DataGridColumns>
</DataGrid>
</CardBody>
</Card>
<UserPicker @ref="UserPickerModalRef" SelectedUserIds="SelectedUserIds" SaveFormAsync="AddSelectedUsersToEventAsync" />

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

@ -0,0 +1,113 @@
using Microsoft.AspNetCore.Components;
using System;
using System.Threading.Tasks;
using EventHub.Admin.Events.Registrations;
using System.Collections.Generic;
using System.Linq;
using Blazorise;
using Volo.Abp.Application.Dtos;
using Blazorise.DataGrid;
using EventHub.Admin.Permissions;
using EventHub.Admin.Web.Components.UserPicker;
using Microsoft.AspNetCore.Authorization;
namespace EventHub.Admin.Web.Pages
{
public partial class AttendeeDetail
{
[Parameter]
public Guid EventId { get; set; }
private IReadOnlyList<EventAttendeeDto> AttendeeList { get; set; }
private int CurrentPage { get; set; }
private string CurrentSorting { get; set; }
private int TotalCount { get; set; }
private int PageSize { get; }
private bool CanAddAttendee { get; set; }
private GetEventRegistrationListInput Filter { get; set; }
public UserPicker UserPickerModalRef { get; set; }
private List<Guid> SelectedUserIds { get; set; }
public AttendeeDetail()
{
PageSize = LimitedResultRequestDto.DefaultMaxResultCount;
Filter = new GetEventRegistrationListInput();
SelectedUserIds = new List<Guid>();
}
protected override async Task OnInitializedAsync()
{
await SetPermissionsAsync();
await GetAttendeesAsync();
}
private async Task GetAttendeesAsync()
{
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()
{
CanAddAttendee = await AuthorizationService.IsGrantedAsync(EventHubPermissions.Events.Registrations.AddAttendee);
}
private async Task OnDataGridReadAsync(DataGridReadDataEventArgs<EventAttendeeDto> 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 GetAttendeesAsync();
await InvokeAsync(StateHasChanged);
}
private async Task RemoveAttendeeAsync(EventAttendeeDto attendee)
{
await EventRegistrationAppService.UnRegisterAttendeeAsync(EventId, attendee.UserId);
await GetAttendeesAsync();
}
private async Task AddSelectedUsersToEventAsync()
{
try
{
var selectedUserIds = UserPickerModalRef
.SelectAllUsers
.Where(x => x.Value)
.Select(x => x.Key)
.ToList();
var removedAttendees = SelectedUserIds.Except(selectedUserIds).ToList();
foreach (var attendeeId in removedAttendees)
{
await EventRegistrationAppService.UnRegisterAttendeeAsync(EventId, attendeeId);
}
await EventRegistrationAppService.RegisterUsersAsync(EventId, selectedUserIds);
await UserPickerModalRef.CloseUserPickerModalAsync();
await GetAttendeesAsync();
await InvokeAsync(StateHasChanged);
}
catch (Exception ex)
{
await HandleErrorAsync(ex);
}
}
private async Task OpenUserPickerModal()
{
await UserPickerModalRef.OpenUserPickerModalAsync();
}
}
}

293
src/EventHub.Admin.Web/Pages/EventManagement.razor

@ -0,0 +1,293 @@
@page "/events"
@using Microsoft.AspNetCore.Authorization
@using EventHub.Admin.Permissions
@using EventHub.Admin.Events
@using EventHub.Events
@using Volo.Abp.AspNetCore.Components.Notifications
@inherits EventHubComponentBase
@attribute [Authorize(EventHubPermissions.Events.Default)]
@inject IEventAppService EventAppService
@inject NavigationManager NavigationManager
<Card>
<CardHeader>
<h2>@L["Events"]</h2>
</CardHeader>
<CardBody>
<Form>
<div id="FilterSection" class="row mt-3">
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel>@L["Title"]</FieldLabel>
<TextEdit TValue="string" KeyPress="OnKeyPress" @bind-Text="@Filter.Title"/>
</Field>
</Column>
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel>@L["OrganizationDisplayName"]</FieldLabel>
<TextEdit TValue="string" KeyPress="OnKeyPress" @bind-Text="@Filter.OrganizationDisplayName"/>
</Field>
</Column>
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel>@L["MinStartTime"]</FieldLabel>
<DateEdit TValue="DateTime?" Date="@Filter.MinStartTime" DateChanged="OnSelectedDateChangedForMinStartTime" />
</Field>
</Column>
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel>@L["MaxStartTime"]</FieldLabel>
<DateEdit TValue="DateTime?" Date="@Filter.MaxStartTime" DateChanged="OnSelectedDateChangedForMaxStartTime" />
</Field>
</Column>
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel>@L["MinAttendeeCount"]</FieldLabel>
<NumericEdit TValue="int?" KeyPress="OnKeyPress" @bind-Value="@Filter.MinAttendeeCount"/>
</Field>
</Column>
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel>@L["MaxAttendeeCount"]</FieldLabel>
<NumericEdit TValue="int?" KeyPress="OnKeyPress" @bind-Value="@Filter.MaxAttendeeCount"/>
</Field>
</Column>
</div>
</Form>
<DataGrid TItem="EventInListDto"
Data="EventList"
ReadData="OnDataGridReadAsync"
TotalItems="TotalCount"
ShowPager="true"
PageSize="PageSize"
Responsive="true">
<DataGridColumns>
<DataGridEntityActionsColumn TItem="EventInListDto">
<DisplayTemplate>
<EntityActions TItem="EventInListDto">
<EntityAction TItem="EventInListDto"
RequiredPolicy="@EventHubPermissions.Events.Update"
Clicked="() => OpenEditEventModal(context)"
Text="@L["Edit"]">
</EntityAction>
<EntityAction TItem="EventInListDto"
RequiredPolicy="@EventHubPermissions.Events.Registrations.Default"
Clicked="@(() => NavigationManager.NavigateTo($"/event/{context.Id}/attendees"))"
Text="@L["Attendees"]">
</EntityAction>
</EntityActions>
</DisplayTemplate>
</DataGridEntityActionsColumn>
<DataGridColumn TItem="EventInListDto"
Field="Title"
Caption="@L["Title"]">
</DataGridColumn>
<DataGridColumn TItem="EventInListDto"
Field="OrganizationDisplayName"
Caption="@L["OrganizationDisplayName"]">
</DataGridColumn>
<DataGridColumn TItem="EventInListDto"
Field="AttendeeCount"
Caption="@L["AttendeeCount"]">
</DataGridColumn>
<DataGridColumn TItem="EventInListDto"
Field="StartTime"
Caption="@L["StartTime"]">
</DataGridColumn>
</DataGridColumns>
</DataGrid>
</CardBody>
</Card>
<Modal @ref="EditEventModal" Closing="@OnEditModalClosing">
<ModalContent Centered="true" Size="ModalSize.Large">
<Form id="EditEventForm">
<ModalHeader>
<ModalTitle>@L["UpdateEvent"]</ModalTitle>
<CloseButton Clicked="() => EditEventModal.Hide()" />
</ModalHeader>
<ModalBody>
<Tabs SelectedTab="@SelectedTabInEditModal" SelectedTabChanged="@OnSelectedTabChangedInEditModal">
<Items>
<Tab Name="@EventEditTabs.EventInfo.ToString()">@L["EventInfo"]</Tab>
<Tab Name="@EventEditTabs.Timing.ToString()">@L["Timing"]</Tab>
<Tab Name="@EventEditTabs.CoverImage.ToString()">@L["CoverImage"]</Tab>
</Items>
<Content>
<TabPanel Name="@EventEditTabs.EventInfo.ToString()" Class="mt-3">
<Validations Mode="ValidationMode.Auto" Model="@EditEventModal" ValidateOnLoad="false">
<Validation>
<Field>
<FieldLabel>@L["Title"] *</FieldLabel>
<TextEdit TValue="string" @bind-Text="@EditingEvent.Title">
<Feedback>
<ValidationError/>
</Feedback>
</TextEdit>
</Field>
</Validation>
<Validation>
<Field>
<FieldLabel>@L["Description"] *</FieldLabel>
<MemoEdit @bind-Text="@EditingEvent.Description">
<Feedback>
<ValidationError/>
</Feedback>
</MemoEdit>
</Field>
</Validation>
<Validation>
<Field>
<FieldLabel>@L["IsOnline"]</FieldLabel>
<Select @bind-SelectedValue="@EditingEvent.IsOnline">
<SelectItem Value="@Boolean.TrueString">@L["Online"]</SelectItem>
<SelectItem Value="@Boolean.FalseString">@L["InPerson"]</SelectItem>
</Select>
</Field>
</Validation>
<Validation>
<Field>
<FieldLabel>@L["Language"]</FieldLabel>
<Select @bind-SelectedValue="@EditingEvent.Language">
@if (Languages != null && Languages.Any())
{
foreach (var language in Languages)
{
<SelectItem Value="@language.Value">@language.Text</SelectItem>
}
}
</Select>
</Field>
</Validation>
@if (EditingEvent.IsOnline)
{
<Validation>
<Field>
<FieldLabel>@L["OnlineLink"] *</FieldLabel>
<MemoEdit @bind-Text="@EditingEvent.OnlineLink">
<Feedback>
<ValidationError/>
</Feedback>
</MemoEdit>
</Field>
</Validation>
}
else
{
<Validation>
<Field>
<FieldLabel>@L["Country"] *</FieldLabel>
<Select @bind-SelectedValue="@EditingEvent.CountryId">
@if (Countries != null && Countries.Any())
{
@foreach (var country in Countries)
{
<SelectItem Value="@country.Id">@country.Name</SelectItem>
}
}
</Select>
</Field>
</Validation>
<Validation>
<Field>
<FieldLabel>@L["City"] *</FieldLabel>
<TextEdit TValue="string" @bind-Text="@EditingEvent.City">
<Feedback>
<ValidationError/>
</Feedback>
</TextEdit>
</Field>
</Validation>
}
<Validation>
<Field>
<FieldLabel>@L["Capacity"]</FieldLabel>
<NumericEdit TValue="int?" @bind-Value="@EditingEvent.Capacity">
<Feedback>
<ValidationError/>
</Feedback>
</NumericEdit>
</Field>
</Validation>
</Validations>
</TabPanel>
<TabPanel Name="@EventEditTabs.Timing.ToString()" Class="mt-3">
<Validations Mode="ValidationMode.Auto" Model="@EditEventModal" ValidateOnLoad="false">
<Validation>
<Field>
<FieldLabel>@L["StartTime"] *</FieldLabel>
<DateEdit TValue="DateTime" @bind-Date="@EditingEvent.StartTime">
<Feedback>
<ValidationError/>
</Feedback>
</DateEdit>
</Field>
</Validation>
<Validation>
<Field>
<FieldLabel>@L["EndTime"] *</FieldLabel>
<DateEdit TValue="DateTime" @bind-Date="@EditingEvent.EndTime">
<Feedback>
<ValidationError/>
</Feedback>
</DateEdit>
</Field>
</Validation>
</Validations>
</TabPanel>
<TabPanel Name="@EventEditTabs.CoverImage.ToString()" Class="mt-3">
@if (!string.IsNullOrEmpty(CoverImageUrl))
{
<div class="text-center mt-4">
<img src="@CoverImageUrl" class="event-cover" width="600" height="340" alt="cover-image"/>
</div>
}
<div class="mt-3 mb-2">
<Field Horizontal="true">
<FieldLabel ColumnSize="ColumnSize.Is3">@L["ChooseCoverImage"]</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<FileEdit MaxMessageSize="@EventConsts.MaxCoverImageFileSize" Filter="@string.Join(", ", EventConsts.AllowedCoverImageExtensions)" Changed="@OnCoverImageFileChanged" AutoReset="true"/>
</FieldBody>
<Column ColumnSize="ColumnSize.Is3">
@if (!string.IsNullOrEmpty(CoverImageUrl))
{
<Button Color="Color.Warning" Clicked="@OnDeleteCoverImageButtonClicked">@L["DeleteCoverImage"]</Button>
}
else
{
<Button disabled Color="Color.Secondary" Clicked="@OnDeleteCoverImageButtonClicked">@L["DeleteCoverImage"]</Button>
}
</Column>
</Field>
</div>
</TabPanel>
</Content>
</Tabs>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary"
Clicked="() => EditEventModal.Hide()">
@L["Cancel"]
</Button>
<Button Type="ButtonType.Submit" PreventDefaultOnSubmit="true" Color="Color.Primary"
Clicked="UpdateEventAsync">
<i class="fa-check fa"></i> @L["Save"]
</Button>
</ModalFooter>
</Form>
</ModalContent>
</Modal>

202
src/EventHub.Admin.Web/Pages/EventManagement.razor.cs

@ -0,0 +1,202 @@
using EventHub.Admin.Events;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Blazorise;
using Blazorise.DataGrid;
using Volo.Abp.Application.Dtos;
using System;
using System.ComponentModel;
using Microsoft.AspNetCore.Components.Web;
using System.IO;
using System.Globalization;
using NUglify.Helpers;
using Volo.Abp;
namespace EventHub.Admin.Web.Pages
{
public partial class EventManagement
{
private IReadOnlyList<EventInListDto> EventList { get; set; }
private EventListFilterDto Filter { get; set; }
private int CurrentPage { get; set; }
private string CurrentSorting { get; set; }
private int TotalCount { get; set; }
private int PageSize { get; }
private Guid EditingEventId { get; set; }
private EventDetailDto Event { get; set; }
private UpdateEventDto EditingEvent { get; set; }
private Modal EditEventModal { get; set; }
private string SelectedTabInEditModal { get; set; }
private string CoverImageUrl { get; set; }
private IFileEntry FileEntry { get; set; }
private List<CountryLookupDto> Countries { get; set; }
private List<Language> Languages { get; set; }
public EventManagement()
{
Filter = new EventListFilterDto();
PageSize = LimitedResultRequestDto.DefaultMaxResultCount;
SelectedTabInEditModal = EventEditTabs.EventInfo.ToString();
EditingEvent = new UpdateEventDto();
Countries = new List<CountryLookupDto>();
Languages = new List<Language>();
}
protected override async Task OnInitializedAsync()
{
await GetEventsAsync();
await FillCountriesAsync();
FillLanguages();
}
private void FillLanguages()
{
var result = CultureInfo.GetCultures(CultureTypes.NeutralCultures)
.DistinctBy(x => x.EnglishName)
.OrderBy(x => x.EnglishName)
.ToList();
result.Remove(result.Single(x => x.TwoLetterISOLanguageName == "iv")); // Invariant Language
Languages = result.Select(cultureInfo => new Language
{
Value = cultureInfo.TwoLetterISOLanguageName,
Text = cultureInfo.EnglishName
}).ToList();
}
private async Task GetEventsAsync()
{
Filter.MaxResultCount = PageSize;
Filter.SkipCount = CurrentPage * PageSize;
Filter.Sorting = CurrentSorting;
var result = await EventAppService.GetListAsync(Filter);
EventList = result.Items;
TotalCount = (int)result.TotalCount;
}
private async Task OnDataGridReadAsync(DataGridReadDataEventArgs<EventInListDto> 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 GetEventsAsync();
await InvokeAsync(StateHasChanged);
}
private async Task OpenEditEventModal(EventInListDto input)
{
EditingEventId = input.Id;
Event = await EventAppService.GetAsync(EditingEventId);
EditingEvent = ObjectMapper.Map<EventDetailDto, UpdateEventDto>(Event);
FillCoverImageUrl(EditingEvent.CoverImageContent);
EditEventModal.Show();
}
private void OnEditModalClosing(CancelEventArgs e)
{
SelectedTabInEditModal = EventEditTabs.EventInfo.ToString();
}
private void OnSelectedTabChangedInEditModal(string name)
{
SelectedTabInEditModal = name;
}
private async Task UpdateEventAsync()
{
if (!EditingEvent.IsOnline && (!EditingEvent.CountryId.HasValue || string.IsNullOrWhiteSpace(EditingEvent.City)))
{
throw new UserFriendlyException(L["CountryAndCityRequiredForUpdateInPersonEvent"]);
}
await EventAppService.UpdateAsync(EditingEventId, EditingEvent);
await GetEventsAsync();
CoverImageUrl = string.Empty;
EditEventModal.Hide();
}
private async Task OnKeyPress(KeyboardEventArgs e)
{
if (e.Code is "Enter" or "NumpadEnter")
{
await GetEventsAsync();
}
}
private async Task OnSelectedDateChangedForMinStartTime(DateTime? minStartTime)
{
Filter.MinStartTime = minStartTime;
await GetEventsAsync();
}
private async Task OnSelectedDateChangedForMaxStartTime(DateTime? maxStartTime)
{
Filter.MaxStartTime = maxStartTime;
await GetEventsAsync();
}
private void FillCoverImageUrl(byte[] content)
{
if (content.IsNullOrEmpty())
{
return;
}
var imageBase64Data = Convert.ToBase64String(content);
var imageDataUrl = $"data:image/png;base64,{imageBase64Data}";
CoverImageUrl = imageDataUrl;
}
private async Task OnCoverImageFileChanged(FileChangedEventArgs e)
{
FileEntry = e.Files.FirstOrDefault();
if (FileEntry is null)
{
return;
}
using (var stream = new MemoryStream())
{
await FileEntry.WriteToStreamAsync(stream);
stream.Seek(0, SeekOrigin.Begin);
EditingEvent.CoverImageContent = stream.ToArray();
FillCoverImageUrl(EditingEvent.CoverImageContent);
await InvokeAsync(StateHasChanged);
}
}
private void OnDeleteCoverImageButtonClicked()
{
EditingEvent.CoverImageContent = null;
FileEntry = new FileEntry();
CoverImageUrl = null;
}
private async Task FillCountriesAsync()
{
Countries = await EventAppService.GetCountriesLookupAsync();
}
private enum EventEditTabs : byte
{
EventInfo,
Timing,
CoverImage
}
private class Language
{
public string Value { get; set; }
public string Text { get; set; }
}
}
}

12
src/EventHub.Application/Events/EventAppService.cs

@ -20,20 +20,20 @@ namespace EventHub.Events
{
private readonly EventManager _eventManager;
private readonly EventRegistrationManager _eventRegistrationManager;
private readonly IRepository<EventRegistration, Guid> _eventRegistrationRepository;
private readonly IRepository<Event, Guid> _eventRepository;
private readonly IEventRegistrationRepository _eventRegistrationRepository;
private readonly IEventRepository _eventRepository;
private readonly IRepository<Organization, Guid> _organizationRepository;
private readonly IRepository<IdentityUser, Guid> _userRepository;
private readonly IUserRepository _userRepository;
private readonly IRepository<Country, Guid> _countriesRepository;
private readonly IBlobContainer<EventCoverImageContainer> _eventBlobContainer;
public EventAppService(
EventManager eventManager,
EventRegistrationManager eventRegistrationManager,
IRepository<EventRegistration, Guid> eventRegistrationRepository,
IRepository<Event, Guid> eventRepository,
IEventRegistrationRepository eventRegistrationRepository,
IEventRepository eventRepository,
IRepository<Organization, Guid> organizationRepository,
IRepository<IdentityUser, Guid> userRepository,
IUserRepository userRepository,
IRepository<Country, Guid> countriesRepository,
IBlobContainer<EventCoverImageContainer> eventBlobContainer)
{

14
src/EventHub.Application/Events/Registrations/EventRegistrationAppService.cs

@ -2,9 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EventHub.Users;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Users;
using Volo.Abp.Identity;
@ -13,16 +13,16 @@ namespace EventHub.Events.Registrations
public class EventRegistrationAppService : EventHubAppService, IEventRegistrationAppService
{
private readonly EventRegistrationManager _eventRegistrationManager;
private readonly IRepository<IdentityUser, Guid> _userRepository;
private readonly IRepository<Event, Guid> _eventRepository;
private readonly IRepository<EventRegistration, Guid> _eventRegistrationRepository;
private readonly IUserRepository _userRepository;
private readonly IEventRepository _eventRepository;
private readonly IEventRegistrationRepository _eventRegistrationRepository;
private readonly EventRegistrationNotifier _eventRegistrationNotifier;
public EventRegistrationAppService(
EventRegistrationManager eventRegistrationManager,
IRepository<IdentityUser, Guid> userRepository,
IRepository<Event, Guid> eventRepository,
IRepository<EventRegistration, Guid> eventRegistrationRepository,
IUserRepository userRepository,
IEventRepository eventRepository,
IEventRegistrationRepository eventRegistrationRepository,
EventRegistrationNotifier eventRegistrationNotifier)
{
_eventRegistrationManager = eventRegistrationManager;

13
src/EventHub.Application/Organizations/Memberships/OrganizationMembershipAppService.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EventHub.Users;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
@ -13,15 +14,15 @@ namespace EventHub.Organizations.Memberships
public class OrganizationMembershipAppService : EventHubAppService, IOrganizationMembershipAppService
{
private readonly OrganizationMembershipManager _organizationMembershipManager;
private readonly IRepository<IdentityUser, Guid> _userRepository;
private readonly IUserRepository _userRepository;
private readonly IRepository<Organization, Guid> _organizationRepository;
private readonly IRepository<OrganizationMembership, Guid> _organizationMembershipsRepository;
private readonly IOrganizationMembershipRepository _organizationMembershipsRepository;
public OrganizationMembershipAppService(
OrganizationMembershipManager organizationMembershipManager,
IRepository<IdentityUser, Guid> userRepository,
IRepository<Organization, Guid> organizationRepository,
IRepository<OrganizationMembership, Guid> organizationMembershipsRepository)
OrganizationMembershipManager organizationMembershipManager,
IUserRepository userRepository,
IRepository<Organization, Guid> organizationRepository,
IOrganizationMembershipRepository organizationMembershipsRepository)
{
_organizationMembershipManager = organizationMembershipManager;
_userRepository = userRepository;

10
src/EventHub.Application/Organizations/OrganizationAppService.cs

@ -17,17 +17,17 @@ namespace EventHub.Organizations
public class OrganizationAppService : EventHubAppService, IOrganizationAppService
{
private readonly IRepository<Organization, Guid> _organizationRepository;
private readonly IRepository<OrganizationMembership, Guid> _organizationMembershipsRepository;
private readonly IOrganizationMembershipRepository _organizationMembershipsRepository;
private readonly OrganizationManager _organizationManager;
private readonly IBlobContainer<OrganizationProfilePictureContainer> _organizationBlobContainer;
private readonly IRepository<IdentityUser, Guid> _userRepository;
private readonly IUserRepository _userRepository;
public OrganizationAppService(
IRepository<Organization, Guid> organizationRepository,
IRepository<OrganizationMembership, Guid> organizationMembershipsRepository,
IOrganizationMembershipRepository organizationMembershipsRepository,
OrganizationManager organizationManager,
IBlobContainer<OrganizationProfilePictureContainer> organizationBlobContainer,
IRepository<IdentityUser, Guid> userRepository)
IBlobContainer<OrganizationProfilePictureContainer> organizationBlobContainer,
IUserRepository userRepository)
{
_organizationRepository = organizationRepository;
_organizationMembershipsRepository = organizationMembershipsRepository;

4
src/EventHub.Application/Users/UserAppService.cs

@ -8,9 +8,9 @@ namespace EventHub.Users
{
public class UserAppService : EventHubAppService, IUserAppService
{
private readonly IRepository<IdentityUser, Guid> _userRepository;
private readonly IUserRepository _userRepository;
public UserAppService(IRepository<IdentityUser, Guid> userRepository)
public UserAppService(IUserRepository userRepository)
{
_userRepository = userRepository;
}

4
src/EventHub.Domain.Shared/Events/EventConsts.cs

@ -2,6 +2,8 @@
{
public static class EventConsts
{
public const string DefaultSorting = "Title desc";
public const int UrlCodeLength = 8;
public const int MaxTitleInUrlLength = 60;
public const int MaxUrlLength = MaxTitleInUrlLength + 1 + UrlCodeLength; //Format: {Title}-{UrlCode}
@ -24,5 +26,7 @@
public const int MaxTimingChangeCountForUser = 2;
public const int MaxCoverImageFileSize = 5 * 1024 * 1024;
public static string[] AllowedCoverImageExtensions = { ".jpg", ".png" };
}
}

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

@ -115,6 +115,41 @@
"Loading": "Loading",
"OrganizationInfo": "Organization Info",
"ProfileImage": "Profile Image",
"OrganizationName": "Organization Name"
"OrganizationName": "Organization Name",
"Permission:EventManagement": "Event Management",
"Menu:EventManagement": "Event Management",
"Menu:Events": "Events",
"Title": "Title",
"OrganizationDisplayName": "Organization Display Name",
"StartTime": "Start Time",
"MinAttendeeCount": "Min Attendee Count",
"MaxAttendeeCount": "Max Attendee Count",
"UpdateEvent": "Update Event",
"EventInfo": "Event Info",
"Timing": "Timing",
"IsOnline": "Is Online",
"OnlineLink": "Online Link",
"Country": "Country",
"City": "City",
"Capacity": "Capacity",
"EndTime": "End Time",
"ChooseCoverImage": "Choose a cover image",
"Permission:RegistrationManagement": "Registration Management",
"Permission:AddAttendee": "Add Attendee",
"Permission:RemoveAttendee": "Remove Attendee",
"Attendees": "Attendees",
"AddNewUser": "Add New User",
"AttendeeRemoveConfirmationMessage": "Are you sure you want to remove this item?",
"RemoveUser": "Remove User",
"AddAttendee": "Add Attendee",
"AddUser": "Add User",
"CountryAndCityRequiredForUpdateInPersonEvent": "You need to select a country and city to update the event.",
"Permission:UserManagement": "User Management",
"Cancel": "Cancel",
"Save": "Save",
"MinStartTime": "Min Start Time",
"MaxStartTime": "Max Start Time",
"Online": "Online",
"InPerson": "In Person"
}
}

17
src/EventHub.Domain/Events/EventWithDetails.cs

@ -0,0 +1,17 @@
using System;
namespace EventHub.Events
{
public class EventWithDetails
{
public Guid Id { get; set; }
public string Title { get; set; }
public string OrganizationDisplayName { get; set; }
public int AttendeeCount { get; set; }
public DateTime StartTime { get; set; }
}
}

34
src/EventHub.Domain/Events/IEventRepository.cs

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace EventHub.Events
{
public interface IEventRepository : IRepository<Event, Guid>
{
Task<int> GetCountAsync(
string title = null,
string organizationDisplayName = null,
int? minAttendeeCount = null,
int? maxAttendeeCount = null,
DateTime? minStartTime = null,
DateTime? maxStartTime = null,
CancellationToken cancellationToken = default
);
Task<List<EventWithDetails>> GetListAsync(
string sorting = null,
int skipCount = 0,
int maxResultCount = int.MaxValue,
string title = null,
string organizationDisplayName = null,
int? minAttendeeCount = null,
int? maxAttendeeCount = null,
DateTime? minStartTime = null,
DateTime? maxStartTime = null,
CancellationToken cancellationToken = default
);
}
}

20
src/EventHub.Domain/Events/Registrations/EventRegistrationWithDetails.cs

@ -0,0 +1,20 @@
using System;
using Volo.Abp.Auditing;
namespace EventHub.Events.Registrations
{
public class EventRegistrationWithDetails : IHasCreationTime
{
public Guid UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public DateTime CreationTime { get; set; }
}
}

21
src/EventHub.Domain/Events/Registrations/IEventRegistrationRepository.cs

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace EventHub.Events.Registrations
{
public interface IEventRegistrationRepository : IRepository<EventRegistration, Guid>
{
Task<int> GetCountAsync(Guid eventId, CancellationToken cancellationToken = default);
Task<List<EventRegistrationWithDetails>> GetListAsync(
Guid eventId,
string sorting = null,
int skipCount = 0,
int maxResultCount = int.MaxValue,
CancellationToken cancellationToken = default
);
}
}

25
src/EventHub.Domain/Users/IUserRepository.cs

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
namespace EventHub.Users
{
public interface IUserRepository : IRepository<IdentityUser, Guid>
{
Task<List<IdentityUser>> GetListAsync(
string sorting = null,
int skipCount = 0,
int maxResultCount = int.MaxValue,
string username = null,
CancellationToken cancellationToken = default
);
Task<int> GetCountAsync(
string username = null,
CancellationToken cancellationToken = default
);
}
}

102
src/EventHub.EntityFrameworkCore/EntityFrameworkCore/Events/EventRepository.cs

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using EventHub.Events;
using EventHub.Events.Registrations;
using EventHub.Organizations;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace EventHub.EntityFrameworkCore.Events
{
public class EventRepository : EfCoreRepository<EventHubDbContext, Event, Guid>, IEventRepository
{
public EventRepository(IDbContextProvider<EventHubDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public async Task<int> GetCountAsync(
string title = null,
string organizationDisplayName = null,
int? minAttendeeCount = null,
int? maxAttendeeCount = null,
DateTime? minStartTime = null,
DateTime? maxStartTime = null,
CancellationToken cancellationToken = default
)
{
var dbContext = await GetDbContextAsync();
var eventQueryable = await GetQueryableAsync();
var eventRegistrationQueryable = dbContext.Set<EventRegistration>().AsQueryable();
var organizationQueryable = dbContext.Set<Organization>().AsQueryable();
var query = (from @event in eventQueryable
join organization in organizationQueryable on @event.OrganizationId equals organization.Id
select new
{
Event = @event,
Organization = organization,
AttendeeCount = (from eventRegistration in eventRegistrationQueryable
where eventRegistration.EventId == @event.Id
select @eventRegistration).Count()
})
.WhereIf(!string.IsNullOrWhiteSpace(title), x => x.Event.Title.ToLower().Contains(title.ToLower()))
.WhereIf(!string.IsNullOrWhiteSpace(organizationDisplayName), x => x.Organization.DisplayName.ToLower().Contains(organizationDisplayName.ToLower()))
.WhereIf(minStartTime.HasValue, x => x.Event.StartTime >= minStartTime)
.WhereIf(maxStartTime.HasValue, x => x.Event.StartTime <= maxStartTime)
.WhereIf(minAttendeeCount.HasValue, x => x.AttendeeCount >= minAttendeeCount)
.WhereIf(maxAttendeeCount.HasValue, x => x.AttendeeCount <= maxAttendeeCount);
return await query.CountAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<EventWithDetails>> GetListAsync(
string sorting = null,
int skipCount = 0,
int maxResultCount = int.MaxValue,
string title = null,
string organizationDisplayName = null,
int? minAttendeeCount = null,
int? maxAttendeeCount = null,
DateTime? minStartTime = null,
DateTime? maxStartTime = null,
CancellationToken cancellationToken = default
)
{
var dbContext = await GetDbContextAsync();
var eventQueryable = await GetQueryableAsync();
var eventRegistrationQueryable = dbContext.Set<EventRegistration>().AsQueryable();
var organizationQueryable = dbContext.Set<Organization>().AsQueryable();
var query = (from @event in eventQueryable
join organization in organizationQueryable on @event.OrganizationId equals organization.Id
select new EventWithDetails
{
Id = @event.Id,
Title = @event.Title,
StartTime = @event.StartTime,
OrganizationDisplayName = organization.DisplayName,
AttendeeCount = (from eventRegistration in eventRegistrationQueryable
where eventRegistration.EventId == @event.Id
select @eventRegistration).Count()
})
.WhereIf(!string.IsNullOrWhiteSpace(title), x => x.Title.ToLower().Contains(title.ToLower()))
.WhereIf(!string.IsNullOrWhiteSpace(organizationDisplayName),
x => x.OrganizationDisplayName.ToLower().Contains(organizationDisplayName.ToLower()))
.WhereIf(minStartTime.HasValue, x => x.StartTime >= minStartTime)
.WhereIf(maxStartTime.HasValue, x => x.StartTime <= maxStartTime)
.WhereIf(minAttendeeCount.HasValue, x => x.AttendeeCount >= minAttendeeCount)
.WhereIf(maxAttendeeCount.HasValue, x => x.AttendeeCount <= maxAttendeeCount)
.OrderBy(string.IsNullOrWhiteSpace(sorting) ? EventConsts.DefaultSorting : sorting)
.PageBy(skipCount, maxResultCount);
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
}
}

61
src/EventHub.EntityFrameworkCore/EntityFrameworkCore/Events/Registrations/EventRegistrationRepository.cs

@ -0,0 +1,61 @@
using EventHub.Events.Registrations;
using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Identity;
namespace EventHub.EntityFrameworkCore.Events.Registrations
{
public class EventRegistrationRepository : EfCoreRepository<EventHubDbContext, EventRegistration, Guid>, IEventRegistrationRepository
{
public EventRegistrationRepository(IDbContextProvider<EventHubDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public async Task<int> GetCountAsync(Guid eventId, CancellationToken cancellationToken = default)
{
var userQueryable = (await GetDbContextAsync()).Set<IdentityUser>().AsQueryable();
var query = from eventRegistration in (await GetQueryableAsync())
join user in userQueryable on eventRegistration.UserId equals user.Id
where eventRegistration.EventId == eventId
select user;
return await query.CountAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<EventRegistrationWithDetails>> GetListAsync(
Guid eventId,
string sorting = null,
int skipCount = 0,
int maxResultCount = int.MaxValue,
CancellationToken cancellationToken = default
)
{
var userQueryable = (await GetDbContextAsync()).Set<IdentityUser>().AsQueryable();
var query = (from eventRegistration in (await GetQueryableAsync())
join user in userQueryable on eventRegistration.UserId equals user.Id
where eventRegistration.EventId == eventId
select new EventRegistrationWithDetails
{
UserId = user.Id,
Name = user.Name,
Surname = user.Surname,
UserName = user.UserName,
Email = user.Email,
CreationTime = user.CreationTime
})
.OrderBy(string.IsNullOrWhiteSpace(sorting) ? nameof(EventRegistrationWithDetails.CreationTime) : sorting)
.PageBy(skipCount, maxResultCount);
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
}
}

43
src/EventHub.EntityFrameworkCore/EntityFrameworkCore/Users/UserRepository.cs

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using EventHub.Users;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Identity;
namespace EventHub.EntityFrameworkCore.Users
{
public class UserRepository : EfCoreRepository<EventHubDbContext, IdentityUser, Guid>, IUserRepository
{
public UserRepository(IDbContextProvider<EventHubDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public async Task<int> GetCountAsync(string username = null, CancellationToken cancellationToken = default)
{
return await (await GetQueryableAsync())
.WhereIf(!string.IsNullOrWhiteSpace(username), user => user.UserName.ToLower().Contains(username.ToLower()))
.CountAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<IdentityUser>> GetListAsync(
string sorting = null,
int skipCount = 0,
int maxResultCount = int.MaxValue,
string username = null,
CancellationToken cancellationToken = default
)
{
return await (await GetQueryableAsync())
.WhereIf(!string.IsNullOrWhiteSpace(username), user => user.UserName.ToLower().Contains(username.ToLower()))
.OrderBy(string.IsNullOrWhiteSpace(sorting) ? nameof(IdentityUser.CreationTime) : sorting)
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
}
}
Loading…
Cancel
Save