Browse Source

Add pagination for Organization member view component

pull/41/head
Berkan Sasmaz 5 years ago
parent
commit
bc5e767f35
  1. 2
      src/EventHub.Application.Contracts/Organizations/IOrganizationAppService.cs
  2. 2
      src/EventHub.Application.Contracts/Organizations/Memberships/IOrganizationMembershipAppService.cs
  3. 10
      src/EventHub.Application.Contracts/Organizations/Memberships/OrganizationMemberListFilterDto.cs
  4. 10
      src/EventHub.Application.Contracts/Organizations/OrganizationListFilterDto.cs
  5. 7
      src/EventHub.Application/Organizations/Memberships/OrganizationMembershipAppService.cs
  6. 35
      src/EventHub.Application/Organizations/OrganizationAppService.cs
  7. 4
      src/EventHub.Domain.Shared/Localization/EventHub/en.json
  8. 2
      src/EventHub.Web/Controllers/OrganizationController.cs
  9. 16
      src/EventHub.Web/Controllers/OrganizationMembershipController.cs
  10. 2
      src/EventHub.Web/Pages/Events/Components/EventsArea/Default.cshtml
  11. 8
      src/EventHub.Web/Pages/Events/Components/EventsArea/events-area.js
  12. 8
      src/EventHub.Web/Pages/Events/Components/RegistrationArea/Default.cshtml
  13. 31
      src/EventHub.Web/Pages/Organizations/Components/MembersArea/Default.cshtml
  14. 28
      src/EventHub.Web/Pages/Organizations/Components/MembersArea/MembersAreaViewComponent.cs
  15. 22
      src/EventHub.Web/Pages/Organizations/Components/MembersArea/_memberListSection.cshtml
  16. 50
      src/EventHub.Web/Pages/Organizations/Components/MembersArea/members-area.js
  17. 8
      src/EventHub.Web/Pages/Organizations/Components/OrganizationsArea/Default.cshtml
  18. 8
      src/EventHub.Web/Pages/Organizations/Components/OrganizationsArea/OrganizationsAreaViewComponent.cs
  19. 8
      src/EventHub.Web/Pages/Organizations/Components/OrganizationsArea/organizations-area.js
  20. 21
      src/EventHub.Web/Pages/Organizations/Index.cshtml.cs
  21. 45
      src/EventHub.Web/Pages/Organizations/Profile.cshtml
  22. 10
      src/EventHub.Web/Pages/Organizations/Profile.cshtml.cs
  23. 412
      src/EventHub.Web/Pages/Profile.cshtml
  24. 16
      src/EventHub.Web/Pages/Profile.cshtml.cs

2
src/EventHub.Application.Contracts/Organizations/IOrganizationAppService.cs

@ -9,7 +9,7 @@ namespace EventHub.Organizations
{ {
Task CreateAsync(CreateOrganizationDto input); Task CreateAsync(CreateOrganizationDto input);
Task<PagedResultDto<OrganizationInListDto>> GetListAsync(PagedResultRequestDto input); Task<PagedResultDto<OrganizationInListDto>> GetListAsync(OrganizationListFilterDto input);
Task<OrganizationProfileDto> GetProfileAsync(string name); Task<OrganizationProfileDto> GetProfileAsync(string name);

2
src/EventHub.Application.Contracts/Organizations/Memberships/IOrganizationMembershipAppService.cs

@ -13,6 +13,6 @@ namespace EventHub.Organizations.Memberships
Task<bool> IsJoinedAsync(Guid organizationId); Task<bool> IsJoinedAsync(Guid organizationId);
Task<PagedResultDto<OrganizationMemberDto>> GetMembersAsync(Guid organizationId); Task<PagedResultDto<OrganizationMemberDto>> GetMembersAsync(OrganizationMemberListFilterDto input);
} }
} }

10
src/EventHub.Application.Contracts/Organizations/Memberships/OrganizationMemberListFilterDto.cs

@ -0,0 +1,10 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EventHub.Organizations.Memberships
{
public class OrganizationMemberListFilterDto : PagedResultRequestDto
{
public Guid OrganizationId { get; set; }
}
}

10
src/EventHub.Application.Contracts/Organizations/OrganizationListFilterDto.cs

@ -0,0 +1,10 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EventHub.Organizations
{
public class OrganizationListFilterDto : PagedResultRequestDto
{
public Guid? RegisteredUserId { get; set; }
}
}

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

