Browse Source

feat: add the ability to publish event

pull/79/head
berkansasmaz 5 years ago
parent
commit
8bae421174
No known key found for this signature in database GPG Key ID: 884D815C3F32BE00
  1. 2
      src/EventHub.Application.Contracts/Events/EventInListDto.cs
  2. 2
      src/EventHub.Application.Contracts/Events/IEventAppService.cs
  3. 2
      src/EventHub.Application.Contracts/Events/UpdateEventDto.cs
  4. 16
      src/EventHub.Application/Events/EventAppService.cs
  5. 1
      src/EventHub.Domain.Shared/EventHubErrorCodes.cs
  6. 40
      src/EventHub.Domain.Shared/Events/EventConsts.cs
  7. 3
      src/EventHub.Domain.Shared/Localization/EventHub/en.json
  8. 104
      src/EventHub.Domain.Shared/Web/EventHubUrlOptions.cs
  9. 31
      src/EventHub.Domain/Countries/Country.cs
  10. 8
      src/EventHub.Domain/Events/Session.cs
  11. 7
      src/EventHub.HttpApi/Controllers/Events/EventController.cs
  12. 46
      src/EventHub.Web/Pages/Events/Components/CreateEventArea/CreateEventAreaViewComponent.cs
  13. 2
      src/EventHub.Web/Pages/Events/Components/CreateEventArea/_previewSection.cshtml
  14. 23
      src/EventHub.Web/Pages/Events/Components/CreateEventArea/create-event-area.js
  15. 5
      src/EventHub.Web/Pages/Events/New.cshtml
  16. 0
      src/EventHub.Web/Pages/Events/New.js

2
src/EventHub.Application.Contracts/Events/EventInListDto.cs

@ -32,7 +32,7 @@ namespace EventHub.Events
public string Url { get; set; } public string Url { get; set; }
public DateTime CreationTime { get; } public DateTime CreationTime { get; set; }
public DateTime? LastModificationTime { get; set; } public DateTime? LastModificationTime { get; set; }
} }

2
src/EventHub.Application.Contracts/Events/IEventAppService.cs

@ -24,6 +24,8 @@ namespace EventHub.Events
Task<bool> IsEventOwnerAsync(Guid id); Task<bool> IsEventOwnerAsync(Guid id);
Task UpdateAsync(Guid id, UpdateEventDto input); Task UpdateAsync(Guid id, UpdateEventDto input);
Task<string> PublishAsync(Guid id);
Task AddTrackAsync(Guid id, AddTractDto input); Task AddTrackAsync(Guid id, AddTractDto input);

2
src/EventHub.Application.Contracts/Events/UpdateEventDto.cs

