Browse Source

Admin: List events in event-management page

pull/53/head
Engincan VESKE 5 years ago
parent
commit
d3069246eb
  1. 12
      src/EventHub.Admin.Application.Contracts/Events/EventDetailDto.cs
  2. 16
      src/EventHub.Admin.Application.Contracts/Events/EventInListDto.cs
  3. 17
      src/EventHub.Admin.Application.Contracts/Events/EventListFilterDto.cs
  4. 16
      src/EventHub.Admin.Application.Contracts/Events/IEventAppService.cs
  5. 17
      src/EventHub.Admin.Application.Contracts/Events/UpdateEventDto.cs
  6. 3
      src/EventHub.Admin.Application.Contracts/Permissions/EventHubPermissionDefinitionProvider.cs
  7. 6
      src/EventHub.Admin.Application.Contracts/Permissions/EventHubPermissions.cs
  8. 4
      src/EventHub.Admin.Application/EventHubApplicationAutoMapperProfile.cs
  9. 83
      src/EventHub.Admin.Application/Events/EventAppService.cs
  10. 45
      src/EventHub.Admin.HttpApi.Host/Controllers/Events/EventController.cs
  11. 3
      src/EventHub.Admin.Web/EventHubBlazorAutoMapperProfile.cs
  12. 17
      src/EventHub.Admin.Web/Menus/EventHubMenuContributor.cs
  13. 6
      src/EventHub.Admin.Web/Menus/EventHubMenus.cs
  14. 138
      src/EventHub.Admin.Web/Pages/EventManagement.razor
  15. 110
      src/EventHub.Admin.Web/Pages/EventManagement.razor.cs
  16. 2
      src/EventHub.Domain.Shared/Events/EventConsts.cs
  17. 13
      src/EventHub.Domain.Shared/Localization/EventHub/en.json

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

@ -0,0 +1,12 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EventHub.Admin.Events
{
public class EventDetailDto : EntityDto<Guid>
{
public string Title { get; set; }
public DateTime StartTime { 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; }
}
}

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

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

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

@ -0,0 +1,16 @@
using System;
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);
}
}

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

@ -0,0 +1,17 @@
using System;
using System.ComponentModel.DataAnnotations;
using EventHub.Events;
namespace EventHub.Admin.Events
{
public class UpdateEventDto
{
[Required]
[StringLength(EventConsts.MaxTitleLength, MinimumLength = EventConsts.MinTitleLength)]
public string Title { get; set; }
[Required]
[DataType(DataType.DateTime)]
public DateTime StartTime { get; set; }
}
}

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

@ -15,6 +15,9 @@ 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"));
}
private static LocalizableString L(string name)

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

@ -16,5 +16,11 @@
public const string Default = Organizations.Default + ".Memberships";
}
}
public static class Events
{
public const string Default = GroupName + ".Events";
public const string Update = Default + ".Update";
}
}
}

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

@ -1,6 +1,8 @@
using AutoMapper;
using EventHub.Admin.Events;
using EventHub.Admin.Organizations;
using EventHub.Admin.Organizations.Memberships;
using EventHub.Events;
using EventHub.Organizations;
using EventHub.Organizations.Memberships;
using Volo.Abp.AutoMapper;
@ -19,6 +21,8 @@ namespace EventHub.Admin
.Ignore(x => x.ProfilePictureContent);
CreateMap<OrganizationMemberWithDetails, OrganizationMemberDto>();
CreateMap<Event, EventDetailDto>();
}
}
}

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

