v1.1.4.0
This commit is contained in:
@@ -159,6 +159,18 @@
|
||||
<data name="activity.caption.activity" xml:space="preserve">
|
||||
<value>Activity</value>
|
||||
</data>
|
||||
<data name="article.caption.article" xml:space="preserve">
|
||||
<value>Article</value>
|
||||
</data>
|
||||
<data name="article.caption.article.create" xml:space="preserve">
|
||||
<value>Create Article</value>
|
||||
</data>
|
||||
<data name="article.caption.article.update" xml:space="preserve">
|
||||
<value>Update Article</value>
|
||||
</data>
|
||||
<data name="article.caption.articles" xml:space="preserve">
|
||||
<value>Articles</value>
|
||||
</data>
|
||||
<data name="company.name" xml:space="preserve">
|
||||
<value>Solum Forti</value>
|
||||
</data>
|
||||
@@ -198,18 +210,6 @@
|
||||
<data name="home.organisation.request.para2" xml:space="preserve">
|
||||
<value>Sign-up now with a few details and we'll let you know when you can login and get going.</value>
|
||||
</data>
|
||||
<data name="journalist.caption.article" xml:space="preserve">
|
||||
<value>Article</value>
|
||||
</data>
|
||||
<data name="journalist.caption.article.create" xml:space="preserve">
|
||||
<value>Create Article</value>
|
||||
</data>
|
||||
<data name="journalist.caption.article.update" xml:space="preserve">
|
||||
<value>Update Article</value>
|
||||
</data>
|
||||
<data name="journalist.caption.articles" xml:space="preserve">
|
||||
<value>Articles</value>
|
||||
</data>
|
||||
<data name="label.account" xml:space="preserve">
|
||||
<value>My Account</value>
|
||||
</data>
|
||||
|
||||
@@ -88,10 +88,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
String messageTitle = Localiser["account.caption.profile.contact"];
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Retrieve user details.
|
||||
SaxUserAccount userAccount = AccountMgr.GetUserAccountById(SessionData.User.UserAccountId);
|
||||
@@ -140,10 +139,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
String messageTitle = Localiser["account.caption.profile.contact"];
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Validate number of images.
|
||||
if (model.AccountContactImage.IsEmpty())
|
||||
@@ -229,10 +227,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
String messageTitle = Localiser["account.caption.profile.contact"];
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Validate data.
|
||||
model.ValidateContactDetails(responseData);
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Query organisations that user is a member of.
|
||||
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
|
||||
|
||||
@@ -75,10 +75,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
String messageTitle = Localiser["account.caption.profile.sports"];
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Item filter.
|
||||
SaxUserSport.Params prmUserSport = new SaxUserSport.Params();
|
||||
@@ -153,10 +152,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_ProfileSport responseData = new AjaxResponse_ProfileSport(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Identify item.
|
||||
SysId userSportId = model.UserSportId.ToSysId();
|
||||
@@ -197,10 +195,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_ProfileSport responseData = new AjaxResponse_ProfileSport(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Validate item properties.
|
||||
model.ValidateProfileSportData(responseData);
|
||||
|
||||
@@ -11,6 +11,7 @@ using Saxonite.Net.Core.Web.Online.Models;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Bus;
|
||||
using Saxonite.Net.Standard.Base.Consoles;
|
||||
using Saxonite.Net.Standard.Base.Mgr;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -49,16 +50,16 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
/// <summary>Article activity info. </summary>
|
||||
private class ActivityResponseData_Article
|
||||
{
|
||||
public ActivityResponseData_Article(SaxController_Online controller, SaxModel_Online model, SaxJournalistArticle article)
|
||||
public ActivityResponseData_Article(SaxController_Online controller, SaxModel_Online model, SaxArticle article)
|
||||
{
|
||||
Author = model.GetUserAccountDisplayName(article.UserAccountIdJournalist);
|
||||
Author = model.GetUserAccountDisplayName(article.UserAccountIdAuthor);
|
||||
Headline = article.Headline;
|
||||
Summary = article.Summary;
|
||||
Sport = model.GetSportCaption(article.SportIdPrimary);
|
||||
Region = model.GetRegionCaption(article.RegionIdPrimary);
|
||||
PublishedOnFmt = model.Localiser.FormatDate(article.PublishedAt);
|
||||
SaxJournalistArticle.ContentData content = SaxJournalistArticle.ExtractContent(article.BodyData);
|
||||
foreach (SaxJournalistArticle.ContentData.SegmentData segment in content.Segments)
|
||||
SaxArticle.ContentData content = SaxArticle.ExtractContent(article.BodyData);
|
||||
foreach (SaxArticle.ContentData.SegmentData segment in content.Segments)
|
||||
Content.Segments.Add(new ContentData.SegmentData(controller, segment));
|
||||
}
|
||||
public String Organisation { get; set; }
|
||||
@@ -72,7 +73,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
{
|
||||
public class SegmentData
|
||||
{
|
||||
public SegmentData(SaxController_Online controller, SaxJournalistArticle.ContentData.SegmentData segment)
|
||||
public SegmentData(SaxController_Online controller, SaxArticle.ContentData.SegmentData segment)
|
||||
{
|
||||
if (segment.Body.IsValid())
|
||||
{
|
||||
@@ -82,7 +83,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
else if (segment.Image.IsValid())
|
||||
{
|
||||
Image = new ImageData();
|
||||
Image.Link = JournalistController.GetArticleImageLink(controller, segment.Image.ItemImageId);
|
||||
Image.Link = ArticleController.GetArticleImageLink(controller, segment.Image.ItemImageId);
|
||||
}
|
||||
}
|
||||
public class BodyData
|
||||
@@ -140,10 +141,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_ActivityList responseData = new AjaxResponse_ActivityList();
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
SaxSessionData_Online sessionData = SessionData_Online;
|
||||
|
||||
// User context.
|
||||
@@ -167,12 +167,14 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
activityItemIds.Add(itemData.ItemId);
|
||||
ActivityResponseData activityData = new ActivityResponseData();
|
||||
activityData.ItemType = itemData.ItemId.Type;
|
||||
if (itemData.ItemId.Type == (int)Sax.DataItemType.JournalistArticle)
|
||||
if (itemData.ItemId.Type == (int)Sax.DataItemType.Article)
|
||||
activityData.ItemTypeClass = "Article";
|
||||
else if (itemData.ItemId.Type == (int)Sax.DataItemType.OrganisationOpportunity)
|
||||
activityData.ItemTypeClass = "Opportunity";
|
||||
// ToDo Mask activity index Id with cross-reference stored in session data.
|
||||
activityData.ItemIdx = SysId.ToLong(itemData.ItemId.Id);
|
||||
activityData.Organisation = itemData.Organisation;
|
||||
activityData.Author = itemData.Author;
|
||||
activityData.Caption = itemData.Caption;
|
||||
activityData.Blurb = itemData.Blurb;
|
||||
activityData.Sport = Localiser.GetSportName(itemData.SportId, itemData.SportName);
|
||||
@@ -211,10 +213,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_ActivityInfo responseData = new AjaxResponse_ActivityInfo();
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
SaxSessionData_Online sessionData = SessionData_Online;
|
||||
|
||||
// Identify activity.
|
||||
@@ -222,18 +223,18 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
SysId itemId = model.ActivityIdx.ToSysId();
|
||||
if (itemType <= 0 || !SysId.IsValid(itemId))
|
||||
{
|
||||
SaLogger.Warn(fn + " Activity type/Id inncorrectly specified." + getLogSuffix());
|
||||
SaLogger.Warn(fn + " Activity type/Id inncorrectly specified." + GetLogSuffix());
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
// Retrieve activity details.
|
||||
if (itemType == Sax.DataItemType.JournalistArticle)
|
||||
if (itemType == Sax.DataItemType.Article)
|
||||
{
|
||||
// Journalist article.
|
||||
SaxJournalistArticle article = ActivityMgr.GetJournalistArticleById(itemId);
|
||||
// Article.
|
||||
SaxArticle article = ActivityMgr.GetArticleById(itemId);
|
||||
if (article == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Article not found for Activity Id: " + itemId.ToString() + "." + getLogSuffix());
|
||||
SaLogger.Warn(fn + " Article not found for Activity Id: " + itemId.ToString() + "." + GetLogSuffix());
|
||||
return Json(responseData);
|
||||
}
|
||||
responseData.Article = new ActivityResponseData_Article(this, model, article);
|
||||
@@ -244,7 +245,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
SaxOrganisationOpportunity opportunity = ActivityMgr.GetOrganisationOpportunityById(itemId);
|
||||
if (opportunity == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Opportunity not found for Activity Id: " + itemId.ToString() + "." + getLogSuffix());
|
||||
SaLogger.Warn(fn + " Opportunity not found for Activity Id: " + itemId.ToString() + "." + GetLogSuffix());
|
||||
return Json(responseData);
|
||||
}
|
||||
responseData.Opportunity = new ActivityResponseData_Opportunity(model, opportunity);
|
||||
@@ -253,7 +254,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// Record activty viewing.
|
||||
if (!ActivityConsole.RecordUserActivityViewed(SessionData.User.UserAccountId, new ItemId((short)itemType, itemId), DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to record Activity Viewing: " + ActivityConsole.ErrorStateMessage + "." + getLogSuffix());
|
||||
SaLogger.Warn(fn + " Failed to record Activity Viewing: " + ActivityConsole.ErrorStateMessage + "." + GetLogSuffix());
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
@@ -280,10 +281,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_ActivityReaction responseData = new AjaxResponse_ActivityReaction();
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
SaxSessionData_Online sessionData = SessionData_Online;
|
||||
|
||||
// Identify activity.
|
||||
@@ -291,14 +291,14 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
SysId itemId = model.ActivityIdx.ToSysId();
|
||||
if (itemType <= 0 || !SysId.IsValid(itemId))
|
||||
{
|
||||
SaLogger.Warn(fn + " Activity type/Id inncorrectly specified." + getLogSuffix());
|
||||
SaLogger.Warn(fn + " Activity type/Id inncorrectly specified." + GetLogSuffix());
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
// Record activity reaction.
|
||||
if (!ActivityConsole.RecordUserActivityReaction(SessionData.User.UserAccountId, new ItemId((short)itemType, itemId), model.GetActivityReaction(), DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to record Activity Reaction: " + ActivityConsole.ErrorStateMessage + "." + getLogSuffix());
|
||||
SaLogger.Warn(fn + " Failed to record Activity Reaction: " + ActivityConsole.ErrorStateMessage + "." + GetLogSuffix());
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
|
||||
+138
-55
@@ -11,6 +11,7 @@ using Saxonite.Net.Core.Web.Online.Models;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Bus;
|
||||
using Saxonite.Net.Standard.Base.Consoles;
|
||||
using Saxonite.Net.Standard.Base.Mgr;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
@@ -21,12 +22,12 @@ using System.Threading.Tasks;
|
||||
namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
{
|
||||
//=======================================================================
|
||||
// Online Journalist Controller - Ajax actions.
|
||||
// Online Article Controller - Ajax actions.
|
||||
//=======================================================================
|
||||
partial class JournalistController
|
||||
partial class ArticleController
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Journalist Article Content data.
|
||||
// Article Content data.
|
||||
private class ArticleContentData
|
||||
{
|
||||
public List<ArticleContentSegmentData> Segments { get; } = new List<ArticleContentSegmentData>();
|
||||
@@ -48,10 +49,11 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Journalist Article data.
|
||||
// Article data.
|
||||
private class ArticleData_List
|
||||
{
|
||||
public String Id { get; set; }
|
||||
public String OrganisationId { get; set; }
|
||||
public String Headline { get; set; }
|
||||
public String Summary { get; set; }
|
||||
public String RegionCaptionPrimary { get; set; }
|
||||
@@ -70,9 +72,10 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
public String PublishedOn_Calendar { get; set; }
|
||||
public ArticleContentData Content { get; } = new ArticleContentData();
|
||||
}
|
||||
private void PopulateArticleResponseData(Model_Journalist model, SaxJournalistArticle article, ArticleData_List data)
|
||||
private void PopulateArticleResponseData(Model_Article model, SaxArticle article, ArticleData_List data)
|
||||
{
|
||||
data.Id = SysId.ToString(article.Id);
|
||||
data.OrganisationId = SysId.ToString(article.OrganisationId);
|
||||
data.Headline = article.Headline;
|
||||
data.Summary = article.Summary;
|
||||
data.RegionCaptionPrimary = model.GetRegionCaption(article.RegionIdPrimary);
|
||||
@@ -82,7 +85,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
data.StatusCode = article.StatusCode;
|
||||
data.StatusDesc = article.StatusDesc;
|
||||
}
|
||||
private void PopulateArticleResponseData(Model_Journalist model, SaxJournalistArticle article, ArticleData_Full data)
|
||||
private void PopulateArticleResponseData(Model_Article model, SaxArticle article, ArticleData_Full data)
|
||||
{
|
||||
PopulateArticleResponseData(model, article, data as ArticleData_List);
|
||||
data.RegionIdPrimary = SysId.ToString(article.RegionIdPrimary);
|
||||
@@ -92,7 +95,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
data.PublishedOn_Calendar = model.FormatDateForForm(article.PublishedAt);
|
||||
|
||||
// Article content.
|
||||
SaxJournalistArticle.ContentData articleContent = SaxJournalistArticle.ExtractContent(article.BodyData);
|
||||
SaxArticle.ContentData articleContent = SaxArticle.ExtractContent(article.BodyData);
|
||||
foreach (var contentSegment in articleContent.Segments)
|
||||
{
|
||||
var segmentData = new ArticleContentSegmentData();
|
||||
@@ -114,48 +117,83 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
//-------------------------------------------------------------------
|
||||
// Get Article List ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
private class OrganisationData : AjaxResponse_Data.ItemIdName { }
|
||||
private class AjaxResponse_ArticleList : AjaxResponse_Data
|
||||
{
|
||||
// Construction.
|
||||
public AjaxResponse_ArticleList(SaxModel_Online model) : base(model) { }
|
||||
// Article list.
|
||||
public List<ArticleData_List> Articles { get; } = new List<ArticleData_List>();
|
||||
/// <summary>Organisations that the user has rights to author articles for.</summary>
|
||||
public List<OrganisationData> Organisations { get; set; }
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Journalist/Ajax/GetArticleList")]
|
||||
public IActionResult Ajax_GetArticleList(Model_Journalist model)
|
||||
[Route("Article/Ajax/GetList")]
|
||||
[Route("Article/Ajax/GetArticles")]
|
||||
public IActionResult Ajax_GetArticleList(Model_Article model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_GetArticleList";
|
||||
String messageTitle = Localiser["journalist.caption.articles"];
|
||||
String messageTitle = Localiser["article.caption.articles"];
|
||||
AjaxResponse_ArticleList responseData = new AjaxResponse_ArticleList(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!UserIsJournalist) return GetAjaxResult_GoHome(responseData);
|
||||
SaxSessionData_Online sessionData = SessionData_Online;
|
||||
SysId userAccountId = SessionData.User.UserAccountId;
|
||||
RefreshModel(model);
|
||||
|
||||
// Organisations that the user has rights to author articles for.
|
||||
foreach (SaxAccountMgr.OrganisationIdName organisation in AccountMgr.GetOrganisationsForUserRole(userAccountId, Sax.OrganisationRole.ArticleAdmin))
|
||||
{
|
||||
if (responseData.Organisations == null) responseData.Organisations = new List<OrganisationData>();
|
||||
OrganisationData organisationData = new OrganisationData()
|
||||
{
|
||||
Id = model.EncryptId(organisation.Id),
|
||||
Name = organisation.Name
|
||||
};
|
||||
responseData.Organisations.Add(organisationData);
|
||||
}
|
||||
|
||||
// User must either be a journalist or allowed to author organisation articles.
|
||||
if (!UserIsJournalist && responseData.Organisations == null) return GetAjaxResult_GoHome(responseData);
|
||||
if (UserIsJournalist && responseData.Organisations != null)
|
||||
{
|
||||
OrganisationData organisationData = new OrganisationData()
|
||||
{
|
||||
Id = "",
|
||||
Name = "No Organisation - Journalist Articles"
|
||||
};
|
||||
responseData.Organisations.Insert(0, organisationData);
|
||||
}
|
||||
|
||||
// Filter organisation.
|
||||
SysId organisationIdFilter = model.ExtractSysId(model.Filter.OrganisationId);
|
||||
|
||||
// Item filter.
|
||||
SaxJournalistArticle.Params prmArticle = new SaxJournalistArticle.Params();
|
||||
prmArticle.UserAccountIdsJournalistIncluded.Add(sessionData.User.UserAccountId);
|
||||
SaxArticle.Params prmArticle = new SaxArticle.Params();
|
||||
prmArticle.UserAccountIdsAuthorIncluded.Add(sessionData.User.UserAccountId);
|
||||
if (SysId.IsValid(organisationIdFilter))
|
||||
prmArticle.OrganisationIdsIncluded.Add(organisationIdFilter);
|
||||
prmArticle.ArticleFilter = model.Filter.Article;
|
||||
prmArticle.StatusCat = SaxJournalistArticle.StatusCat.NotDeleted;
|
||||
model.Paging.ItemTotal = (ulong)ActivityMgr.GetJournalistArticleCount(prmArticle);
|
||||
prmArticle.StatusCat = SaxArticle.StatusCat.NotDeleted;
|
||||
model.Paging.ItemTotal = (ulong)ActivityMgr.GetArticleCount(prmArticle);
|
||||
model.PopulatePagingTo(prmArticle.ResultsPaging);
|
||||
|
||||
// Item columns.
|
||||
ColumnDfn colId = ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.Id);
|
||||
ColumnDfn colHeadline = ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.Headline);
|
||||
ColumnDfn colSummary = ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.Summary);
|
||||
ColumnDfn colRegionIdPrimary = ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.RegionIdPrimary);
|
||||
ColumnDfn colSportIdPrimary = ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.SportIdPrimary);
|
||||
ColumnDfn colPublishedOn = ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.PublishedAt_Date);
|
||||
ColumnDfn colStatus = ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.Status);
|
||||
ColumnDfn colCreatedOn = ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.CreateOn_Date);
|
||||
ColumnDfn colId = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Id);
|
||||
ColumnDfn colOrganisationId = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.OrganisationId);
|
||||
ColumnDfn colHeadline = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Headline);
|
||||
ColumnDfn colSummary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Summary);
|
||||
ColumnDfn colRegionIdPrimary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.RegionIdPrimary);
|
||||
ColumnDfn colSportIdPrimary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.SportIdPrimary);
|
||||
ColumnDfn colPublishedOn = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.PublishedAt_Date);
|
||||
ColumnDfn colStatus = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Status);
|
||||
ColumnDfn colCreatedOn = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.CreateOn_Date);
|
||||
List<ColumnDfn> columns = new List<ColumnDfn>()
|
||||
{
|
||||
colId, colHeadline, colSummary,
|
||||
colId, colOrganisationId, colHeadline, colSummary,
|
||||
colRegionIdPrimary, colSportIdPrimary, colPublishedOn,
|
||||
colStatus, colCreatedOn
|
||||
};
|
||||
@@ -165,7 +203,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
prmArticle.SortColumns.Add(colCreatedOn);
|
||||
|
||||
// Query items.
|
||||
using (DbResultSet resultSet = ActivityMgr.ExecuteJournalistArticleQuery(columns, prmArticle))
|
||||
using (DbResultSet resultSet = ActivityMgr.ExecuteArticleQuery(columns, prmArticle))
|
||||
{
|
||||
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
|
||||
{
|
||||
@@ -173,6 +211,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
ArticleData_List articleData = new ArticleData_List()
|
||||
{
|
||||
Id = values.GetString(colId.DataName),
|
||||
OrganisationId = values.GetString(colOrganisationId.DataName),
|
||||
Headline = values.GetString(colHeadline.DataName),
|
||||
Summary = values.GetString(colSummary.DataName),
|
||||
RegionCaptionPrimary = model.GetRegionCaption(values.GetString(colRegionIdPrimary.DataName).ToSysId()),
|
||||
@@ -206,20 +245,20 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Journalist/Ajax/GetArticle")]
|
||||
public IActionResult Ajax_GetArticle(Model_Journalist model)
|
||||
[Route("Article/Ajax/Get")]
|
||||
[Route("Article/Ajax/GetItem")]
|
||||
[Route("Article/Ajax/GetArticle")]
|
||||
public IActionResult Ajax_GetArticle(Model_Article model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_GetArticle";
|
||||
String messageTitle = Localiser["journalist.caption.article"];
|
||||
String messageTitle = Localiser["article.caption.article"];
|
||||
AjaxResponse_Article responseData = new AjaxResponse_Article(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!UserIsJournalist)
|
||||
return GetAjaxResult_GoHome(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
SysId userAccountId = SessionData.User.UserAccountId;
|
||||
RefreshModel(model);
|
||||
|
||||
// Identify item.
|
||||
SysId articleId = model.ArticleId.ToSysId();
|
||||
@@ -227,16 +266,21 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
|
||||
|
||||
// Retrieve item.
|
||||
SaxJournalistArticle article = ActivityMgr.GetJournalistArticleById(articleId);
|
||||
SaxArticle article = ActivityMgr.GetArticleById(articleId);
|
||||
if (article == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve Journalist Article for Id: '" + model.ArticleId + "'");
|
||||
SaLogger.Warn(fn + " Failed to retrieve Article for Id: '" + model.ArticleId + "'");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||
}
|
||||
if (!article.UserAccountIdAuthor.Equals(userAccountId))
|
||||
{
|
||||
SaLogger.Warn(fn + " Inconsistent Article Author. Expected: " + userAccountId + ". Found: " + article.UserAccountIdAuthor);
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
|
||||
// Delete upload images.
|
||||
SaxItemImage.Params prmItemImage = new SaxItemImage.Params();
|
||||
prmItemImage.ItemIdsIncluded.Add(new ItemId((short)Sax.DataItemType.JournalistArticle, articleId));
|
||||
prmItemImage.ItemIdsIncluded.Add(new ItemId((short)Sax.DataItemType.Article, articleId));
|
||||
prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.ArticleUpload);
|
||||
prmItemImage.StatusCat = SaxItemImage.StatusCat.NotDeleted;
|
||||
foreach (SaxItemImage itemImage in ItemDataMgr.GetItemImageList(prmItemImage))
|
||||
@@ -254,7 +298,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Journalist - Upload Article Image.
|
||||
// Article - Upload Image.
|
||||
//-------------------------------------------------------------------
|
||||
private class AjaxResponse_UploadArticleImage : AjaxResponse_Data
|
||||
{
|
||||
@@ -266,17 +310,18 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
}
|
||||
// Ajax request.
|
||||
[HttpPost]
|
||||
[Route("Journalist/Ajax/UploadArticleImage")]
|
||||
public IActionResult UploadArticleImage(Model_Journalist model)
|
||||
[Route("Article/Ajax/UploadImage")]
|
||||
public IActionResult UploadArticleImage(Model_Article model)
|
||||
{
|
||||
String fn = GetType().Name + ".UploadArticleImage";
|
||||
AjaxResponse_UploadArticleImage responseData = new AjaxResponse_UploadArticleImage(model);
|
||||
String messageTitle = Localiser["journalist.caption.article"];
|
||||
String messageTitle = Localiser["article.caption.article"];
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
SaxSessionData_Online sessionData = SessionData_Online;
|
||||
RefreshModel(model);
|
||||
|
||||
// Validate number of images.
|
||||
if (model.ArticleImage.IsEmpty())
|
||||
@@ -307,7 +352,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// Image belongs to the article.
|
||||
// If the article doesn't yet exist, it will need to be uploaded to the user first and later transferred.
|
||||
SysId articleId = model.ArticleId.ToSysId();
|
||||
ItemId articleItemId = new ItemId((short)Sax.DataItemType.JournalistArticle, articleId);
|
||||
ItemId articleItemId = new ItemId((short)Sax.DataItemType.Article, articleId);
|
||||
ItemId userItemId = new ItemId((short)Sax.DataItemType.UserAccount, sessionData.User.UserAccountId);
|
||||
ItemId imageItemId = SysId.IsValid(articleId) ? articleItemId : userItemId;
|
||||
|
||||
@@ -369,35 +414,59 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
}
|
||||
public static String GetArticleImageLink(SaxController_Online controller, SysId itemImageId)
|
||||
{
|
||||
String imageLink = "Image/Journalist/Article?";
|
||||
String imageLink = "Image/Article?";
|
||||
NameValueCollection parameters = new NameValueCollection();
|
||||
parameters.Add(ImageController.ParamName_ItemImageId, SysId.ToString(itemImageId));
|
||||
return imageLink + ImageController.ParamName_JournalistArticleImageEncrypted + "=" + SaxController_Online.EncryptOnlineParams(controller, parameters);
|
||||
return imageLink + ImageController.ParamName_ArticleImageEncrypted + "=" + SaxController_Online.EncryptOnlineParams(controller, parameters);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Store Article ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Journalist/Ajax/StoreArticle")]
|
||||
public IActionResult Ajax_StoreArticle(Model_Journalist model)
|
||||
[Route("Article/Ajax/Store")]
|
||||
[Route("Article/Ajax/StoreItem")]
|
||||
[Route("Article/Ajax/StoreArticle")]
|
||||
public IActionResult Ajax_StoreArticle(Model_Article model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_StoreArticle";
|
||||
String messageTitle = Localiser["journalist.caption.article"];
|
||||
String messageTitle = Localiser["article.caption.article"];
|
||||
AjaxResponse_Article responseData = new AjaxResponse_Article(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!UserIsJournalist) return GetAjaxResult_GoHome(responseData);
|
||||
SaxSessionData_Online sessionData = SessionData_Online;
|
||||
RefreshModel(model);
|
||||
|
||||
// Validate item properties.
|
||||
model.ValidateArticleData(responseData);
|
||||
if (responseData.HasControlErrors())
|
||||
return Json(responseData);
|
||||
|
||||
// Validate Article against Id against 'Exists' flag.
|
||||
// Validate User & Organisation.
|
||||
SysId userAccountId = SessionData.User.UserAccountId;
|
||||
SysId organisationId = model.ExtractSysId(model.ArticleOrganisationId);
|
||||
if (SysId.IsValid(organisationId))
|
||||
{
|
||||
// Organisation specified - User must have Article Admin role.
|
||||
if (!AccountMgr.UserHasOrganisationRole(userAccountId, organisationId, Sax.OrganisationRole.ArticleAdmin))
|
||||
{
|
||||
SaLogger.Warn(fn + " User does not have Article Admin role for organisation." + GetLogSuffix());
|
||||
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Organisation not specified - User must be a Journalist.
|
||||
if (!UserIsJournalist)
|
||||
{
|
||||
SaLogger.Warn(fn + " User is not a Journalist for non-organisation article." + GetLogSuffix());
|
||||
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
}
|
||||
|
||||
// Validate item Id against 'Exists' flag.
|
||||
SysId articleId = model.ArticleId.ToSysId();
|
||||
bool articleExists = StringUtil.ToBool(model.ArticleExists);
|
||||
if (articleExists && !SysId.IsValid(articleId))
|
||||
@@ -412,16 +481,30 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
}
|
||||
|
||||
// Retrieve existing item.
|
||||
SaxJournalistArticle article = ActivityMgr.GetJournalistArticleById(articleId);
|
||||
SaxArticle article = ActivityMgr.GetArticleById(articleId);
|
||||
if (article == null && SysId.IsValid(articleId))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve article for Id: '" + model.ArticleId + "'");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||
}
|
||||
if (article != null)
|
||||
{
|
||||
// Validate existing article.
|
||||
if (SysId.ToLong(article.UserAccountIdAuthor) != SysId.ToLong(userAccountId))
|
||||
{
|
||||
SaLogger.Warn(fn + " Inconsistent Article Author." + GetLogSuffix());
|
||||
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
if (SysId.ToLong(article.OrganisationId) != SysId.ToLong(organisationId))
|
||||
{
|
||||
SaLogger.Warn(fn + " Inconsistent Article Organisation." + GetLogSuffix());
|
||||
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
}
|
||||
|
||||
// Create new item if required.
|
||||
if (article == null)
|
||||
article = ActivityMgr.CreateJournalistArticle(sessionData.User.UserAccountId);
|
||||
article = ActivityMgr.CreateArticle(sessionData.User.UserAccountId, organisationId);
|
||||
|
||||
// Populate item properties.
|
||||
if (model.ArticleRegionId != null)
|
||||
@@ -451,7 +534,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// If Article doesn't yet exist, create it now so that images can be assigned.
|
||||
if (!SysId.IsValid(article.Id))
|
||||
{
|
||||
if (!ActivityMgr.InsertJournalistArticle(article, DbUpdateInfo))
|
||||
if (!ActivityMgr.InsertArticle(article, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to insert article: " + ActivityMgr.ErrorStateMessage);
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"]));
|
||||
@@ -461,7 +544,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// Content.
|
||||
if (model.ArticleContentSegmentBodies != null)
|
||||
{
|
||||
SaxJournalistArticle.ContentData articleContent = new SaxJournalistArticle.ContentData();
|
||||
SaxArticle.ContentData articleContent = new SaxArticle.ContentData();
|
||||
for (int segmentIdx = 0; segmentIdx < model.ArticleContentSegmentBodies.Count; segmentIdx++)
|
||||
{
|
||||
String segmentBody = model.ArticleContentSegmentBodies[segmentIdx];
|
||||
@@ -505,11 +588,11 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
SaLogger.Warn(fn + " Failed to identify article image. ItemImageId: " + itemImageId.ToInt() + ". SessionIdx: " + sessionData.SessionIdx + ". ImageIdx: " + imageIdx + ".");
|
||||
}
|
||||
}
|
||||
article.BodyData = SaxJournalistArticle.GetContentData(articleContent);
|
||||
article.BodyData = SaxArticle.GetContentData(articleContent);
|
||||
}
|
||||
|
||||
// Update the Article.
|
||||
if (!ActivityMgr.UpdateJournalistArticle(article, DbUpdateInfo))
|
||||
if (!ActivityMgr.UpdateArticle(article, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to update article [Id:" + SysId.ToString(article.Id) + "]: " + ActivityMgr.ErrorStateMessage);
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"]));
|
||||
+20
-17
@@ -1,7 +1,11 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Saxonite.Net.Core.Web.Base.App;
|
||||
using Saxonite.Net.Core.Web.Online.Models;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Bus;
|
||||
using Saxonite.Net.Standard.Base.Mgr;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -12,11 +16,11 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
//=======================================================================
|
||||
// Online Journalist Controller.
|
||||
//=======================================================================
|
||||
public partial class JournalistController : SaxController_Online
|
||||
public partial class ArticleController : SaxController_Online
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public JournalistController(SaxLocaliser localiser, ILogger<HomeController> logger) :
|
||||
public ArticleController(SaxLocaliser localiser, ILogger<HomeController> logger) :
|
||||
base(localiser, logger)
|
||||
{
|
||||
}
|
||||
@@ -26,25 +30,24 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
public IActionResult Index()
|
||||
{
|
||||
// Validate session.
|
||||
if (!ValidUserSession || !UserIsJournalist)
|
||||
if (!ValidUserSession)
|
||||
return RedirectToAction("", "");
|
||||
|
||||
// No 'Index' view as yet - default to 'Articles' view.
|
||||
//Model_Journalist model = new Model_Journalist(Localiser);
|
||||
//return View(model);
|
||||
return RedirectToAction("Articles", "Journalist");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[HttpGet]
|
||||
public IActionResult Articles()
|
||||
{
|
||||
// Validate session.
|
||||
if (!ValidUserSession || !UserIsJournalist)
|
||||
// User must either be a Journalist or have Article Admin rights with at least one organisation.
|
||||
List<SaxAccountMgr.OrganisationIdName> organisations = AccountMgr.GetOrganisationsForUserRole(SessionData.User.UserAccountId, Sax.OrganisationRole.ArticleAdmin);
|
||||
if (organisations.Count < 1 && !UserIsJournalist)
|
||||
return RedirectToAction("", "");
|
||||
|
||||
// Paging.
|
||||
Model_Journalist model = new Model_Journalist(Localiser);
|
||||
// Model.
|
||||
Model_Article model = new Model_Article(Localiser);
|
||||
model.UserCanAuthorOrganisationArticles = organisations.Count > 0;
|
||||
model.UserCanAuthorJournalistArticles = UserIsJournalist;
|
||||
if (organisations.Count > 0)
|
||||
{
|
||||
// Default filter to first organisation.
|
||||
model.Filter.OrganisationId = model.EncryptId(organisations[0].Id);
|
||||
model.Filter.OrganisationCaption = organisations[0].Name;
|
||||
}
|
||||
model.Paging.PageNo = 1;
|
||||
model.Paging.PageLength = 6;
|
||||
|
||||
@@ -92,10 +92,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
String fn = GetType().Name + ".GetAccountContactImage";
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return Forbid();
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return Forbid();
|
||||
ItemId userItemId = new ItemId((short)Sax.DataItemType.UserAccount, userAccountId);
|
||||
|
||||
// Retrieve account contact images.
|
||||
@@ -120,28 +118,29 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Journalist Article image
|
||||
// Article image
|
||||
//-------------------------------------------------------------------
|
||||
public static String ParamName_JournalistArticleImageEncrypted { get; } = "jaie";
|
||||
public static String ParamName_ArticleImageEncrypted { get; } = "aie";
|
||||
public static String ParamName_ItemImageId { get; } = "iii";
|
||||
/// <summary>
|
||||
/// Get the specified Journalist Article Image.
|
||||
/// Get the specified Article Image.
|
||||
/// <para>Method parameter name (aie) must match name of encrypted parameter.</para>
|
||||
/// <para>Encrypted parameters:</para>
|
||||
/// <para>- iii: item Image Id.</para>
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
[Route("Image/Journalist/Article")]
|
||||
public IActionResult GetJournalistArticleImage(String jaie)
|
||||
[Route("Image/Article")]
|
||||
public IActionResult GetArticleImage(String aie)
|
||||
{
|
||||
String fn = GetType().Name + ".GetJournalistArticleImage";
|
||||
String fn = GetType().Name + ".GetArticleImage";
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return Forbid();
|
||||
ItemId userItemId = new ItemId((short)Sax.DataItemType.UserAccount, SessionData.User.UserAccountId);
|
||||
|
||||
// EXtract encrypted parameters.
|
||||
NameValueCollection parameters = ExtractOnlineParams(jaie);
|
||||
// Extract encrypted parameters.
|
||||
NameValueCollection parameters = ExtractOnlineParams(aie);
|
||||
if (parameters.Count<1) return Forbid();
|
||||
|
||||
// Item Image.
|
||||
|
||||
@@ -102,6 +102,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Organisation.
|
||||
SysId organisationId = model.Filter.OrganisationId.ToSysId();
|
||||
@@ -167,7 +168,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
NamedValue.Map values = resultSet.GetRecordValues();
|
||||
MemberData_List memberData = new MemberData_List()
|
||||
{
|
||||
Id = values.GetString(colId.DataName),
|
||||
Id = values.GetLong(colId.DataName).ToString(),
|
||||
UserAccountId = values.GetString(colUserAccountId.DataName),
|
||||
EmailAddress = values.GetString(colEmailAddress.DataName),
|
||||
DisplayName = AccountMgr.GetUserOrganisationDataValue(colDisplayName, values).ToString(),
|
||||
@@ -222,6 +223,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Identify item.
|
||||
SysId memberId = model.MemberId.ToSysId();
|
||||
@@ -295,6 +297,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Validate item properties.
|
||||
model.ValidateMemberData(responseData);
|
||||
@@ -519,6 +522,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Record disposable items as they are created so all can be disposed when needed.
|
||||
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
|
||||
@@ -609,6 +613,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
|
||||
// Replace dynamic tag for link back to change password page.
|
||||
SaEmailConsole.ReplaceDynamicEmailTag(emailData, "[#Link.RequestPassword]", SecurityController.GenerateRequestPasswordLink(this, userAccount.Id, userAccount.EmailAddress, ""));
|
||||
SaEmailConsole.ReplaceDynamicEmailTag(emailData, "[#Link.SignIn]", GetRedirectLocation(RedirectLocation.WebAppBase) + "Security/SignIn");
|
||||
SaEmailConsole.ReplaceDynamicEmailTag(emailData, "[#Link.ExpiresMinutes]", SecurityController.GetRequestPasswordEmailLinkExpiresMinutes(this).ToString());
|
||||
}
|
||||
|
||||
@@ -633,6 +638,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Record disposable items as they are created so all can be disposed when needed.
|
||||
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
|
||||
|
||||
+10
-13
@@ -92,10 +92,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_OpportunityList responseData = new AjaxResponse_OpportunityList(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Organisation.
|
||||
SysId organisationId = model.Filter.OrganisationId.ToSysId();
|
||||
@@ -170,7 +169,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
NamedValue.Map values = resultSet.GetRecordValues();
|
||||
OpportunityData_List opportunityData = new OpportunityData_List()
|
||||
{
|
||||
Id = values.GetString(colId.DataName),
|
||||
Id = values.GetLong(colId.DataName).ToString(),
|
||||
TypeCode = values.GetString(colOpportunityTypeCode.DataName),
|
||||
TypeDesc = Localiser.GetOpportunityTypeCaption((Sax.OpportunityType)OpportunityTypeCodes.GetTypeForCode(values.GetString(colOpportunityTypeCode.DataName))),
|
||||
Position = values.GetString(colPosition.DataName),
|
||||
@@ -218,10 +217,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_Opportunity responseData = new AjaxResponse_Opportunity(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Identify item.
|
||||
SysId opportunityId = model.OpportunityId.ToSysId();
|
||||
@@ -271,10 +269,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_Opportunity responseData = new AjaxResponse_Opportunity(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Validate item properties.
|
||||
model.ValidateOpportunityData(responseData);
|
||||
|
||||
@@ -41,8 +41,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_RequestOrganisation responseData = new AjaxResponse_RequestOrganisation(model);
|
||||
|
||||
// Validate session and referrer. User does not need to be logged in.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidReferer) return Forbid();
|
||||
SaxSessionData_Online sessionData = SessionData_Online;
|
||||
|
||||
if (!model.ValidateOrganisationRequestData(responseData))
|
||||
@@ -52,13 +51,13 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
SaxRegion regionCountry = Internals.GetRegion(model.OrganisationRegionIdCountry.ToSysId());
|
||||
if (SysId.IsValid(model.OrganisationRegionIdCountry.ToSysId()) && regionCountry == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Country region not found. Id: " + model.OrganisationRegionIdCountry + ". " + getLogSuffix());
|
||||
SaLogger.Warn(fn + " Country region not found. Id: " + model.OrganisationRegionIdCountry + ". " + GetLogSuffix());
|
||||
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
SaxRegion regionProvince = Internals.GetRegion(model.OrganisationAddressRegionIdProvince.ToSysId());
|
||||
if (SysId.IsValid(model.OrganisationAddressRegionIdProvince.ToSysId()) && regionProvince == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Province region not found. Id: " + model.OrganisationAddressRegionIdProvince + ". " + getLogSuffix());
|
||||
SaLogger.Warn(fn + " Province region not found. Id: " + model.OrganisationAddressRegionIdProvince + ". " + GetLogSuffix());
|
||||
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
|
||||
@@ -71,7 +70,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
// hence 'System' error response and nothing more specific.
|
||||
if (!StringUtil.IsEmpty(model.ContactEmailAddress))
|
||||
{
|
||||
SaLogger.Warn(fn + " Contact Email supplied when user logged in. " + getLogSuffix());
|
||||
SaLogger.Warn(fn + " Contact Email supplied when user logged in. " + GetLogSuffix());
|
||||
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
// Retrieve user account.
|
||||
|
||||
@@ -52,10 +52,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_OrganisationList responseData = new AjaxResponse_OrganisationList(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Query columns.
|
||||
ColumnDfn colOrganisationId = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Id);
|
||||
@@ -126,10 +125,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_MemberOrganisationList responseData = new AjaxResponse_MemberOrganisationList(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Query columns.
|
||||
ColumnDfn colOrganisationId = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.OrganisationId);
|
||||
|
||||
@@ -43,8 +43,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_SportList responseData = new AjaxResponse_SportList();
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidReferer) return Forbid();
|
||||
// User doesn't have to be logged in, eg. to register organisation.
|
||||
//if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
|
||||
@@ -75,9 +74,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_RegionList responseData = new AjaxResponse_RegionList();
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
// User doesn't have to be logged in, eg. to register organisation.
|
||||
if (!ValidReferer) return Forbid();
|
||||
// User doesn't have to be logged in to query regions, eg. for organisation request.
|
||||
//if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
|
||||
// Populate regions.
|
||||
|
||||
@@ -258,7 +258,13 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
//-------------------------------------------------------------------
|
||||
// Logging.
|
||||
//-------------------------------------------------------------------
|
||||
protected String getLogSuffix()
|
||||
/// <summary>
|
||||
/// Log suffix:
|
||||
/// <para>- User's email address.</para>
|
||||
/// <para>- Prefixed with space.</para>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected String GetLogSuffix()
|
||||
{
|
||||
List<String> logSuffix = new List<string>();
|
||||
SaxSessionData_Online sessionData = SessionData_Online;
|
||||
|
||||
@@ -43,8 +43,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
String messageTitle = Localiser["signin.caption"];
|
||||
|
||||
// Validate referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidReferer) return Forbid();
|
||||
|
||||
// Validate Sign-in data.
|
||||
model.ValidateSignInData(responseData);
|
||||
@@ -81,10 +80,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
AjaxResponse_KeepLoggedIn responseData = new AjaxResponse_KeepLoggedIn();
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return Json(responseData.SetGoHome());
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return Json(responseData.SetGoHome());
|
||||
RefreshModel(model);
|
||||
|
||||
if (!AppConfig.Security.SignIn.KeepLoggedIn.Allowed)
|
||||
return Json(responseData);
|
||||
@@ -155,10 +153,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
String messageTitle = Localiser["signin.caption.signout"];
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return Json(responseData.SetSessionExpired(messageTitle, Localiser["security.msg.warn.sessionExpired"]));
|
||||
if (!ValidReferer) return Forbid();
|
||||
if (!ValidUserSession) return Json(responseData.SetSessionExpired(messageTitle, Localiser["security.msg.warn.sessionExpired"]));
|
||||
RefreshModel(model);
|
||||
|
||||
// Retrieve user account - in case sign-out needs to be recorded.
|
||||
SaxUserAccount userAccount = AccountMgr.GetUserAccountById(SessionData_Online.User.UserAccountId);
|
||||
@@ -194,8 +191,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
public ActionResult Ajax_ScorePassword(Model_Security model)
|
||||
{
|
||||
// Validate referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidReferer) return Forbid();
|
||||
|
||||
// No need to store the session data for this request.
|
||||
StoreSessionData = false;
|
||||
@@ -225,8 +221,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
String messageTitle = Localiser["security.caption.change.password"];
|
||||
|
||||
// Validate referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidReferer) return Forbid();
|
||||
|
||||
// If 'Request Password' encrypted params (from email link) are present,
|
||||
// Session is not required and password can be set directly against the user.
|
||||
@@ -324,8 +319,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
String messageTitle = Localiser["security.caption.request.password"];
|
||||
|
||||
// Validate referrer.
|
||||
if (!ValidReferer)
|
||||
return Forbid();
|
||||
if (!ValidReferer) return Forbid();
|
||||
|
||||
// Validate data.
|
||||
model.ValidateRequestPasswordData(responseData);
|
||||
@@ -378,11 +372,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
private static String ParamName_EmailAddress { get; } = "ema";
|
||||
private static String ParamName_ExpiresAt { get; } = "exp";
|
||||
private static String ParamName_Token { get; } = "tok";
|
||||
// NB IV value is generated from the key and fixed so that it doesn't change when the application restarts.
|
||||
// IV Must be regenerated if key is changed.
|
||||
private static String Base64Key_RequestPassword { get; } = SacsEncryptionHelper.EncodePlainKey("{~Saxonite@@Request^Password=}", SacsEncryptionHelper.KeyLength);
|
||||
private static String Base64IV_RequestPassword_Generated { get; } = SacsEncryptionHelper.InitSymmetricEncryptionIV(Base64Key_RequestPassword);
|
||||
private static String Base64IV_RequestPassword { get; } = "1VAWYTW6d72n/6HDNhbqow==";
|
||||
// Request Password encryption parameters (key & IV) are defined in the base Controller
|
||||
// so that they can be shared with the Adnin application.
|
||||
internal static String GenerateRequestPasswordLink(SaxController_Online controller, SysId userAccountId, String emailAddress, String requestPasswordToken)
|
||||
{
|
||||
NameValueCollection parameters = new NameValueCollection();
|
||||
@@ -392,7 +383,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
parameters.Add(ParamName_Token, requestPasswordToken);
|
||||
String link =
|
||||
controller.GetRedirectLocation(RedirectLocation.WebAppBase) + "Security/ChangePassword?" +
|
||||
ParamName_RequestPasswordEncrypted + "=" + HttpUtility.UrlEncode(controller.EncryptParameters(parameters, Base64IV_RequestPassword, Base64Key_RequestPassword));
|
||||
ParamName_RequestPasswordEncrypted + "=" + HttpUtility.UrlEncode(EncryptParameters(parameters, Base64IV_RequestPassword_Online, Base64Key_RequestPassword_Online));
|
||||
return link;
|
||||
}
|
||||
internal static int GetRequestPasswordEmailLinkExpiresMinutes(SaxController_Online controller)
|
||||
@@ -445,7 +436,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
RequestPasswordParams requestPasswordParams = new RequestPasswordParams();
|
||||
if (!StringUtil.IsEmpty(encryptedParams))
|
||||
{
|
||||
NameValueCollection linkParams = DecryptParameters(encryptedParams, Base64IV_RequestPassword, Base64Key_RequestPassword);
|
||||
NameValueCollection linkParams = DecryptParameters(encryptedParams, Base64IV_RequestPassword_Online, Base64Key_RequestPassword_Online);
|
||||
requestPasswordParams.UserAccountId = new SysId(StringUtil.ToInt(linkParams.Get(ParamName_UserAccountId)));
|
||||
requestPasswordParams.EmailAddress = linkParams.Get(ParamName_EmailAddress);
|
||||
requestPasswordParams.ExpiresAt = DateUtil.ParseXmlDateTime(linkParams.Get(ParamName_ExpiresAt));
|
||||
|
||||
+25
-9
@@ -15,29 +15,45 @@ using System.Threading.Tasks;
|
||||
namespace Saxonite.Net.Core.Web.Online.Models
|
||||
{
|
||||
//=======================================================================
|
||||
public class Model_Journalist : SaxModel_Online
|
||||
public class Model_Article : SaxModel_Online
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public Model_Journalist(SaxLocaliser localiser) :
|
||||
public Model_Article(SaxLocaliser localiser) :
|
||||
base(localiser)
|
||||
{
|
||||
AdditionalFiles_CSS.Add("css/sax-jrn-art.css");
|
||||
AdditionalFiles_JS.Add("js/sax-jrn-art.js");
|
||||
AdditionalFiles_CSS.Add("css/sax-art.css");
|
||||
AdditionalFiles_JS.Add("js/sax-art.js");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// List configuration.
|
||||
public class FilterData
|
||||
{
|
||||
public String OrganisationId { get; set; }
|
||||
public String OrganisationCaption { get; set; }
|
||||
public String Article { get; set; }
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
/// <summary>
|
||||
/// User has rights to author articles for at least one organisation.
|
||||
/// <para>- Output only - not returned with form data.</para>
|
||||
/// <para>- Only populated for initial page construction.</para>
|
||||
/// </summary>
|
||||
public bool UserCanAuthorOrganisationArticles { get; set; }
|
||||
/// <summary>
|
||||
/// User has rights to author articles as a journalist.
|
||||
/// <para>- Output only - not returned with form data.</para>
|
||||
/// <para>- Only populated for initial page construction.</para>
|
||||
/// </summary>
|
||||
public bool UserCanAuthorJournalistArticles { get; set; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Article properties.
|
||||
public String ArticleId { get; set; }
|
||||
public String ArticleExists { get; set; }
|
||||
// Organisation.
|
||||
public String ArticleOrganisationId { get; set; }
|
||||
// Sport.
|
||||
public String ArticleSportId { get; set; }
|
||||
public String ArticleSportCaption { get; set; }
|
||||
@@ -75,8 +91,8 @@ namespace Saxonite.Net.Core.Web.Online.Models
|
||||
responseData.SetControlValue(nameof(ArticleHeadline), ArticleHeadline);
|
||||
if (StringUtil.IsEmpty(ArticleHeadline))
|
||||
responseData.SetControlError(nameof(ArticleHeadline), Localiser["msg.validation.mandatory.value"]);
|
||||
else if (StringUtil.GetLength(ArticleHeadline) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Headline))
|
||||
responseData.SetControlError(nameof(ArticleHeadline), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Headline)]);
|
||||
else if (StringUtil.GetLength(ArticleHeadline) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Article_Headline))
|
||||
responseData.SetControlError(nameof(ArticleHeadline), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Article_Headline)]);
|
||||
}
|
||||
|
||||
// Article summary.
|
||||
@@ -85,8 +101,8 @@ namespace Saxonite.Net.Core.Web.Online.Models
|
||||
responseData.SetControlValue(nameof(ArticleSummary), ArticleSummary);
|
||||
if (StringUtil.IsEmpty(ArticleSummary))
|
||||
responseData.SetControlError(nameof(ArticleSummary), Localiser["msg.validation.mandatory.value"]);
|
||||
else if (StringUtil.GetLength(ArticleSummary) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Summary))
|
||||
responseData.SetControlError(nameof(ArticleSummary), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Summary)]);
|
||||
else if (StringUtil.GetLength(ArticleSummary) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Article_Summary))
|
||||
responseData.SetControlError(nameof(ArticleSummary), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Article_Summary)]);
|
||||
}
|
||||
|
||||
// Article sport.
|
||||
@@ -123,7 +139,7 @@ namespace Saxonite.Net.Core.Web.Online.Models
|
||||
{
|
||||
if (StringUtil.IsEmpty(ArticleStatusCode))
|
||||
responseData.SetControlError(nameof(ArticleStatusCode), Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SaxJournalistArticle.ValidStatuses.Contains(ArticleStatus))
|
||||
else if (!SaxArticle.ValidStatuses.Contains(ArticleStatus))
|
||||
responseData.SetControlError(nameof(ArticleStatusCode), Localiser["msg.validation.invalid.value"]);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using Saxonite.Net.Core.Web.Base.App;
|
||||
using Saxonite.Net.Core.Web.Base.Controllers;
|
||||
using Saxonite.Net.Core.Web.Base.Models;
|
||||
using Saxonite.Net.Core.Web.Online.App;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Bus;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -16,10 +21,9 @@ namespace Saxonite.Net.Core.Web.Online.Models
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private bool userCanManageOrganisationMembers = false;
|
||||
private bool userCanManageOrganisationMembersChecked = false;
|
||||
private bool userCanManageOrganisationOpportunities = false;
|
||||
private bool userCanManageOrganisationOpportunitiesChecked = false;
|
||||
private bool? userCanManageOrganisationMembers = null;
|
||||
private bool? userCanManageOrganisationArticles = null;
|
||||
private bool? userCanManageOrganisationOpportunities = null;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Protected construction.
|
||||
@@ -30,14 +34,19 @@ namespace Saxonite.Net.Core.Web.Online.Models
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Session.
|
||||
//-------------------------------------------------------------------
|
||||
public SaxSessionData_Online SessionData_Online { get { return SessionData as SaxSessionData_Online; } }
|
||||
// Menu options.
|
||||
public bool MembersAllowed { get { return UserCanManageOrganisationMembers; } }
|
||||
public bool ArticlesAllowed { get { return UserIsJournalist || UserCanManageOrganisationArticles; } }
|
||||
public bool OpportunitiesAllowed { get { return UserCanManageOrganisationOpportunities; } }
|
||||
// Security profile.
|
||||
public bool UserIsJournalist { get { return SessionData != null && SessionData.User != null && SessionData.User.IsJournalist; } }
|
||||
public bool UserCanManageOrganisationMembers
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!userCanManageOrganisationMembersChecked && ValidUserSession)
|
||||
if (userCanManageOrganisationMembers == null && ValidUserSession)
|
||||
{
|
||||
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
|
||||
prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId);
|
||||
@@ -45,16 +54,31 @@ namespace Saxonite.Net.Core.Web.Online.Models
|
||||
prmUserOrganisation.OrganisationRoles.Add(Sax.OrganisationRole.OpportunityAdmin);
|
||||
prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly;
|
||||
userCanManageOrganisationMembers = (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) > 0);
|
||||
userCanManageOrganisationMembersChecked = true;
|
||||
}
|
||||
return userCanManageOrganisationMembers;
|
||||
return userCanManageOrganisationMembers == true ? true : false;
|
||||
}
|
||||
}
|
||||
public bool UserCanManageOrganisationArticles
|
||||
{
|
||||
get
|
||||
{
|
||||
if (userCanManageOrganisationArticles == null && ValidUserSession)
|
||||
{
|
||||
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
|
||||
prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId);
|
||||
prmUserOrganisation.OrganisationMembersOnly = true;
|
||||
prmUserOrganisation.OrganisationRoles.Add(Sax.OrganisationRole.ArticleAdmin);
|
||||
prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly;
|
||||
userCanManageOrganisationArticles = (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) > 0);
|
||||
}
|
||||
return userCanManageOrganisationArticles == true ? true : false;
|
||||
}
|
||||
}
|
||||
public bool UserCanManageOrganisationOpportunities
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!userCanManageOrganisationOpportunitiesChecked && ValidUserSession)
|
||||
if (userCanManageOrganisationOpportunities == null && ValidUserSession)
|
||||
{
|
||||
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
|
||||
prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId);
|
||||
@@ -62,12 +86,57 @@ namespace Saxonite.Net.Core.Web.Online.Models
|
||||
prmUserOrganisation.OrganisationRoles.Add(Sax.OrganisationRole.OpportunityAdmin);
|
||||
prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly;
|
||||
userCanManageOrganisationOpportunities = (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) > 0);
|
||||
userCanManageOrganisationOpportunitiesChecked = true;
|
||||
}
|
||||
return userCanManageOrganisationOpportunities;
|
||||
return userCanManageOrganisationOpportunities == true ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Item Id Obfuscation.
|
||||
//-------------------------------------------------------------------
|
||||
public SysId ExtractSysId(String idx)
|
||||
{
|
||||
String fn = GetType().Name + ".ExtractSysId";
|
||||
if (StringUtil.IsEmpty(idx)) return null;
|
||||
|
||||
// Numeric values are assumed to be unencrypted Ids.
|
||||
if (StringUtil.IsNumeric(idx))
|
||||
return idx.ToSysId();
|
||||
|
||||
try
|
||||
{
|
||||
// Attempt to decrypt.
|
||||
SysId id = DecryptId(idx);
|
||||
if (SysId.IsValid(id))
|
||||
return id;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Warn(fn + " " + ExceptionUtil.GetErrorStateMessage(exc));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Id encryption.
|
||||
// To obfuscate Id values that are sent to and from the browser.
|
||||
// NB IV value can be reset evert time the application restarts.
|
||||
public static String Base64Key_IdObfuscation = SacsEncryptionHelper.EncodePlainKey("|SaxOnIte.Onl1n3-iD+0bfuscAtion|", SacsEncryptionHelper.KeyLength);
|
||||
public static String Base64IV_IdObfuscation = SacsEncryptionHelper.InitSymmetricEncryptionIV(Base64Key_IdObfuscation);
|
||||
public static String ParamName_IdObfuscation_Id { get; } = "iob";
|
||||
public String EncryptId(SysId id)
|
||||
{
|
||||
NameValueCollection idObfuscationParams = new NameValueCollection();
|
||||
idObfuscationParams.Add(ParamName_IdObfuscation_Id, SysId.ToString(id));
|
||||
return SaxController_Base.EncryptParameters(idObfuscationParams, Base64IV_IdObfuscation, Base64Key_IdObfuscation);
|
||||
}
|
||||
public SysId DecryptId(String encryptedParams)
|
||||
{
|
||||
NameValueCollection idObfuscationParams = SaxController_Base.DecryptParameters(encryptedParams, Base64IV_IdObfuscation, Base64Key_IdObfuscation);
|
||||
return idObfuscationParams.Get(ParamName_IdObfuscation_Id).ToSysId();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Reference Data.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
+14
-2
@@ -1,4 +1,4 @@
|
||||
@model Model_Journalist
|
||||
@model Model_Article
|
||||
@inject SaxLocaliser Localiser
|
||||
@{
|
||||
ViewData["Title"] = "Journalist - Articles";
|
||||
@@ -10,7 +10,7 @@
|
||||
{
|
||||
<div class="sax-panel-filter">
|
||||
<div class="sax-header row">
|
||||
<div class="col"><div class="sax-caption">@Localiser["journalist.caption.articles"]</div></div>
|
||||
<div class="col"><div class="sax-caption">@Localiser["article.caption.articles"]</div></div>
|
||||
<div class="fixed row">
|
||||
<div>
|
||||
<partial name="~/Views/Common/ResultsPaging.cshtml" />
|
||||
@@ -20,6 +20,17 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="sax-content">
|
||||
@if (Model.UserCanAuthorOrganisationArticles)
|
||||
{
|
||||
<div class="sax-control row OrganisationFilter">
|
||||
<div class="col-sm-4"><div class="sax-label text-left text-sm-right">@Localiser["label.organisation"]</div></div>
|
||||
<div class="col-sm-8 row">
|
||||
@Html.HiddenFor(model => model.Filter.OrganisationId, new { @id = "ifFilterOrganisationId", @class = "FilterOrganisationId" })
|
||||
<div class="col"><input type="text" id="ifFilterOrganisation" class="FilterOrganisation sax-input" readonly="readonly" value="@(Model.Filter.OrganisationCaption)" /></div>
|
||||
<div class="fixed"><button class="sax-button" onclick="sax.selectFilterOrganisation()">@Localiser["label.select"]</button></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-sm-4"><div class="sax-label text-left text-sm-right">@Localiser["label.search"]</div></div>
|
||||
<div class="col-sm-8"><input type="search" name="Filter.Article" id="ifArticleFilter" class="ArticleFilter sax-input" maxlength="64" /></div>
|
||||
@@ -59,5 +70,6 @@
|
||||
|
||||
</div>
|
||||
|
||||
<partial name="~/Views/Common/OrganisationSelect.cshtml" />
|
||||
<partial name="Panel-ArticleDialog.cshtml" />
|
||||
|
||||
+29
-12
@@ -1,12 +1,12 @@
|
||||
@model Model_Journalist
|
||||
@model Model_Article
|
||||
@inject SaxLocaliser Localiser
|
||||
@{
|
||||
/* Articles - Article dialog panel */
|
||||
}
|
||||
|
||||
<script type="text/javascript">
|
||||
sax.dlg.title.createArticle = '@Localiser.GetJavascriptText("journalist.caption.article.create")';
|
||||
sax.dlg.title.updateArticle = '@Localiser.GetJavascriptText("journalist.caption.article.update")';
|
||||
sax.dlg.title.createArticle = '@Localiser.GetJavascriptText("article.caption.article.create")';
|
||||
sax.dlg.title.updateArticle = '@Localiser.GetJavascriptText("article.caption.article.update")';
|
||||
sax.dlg.title.selectRegion = '@Localiser.GetJavascriptText("reference.caption.region.select")';
|
||||
sax.dlg.title.selectSport = '@Localiser.GetJavascriptText("reference.caption.sport.select")';
|
||||
</script>
|
||||
@@ -20,18 +20,35 @@
|
||||
{
|
||||
@Html.HiddenFor(model => model.ArticleId, new { @id = "ifArticleId", @class = "ArticleId" })
|
||||
@Html.HiddenFor(model => model.ArticleExists, new { @id = "ifArticleExists", @class = "ArticleExists" })
|
||||
@Html.HiddenFor(model => model.ArticleOrganisationId, new { @id = "ifArticleOrganisationId", @class = "ArticleOrganisationId" })
|
||||
|
||||
<div class="sax-article ArticleHeader">
|
||||
|
||||
<div class="sax-article-panel sax-article-header">
|
||||
|
||||
@* Organisation *@
|
||||
<div class="sax-form-control ArticleOrganisation">
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div class="sax-label right pt4 pr8">
|
||||
<label for="ifArticleOrganisation"><span>@Localiser["label.organisation"]</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<div class="sax-control">
|
||||
<input type="text" id="ifArticleOrganisation" class="ArticleOrganisation sax-input" readonly="readonly" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Article headline *@
|
||||
<div class="sax-form-control ArticleHeadline">
|
||||
<div class="sax-label">
|
||||
<label for="ifArticleHeadline"><span><span class="required">*</span> @Localiser["label.headline"]</span></label>
|
||||
<label for="ifArticleHeadline"><span>@Localiser["label.headline"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sax-control">
|
||||
@Html.TextBoxFor(model => model.ArticleHeadline, new { @id = "ifArticleHeadline", @class = "ArticleHeadline sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Headline) })
|
||||
@Html.TextBoxFor(model => model.ArticleHeadline, new { @id = "ifArticleHeadline", @class = "ArticleHeadline sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Article_Headline) })
|
||||
</div>
|
||||
<div class="sax-message"></div>
|
||||
</div>
|
||||
@@ -39,10 +56,10 @@
|
||||
@* Article summary *@
|
||||
<div class="sax-form-control ArticleSummary">
|
||||
<div class="sax-label">
|
||||
<label for="ifArticleSummary"><span><span class="required">*</span> @Localiser["label.summary"]</span></label>
|
||||
<label for="ifArticleSummary"><span>@Localiser["label.summary"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sax-control">
|
||||
@Html.TextAreaFor(model => model.ArticleSummary, new { @id = "ifArticleSummary", @class = "ArticleSummary sax-textarea", @rows = 6, @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Summary) })
|
||||
@Html.TextAreaFor(model => model.ArticleSummary, new { @id = "ifArticleSummary", @class = "ArticleSummary sax-textarea", @rows = 6, @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Article_Summary) })
|
||||
</div>
|
||||
<div class="sax-message"></div>
|
||||
</div>
|
||||
@@ -50,7 +67,7 @@
|
||||
@* Sport *@
|
||||
<div class="sax-form-control ArticleSportId">
|
||||
<div class="sax-label">
|
||||
<label for="ifArticleSportId"><span><span class="required">*</span> @Localiser["label.sport"]</span></label>
|
||||
<label for="ifArticleSportId"><span>@Localiser["label.sport"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sax-control row">
|
||||
@Html.HiddenFor(model => model.ArticleSportId, new { @id = "ifArticleSportId", @class = "ArticleSportId" })
|
||||
@@ -63,7 +80,7 @@
|
||||
@* Region *@
|
||||
<div class="sax-form-control ArticleRegionId">
|
||||
<div class="sax-label">
|
||||
<label for="ifArticleRegionId"><span><span class="required">*</span> @Localiser["label.region"]</span></label>
|
||||
<label for="ifArticleRegionId"><span>@Localiser["label.region"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sax-control row">
|
||||
@Html.HiddenFor(model => model.ArticleRegionId, new { @id = "ifArticleRegionId", @class = "ArticleRegionId" })
|
||||
@@ -107,7 +124,7 @@
|
||||
<div class="sax-panel-file-drop row">
|
||||
<div class="col">Drop image here</div>
|
||||
<div class="fixed">
|
||||
<img id="" class="ContactImageUploadProgress" src="~/img/animated/progress-basketball-32.gif" style="display:none;margin:8px 4px;" />
|
||||
<img class="ContactImageUploadProgress" src="~/img/animated/progress-basketball-32.gif" style="display:none;margin:8px 4px;" />
|
||||
</div>
|
||||
</div>
|
||||
@* Segment details *@
|
||||
@@ -138,7 +155,7 @@
|
||||
<div id="dlgSelectArticleImage" class="sax-dialog">
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmSelectArticleImage", @class = "sax-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
<input type="hidden" id="" class="SegmentIdx" />
|
||||
<input type="hidden" class="SegmentIdx" />
|
||||
<div class="spacer4"></div>
|
||||
<div class="sax-form-control ArticleImage">
|
||||
<div class="row">
|
||||
@@ -150,7 +167,7 @@
|
||||
<div class="spacer2"></div>
|
||||
<div class="row">
|
||||
<div class="col"><div class="UploadMessage"></div></div>
|
||||
<div class="fixed"><img id="" class="ArticleImageUploadProgress" src="~/img/animated/progress-basketball-32.gif" style="display:none;margin:8px 4px;" /></div>
|
||||
<div class="fixed"><img class="ArticleImageUploadProgress" src="~/img/animated/progress-basketball-32.gif" style="display:none;margin:8px 4px;" /></div>
|
||||
</div>
|
||||
<div class="spacer2"></div>
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
<input type="hidden" class="FilterPageNo" name="DataPageNo" value="0" />
|
||||
<div class="row">
|
||||
<div class="col-sm-5 sax-label text-left text-sm-right">@Localiser["label.search"]</div>
|
||||
<div class="col-sm-7"><input type="search" id="" class="sax-input FilterOrganisation" name="Filter.Organisation" maxlength="32" autocomplete="off" /></div>
|
||||
<div class="col-sm-7"><input type="search" class="sax-input FilterOrganisation" name="Filter.Organisation" maxlength="32" autocomplete="off" /></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,12 @@ else
|
||||
<div class="sax-panel-item Activity">
|
||||
<div class="sax-header row">
|
||||
<div class="col">
|
||||
<div class="sax-caption"><div class="sax-action ActivityCaption"></div></div>
|
||||
<div class="sax-caption">
|
||||
<div class="row">
|
||||
<div class="col"><div class="sax-action ActivityCaption"></div></div>
|
||||
<div class="col right"><div class="sax-action ActivityOrganisation"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed sax-actions">
|
||||
</div>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<div class="col-sm-4"><div class="sax-label text-left text-sm-right">@Localiser["label.organisation"]</div></div>
|
||||
<div class="col-sm-8 row">
|
||||
@Html.HiddenFor(model => model.Filter.OrganisationId, new { @id = "ifFilterOrganisationId", @class = "FilterOrganisationId" })
|
||||
<div class="col"><input type="text" id="ifFilterOrganisation" class="FilterOrganisation sax-input" value="@(Model.Filter.OrganisationCaption)" /></div>
|
||||
<div class="col"><input type="text" id="ifFilterOrganisation" class="FilterOrganisation sax-input" readonly="readonly" value="@(Model.Filter.OrganisationCaption)" /></div>
|
||||
<div class="fixed"><button class="sax-button" onclick="sax.selectFilterOrganisation()">@Localiser["label.select"]</button></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,6 +64,6 @@
|
||||
|
||||
</div>
|
||||
|
||||
<partial name="Panel-OpportunityDialog.cshtml" />
|
||||
<partial name="~/Views/Common/OrganisationSelect.cshtml" />
|
||||
<partial name="Panel-OpportunityDialog.cshtml" />
|
||||
|
||||
|
||||
@@ -129,15 +129,15 @@
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Account/Profile');">@Localiser["account.caption.profile"]</div>
|
||||
@if (Model.UserIsJournalist)
|
||||
@if (Model.ArticlesAllowed)
|
||||
{
|
||||
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Journalist/Articles');">@Localiser["journalist.caption.articles"]</div>
|
||||
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Article/Index');">@Localiser["article.caption.articles"]</div>
|
||||
}
|
||||
@if (Model.UserCanManageOrganisationMembers)
|
||||
@if (Model.MembersAllowed)
|
||||
{
|
||||
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Organisation/Members');">@Localiser["label.members"]</div>
|
||||
}
|
||||
@if (Model.UserCanManageOrganisationOpportunities)
|
||||
@if (Model.OpportunitiesAllowed)
|
||||
{
|
||||
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Organisation/Opportunities');">@Localiser["label.opportunities"]</div>
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@
|
||||
}
|
||||
sax.onRefreshProfileOrganisationsInfo = function (response)
|
||||
{
|
||||
sax.debug('onRefreshProfileOrganisationsInfo', response);
|
||||
//sax.debug('onRefreshProfileOrganisationsInfo', response);
|
||||
if (!response || !response.success) return;
|
||||
var $section = $('.sax-panel-section.ProfileOrganisations');
|
||||
$('.sax-message', $section).stop(true, false).fadeOut(200).empty();
|
||||
|
||||
+73
-56
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Journalist - Articles page scripts.
|
||||
* Article page scripts.
|
||||
*/
|
||||
|
||||
(function (win, doc, undef)
|
||||
@@ -8,18 +8,18 @@
|
||||
sax.itemIdPrefix = 'Itm_';
|
||||
sax.segIdPrefix = 'Seg_';
|
||||
sax.classFileDrag = 'sax-file-drag';
|
||||
let $pnl = sax.$pnl, $frm = sax.$frm;
|
||||
let ac = sax.articleContent = sax.articleContent || {};
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sax.refreshResults = function (delay)
|
||||
{
|
||||
var $results = $('.sax-panel-results');
|
||||
if (!sax.awaitingRefreshResponse)
|
||||
{
|
||||
var $items = $('.sax-panel-item-list', $results).fadeOut(200).empty();
|
||||
var $msgs = $('.sax-panel-messages', $results).hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
var $items = $('.sax-panel-item-list', $pnl.results).fadeOut(200).empty();
|
||||
var $msgs = $('.sax-panel-messages', $pnl.results).hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
}
|
||||
sax.ajaxRefreshResults = sax.ajaxRefreshResults || { url: sax.url.base + 'Journalist/Ajax/GetArticleList', formId: 'frmArticleFilter', callbackFn: sax.doRefreshResults };
|
||||
sax.ajaxRefreshResults = sax.ajaxRefreshResults || { url: sax.url.base + 'Article/Ajax/GetList', formId: 'frmArticleFilter', callbackFn: sax.doRefreshResults };
|
||||
sax.doAjaxRequest(sax.ajaxRefreshResults, delay || 50);
|
||||
sax.awaitingRefreshResponse = true;
|
||||
}
|
||||
@@ -28,11 +28,11 @@
|
||||
//sax.debug('doRefreshResults', response);
|
||||
delete sax.awaitingRefreshResponse;
|
||||
sax.refreshControlValues(response.controlValues);
|
||||
var $results = $('.sax-panel-results');
|
||||
var $msgs = $('.sax-panel-messages', $results).hide().empty();
|
||||
var $items = $('.sax-panel-item-list', $results).hide().empty();
|
||||
var $tmpl = $('.sax-panel-item-template .sax-panel-item', $results);
|
||||
var $msgs = $('.sax-panel-messages', $pnl.results).hide().empty();
|
||||
var $items = $('.sax-panel-item-list', $pnl.results).hide().empty();
|
||||
var $tmpl = $('.sax-panel-item-template .sax-panel-item', $pnl.results);
|
||||
if (!response.success) return;
|
||||
sax.data.articleOrganisations = response.organisations;
|
||||
sax.refreshPaging(response);
|
||||
var items = response.articles;
|
||||
if (!items.length)
|
||||
@@ -60,7 +60,26 @@
|
||||
$('.ArticleStatusDesc', $item).text(item.statusDesc);
|
||||
$('.sax-caption .sax-action, .sax-actions .sax-action.sax-item-update', $item).off('click').on('click', function () { sax.updateItem(item.id) })
|
||||
$item.off('dblclick').on('dblclick', function () { sax.updateItem(item.id) })
|
||||
$('.sax-panel-results .sax-panel-messages').hide().empty();
|
||||
$('.sax-panel-messages', $pnl.results).hide().empty();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sax.selectFilterOrganisation = function ()
|
||||
{
|
||||
if (!sax.data.articleOrganisations || !sax.data.articleOrganisations.length) return;
|
||||
sax.showSelectOrganisation();
|
||||
}
|
||||
sax.showSelectOrganisation = function ()
|
||||
{
|
||||
//sax.debug('sax.selectFilterOrganisation', sax.data.articleOrganisations);
|
||||
sax.selectOrganisation.fn.selectOrganisation({ caption: sax.dlg.title.selectOrganisation, items: sax.data.articleOrganisations, fnCallback: sax.onOrganisationSelected });
|
||||
}
|
||||
sax.onOrganisationSelected = function (id, name)
|
||||
{
|
||||
//sax.debug('sax.onOrganisationSelected', id, name);
|
||||
$('#frmArticleFilter #ifFilterOrganisationId, #frmArticle #ifArticleOrganisationId').val(id);
|
||||
$('#frmArticleFilter #ifFilterOrganisation').val(name);
|
||||
sax.refreshResults(50);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
@@ -245,13 +264,13 @@
|
||||
if (file.type != 'image/jpg' && file.type != 'image/jpeg' && file.type != 'image/png') return sax.doAlert(sax.dlg.title.imageUpload, sax.msg.uploadFileTypeInvalid.format(sax.getFileType(file)));
|
||||
$(".UploadMessage", context).text(sax.msg.uploadingFile.format(file.name));
|
||||
$('img.ArticleImageUploadProgress', context).fadeIn(200);
|
||||
sax.clearControlError(sax.$pnl.contactImageDrag);
|
||||
sax.clearControlError();
|
||||
sax.data.contactImageUploadContext = context;
|
||||
|
||||
sax.ajax.uploadArticleImage = sax.ajax.uploadArticleImage || { url: sax.url.base + 'Journalist/Ajax/UploadArticleImage', callbackFn: sax.handleArticleImageUploadResponse, noWaitIcon: true };
|
||||
sax.ajax.uploadArticleImage = sax.ajax.uploadArticleImage || { url: sax.url.base + 'Article/Ajax/UploadImage', callbackFn: sax.handleArticleImageUploadResponse, noWaitIcon: true };
|
||||
sax.ajax.uploadArticleImage.formData = new FormData();
|
||||
sax.ajax.uploadArticleImage.formData.append("__RequestVerificationToken", $('#frmNavigate input[name="__RequestVerificationToken"]').val());
|
||||
sax.ajax.uploadArticleImage.formData.append("ArticleId", $('#ifArticleId', sax.$frm.article).val());
|
||||
sax.ajax.uploadArticleImage.formData.append("ArticleId", $('#ifArticleId', $frm.article).val());
|
||||
sax.ajax.uploadArticleImage.formData.append("ArticleImage", file);
|
||||
sax.doAjaxRequest(sax.ajax.uploadArticleImage, 50);
|
||||
}
|
||||
@@ -275,9 +294,21 @@
|
||||
sax.createItem = function ()
|
||||
{
|
||||
sax.clearItem();
|
||||
let orgId = $('#ifFilterOrganisationId', $frm.filter).val();
|
||||
$('#ifArticleOrganisationId', $frm.article).val(orgId);
|
||||
$('#ifArticleOrganisation', $frm.article).val($('#ifFilterOrganisation', $frm.filter).val());
|
||||
$('.sax-form-control.ArticleOrganisation', $frm.article).toggle(!!orgId);
|
||||
sax.populateArticleContent({});
|
||||
sax.openArticleDialog(sax.dlg.title.createArticle);
|
||||
}
|
||||
sax.clearItem = function ()
|
||||
{
|
||||
let frm = $frm.article;
|
||||
$('#ifArticleId,#ifArticleExists,#ifArticleOrganisationId,#ifArticleRegionId,#ifArticleSportId,input[type="text"],textarea,select', frm).val('');
|
||||
$('#chkArticlePublish', frm).prop("checked", false);
|
||||
$('.sax-input.sax-calendar.ArticlePublishOn', frm).datepicker('setDate', 'today');
|
||||
sax.clearControlErrors();
|
||||
}
|
||||
sax.openArticleDialog = function (title)
|
||||
{
|
||||
sax.clearControlErrors();
|
||||
@@ -285,24 +316,12 @@
|
||||
sax.$dlg.article.dialog('option', 'title', title);
|
||||
sax.openDialog(sax.$dlg.article, 600, 800);
|
||||
}
|
||||
sax.clearItem = function ()
|
||||
{
|
||||
let $frm = sax.$frm.article;
|
||||
$('#ifArticleId,#ifArticleExists,#ifArticleRegionId,#ifArticleSportId,input[type="text"],textarea,select', $frm).val('');
|
||||
$('#chkArticlePublish', $frm).prop("checked", false);
|
||||
$('.sax-input.sax-calendar.ArticlePublishOn', $frm).datepicker('setDate', 'today');
|
||||
sax.clearControlErrors();
|
||||
}
|
||||
sax.doCreateItem = function ()
|
||||
{
|
||||
sax.storeItem();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sax.updateItem = function (id)
|
||||
{
|
||||
$('.ArticleId', sax.$frm.articleId).val(id);
|
||||
sax.ajaxUpdateItem = sax.ajaxUpdateItem || { url: sax.url.base + 'Journalist/Ajax/GetArticle', formId: 'frmArticleId', callbackFn: sax.onUpdateItem };
|
||||
$('.ArticleId', $frm.articleId).val(id);
|
||||
sax.ajaxUpdateItem = sax.ajaxUpdateItem || { url: sax.url.base + 'Article/Ajax/GetItem', formId: 'frmArticleId', callbackFn: sax.onUpdateItem };
|
||||
sax.doAjaxRequest(sax.ajaxUpdateItem, 50);
|
||||
}
|
||||
sax.onUpdateItem = function (response)
|
||||
@@ -310,28 +329,24 @@
|
||||
//sax.debug('onUpdateItem', response);
|
||||
sax.clearItem();
|
||||
if (!response.success) return;
|
||||
let $frm = sax.$frm.article;
|
||||
let frm = $frm.article;
|
||||
let item = response.article;
|
||||
$('#ifArticleId', $frm).val(item.id);
|
||||
$('#ifArticleExists', $frm).val(1);
|
||||
$('#ifArticleHeadline', $frm).val(item.headline);
|
||||
$('#ifArticleSummary', $frm).val(item.summary);
|
||||
$('#ifArticleRegionId', $frm).val(item.regionIdPrimary);
|
||||
$('#ifArticleRegionCaption', $frm).val(item.regionCaptionPrimary);
|
||||
$('#ifArticleSportId', $frm).val(item.sportIdPrimary);
|
||||
$('#ifArticleSportCaption', $frm).val(item.sportCaptionPrimary);
|
||||
$('#ifArticleId', frm).val(item.id);
|
||||
$('#ifArticleExists', frm).val(1);
|
||||
$('#ifArticleHeadline', frm).val(item.headline);
|
||||
$('#ifArticleSummary', frm).val(item.summary);
|
||||
$('#ifArticleRegionId', frm).val(item.regionIdPrimary);
|
||||
$('#ifArticleRegionCaption', frm).val(item.regionCaptionPrimary);
|
||||
$('#ifArticleSportId', frm).val(item.sportIdPrimary);
|
||||
$('#ifArticleSportCaption', frm).val(item.sportCaptionPrimary);
|
||||
if (item.published)
|
||||
$('span.ArticlePublishedOn', $frm).text(item.publishedOnFmt);
|
||||
$('div.ArticlePublish', $frm).toggle(!item.published);
|
||||
$('div.ArticlePublished', $frm).toggle(!!item.published);
|
||||
$('#cbArticleStatusCode', $frm).val(item.statusCode);
|
||||
$('span.ArticlePublishedOn', frm).text(item.publishedOnFmt);
|
||||
$('div.ArticlePublish', frm).toggle(!item.published);
|
||||
$('div.ArticlePublished', frm).toggle(!!item.published);
|
||||
$('#cbArticleStatusCode', frm).val(item.statusCode);
|
||||
sax.populateArticleContent(item.content);
|
||||
sax.openArticleDialog(sax.dlg.title.updateArticle);
|
||||
}
|
||||
sax.doUpdateItem = function ()
|
||||
{
|
||||
sax.storeItem();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sax.switchArticleHeader = function ()
|
||||
@@ -368,7 +383,7 @@
|
||||
//--------------------------------------------------------------
|
||||
sax.storeItem = function ()
|
||||
{
|
||||
sax.ajaxStoreItem = sax.ajaxStoreItem || { url: sax.url.base + 'Journalist/Ajax/StoreArticle', formId: 'frmArticle', callbackFn: sax.onStoreItem };
|
||||
sax.ajaxStoreItem = sax.ajaxStoreItem || { url: sax.url.base + 'Article/Ajax/StoreItem', formId: 'frmArticle', callbackFn: sax.onStoreItem };
|
||||
sax.doAjaxRequest(sax.ajaxStoreItem, 50);
|
||||
}
|
||||
sax.onStoreItem = function (response)
|
||||
@@ -382,9 +397,8 @@
|
||||
var $item = $('#' + sax.itemIdPrefix + item.id);
|
||||
if (!$item.length)
|
||||
{
|
||||
var $results = $('.sax-panel-results');
|
||||
$item = $('.sax-panel-item-template .sax-panel-item', $results).clone();
|
||||
$('.sax-panel-item-list', $results).prepend($item).show();
|
||||
$item = $('.sax-panel-item-template .sax-panel-item', $pnl.results).clone();
|
||||
$('.sax-panel-item-list', $pnl.results).prepend($item).show();
|
||||
}
|
||||
sax.populateItem($item, item)
|
||||
}
|
||||
@@ -392,20 +406,23 @@
|
||||
//--------------------------------------------------------------
|
||||
$(function ()
|
||||
{
|
||||
sax.$frm.filter = $('#frmArticleFilter');
|
||||
$('.sax-panel-filter .sax-action.sax-item-create').on('click', function () { sax.createItem(); });
|
||||
$('.sax-panel-filter .sax-action.sax-results-refresh').on('click', function () { sax.refreshResults(); });
|
||||
$('.ArticleFilter', sax.$frm.filter).on('input', function () { sax.refreshResults(250); }).on('keypress', function (event)
|
||||
$pnl.filter = $('.sax-panel-filter');
|
||||
$pnl.results= $('.sax-panel-results');
|
||||
|
||||
$frm.filter = $('#frmArticleFilter');
|
||||
$('.sax-action.sax-item-create', $pnl.filter).on('click', function () { sax.createItem(); });
|
||||
$('.sax-action.sax-results-refresh', $pnl.filter).on('click', function () { sax.refreshResults(); });
|
||||
$('.ArticleFilter', $frm.filter).on('input', function () { sax.refreshResults(250); }).on('keypress', function (event)
|
||||
{
|
||||
if (event.keyCode == 13) setTimeout(sax.refreshResults, 50);
|
||||
});
|
||||
sax.$frm.articleId = $('#frmArticleId');
|
||||
sax.$frm.article = $('#frmArticle');
|
||||
$('.sax-input', sax.$frm.article).on('input', function () { sax.clearControlError(this); });
|
||||
$frm.articleId = $('#frmArticleId');
|
||||
$frm.article = $('#frmArticle');
|
||||
$('.sax-input', $frm.article).on('input', function () { sax.clearControlError(this); });
|
||||
|
||||
var opt = sax.dlgOpts();
|
||||
opt.buttons[sax.dlg.btn.cancel] = { text: sax.dlg.btn.cancel, class: "floatr", click: function () { $(this).dialog('close'); } };
|
||||
opt.buttons[sax.dlg.btn.ok] = { text: sax.dlg.btn.ok, class: "floatr", click: function () { sax.doCreateItem(); } };
|
||||
opt.buttons[sax.dlg.btn.ok] = { text: sax.dlg.btn.ok, class: "floatr", click: function () { sax.storeItem(); } };
|
||||
opt.buttons['Header'] = { text: 'Header', class: "floatl", click: function () { sax.switchArticleHeader(); } };
|
||||
opt.buttons['Content'] = { text: 'Content', class: "floatl", click: function () { sax.switchArticleContent(); } };
|
||||
sax.$dlg.article = $('#dlgArticle').dialog(opt);
|
||||
@@ -44,9 +44,11 @@
|
||||
}
|
||||
sax.populateItem = function ($item, item)
|
||||
{
|
||||
//sax.debug('populateItem', item);
|
||||
sax.debug('populateItem', item);
|
||||
if (!item) return;
|
||||
$item.prop('id', sax.itemIdPrefix + item.itemIdx).addClass(item.itemTypeClass).toggleClass('sax-activity-reaction-' + item.reaction, !!item.reaction);
|
||||
$('.ActivityOrganisation', $item).text(item.organisation);
|
||||
$('.ActivityAuthor', $item).text(item.author);
|
||||
$('.ActivityCaption', $item).text(item.caption);
|
||||
$('.ActivityBlurb', $item).text(item.blurb);
|
||||
$('.ActivitySport', $item).text(item.sport);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
}
|
||||
sax.doRefreshResults = function (response)
|
||||
{
|
||||
sax.debug('doRefreshResults', response);
|
||||
//sax.debug('doRefreshResults', response);
|
||||
delete sax.awaitingRefreshResponse;
|
||||
sax.refreshControlValues(response.controlValues);
|
||||
let $mnu = $('.sax-burger ul.sax-dropdown-menu', sax.$pnl.filter).empty();
|
||||
@@ -201,7 +201,7 @@
|
||||
}
|
||||
sax.updateMemberRoles = function (memberRoleCodes)
|
||||
{
|
||||
sax.debug('updateMemberRoles', memberRoleCodes);
|
||||
//sax.debug('updateMemberRoles', memberRoleCodes);
|
||||
let $frm = sax.$frm.member;
|
||||
sax.member.roleCodes = memberRoleCodes;
|
||||
$('.MemberRoleCodes',$frm).val(memberRoleCodes.join(sax.data.memberRoleCodeDelim));
|
||||
@@ -230,7 +230,7 @@
|
||||
}
|
||||
sax.onStoreItem = function (response)
|
||||
{
|
||||
sax.debug('onStoreItem', response);
|
||||
//sax.debug('onStoreItem', response);
|
||||
sax.refreshControlValues(response.controlValues);
|
||||
if (!response.success) return;
|
||||
let $frm = sax.$frm.member;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
}
|
||||
or.fn.handleRequestOrganisationResponse = function (response)
|
||||
{
|
||||
sax.debug('or.handleRequestOrganisationResponse', response);
|
||||
//sax.debug('or.handleRequestOrganisationResponse', response);
|
||||
if (!response) return;
|
||||
sax.refreshControlValues(response.controlValues, or.$frm);
|
||||
if (!response.success) return;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{
|
||||
"use strict";
|
||||
let so = sax.selectOrganisation;
|
||||
so.data = {}; so.fn = {}; so.itemIdPrefix = 'Org_';
|
||||
so.data = {}; so.fn = {};
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/*
|
||||
@@ -52,7 +52,8 @@
|
||||
{
|
||||
let item = items[itemIdx];
|
||||
if (!so.fn.matchesFilter(item)) continue;
|
||||
let $item = $tmpl.clone().prop('id', so.itemIdPrefix + item.id).on('click', function () { so.fn.onClickOrganisation(item); }).on('dblclick', function () { so.fn.onDblClickOrganisation(item); });
|
||||
let $item = $tmpl.clone();
|
||||
$item.on('click', function () { so.fn.onClickOrganisation(item, $item); }).on('dblclick', function () { so.fn.onDblClickOrganisation(item, $item); });
|
||||
$('.Name', $item).text(item.name);
|
||||
so.$results.append($item);
|
||||
}
|
||||
@@ -69,16 +70,16 @@
|
||||
}
|
||||
return true;
|
||||
}
|
||||
so.fn.onClickOrganisation = function (item)
|
||||
so.fn.onClickOrganisation = function (item, $item)
|
||||
{
|
||||
//sax.debug('onClickOrganisation', item);
|
||||
//sax.debug('onClickOrganisation', item, $item);
|
||||
so.data.item = item;
|
||||
$('.sax-panel-item.Organisation', so.$dlg).removeClass('sel');
|
||||
$('.sax-panel-item.Organisation#' + so.itemIdPrefix + item.id, so.$dlg).addClass('sel');
|
||||
$item.addClass('sel');
|
||||
}
|
||||
so.fn.onDblClickOrganisation = function (item)
|
||||
so.fn.onDblClickOrganisation = function (item, $item)
|
||||
{
|
||||
//sax.debug('onDblClickCode', item);
|
||||
//sax.debug('onDblClickCode', item, $item);
|
||||
so.data.item = item;
|
||||
so.fn.confirmSelection();
|
||||
}
|
||||
@@ -99,7 +100,6 @@
|
||||
delete so.data.item;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
so.fn.init = function ()
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
{
|
||||
if (!response || !response.success) return;
|
||||
sr.regions = response.regions;
|
||||
sax.debug(sr.cfg);
|
||||
//sax.debug(sr.cfg);
|
||||
sr.fn.showSelectRegion();
|
||||
}
|
||||
sr.fn.showSelectRegion = function ()
|
||||
|
||||
Reference in New Issue
Block a user