@ -7,8 +7,6 @@ namespace EventHub.Events
{ {
public class UpdateEventDto public class UpdateEventDto
{ {
//TODO: Add OrganizationId
[Required] [Required]
[StringLength(EventConsts.MaxTitleLength, MinimumLength = EventConsts.MinTitleLength)] [StringLength(EventConsts.MaxTitleLength, MinimumLength = EventConsts.MinTitleLength)]
public string Title { get; set; } public string Title { get; set; }

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

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Authentication;
using System.Threading.Tasks; using System.Threading.Tasks;
using EventHub.Countries; using EventHub.Countries;
using EventHub.Events.Registrations; using EventHub.Events.Registrations;
@ -181,7 +182,7 @@ namespace EventHub.Events
{ {
if (!CurrentUser.Id.HasValue) if (!CurrentUser.Id.HasValue)
{ {
throw new AbpAuthorizationException(); throw new AuthenticationException();
} }
await CheckIfValidOwnerAsync(@event); await CheckIfValidOwnerAsync(@event);
@ -281,6 +282,19 @@ namespace EventHub.Events
await _eventRepository.UpdateAsync(@event); await _eventRepository.UpdateAsync(@event);
} }
[Authorize]
public async Task<string> PublishAsync(Guid id)
{
var @event = await _eventRepository.GetAsync(id);
await CheckIfValidOwnerAsync(@event);
@event.Publish();
await _eventRepository.UpdateAsync(@event, true);
return @event.UrlCode;
}
[Authorize] [Authorize]
public async Task AddTrackAsync(Guid id, AddTractDto input) public async Task AddTrackAsync(Guid id, AddTractDto input)
{ {

1
src/EventHub.Domain.Shared/EventHubErrorCodes.cs

@ -19,5 +19,6 @@
public const string TrackNameAlreadyExist = "EventHub:TrackNameAlreadyExist"; public const string TrackNameAlreadyExist = "EventHub:TrackNameAlreadyExist";
public const string TrackNotFound = "EventHub:TrackNotFound"; public const string TrackNotFound = "EventHub:TrackNotFound";
public const string SessionNotFound = "EventHub:SessionNotFound"; public const string SessionNotFound = "EventHub:SessionNotFound";
public const string DraftEventNotFound = "EventHub:DraftEventNotFound";
} }
} }

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

@ -1,32 +1,32 @@
namespace EventHub.Events namespace EventHub.Events
{ {
public static class EventConsts public static class EventConsts
{ {
public const string DefaultSorting = "Title desc"; public const string DefaultSorting = "Title desc";
public const int UrlCodeLength = 8; public const int UrlCodeLength = 8;
public const int MaxTitleInUrlLength = 60; public const int MaxTitleInUrlLength = 60;
public const int MaxUrlLength = MaxTitleInUrlLength + 1 + UrlCodeLength; //Format: {Title}-{UrlCode} public const int MaxUrlLength = MaxTitleInUrlLength + 1 + UrlCodeLength; //Format: {Title}-{UrlCode}
public const int MinTitleLength = 8; public const int MinTitleLength = 8;
public const int MaxTitleLength = 128; public const int MaxTitleLength = 128;
public const int MinDescriptionLength = 50; public const int MinDescriptionLength = 50;
public const int MaxDescriptionLength = 2000; public const int MaxDescriptionLength = 2000;
public const int MinOnlineLinkLength = 4; public const int MinOnlineLinkLength = 4;
public const int MaxOnlineLinkLength = 2000; public const int MaxOnlineLinkLength = 2000;
public const int MinCityLength = 2; public const int MinCityLength = 2;
public const int MaxCityLength = 32; public const int MaxCityLength = 32;
public const int MinLanguageLength = 2; public const int MinLanguageLength = 2;
public const int MaxLanguageLength = 16; public const int MaxLanguageLength = 16;
public const int MaxTimingChangeCountForUser = 2; public const int MaxTimingChangeCountForUser = 2;
public const int MaxCoverImageFileSize = 5 * 1024 * 1024; public const int MaxCoverImageFileSize = 5 * 1024 * 1024;
public static string[] AllowedCoverImageExtensions = { ".jpg", ".png" }; public static string[] AllowedCoverImageExtensions = { ".jpg", ".png" };
} }
} }

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

@ -157,6 +157,7 @@
"EventHub:TrackNotFound": "The track not found!", "EventHub:TrackNotFound": "The track not found!",
"EventHub:SessionNotFound": "The session not found!", "EventHub:SessionNotFound": "The session not found!",
"EventHub:SessionTimeShouldBeInTheEventTime": "Session time should be in the event time!", "EventHub:SessionTimeShouldBeInTheEventTime": "Session time should be in the event time!",
"EventHub:SessionTimeConflictsWithAnExistingSession": "Session time conflicts with an existing session!" "EventHub:SessionTimeConflictsWithAnExistingSession": "Session time conflicts with an existing session!",
"EventHub:DraftEventNotFound": "The draft event not found!"
} }
} }

104
src/EventHub.Domain.Shared/Web/EventHubUrlOptions.cs