@ -0,0 +1,83 @@
using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using EventHub.Events;
using EventHub.Events.Registrations;
using EventHub.Organizations;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
namespace EventHub.Admin.Events
{
//[Authorize(EventHubPermissions.Events.Default)]
public class EventAppService : EventHubAdminAppService, IEventAppService
{
private readonly IRepository<Event, Guid> _eventRepository;
private readonly IRepository<EventRegistration, Guid> _eventRegistrationRepository;
private readonly IRepository<Organization, Guid> _organizationRepository;
public EventAppService(
IRepository<Event, Guid> eventRepository,
IRepository<EventRegistration, Guid> eventRegistrationRepository,
IRepository<Organization, Guid> organizationRepository
)
{
_eventRepository = eventRepository;
_eventRegistrationRepository = eventRegistrationRepository;
_organizationRepository = organizationRepository;
}
public async Task<EventDetailDto> GetAsync(Guid id)
{
var @event = await _eventRepository.GetAsync(id);
return ObjectMapper.Map<Event, EventDetailDto>(@event);
}
public async Task<PagedResultDto<EventInListDto>> GetListAsync(EventListFilterDto input)
{
var eventQueryable = await _eventRepository.GetQueryableAsync();
var eventRegistrationQueryable = await _eventRegistrationRepository.GetQueryableAsync();
var organizationQueryable = await _organizationRepository.GetQueryableAsync();
var query = (from @event in eventQueryable
join organization in organizationQueryable on @event.OrganizationId equals organization.Id
select new EventInListDto
{
Id = @event.Id,
Title = @event.Title,
StartTime = @event.StartTime,
OrganizationDisplayName = organization.DisplayName,
AttendeeCount = (from eventRegistration in eventRegistrationQueryable
where eventRegistration.EventId == @event.Id
group @event by @event.Id into g
select g.Key).Count()
})
.WhereIf(!string.IsNullOrWhiteSpace(input.Title), x => x.Title.ToLower().Contains(input.Title.ToLower()))
.WhereIf(!string.IsNullOrWhiteSpace(input.OrganizationDisplayName), x => x.OrganizationDisplayName.ToLower().Contains(input.OrganizationDisplayName.ToLower()))
.WhereIf(input.StartTime.HasValue, x => x.StartTime > input.StartTime)
.WhereIf(input.MinAttendeeCount.HasValue, x => x.AttendeeCount >= input.MinAttendeeCount)
.WhereIf(input.MaxAttendeeCount.HasValue, x => x.AttendeeCount <= input.MaxAttendeeCount);
var totalCount = await AsyncExecuter.CountAsync(query);
query = query.OrderBy(string.IsNullOrWhiteSpace(input.Sorting) ? EventConsts.DefaultSorting : input.Sorting);
query = query.PageBy(input);
var events = await AsyncExecuter.ToListAsync(query);
return new PagedResultDto<EventInListDto>(totalCount, events);
}
//[Authorize(EventHubPermissions.Events.Update)]
public async Task UpdateAsync(Guid id, UpdateEventDto input)
{
var @event = await _eventRepository.GetAsync(id);
@event.SetTitle(input.Title);
@event.SetTime(input.StartTime, @event.EndTime);
await _eventRepository.UpdateAsync(@event);
}
}
}

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

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
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]
public Task<PagedResultDto<EventInListDto>> GetListAsync(EventListFilterDto input)
{
return _eventAppService.GetListAsync(input);
}
[HttpPut]
public Task UpdateAsync(Guid id, UpdateEventDto input)
{
return _eventAppService.UpdateAsync(id, input);
}
}
}

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

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

@ -0,0 +1,138 @@
@page "/events"
@using Microsoft.AspNetCore.Authorization
@using EventHub.Admin.Permissions
@using EventHub.Admin.Events
@inherits EventHubComponentBase
@attribute [Authorize(EventHubPermissions.Events.Default)]
@inject IEventAppService EventAppService
<Card>
<CardHeader>
@* ************************* PAGE HEADER ************************* *@
<h2>@L["Events"]</h2>
</CardHeader>
<CardBody>
@* ************************* SEARCH ************************* *@
<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["StartTime"]</FieldLabel>
<DateEdit TValue="DateTime?" Date="@Filter.StartTime" DateChanged="OnSelectedDateChanged"/>
</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>
@* ************************* DATA GRID ************************* *@
<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>
</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>
@* ************************* EDIT MODAL ************************* *@
<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()">
EventInfo
</TabPanel>
<TabPanel Name="@EventEditTabs.Timing.ToString()">
Timing
</TabPanel>
<TabPanel Name="@EventEditTabs.CoverImage.ToString()">
CoverImage
</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>

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

@ -0,0 +1,110 @@
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;
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; }
public EventManagement()
{
Filter = new EventListFilterDto();
PageSize = LimitedResultRequestDto.DefaultMaxResultCount;
SelectedTabInEditModal = EventEditTabs.EventInfo.ToString();
}
protected override async Task OnInitializedAsync()
{
await GetEventsAsync();
}
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);
EditEventModal.Show();
}
private void OnEditModalClosing(CancelEventArgs e)
{
SelectedTabInEditModal = EventEditTabs.EventInfo.ToString();
}
private void OnSelectedTabChangedInEditModal(string name)
{
SelectedTabInEditModal = name;
}
private async Task UpdateEventAsync()
{
await EventAppService.UpdateAsync(EditingEventId, EditingEvent);
await GetEventsAsync();
EditEventModal.Hide();
}
private async Task OnKeyPress(KeyboardEventArgs e)
{
if (e.Code is "Enter" or "NumpadEnter")
{
await GetEventsAsync();
}
}
private async Task OnSelectedDateChanged(DateTime? changedDate)
{
Filter.StartTime = changedDate;
await GetEventsAsync();
}
}
public enum EventEditTabs : byte
{
EventInfo,
Timing,
CoverImage
}
}

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

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

@ -115,6 +115,17 @@
"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"
}
}

Loading…
Cancel
Save