@ -55,19 +55,20 @@ namespace EventHub.Organizations.Memberships
); );
} }
public async Task<PagedResultDto<OrganizationMemberDto>> GetMembersAsync(Guid organizationId) public async Task<PagedResultDto<OrganizationMemberDto>> GetMembersAsync(OrganizationMemberListFilterDto input)
{ {
var organizationMembershipsQueryable = await _organizationMembershipsRepository.GetQueryableAsync(); var organizationMembershipsQueryable = await _organizationMembershipsRepository.GetQueryableAsync();
var userQueryable = await _userRepository.GetQueryableAsync(); var userQueryable = await _userRepository.GetQueryableAsync();
var query = from organizationMembership in organizationMembershipsQueryable var query = from organizationMembership in organizationMembershipsQueryable
join user in userQueryable on organizationMembership.UserId equals user.Id join user in userQueryable on organizationMembership.UserId equals user.Id
where organizationMembership.OrganizationId == organizationId where organizationMembership.OrganizationId == input.OrganizationId
orderby organizationMembership.CreationTime descending orderby organizationMembership.CreationTime descending
select user; select user;
var totalCount = await AsyncExecuter.CountAsync(query); var totalCount = await AsyncExecuter.CountAsync(query);
var users = await AsyncExecuter.ToListAsync(query.Take(10));
var users = await AsyncExecuter.ToListAsync(query.PageBy(input));
return new PagedResultDto<OrganizationMemberDto>( return new PagedResultDto<OrganizationMemberDto>(
totalCount, totalCount,

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

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EventHub.Organizations.Memberships;
using EventHub.Users; using EventHub.Users;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Volo.Abp; using Volo.Abp;
@ -15,17 +16,20 @@ namespace EventHub.Organizations
public class OrganizationAppService : EventHubAppService, IOrganizationAppService public class OrganizationAppService : EventHubAppService, IOrganizationAppService
{ {
private readonly IRepository<Organization, Guid> _organizationRepository; private readonly IRepository<Organization, Guid> _organizationRepository;
private readonly IRepository<OrganizationMembership, Guid> _organizationMembershipsRepository;
private readonly OrganizationManager _organizationManager; private readonly OrganizationManager _organizationManager;
private readonly IBlobContainer<OrganizationProfilePictureContainer> _organizationBlobContainer; private readonly IBlobContainer<OrganizationProfilePictureContainer> _organizationBlobContainer;
private readonly IRepository<AppUser, Guid> _userRepository; private readonly IRepository<AppUser, Guid> _userRepository;
public OrganizationAppService( public OrganizationAppService(
IRepository<Organization, Guid> organizationRepository, IRepository<Organization, Guid> organizationRepository,
IRepository<OrganizationMembership, Guid> organizationMembershipsRepository,
OrganizationManager organizationManager, OrganizationManager organizationManager,
IBlobContainer<OrganizationProfilePictureContainer> organizationBlobContainer, IBlobContainer<OrganizationProfilePictureContainer> organizationBlobContainer,
IRepository<AppUser, Guid> userRepository) IRepository<AppUser, Guid> userRepository)
{ {
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_organizationMembershipsRepository = organizationMembershipsRepository;
_organizationManager = organizationManager; _organizationManager = organizationManager;
_organizationBlobContainer = organizationBlobContainer; _organizationBlobContainer = organizationBlobContainer;
_userRepository = userRepository; _userRepository = userRepository;
@ -56,16 +60,29 @@ namespace EventHub.Organizations
} }
} }
public async Task<PagedResultDto<OrganizationInListDto>> GetListAsync(PagedResultRequestDto input) public async Task<PagedResultDto<OrganizationInListDto>> GetListAsync(OrganizationListFilterDto input)
{ {
var organizationCount = await _organizationRepository.GetCountAsync(); var organizationQueryable = await _organizationRepository.GetQueryableAsync();
var organizations = await _organizationRepository.GetPagedListAsync( var organizationMemberQueryable = await _organizationMembershipsRepository.GetQueryableAsync();
input.SkipCount,
input.MaxResultCount,
nameof(Organization.DisplayName)
);
var organizationDto = ObjectMapper.Map<List<Organization>, List<OrganizationInListDto>>(organizations); var query = organizationQueryable;
if (input.RegisteredUserId.HasValue)
{
var registeredOrganization = organizationMemberQueryable
.Where(x => x.UserId == input.RegisteredUserId)
.Select(x => x.OrganizationId);
var organizationIds = await AsyncExecuter.ToListAsync(registeredOrganization);
query = query.Where(x => organizationIds.Contains(x.Id));
}
var totalCount = await AsyncExecuter.CountAsync(query);
query = query.PageBy(input);
var organizationDto = ObjectMapper
.Map<List<Organization>, List<OrganizationInListDto>>(await AsyncExecuter.ToListAsync(query));
foreach (var organization in organizationDto) foreach (var organization in organizationDto)
{ {
@ -73,7 +90,7 @@ namespace EventHub.Organizations
} }
return new PagedResultDto<OrganizationInListDto>( return new PagedResultDto<OrganizationInListDto>(
organizationCount, totalCount,
organizationDto organizationDto
); );
} }

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

@ -26,9 +26,9 @@
"Organization": "Organization", "Organization": "Organization",
"Submit": "Submit", "Submit": "Submit",
"SeeEvent": "See event", "SeeEvent": "See event",
"RegisterNow": "Register Now", "JoinThisEvent": "Join This Event",
"LoginToRegister": "Login to register", "LoginToRegister": "Login to register",
"CancelRegistration": "Cancel registration", "YouAttendedThisEvent": "You Attended This Event",
"EventRegisterSuccessMessage": "Your event registration has been done successfully.", "EventRegisterSuccessMessage": "Your event registration has been done successfully.",
"EventRegistrationCancelledMessage": "Your event registration has been cancelled.", "EventRegistrationCancelledMessage": "Your event registration has been cancelled.",
"OrganizedBy": "Organized by", "OrganizedBy": "Organized by",

2
src/EventHub.Web/Controllers/OrganizationController.cs

@ -22,7 +22,7 @@ namespace EventHub.Web.Controllers
[HttpGet] [HttpGet]
[Route("get-list")] [Route("get-list")]
public async Task<IActionResult> GetList(PagedResultRequestDto input) public async Task<IActionResult> GetList(OrganizationListFilterDto input)
{ {
ViewData.Model = (await _organizationAppService.GetListAsync(input)).Items.ToList(); ViewData.Model = (await _organizationAppService.GetListAsync(input)).Items.ToList();

16
src/EventHub.Web/Controllers/OrganizationMembershipController.cs

@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EventHub.Organizations.Memberships; using EventHub.Organizations.Memberships;
using EventHub.Web.Pages.Organizations.Components.JoinArea; using EventHub.Web.Pages.Organizations.Components.JoinArea;
@ -7,6 +9,7 @@ using Volo.Abp.AspNetCore.Mvc;
namespace EventHub.Web.Controllers namespace EventHub.Web.Controllers
{ {
[Route("api/organization-membership")]
public class OrganizationMembershipController : AbpController public class OrganizationMembershipController : AbpController
{ {
private readonly IOrganizationMembershipAppService _organizationMembershipAppService; private readonly IOrganizationMembershipAppService _organizationMembershipAppService;
@ -16,6 +19,19 @@ namespace EventHub.Web.Controllers
_organizationMembershipAppService = organizationMembershipAppService; _organizationMembershipAppService = organizationMembershipAppService;
} }
[HttpGet]
[Route("get-list")]
public async Task<IActionResult> GetList(OrganizationMemberListFilterDto input)
{
ViewData.Model = (await _organizationMembershipAppService.GetMembersAsync(input)).Items.ToList();
return new PartialViewResult
{
ViewName = "~/Pages/Organizations/Components/MembersArea/_memberListSection.cshtml",
ViewData = ViewData
};
}
[HttpPost] [HttpPost]
public async Task<NoContentResult> Join(Guid organizationId) public async Task<NoContentResult> Join(Guid organizationId)
{ {

2
src/EventHub.Web/Pages/Events/Components/EventsArea/Default.cshtml

@ -8,7 +8,7 @@
@if (Model.IsPagination && Model.TotalCount > Model.MaxResultCount && Model.TotalCount > Model.Events.Count) @if (Model.IsPagination && Model.TotalCount > Model.MaxResultCount && Model.TotalCount > Model.Events.Count)
{ {
<div class="row load-more-section-@Model.GetHashCode()"> <div id="load-more-section-@Model.GetHashCode()" class="row">
<div class="col text-center"> <div class="col text-center">
<button <button
id="LoadMoreButton-@Model.GetHashCode()" id="LoadMoreButton-@Model.GetHashCode()"

8
src/EventHub.Web/Pages/Events/Components/EventsArea/events-area.js

@ -4,12 +4,12 @@
var skipCount = Number($wrapper.find('[data-skip-count]').attr('data-skip-count')) var skipCount = Number($wrapper.find('[data-skip-count]').attr('data-skip-count'))
var maxResultCount = Number($wrapper.find('[data-max-result-count]').attr('data-max-result-count')) var maxResultCount = Number($wrapper.find('[data-max-result-count]').attr('data-max-result-count'))
var hashCode = Number($wrapper.find('[data-hash-code]').attr('data-hash-code')) var hashCode = Number($wrapper.find('[data-hash-code]').attr('data-hash-code'))
skipCount += maxResultCount;
function init() { function init() {
var loadMoreButton = $wrapper.find('#LoadMoreButton-' + hashCode); var loadMoreButton = $wrapper.find('#LoadMoreButton-' + hashCode);
loadMoreButton.click(function (e) { loadMoreButton.click(function (e) {
e.preventDefault(); e.preventDefault();
skipCount += maxResultCount;
loadMoreButton.buttonBusy(true); loadMoreButton.buttonBusy(true);
abp.ajax({ abp.ajax({
type: 'GET', type: 'GET',
@ -19,10 +19,10 @@
}).then(function (response) { }).then(function (response) {
var eventList = $wrapper.find('#EventList') var eventList = $wrapper.find('#EventList')
eventList.append(response); eventList.append(response);
skipCount += maxResultCount;
}).always(function () { }).always(function () {
var eventCount = $('.event').length; if (skipCount >= totalCount) {
if (Number(eventCount) >= totalCount) { $('#load-more-section-' + hashCode).hide();
$('.load-more-section-' + hashCode).hide();
} }
loadMoreButton.buttonBusy(false); loadMoreButton.buttonBusy(false);
}); });

8
src/EventHub.Web/Pages/Events/Components/RegistrationArea/Default.cshtml

@ -8,10 +8,9 @@
if (Model.IsRegistered) if (Model.IsRegistered)
{ {
<abp-button class="mt-4" id="EventCancelRegistrationButton" <abp-button class="mt-4" id="EventCancelRegistrationButton"
button-type="Primary" button-type="Success"
size="Large" size="Large"
icon="fas fa-times" text="@L["YouAttendedThisEvent"].Value"
text="@L["CancelRegistration"].Value"
data-url="@Url.Action("Unregister", "EventRegistration", new {eventId = Model.EventId})"/> data-url="@Url.Action("Unregister", "EventRegistration", new {eventId = Model.EventId})"/>
} }
else else
@ -19,8 +18,7 @@
<abp-button class="mt-4" id="EventRegisterButton" <abp-button class="mt-4" id="EventRegisterButton"
button-type="Primary" button-type="Primary"
size="Large" size="Large"
icon="fas fa-plus" text="@L["JoinThisEvent"].Value"
text="@L["RegisterNow"].Value"
data-url="@Url.Action("Register","EventRegistration", new { eventId = Model.EventId })"/> data-url="@Url.Action("Register","EventRegistration", new { eventId = Model.EventId })"/>
} }
} }

31
src/EventHub.Web/Pages/Organizations/Components/MembersArea/Default.cshtml

@ -1,15 +1,26 @@
@model EventHub.Web.Pages.Organizations.Components.MembersArea.MembersAreaViewComponent.MembersAreaViewComponentModel @model EventHub.Web.Pages.Organizations.Components.MembersArea.MembersAreaViewComponent.MembersAreaViewComponentModel
<h5 class="detail-head mt-5 font-weight-bold" data-organization-id="@Model.OrganizationId">Members (@Model.TotalCount)</h5> <h5 class="detail-head mt-3 font-weight-bold" data-is-more-detail="@Model.IsMoreDetail" data-organization-id="@Model.OrganizationId" data-hash-code="@Model.GetHashCode()" data-total-count="@Model.TotalCount" data-skip-count="@Model.SkipCount" data-max-result-count="@Model.MaxResultCount">
<div> Members
@foreach (var member in Model.Members) @if (Model.IsMoreDetail)
{ {
<img gravatar-email="@member.Email" default-image="Wavatar" gravatar-size="60" class="org-avatar avatar rounded-circle"/> <span class="badge badge-primary">@Model.TotalCount</span>
} }
</div> else
@if (Model.TotalCount > 10) {
<span>(@Model.TotalCount)</span>
}
</h5>
<div id="MemberList-@Model.GetHashCode()" class="row">
<partial name="~/Pages/Organizations/Components/MembersArea/_memberListSection.cshtml" model="@Model.Members"/>
</div>
@if (Model.IsPagination && Model.TotalCount > Model.MaxResultCount && Model.TotalCount > Model.Members.Count)
{ {
// ToDo: Implement show more!!! <div id="load-more-section-@Model.GetHashCode()">
<button class="btn btn-secondary btn-lg mt-3"> <button
Show More id="LoadMoreButton-@Model.GetHashCode()"
</button> class="btn btn-secondary btn-lg mt-3"
data-url="@Url.Action("GetList", "OrganizationMembership", new { organizationId = Model.OrganizationId, maxResultCount = Model.MaxResultCount})">
Show More
</button>
</div>
} }

28
src/EventHub.Web/Pages/Organizations/Components/MembersArea/MembersAreaViewComponent.cs

@ -24,9 +24,19 @@ namespace EventHub.Web.Pages.Organizations.Components.MembersArea
_organizationMembershipAppService = organizationMembershipAppService; _organizationMembershipAppService = organizationMembershipAppService;
} }
public async Task<IViewComponentResult> InvokeAsync(Guid organizationId) public async Task<IViewComponentResult> InvokeAsync(
Guid organizationId,
int? skipCount,
int maxResultCount = 26,
bool isPagination = true,
bool isMoreDetail = false)
{ {
var result = await _organizationMembershipAppService.GetMembersAsync(organizationId); var result = await _organizationMembershipAppService.GetMembersAsync(new OrganizationMemberListFilterDto
{
OrganizationId = organizationId,
SkipCount = skipCount.GetValueOrDefault(),
MaxResultCount = maxResultCount
});
return View( return View(
"~/Pages/Organizations/Components/MembersArea/Default.cshtml", "~/Pages/Organizations/Components/MembersArea/Default.cshtml",
@ -34,7 +44,11 @@ namespace EventHub.Web.Pages.Organizations.Components.MembersArea
{ {
OrganizationId = organizationId, OrganizationId = organizationId,
Members = result.Items, Members = result.Items,
TotalCount = result.TotalCount TotalCount = result.TotalCount,
SkipCount = skipCount.GetValueOrDefault(),
MaxResultCount = maxResultCount,
IsPagination = isPagination,
IsMoreDetail = isMoreDetail
} }
); );
} }
@ -46,6 +60,14 @@ namespace EventHub.Web.Pages.Organizations.Components.MembersArea
public long TotalCount { get; set; } public long TotalCount { get; set; }
public Guid OrganizationId { get; set; } public Guid OrganizationId { get; set; }
public int SkipCount { get; set; }
public int MaxResultCount { get; set; }
public bool IsPagination { get; set; }
public bool IsMoreDetail { get; set; }
public string GetMemberName(OrganizationMemberDto member) public string GetMemberName(OrganizationMemberDto member)
{ {

22
src/EventHub.Web/Pages/Organizations/Components/MembersArea/_memberListSection.cshtml

@ -0,0 +1,22 @@
@model List<EventHub.Organizations.Memberships.OrganizationMemberDto>
@foreach (var member in Model)
{
<div>
<div>
<img gravatar-email="@member.Email" default-image="Wavatar" gravatar-size="60" class="org-avatar avatar rounded-circle"/>
<span class="member-name" style="display: none">
@if (!string.IsNullOrWhiteSpace(member.Name) && !string.IsNullOrWhiteSpace(member.Surname))
{
@(member.Name + " " + member.Surname)
}
else
{
{
@member.UserName
}
}
</span>
</div>
</div>
}

50
src/EventHub.Web/Pages/Organizations/Components/MembersArea/members-area.js

@ -1,16 +1,62 @@
(function () { (function () {
abp.widgets.MembersArea = function ($wrapper) { abp.widgets.MembersArea = function ($wrapper) {
var organizationId = $wrapper.find('[data-organization-id]').attr('data-organization-id'); var organizationId = $wrapper.find('[data-organization-id]').attr('data-organization-id');
var totalCount = Number($wrapper.find('[data-total-count]').attr('data-total-count'))
var skipCount = Number($wrapper.find('[data-skip-count]').attr('data-skip-count'))
var maxResultCount = Number($wrapper.find('[data-max-result-count]').attr('data-max-result-count'))
var isMoreDetail = $wrapper.find('[data-is-more-detail]').attr('data-is-more-detail')
var hashCode = Number($wrapper.find('[data-hash-code]').attr('data-hash-code'))
skipCount += maxResultCount;
function moreDetailFilter() {
var hashCode = Number($wrapper.find('[data-hash-code]').attr('data-hash-code'))
$('#MemberList-' + hashCode + '> div').addClass('col-6 col-md-4 col-lg-2');
$('#MemberList-' + hashCode + '> * > div > .member-name').removeAttr('style');
$('#MemberList-' + hashCode + '> * > div').addClass('member-container text-center');
$('#load-more-section-' + hashCode).addClass('text-center mt-3');
}
if (isMoreDetail === 'True'){
moreDetailFilter()
}
function init() {
var loadMoreButton = $wrapper.find('#LoadMoreButton-' + hashCode);
loadMoreButton.click(function (e) {
e.preventDefault();
loadMoreButton.buttonBusy(true);
abp.ajax({
type: 'GET',
dataType: 'html',
contentType: 'text/html; charset=utf-8',
url: (loadMoreButton.attr('data-url') + '&skipCount=' + skipCount)
}).then(function (response) {
var memberList = $wrapper.find('#MemberList-' + hashCode)
memberList.append(response);
skipCount += maxResultCount;
}).always(function () {
if (isMoreDetail === 'True'){
moreDetailFilter()
}
if (skipCount >= totalCount) {
loadMoreButton.hide();
}
loadMoreButton.buttonBusy(false);
});
});
}
return { return {
getFilters: function () { getFilters: function () {
return { return {
organizationId: organizationId organizationId: organizationId
}; };
} },
init: init
}; };
}; };
abp.event.on("EventHub.Organization.JoinStatusChanged", function(){ abp.event.on("EventHub.Organization.JoinStatusChanged", function () {
$('[data-widget-name="MembersArea"]') $('[data-widget-name="MembersArea"]')
.data('abp-widget-manager') .data('abp-widget-manager')
.refresh(); .refresh();

8
src/EventHub.Web/Pages/Organizations/Components/OrganizationsArea/Default.cshtml

@ -8,12 +8,16 @@
@if (Model.IsPagination && Model.TotalCount > Model.MaxResultCount && Model.TotalCount > Model.Organizations.Count) @if (Model.IsPagination && Model.TotalCount > Model.MaxResultCount && Model.TotalCount > Model.Organizations.Count)
{ {
<div class="row load-more-section-@Model.GetHashCode()"> <div id="load-more-section-@Model.GetHashCode()" class="row">
<div class="col text-center"> <div class="col text-center">
<button <button
id="LoadMoreButton-@Model.GetHashCode()" id="LoadMoreButton-@Model.GetHashCode()"
class="btn btn-secondary btn-lg" class="btn btn-secondary btn-lg"
data-url="@Url.Action("GetList", "Organization", new {maxResultCount = Model.MaxResultCount})"> data-url="@Url.Action("GetList", "Organization",
new {
registeredUserId = Model.RegisteredUserId,
maxResultCount = Model.MaxResultCount
})">
Load More Load More
</button> </button>
</div> </div>

8
src/EventHub.Web/Pages/Organizations/Components/OrganizationsArea/OrganizationsAreaViewComponent.cs

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using EventHub.Organizations; using EventHub.Organizations;
@ -21,13 +22,15 @@ namespace EventHub.Web.Pages.Organizations.Components.OrganizationsArea
} }
public async Task<IViewComponentResult> InvokeAsync( public async Task<IViewComponentResult> InvokeAsync(
Guid? registeredUserId,
int? skipCount, int? skipCount,
int maxResultCount = 15, int maxResultCount = 15,
bool isPagination = true) bool isPagination = true)
{ {
var result = await _organizationAppService.GetListAsync( var result = await _organizationAppService.GetListAsync(
new PagedResultRequestDto new OrganizationListFilterDto
{ {
RegisteredUserId = registeredUserId,
SkipCount = skipCount.GetValueOrDefault(), SkipCount = skipCount.GetValueOrDefault(),
MaxResultCount = maxResultCount MaxResultCount = maxResultCount
} }
@ -39,6 +42,7 @@ namespace EventHub.Web.Pages.Organizations.Components.OrganizationsArea
{ {
Organizations = result.Items, Organizations = result.Items,
TotalCount = result.TotalCount, TotalCount = result.TotalCount,
RegisteredUserId = registeredUserId,
SkipCount = skipCount.GetValueOrDefault(), SkipCount = skipCount.GetValueOrDefault(),
MaxResultCount = maxResultCount, MaxResultCount = maxResultCount,
IsPagination = isPagination IsPagination = isPagination
@ -51,6 +55,8 @@ namespace EventHub.Web.Pages.Organizations.Components.OrganizationsArea
public IReadOnlyList<OrganizationInListDto> Organizations { get; set; } public IReadOnlyList<OrganizationInListDto> Organizations { get; set; }
public long TotalCount { get; set; } public long TotalCount { get; set; }
public Guid? RegisteredUserId { get; set; }
public int SkipCount { get; set; } public int SkipCount { get; set; }

8
src/EventHub.Web/Pages/Organizations/Components/OrganizationsArea/organizations-area.js

@ -4,12 +4,12 @@
var skipCount = Number($wrapper.find('[data-skip-count]').attr('data-skip-count')) var skipCount = Number($wrapper.find('[data-skip-count]').attr('data-skip-count'))
var maxResultCount = Number($wrapper.find('[data-max-result-count]').attr('data-max-result-count')) var maxResultCount = Number($wrapper.find('[data-max-result-count]').attr('data-max-result-count'))
var hashCode = Number($wrapper.find('[data-hash-code]').attr('data-hash-code')) var hashCode = Number($wrapper.find('[data-hash-code]').attr('data-hash-code'))
skipCount += maxResultCount;
function init() { function init() {
var loadMoreButton = $wrapper.find('#LoadMoreButton-' + hashCode); var loadMoreButton = $wrapper.find('#LoadMoreButton-' + hashCode);
loadMoreButton.click(function (e) { loadMoreButton.click(function (e) {
e.preventDefault(); e.preventDefault();
skipCount += maxResultCount;
loadMoreButton.buttonBusy(true); loadMoreButton.buttonBusy(true);
abp.ajax({ abp.ajax({
type: 'GET', type: 'GET',
@ -19,10 +19,10 @@
}).then(function (response) { }).then(function (response) {
var organizationList = $wrapper.find('#OrganizationList') var organizationList = $wrapper.find('#OrganizationList')
organizationList.append(response); organizationList.append(response);
skipCount += maxResultCount;
}).always(function () { }).always(function () {
var organizationCount = $('.organization').length; if (skipCount >= totalCount) {
if (Number(organizationCount) >= totalCount) { $('#load-more-section-' + hashCode).hide();
$('.load-more-section-' + hashCode).hide();
} }
loadMoreButton.buttonBusy(false); loadMoreButton.buttonBusy(false);
}); });

21
src/EventHub.Web/Pages/Organizations/Index.cshtml.cs

@ -1,25 +1,10 @@
using System.Collections.Generic; namespace EventHub.Web.Pages.Organizations
using System.Threading.Tasks;
using EventHub.Organizations;
using Volo.Abp.Application.Dtos;
namespace EventHub.Web.Pages.Organizations
{ {
public class IndexPageModel : EventHubPageModel public class IndexPageModel : EventHubPageModel
{ {
public IReadOnlyList<OrganizationInListDto> Organizations { get; set; } public void OnGet()
private readonly IOrganizationAppService _organizationAppService;
public IndexPageModel(IOrganizationAppService organizationAppService)
{ {
_organizationAppService = organizationAppService;
}
public async Task OnGetAsync()
{
var result = await _organizationAppService.GetListAsync(new PagedResultRequestDto());
Organizations = result.Items;
} }
} }
} }

45
src/EventHub.Web/Pages/Organizations/Profile.cshtml

@ -59,8 +59,14 @@
</div> </div>
@await Component.InvokeAsync(typeof(JoinAreaViewComponent), new {organizationId = Model.Organization.Id}) @await Component.InvokeAsync(typeof(JoinAreaViewComponent), new {organizationId = Model.Organization.Id})
@await Component.InvokeAsync(typeof(MembersAreaViewComponent), new {organizationId = Model.Organization.Id}) @await Component.InvokeAsync(typeof(MembersAreaViewComponent),
new
{
organizationId = Model.Organization.Id,
isPagination = true,
maxResultCount = 15
})
<h5 class="detail-head mt-5 font-weight-bold">Share Organizations</h5> <h5 class="detail-head mt-5 font-weight-bold">Share Organizations</h5>
<div class="share-container"> <div class="share-container">
<a href="https://twitter.com/@Model.Organization.TwitterUsername"> <a href="https://twitter.com/@Model.Organization.TwitterUsername">
@ -112,35 +118,14 @@
</div> </div>
</div> </div>
<div id="members-section" class="tab-pane fade"> <div id="members-section" class="tab-pane fade">
<h4 class="mb-5 mt-3">Members <span class="badge badge-primary">@Model.Members.Count</span></h4> @await Component.InvokeAsync(typeof(MembersAreaViewComponent),
<div class="row"> new
@foreach (var member in Model.Members)
{ {
<div class="col-6 col-md-4 col-lg-2"> organizationId = Model.Organization.Id,
<div class="member-container text-center"> isPagination = true,
<img gravatar-email="@member.Email" default-image="Wavatar" gravatar-size="60" class="org-avatar avatar rounded-circle" data-toggle="tooltip" title="" data-original-title="@member.UserName"/> maxResultCount = 18,
<span class="member-name"> isMoreDetail = true
@if (!string.IsNullOrWhiteSpace(member.Name) && !string.IsNullOrWhiteSpace(member.Surname)) })
{
@(member.Name + " " + member.Surname)
}
else
{
{
@member.UserName
}
}
</span>
</div>
</div>
}
</div>
<div class="text-center mt-3">
@* ToDo: Implement show more!!! *@
<button class="btn btn-secondary btn-lg mt-3">
Load More
</button>
</div>
</div> </div>
</div> </div>

10
src/EventHub.Web/Pages/Organizations/Profile.cshtml.cs

@ -17,23 +17,18 @@ namespace EventHub.Web.Pages.Organizations
public bool IsOrganizationOwner { get; private set; } public bool IsOrganizationOwner { get; private set; }
public List<OrganizationMemberDto> Members { get; private set; }
private readonly IOrganizationAppService _organizationAppService; private readonly IOrganizationAppService _organizationAppService;
private readonly IOrganizationMembershipAppService _organizationMembershipAppService;
public ProfilePageModel( public ProfilePageModel(
IOrganizationAppService organizationAppService, IOrganizationAppService organizationAppService,
IOrganizationMembershipAppService organizationMembershipAppService) IOrganizationMembershipAppService organizationMembershipAppService)
{ {
_organizationAppService = organizationAppService; _organizationAppService = organizationAppService;
_organizationMembershipAppService = organizationMembershipAppService;
} }
public async Task OnGetAsync() public async Task OnGetAsync()
{ {
await GetProfileAsync(); await GetProfileAsync();
await GetMembersAsync();
IsOrganizationOwner = await _organizationAppService.IsOrganizationOwnerAsync(Organization.Id); IsOrganizationOwner = await _organizationAppService.IsOrganizationOwnerAsync(Organization.Id);
} }
@ -42,10 +37,5 @@ namespace EventHub.Web.Pages.Organizations
{ {
Organization = await _organizationAppService.GetProfileAsync(Name); Organization = await _organizationAppService.GetProfileAsync(Name);
} }
private async Task GetMembersAsync()
{
Members = (await _organizationMembershipAppService.GetMembersAsync(Organization.Id)).Items.ToList();
}
} }
} }

412
src/EventHub.Web/Pages/Profile.cshtml

@ -1,7 +1,6 @@
@page @page
@using EventHub.Web.Pages.Events.Components.EventsArea @using EventHub.Web.Pages.Events.Components.EventsArea
@using Volo.Abp.Identity @using EventHub.Web.Pages.Organizations.Components.OrganizationsArea
@using Volo.Abp.ObjectExtending
@using Volo.Abp.Timing @using Volo.Abp.Timing
@using Volo.Abp.Users @using Volo.Abp.Users
@inject ICurrentUser CurrentUser @inject ICurrentUser CurrentUser
@ -9,213 +8,189 @@
@model EventHub.Web.Pages.ProfileModel @model EventHub.Web.Pages.ProfileModel
<div class="container pt-4"> <div class="container pt-4">
<div class="row py-4"> <div class="row py-4">
<div class="col-md"> <div class="col-md">
<ul class="nav nav-tabs profile-nav" id="myTab"> <ul class="nav nav-tabs profile-nav" id="myTab">
<li class="nav-item"> <li class="nav-item">
<a href="#MyProfile" class="nav-link active" data-toggle="tab">My Profile</a> <a href="#MyProfile" class="nav-link active" data-toggle="tab">My Profile</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="#NotificationSettings" class="nav-link" data-toggle="tab">Notification Settings</a> <a href="#MyOrganizations" class="nav-link" data-toggle="tab">My Organizations</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="#MyEvents" class="nav-link" data-toggle="tab">My Events</a> <a href="#MyPastEvents" class="nav-link" data-toggle="tab">My Past Events</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="#MyPastEvents" class="nav-link" data-toggle="tab">My Past Events</a> <a href="#MyUpcomingEvents" class="nav-link" data-toggle="tab">My Upcoming Events</a>
</li> </li>
<li class="nav-item"> </ul>
<a href="#MyUpcomingEvents" class="nav-link" data-toggle="tab">My Upcoming Events</a> <div class="tab-content profile-content py-4">
</li> <div id="MyProfile" class="tab-pane fade show active">
</ul> <div class="row">
<div class="tab-content profile-content py-4"> <div class="col-md-4">
<div id="MyProfile" class="tab-pane fade show active"> <div class="card">
<div class="row"> <div class="card-body text-center">
<div class="col-md-4"> <h3 class="text-left">Profile Photo</h3>
<div class="card"> <img src="assets/big-avatar.png">
<div class="card-body text-center"> <p class="mt-3">
<h3 class="text-left">Profile Photo</h3> You should note that the photo to be added does not exceed <span class="text-primary">30 MB</span> in <span class="text-primary">JPEG</span> or <span class="text-primary">PNG</span> format.
<img src="assets/big-avatar.png"> </p>
<p class="mt-3">
You should note that the photo to be added does not exceed <span class="text-primary">30 MB</span> in <span class="text-primary">JPEG</span> or <span class="text-primary">PNG</span> format.
</p>
<a href="#" class="btn btn-primary btn-lg mt-2"> <a href="#" class="btn btn-primary btn-lg mt-2">
Update Profile Photo Update Profile Photo
</a> </a>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card">
<div class="card-body" style="min-height: 496px">
<h3 class="mb-4">Profile Informations</h3>
<div class="form">
<div class="row">
<div class="col-md-6">
<div class="form-label-group">
<input type="Name" id="inputName" class="form-control" placeholder="Name" required="">
<label for="inputName">Name</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="Surname" id="inputSurname" class="form-control" placeholder="Surname" required="">
<label for="inputSurname">Surname</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="Email" id="inputEmail" class="form-control" placeholder="Email" required="">
<label for="inputEmail">E-mail Address</label>
</div> </div>
</div> </div>
<div class="col-md-6">
<div class="form-label-group">
<input type="location" id="inputLocation" class="form-control" placeholder="Location" required="">
<label for="inputLocation">Location</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="Company" id="inputCompany" class="form-control" placeholder="Company" required="">
<label for="inputCompany">Company</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="Title" id="inputTitle" class="form-control" placeholder="Title" required="">
<label for="inputTitle">Title</label>
</div>
</div>
<div class="col-md-12">
<div class="form-label-group">
<input type="Bio" id="inputBio" class="form-control" placeholder="Bio" required="">
<label for="inputBio">Bio</label>
</div>
</div>
<div class="col-md-12 text-right">
<a href="#" class="btn btn-primary btn-lg">
Update Information
</a>
</div>
</div> </div>
</div> <div class="col-md-8">
</div> <div class="card">
</div> <div class="card-body" style="min-height: 496px">
<h3 class="mb-4">Profile Informations</h3>
<div class="form">
<div class="row">
<div class="col-md-6">
<div class="form-label-group">
<input type="Name" id="inputName" class="form-control" placeholder="Name" required="">
<label for="inputName">Name</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="Surname" id="inputSurname" class="form-control" placeholder="Surname" required="">
<label for="inputSurname">Surname</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="Email" id="inputEmail" class="form-control" placeholder="Email" required="">
<label for="inputEmail">E-mail Address</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="location" id="inputLocation" class="form-control" placeholder="Location" required="">
<label for="inputLocation">Location</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="Company" id="inputCompany" class="form-control" placeholder="Company" required="">
<label for="inputCompany">Company</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="Title" id="inputTitle" class="form-control" placeholder="Title" required="">
<label for="inputTitle">Title</label>
</div>
</div>
<div class="card"> <div class="col-md-12">
<div class="card-body"> <div class="form-label-group">
<h3 class="mb-4">Change Password</h3> <input type="Bio" id="inputBio" class="form-control" placeholder="Bio" required="">
<div class="form"> <label for="inputBio">Bio</label>
<div class="row"> </div>
<div class="col-md-6"> </div>
<div class="form-label-group">
<input type="OldPassword" id="inputName" class="form-control" placeholder="Old Password" required="">
<label for="inputOldPassword">Old Password</label>
</div>
</div>
<div class="col-md-6">
</div>
<div class="col-md-6"> <div class="col-md-12 text-right">
<div class="form-label-group"> <a href="#" class="btn btn-primary btn-lg">
<input type="NewPassword" id="inputName" class="form-control" placeholder="New Password" required=""> Update Information
<label for="inputNewPassword">New Password</label> </a>
</div>
</div>
</div>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="card">
<div class="form-label-group"> <div class="card-body">
<input type="NewPassword2" id="inputName" class="form-control" placeholder="New Password (Again)" required=""> <h3 class="mb-4">Change Password</h3>
<label for="inputNewPassword2">New Password (Again)</label> <div class="form">
<div class="row">
<div class="col-md-6">
<div class="form-label-group">
<input type="OldPassword" id="inputName" class="form-control" placeholder="Old Password" required="">
<label for="inputOldPassword">Old Password</label>
</div>
</div>
<div class="col-md-6">
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="NewPassword" id="inputName" class="form-control" placeholder="New Password" required="">
<label for="inputNewPassword">New Password</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="NewPassword2" id="inputName" class="form-control" placeholder="New Password (Again)" required="">
<label for="inputNewPassword2">New Password (Again)</label>
</div>
</div>
<div class="col-md-12 text-right">
<a href="#" class="btn btn-primary btn-lg">
Update Information
</a>
</div>
</div>
</div>
</div> </div>
</div> </div>
<div class="col-md-12 text-right">
<a href="#" class="btn btn-primary btn-lg">
Update Information
</a>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> <div id="MyOrganizations" class="tab-pane fade">
</div> <div class="row">
</div> <div class="col">
</div> <div class="card">
<div id="NotificationSettings" class="tab-pane fade"> <div class="card-body" style="min-height: 496px">
<div class="row"> <h3 class="mb-4">My Organizations</h3>
<div class="col-md-8 mx-auto"> @await Component.InvokeAsync(typeof(OrganizationsAreaViewComponent), new
<div class="card"> {
<div class="card-body" style="min-height: 496px"> registeredUserId = CurrentUser.GetId(),
<h3 class="mb-5">Notification Settings</h3> maxResultCount = 12
<h4 class="mt-4 mb-3">General Notifications</h4> })
<div class="row my-1"> </div>
<div class="col">Send SMS notification</div>
<div class="col-auto text-right">
<div class="checkbox switcher">
<label for="switch1">
<input type="checkbox" id="switch1" value="">
<span>
<small></small>
</span>
</label>
</div>
</div>
</div>
<div class="row my-1">
<div class="col">Send E-mail notification</div>
<div class="col-auto text-right">
<div class="checkbox switcher">
<label for="switch2">
<input type="checkbox" id="switch2" value="" checked>
<span>
<small></small>
</span>
</label>
</div>
</div>
</div>
<h4 class="mt-4 mb-3">Special Notifications to EventHub</h4>
<div class="row my-1">
<div class="col">Send notification about updates</div>
<div class="col-auto text-right">
<div class="checkbox switcher">
<label for="switch3">
<input type="checkbox" id="switch3" value="">
<span>
<small></small>
</span>
</label>
</div> </div>
</div> </div>
</div> </div>
<div class="row my-1"> </div>
<div class="col">Send notification for organization suggestions</div> <div id="MyPastEvents" class="tab-pane fade">
<div class="col-auto text-right"> <div class="row">
<div class="checkbox switcher"> <div class="col">
<label for="switch4"> <div class="card">
<input type="checkbox" id="switch4" value="" checked> <div class="card-body" style="min-height: 496px">
<span> <h3 class="mb-4">My Past Events</h3>
<small></small> <div class="past-events">
</span> @await Component.InvokeAsync(typeof(EventsAreaViewComponent), new
</label> {
maxDate = Clock.Now.ClearTime(),
registeredUserId = CurrentUser.GetId(),
maxResultCount = 6,
skipCount = 0
})
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="row my-1"> </div>
<div class="col">Send notifications for new organizations</div> <div id="MyUpcomingEvents" class="tab-pane fade">
<div class="col-auto text-right"> <div class="row">
<div class="checkbox switcher"> <div class="col">
<label for="switch5"> <div class="card">
<input type="checkbox" id="switch5" value=""> <div class="card-body" style="min-height: 496px">
<span> <h3 class="mb-4">My Upcoming Events</h3>
<small></small> @await Component.InvokeAsync(typeof(EventsAreaViewComponent), new
</span> {
</label> minDate = Clock.Now.ClearTime(),
registeredUserId = CurrentUser.GetId(),
maxResultCount = 6,
skipCount = 0
})
</div>
</div> </div>
</div> </div>
</div> </div>
@ -223,63 +198,4 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div id="MyEvents" class="tab-pane fade">
<div class="row">
<div class="col">
<div class="card">
<div class="card-body" style="min-height: 496px">
<h3 class="mb-4">My Events</h3>
@await Component.InvokeAsync(typeof(EventsAreaViewComponent), new
{
registeredUserId = CurrentUser.Id,
maxResultCount = 6,
skipCount = 0
})
</div>
</div>
</div>
</div>
</div>
<div id="MyPastEvents" class="tab-pane fade">
<div class="row">
<div class="col">
<div class="card">
<div class="card-body" style="min-height: 496px">
<h3 class="mb-4">My Past Events</h3>
<div class="past-events">
@await Component.InvokeAsync(typeof(EventsAreaViewComponent), new
{
maxDate = Clock.Now.ClearTime(),
registeredUserId = CurrentUser.Id,
maxResultCount = 6,
skipCount = 0
})
</div>
</div>
</div>
</div>
</div>
</div>
<div id="MyUpcomingEvents" class="tab-pane fade">
<div class="row">
<div class="col">
<div class="card">
<div class="card-body" style="min-height: 496px">
<h3 class="mb-4">My Upcoming Events</h3>
@await Component.InvokeAsync(typeof(EventsAreaViewComponent), new
{
minDate = Clock.Now.ClearTime(),
registeredUserId = CurrentUser.Id,
maxResultCount = 6,
skipCount = 0
})
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>

16
src/EventHub.Web/Pages/Profile.cshtml.cs

@ -1,9 +1,23 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using EventHub.Organizations;
namespace EventHub.Web.Pages namespace EventHub.Web.Pages
{ {
public class ProfileModel : EventHubPageModel public class ProfileModel : EventHubPageModel
{ {
public void OnGet() private readonly IOrganizationAppService _organizationAppService;
public IReadOnlyList<OrganizationInListDto> MyOrganizations { get; set; }
public ProfileModel(IOrganizationAppService organizationAppService)
{ {
_organizationAppService = organizationAppService;
}
public async Task OnGetAsync()
{
MyOrganizations = (await _organizationAppService.GetMyOrganizationsAsync()).Items;
} }
} }
} }
Loading…
Cancel
Save