@ -2,64 +2,64 @@
namespace EventHub.Web namespace EventHub.Web
{ {
public class EventHubUrlOptions public class EventHubUrlOptions
{ {
private const string ConfigurationName = "AppUrls"; private const string ConfigurationName = "AppUrls";
private const string AccountDefaultValue = "https://localhost:44313"; private const string AccountDefaultValue = "https://localhost:44313";
private const string AdminDefaultValue = "https://localhost:44307"; private const string AdminDefaultValue = "https://localhost:44307";
private const string WwwDefaultValue = "https://localhost:44308"; private const string WwwDefaultValue = "https://localhost:44308";
private const string ApiDefaultValue = "https://localhost:44362"; private const string ApiDefaultValue = "https://localhost:44362";
private const string ApiInternalDefaultValue = ApiDefaultValue; private const string ApiInternalDefaultValue = ApiDefaultValue;
private const string AdminApiDefaultValue = "https://localhost:44305"; private const string AdminApiDefaultValue = "https://localhost:44305";
public string Account { get; set; } = AccountDefaultValue; public string Account { get; set; } = AccountDefaultValue;
public string Www { get; set; } = WwwDefaultValue; public string Www { get; set; } = WwwDefaultValue;
public string Api { get; set; } = ApiDefaultValue; public string Api { get; set; } = ApiDefaultValue;
public string ApiInternal { get; set; } = ApiInternalDefaultValue; public string ApiInternal { get; set; } = ApiInternalDefaultValue;
public string Admin { get; set; } = AdminDefaultValue; public string Admin { get; set; } = AdminDefaultValue;
public string AdminApi { get; set; } = AdminApiDefaultValue; public string AdminApi { get; set; } = AdminApiDefaultValue;
public static string GetAccountConfigValue(IConfiguration configuration) public static string GetAccountConfigValue(IConfiguration configuration)
{ {
return GetConfigValue(configuration, nameof(Account), AccountDefaultValue); return GetConfigValue(configuration, nameof(Account), AccountDefaultValue);
} }
public static string GetWwwConfigValue(IConfiguration configuration) public static string GetWwwConfigValue(IConfiguration configuration)
{ {
return GetConfigValue(configuration, nameof(Www), WwwDefaultValue); return GetConfigValue(configuration, nameof(Www), WwwDefaultValue);
} }
public static string GetApiInternalConfigValue(IConfiguration configuration) public static string GetApiInternalConfigValue(IConfiguration configuration)
{ {
return GetConfigValue(configuration, nameof(ApiInternal), ApiInternalDefaultValue); return GetConfigValue(configuration, nameof(ApiInternal), ApiInternalDefaultValue);
} }
public static string GetApiConfigValue(IConfiguration configuration) public static string GetApiConfigValue(IConfiguration configuration)
{ {
return GetConfigValue(configuration, nameof(Api), ApiDefaultValue); return GetConfigValue(configuration, nameof(Api), ApiDefaultValue);
} }
public static string GetAdminConfigValue(IConfiguration configuration) public static string GetAdminConfigValue(IConfiguration configuration)
{ {
return GetConfigValue(configuration, nameof(Admin), AdminDefaultValue); return GetConfigValue(configuration, nameof(Admin), AdminDefaultValue);
} }
public static string GetAdminApiConfigValue(IConfiguration configuration) public static string GetAdminApiConfigValue(IConfiguration configuration)
{ {
return GetConfigValue(configuration, nameof(AdminApi), AdminApiDefaultValue); return GetConfigValue(configuration, nameof(AdminApi), AdminApiDefaultValue);
} }
private static string GetConfigKey(string appName) private static string GetConfigKey(string appName)
{ {
return $"{ConfigurationName}:{appName}"; return $"{ConfigurationName}:{appName}";
} }
private static string GetConfigValue( private static string GetConfigValue(
IConfiguration configuration, IConfiguration configuration,
string appName, string appName,
string defaultValue) string defaultValue)
{ {
return configuration[GetConfigKey(appName)] ?? defaultValue; return configuration[GetConfigKey(appName)] ?? defaultValue;
} }
} }
} }

31
src/EventHub.Domain/Countries/Country.cs

@ -4,21 +4,20 @@ using Volo.Abp.Domain.Entities;
namespace EventHub.Countries namespace EventHub.Countries
{ {
public class Country : BasicAggregateRoot<Guid> public class Country : BasicAggregateRoot<Guid>
{ {
public string Name { get; private set; } public string Name { get; private set; }
private Country() private Country()
{ {
}
} internal Country(
Guid id,
internal Country( string name)
Guid id, : base(id)
string name) {
: base(id) Name = Check.NotNullOrWhiteSpace(name, nameof(name), CountryConsts.MaxNameLength);
{ }
Name = Check.NotNullOrWhiteSpace(name, nameof(name), CountryConsts.MaxNameLength); }
} }
}
}

8
src/EventHub.Domain/Events/Session.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
@ -91,7 +92,12 @@ namespace EventHub.Events
internal Session AddSpeaker(Guid userId) internal Session AddSpeaker(Guid userId)
{ {
Speakers.AddIfNotContains(new Speaker(Id, userId)); if (Speakers.Any(x => x.UserId == userId))
{
return this;
}
Speakers.Add(new Speaker(Id, userId));
return this; return this;
} }

7
src/EventHub.HttpApi/Controllers/Events/EventController.cs

@ -82,6 +82,13 @@ namespace EventHub.Controllers.Events
await _eventAppService.UpdateAsync(id, input); await _eventAppService.UpdateAsync(id, input);
} }
[HttpPut]
[Route("/publish/{id}")]
public async Task<string> PublishAsync(Guid id)
{
return await _eventAppService.PublishAsync(id);
}
[HttpPost] [HttpPost]
[Route("{id}/tracks")] [Route("{id}/tracks")]
public async Task AddTrackAsync(Guid id, AddTractDto input) public async Task AddTrackAsync(Guid id, AddTractDto input)

46
src/EventHub.Web/Pages/Events/Components/CreateEventArea/CreateEventAreaViewComponent.cs

@ -13,9 +13,11 @@ using JetBrains.Annotations;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
using Volo.Abp.AspNetCore.Mvc.UI.Widgets; using Volo.Abp.AspNetCore.Mvc.UI.Widgets;
using Volo.Abp.Authorization;
using Volo.Abp.Users; using Volo.Abp.Users;
namespace EventHub.Web.Pages.Events.Components.CreateEventArea; namespace EventHub.Web.Pages.Events.Components.CreateEventArea;
@ -62,25 +64,7 @@ public class CreateEventAreaViewComponent : AbpViewComponent
EndTime = DateTime.Now.ClearTime().AddDays(2).AddHours(21) EndTime = DateTime.Now.ClearTime().AddDays(2).AddHours(21)
}; };
ViewData["StepType"] = stepType.ToString(); await FillViewDataAsync(stepType, model);
switch (stepType)
{
case ProgressStepType.NewEvent:
ViewData["Organizations"] = await GetOrganizationsSelectItemAsync();
ViewData["Countries"] = await GetCountriesSelectItemAsync();
ViewData["Languages"] = GetLanguagesSelectItem();
break;
case ProgressStepType.NewSession:
ViewData["Languages"] = GetLanguagesSelectItem();
break;
case ProgressStepType.Preview:
ViewData["OrganizationName"] = await GetOrganizationNameAsync(model.OrganizationId);
if (model.CountryId is not null)
{
ViewData["CountryName"] = await GetCountryNameAsync(model.CountryId!.Value);
}
break;
}
return View("~/Pages/Events/Components/CreateEventArea/Default.cshtml", model); return View("~/Pages/Events/Components/CreateEventArea/Default.cshtml", model);
} }
@ -141,6 +125,30 @@ public class CreateEventAreaViewComponent : AbpViewComponent
} }
).ToList(); ).ToList();
} }
private async Task FillViewDataAsync(ProgressStepType stepType, NewEventViewModel model)
{
ViewData["StepType"] = stepType.ToString();
switch (stepType)
{
case ProgressStepType.NewEvent:
ViewData["Organizations"] = await GetOrganizationsSelectItemAsync();
ViewData["Countries"] = await GetCountriesSelectItemAsync();
ViewData["Languages"] = GetLanguagesSelectItem();
break;
case ProgressStepType.NewSession:
ViewData["Languages"] = GetLanguagesSelectItem();
break;
case ProgressStepType.Preview:
ViewData["OrganizationName"] = await GetOrganizationNameAsync(model.OrganizationId);
if (model.CountryId is not null)
{
ViewData["CountryName"] = await GetCountryNameAsync(model.CountryId!.Value);
}
break;
}
}
public class NewEventViewModel public class NewEventViewModel
{ {

2
src/EventHub.Web/Pages/Events/Components/CreateEventArea/_previewSection.cshtml

@ -216,7 +216,7 @@
} }
</div> </div>
<div class="col-6 text-end"> <div class="col-6 text-end">
<button href="#" class="btn btn-success">Publish <i class="fa fa-arrow-right ms-2"></i></button> <button id="PublishButton" class="btn btn-success">Publish <i class="fa fa-arrow-right ms-2"></i></button>
</div> </div>
</div> </div>
</div> </div>

23
src/EventHub.Web/Pages/Events/Components/CreateEventArea/create-event-area.js

@ -33,8 +33,7 @@
FilFileInputChangeEventHandler(); FilFileInputChangeEventHandler();
if (eventIdInput.val().length === 36) { if (eventIdInput.val().length === 36) {
// TODO: Add organization in UppdateEventDto $('#OrganizationId').prop("disabled", true); // Once the Organization is selected, it cannot be changed again.
$('#OrganizationId').prop("disabled", true).removeAttr('name');
} }
$("#CreateEventForm").submit(function (e) { $("#CreateEventForm").submit(function (e) {
@ -75,9 +74,9 @@
if (eventIdInput.val().length === 36) { if (eventIdInput.val().length === 36) {
abp.notify.success('Updated event'); abp.notify.success('Updated event');
}else{ }else{
abp.notify.success('Created event as a draft'); abp.notify.success('Created event as a draft' , '', toastr.options.timeOut = 2500);
eventIdInput.val(response.id); eventIdInput.val(response.id);
eventUrlCodeInput.val(response.urlCode); eventUrlCodeInput.val(response.urlCode);
} }
SwitchToTrackCreation() SwitchToTrackCreation()
} }
@ -101,6 +100,8 @@
EditSessionEventHandler(); EditSessionEventHandler();
DeleteSessionButtonClickEventHandler(); DeleteSessionButtonClickEventHandler();
PublishEventButtonClickEventHandler();
PrevieousOrNextStepTransitionEventHandler() PrevieousOrNextStepTransitionEventHandler()
}; };
@ -179,6 +180,7 @@
function DeleteTrackButtonClickEventHandler() { function DeleteTrackButtonClickEventHandler() {
$('.delete-track-button').click(function (e) { $('.delete-track-button').click(function (e) {
e.preventDefault();
eventApiService.deleteTrack(eventIdInput.val(), this.id).then(function () { eventApiService.deleteTrack(eventIdInput.val(), this.id).then(function () {
abp.notify.success('Successfully deleted'); abp.notify.success('Successfully deleted');
FillFilter(stepType.NewTrack) FillFilter(stepType.NewTrack)
@ -224,6 +226,7 @@
function OpenEditSessionModalClickEventHandler() { function OpenEditSessionModalClickEventHandler() {
$('.edit-session-button').click(function (e) { $('.edit-session-button').click(function (e) {
e.preventDefault();
var editSessionModal = $('#EditSessionModal'); var editSessionModal = $('#EditSessionModal');
var clickedSessionId = this.id; var clickedSessionId = this.id;
@ -269,6 +272,7 @@
function DeleteSessionButtonClickEventHandler() { function DeleteSessionButtonClickEventHandler() {
$('.delete-session-button').click(function (e) { $('.delete-session-button').click(function (e) {
e.preventDefault();
var clickedSessionId = this.id; var clickedSessionId = this.id;
var trackId = $('#' + clickedSessionId).data('track-id'); var trackId = $('#' + clickedSessionId).data('track-id');
@ -280,6 +284,17 @@
}); });
} }
function PublishEventButtonClickEventHandler() {
$('#PublishButton').click(function (e) {
e.preventDefault();
eventApiService.publish(eventIdInput.val()).then(function (res) {
e.prefe
abp.notify.success('Event Published');
window.location.replace('https://' + window.location.host + '/events/' + res);
});
});
}
function PrevieousOrNextStepTransitionEventHandler() { function PrevieousOrNextStepTransitionEventHandler() {
$('.step-transition').click(function (e) { $('.step-transition').click(function (e) {
var clickedButtonId = this.id; var clickedButtonId = this.id;

5
src/EventHub.Web/Pages/Events/New.cshtml

@ -6,10 +6,7 @@
@model EventHub.Web.Pages.Events.NewPageModel @model EventHub.Web.Pages.Events.NewPageModel
@section scripts { @section scripts {
<abp-script-bundle> <abp-script src="/libs/awesomplete/awesomplete.min.js" />
<abp-script src="/Pages/Events/New.js"/>
<abp-script src="/libs/awesomplete/awesomplete.min.js" />
</abp-script-bundle>
} }
@section styles { @section styles {

0
src/EventHub.Web/Pages/Events/New.js

Loading…
Cancel
Save