This commit is contained in:
2021-06-22 10:05:59 +01:00
parent 558be9063f
commit e40ff8a7f2
50 changed files with 899 additions and 184 deletions
@@ -48,6 +48,10 @@ namespace Saxonite.Net.Core.UnitTests.Web.Admin.App
Assert.IsTrue(sessionData.ValidUserSession);
Assert.AreNotEqual("", sessionData.User.DisplayName);
int idx = sessionData.NextItemIdx;
idx = sessionData.NextItemIdx;
idx = sessionData.NextItemIdx;
// Serialise session data using same method as base controller.
String sessionDataJson = JsonConvert.SerializeObject(sessionData);
Assert.AreNotEqual("", sessionDataJson);
@@ -61,6 +65,8 @@ namespace Saxonite.Net.Core.UnitTests.Web.Admin.App
Assert.IsNotNull(sessionDataDeserialized);
// Validate deserialised values.
Assert.AreEqual(sessionData.SessionIdx, sessionDataDeserialized.SessionIdx);
Assert.AreEqual(sessionData.ItemIdx, sessionDataDeserialized.ItemIdx);
Assert.AreEqual(App.SessionContext.Index, sessionDataDeserialized.SessionContext.Index);
Assert.AreEqual(Sax.Application.Admin, sessionDataDeserialized.SessionContext.Application);
Assert.AreEqual(SysId.ToInt(sessionDataDeserialized.User.UserAccountId), SysId.ToInt(sessionDataDeserialized.User.UserAccountId));
@@ -77,6 +77,10 @@ namespace Saxonite.Net.Core.UnitTests.Web.Online.App
sessionData.Filter.OrganisationIdMember = filterOrganisationIdMember;
sessionData.Filter.OrganisationCaptionMember = filterOrganisationCaptionMember;
int idx = sessionData.NextItemIdx;
idx = sessionData.NextItemIdx;
idx = sessionData.NextItemIdx;
// Serialise session data using same method as base controller.
String sessionDataJson = JsonConvert.SerializeObject(sessionData);
Assert.AreNotEqual("", sessionDataJson);
@@ -90,8 +94,13 @@ namespace Saxonite.Net.Core.UnitTests.Web.Online.App
Assert.IsNotNull(sessionDataDeserialised);
// Validate deserialised values.
Assert.AreEqual(sessionData.SessionIdx, sessionDataDeserialised.SessionIdx);
Assert.AreEqual(sessionData.ItemIdx, sessionDataDeserialised.ItemIdx);
Assert.AreEqual(sessionData.Base64IV_OnlineApp, sessionDataDeserialised.Base64IV_OnlineApp);
Assert.AreEqual(App.SessionContext.Index, sessionDataDeserialised.SessionContext.Index);
Assert.AreEqual(Sax.Application.Online, sessionDataDeserialised.SessionContext.Application);
// User details.
Assert.AreEqual(SysId.ToInt(sessionDataDeserialised.User.UserAccountId), SysId.ToInt(sessionDataDeserialised.User.UserAccountId));
Assert.AreEqual(SysId.ToInt(sessionData.User.UserAccountId), SysId.ToInt(sessionDataDeserialised.User.UserAccountId));
Assert.AreEqual(sessionData.User.EmailAddress, sessionDataDeserialised.User.EmailAddress);
@@ -10,6 +10,11 @@ namespace Saxonite.Net.Core.Web.Base.App
public abstract class SaxSessionData_Web : SaxSessionData
{
//-------------------------------------------------------------------
// Private construction - for JSON deserialisation.
protected SaxSessionData_Web(long sessionIdx, int itemIdx, SaxSessionContext sessionContext) :
base(sessionIdx, itemIdx, sessionContext)
{
}
// Protected construction.
protected SaxSessionData_Web(SaxSessionContext sessionContext, SaxUserAccount userAccount, List<SaxUserRole> userRoles) :
base(sessionContext, userAccount, userRoles)
@@ -15,7 +15,9 @@ namespace Saxonite.Net.Core.Web.Admin.App
//-------------------------------------------------------------------
// Construction.
[JsonConstructor]
private SaxSessionData_Admin(SaxSessionContext sessionContext) : this(sessionContext, null, null) { }
private SaxSessionData_Admin(long sessionIdx, int itemIdx, SaxSessionContext sessionContext) :
base(sessionIdx, itemIdx, sessionContext)
{ }
/// <summary>
/// SessionData construction.
/// <para>SessionContext and UserAccount must be supplied.</para>
@@ -23,8 +25,7 @@ namespace Saxonite.Net.Core.Web.Admin.App
/// </summary>
public SaxSessionData_Admin(SaxSessionContext sessionContext, SaxUserAccount userAccount, List<SaxUserRole> userRoles) :
base(sessionContext, userAccount, userRoles)
{
}
{ }
//-------------------------------------------------------------------
// Properties.
@@ -369,6 +369,9 @@
<data name="label.yes" xml:space="preserve">
<value>Yes</value>
</data>
<data name="msg.confirm.item.remove" xml:space="preserve">
<value>Are you sure that this item should be removed?</value>
</data>
<data name="msg.data.noneFound" xml:space="preserve">
<value>No matching data has been found.</value>
</data>
@@ -414,6 +417,9 @@
<data name="msg.upload.file.uploading" xml:space="preserve">
<value>Uploading {0}.</value>
</data>
<data name="msg.upload.image.invalid" xml:space="preserve">
<value>Invalid image file uploaded</value>
</data>
<data name="msg.upload.image.single" xml:space="preserve">
<value>Only one image can be uploaded.</value>
</data>
@@ -3,7 +3,9 @@ using Newtonsoft.Json.Linq;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Helpers;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Online.Controllers;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
using System;
@@ -20,7 +22,9 @@ namespace Saxonite.Net.Core.Web.Online.App
//-------------------------------------------------------------------
// Construction.
[JsonConstructor]
private SaxSessionData_Online(SaxSessionContext sessionContext) : this(sessionContext, null, null) { }
private SaxSessionData_Online(long sessionIdx, int itemIdx, SaxSessionContext sessionContext) :
base(sessionIdx, itemIdx, sessionContext)
{ }
/// <summary>
/// SessionData construction.
/// <para>SessionContext and UserAccount must be supplied.</para>
@@ -148,6 +152,10 @@ namespace Saxonite.Net.Core.Web.Online.App
}
public FilterData Filter { get; private set; } = new FilterData();
//-------------------------------------------------------------------
// Online application encryption IV value - for consistent encryption during session.
public String Base64IV_OnlineApp { get; private set; } = SacsEncryptionHelper.InitSymmetricEncryptionIV(SaxController_Online.Base64Key_OnlineApp);
//-------------------------------------------------------------------
// JSON Deserialisation.
[JsonExtensionData]
@@ -148,7 +148,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
if (model.AccountContactImage.Count != 1)
{
SaLogger.Warn(fn + " Invalid number of image files uploaded: " + model.AccountContactImage.Count);
return Json(responseData.SetControlError("AccountContactImage", "Only one image can be uploaded."));
return Json(responseData.SetControlError("AccountContactImage", Localiser["msg.upload.image.single"]));
}
IFormFile file = model.AccountContactImage[0];
@@ -163,7 +163,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
// Validate the image.
ImageUtils.ImageConfig imageConfig = ImageUtils.VerifyImageData(imageData);
if (!imageConfig.ValidImage)
return Json(responseData.SetControlError("AccountContactImage", "Invalid image file uploaded."));
return Json(responseData.SetControlError("AccountContactImage", Localiser["msg.upload.image.invalid"]));
// Image belongs to the user's account.
ItemId userItemId = GetUserItemId(SessionData.User.UserAccountId);
@@ -47,7 +47,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
/// <summary>Article activity info. </summary>
public class ActivityResponseData_Article
{
public ActivityResponseData_Article(SaxModel_Online model, SaxJournalistArticle article)
public ActivityResponseData_Article(SaxController_Online controller, SaxModel_Online model, SaxJournalistArticle article)
{
Headline = article.Headline;
Summary = article.Summary;
@@ -56,7 +56,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
PublishedOnFmt = model.Localiser.FormatDate(article.PublishedAt);
SaxJournalistArticle.ContentData content = SaxJournalistArticle.ExtractContent(article.BodyData);
foreach (SaxJournalistArticle.ContentData.SegmentData segment in content.Segments)
Content.Segments.Add(new ContentData.SegmentData(segment));
Content.Segments.Add(new ContentData.SegmentData(controller, segment));
}
public String Headline { get; set; }
public String Summary { get; set; }
@@ -67,15 +67,29 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
{
public class SegmentData
{
public SegmentData(SaxJournalistArticle.ContentData.SegmentData segment)
public SegmentData(SaxController_Online controller, SaxJournalistArticle.ContentData.SegmentData segment)
{
if (segment.Body.IsValid())
{
Body = new BodyData();
Body.Html = segment.Body.Html;
}
else if (segment.Image.IsValid())
{
Image = new ImageData();
Image.Link = JournalistController.GetArticleImageLink(controller, segment.Image.ItemImageId);
}
}
public class BodyData
{
public String Html { get; set; }
}
public BodyData Body { get; } = new BodyData();
public BodyData Body { get; }
public class ImageData
{
public String Link { get; set; }
}
public ImageData Image { get; }
}
public List<SegmentData> Segments { get; } = new List<SegmentData>();
}
@@ -214,7 +228,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
SaLogger.Warn(fn + " Article not found for Activity Id: " + itemId.ToString() + "." + getLogSuffix());
return Json(responseData);
}
responseData.Article = new ActivityResponseData_Article(model, article);
responseData.Article = new ActivityResponseData_Article(this, model, article);
}
else if (itemType == Sax.DataItemType.OrganisationOpportunity)
{
@@ -19,6 +19,7 @@ using System.IO;
using System.Drawing;
using Sarand.Net.Standard.Base.Core;
using Microsoft.Net.Http.Headers;
using System.Collections.Specialized;
namespace Saxonite.Net.Core.Web.Online.Controllers
{
@@ -118,6 +119,42 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
return File(itemImage.ImageData, itemImage.ContentType);
}
//-------------------------------------------------------------------
// Journalist Article image
//-------------------------------------------------------------------
public static String ParamName_JournalistArticleImageEncrypted { get; } = "jaie";
public static String ParamName_ItemImageId { get; } = "iii";
/// <summary>
/// Get the specified Journalist Article Image.
/// <para>Encrypted parameters:</para>
/// <para>- iii: item Image Id.</para>
/// </summary>
[HttpGet]
[Route("Image/Journalist/Article")]
public IActionResult GetJournalistArticleImage(String jaie)
{
String fn = GetType().Name + ".GetJournalistArticleImage";
// 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);
if (parameters.Count<1) return Forbid();
// Item Image.
SysId itemImageId = parameters.Get(ParamName_ItemImageId).ToSysId();
if (!SysId.IsValid(itemImageId)) return Forbid();
SaxItemImage itemImage = ItemDataMgr.GetItemImageById(itemImageId);
if (itemImage == null)
return NotFound();
// Construct response.
return File(itemImage.ImageData, itemImage.ContentType);
}
//-------------------------------------------------------------------
}
//=======================================================================
@@ -1,15 +1,20 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Helpers;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Net.Core.Web.Online.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.Consoles;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@@ -28,12 +33,19 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
}
public class ArticleContentSegmentData
{
public ArticleContentSegmentBodyData Body { get; } = new ArticleContentSegmentBodyData();
public ArticleContentSegmentBodyData Body { get; set; }
public ArticleContentSegmentImageData Image { get; set; }
}
public class ArticleContentSegmentBodyData
{
public String Html { get; set; }
}
public class ArticleContentSegmentImageData
{
public int ItemImageId { get; set; }
public int ImageIdx { get; set; }
public String ImageLink { get; set; }
}
//-------------------------------------------------------------------
// Journalist Article data.
@@ -80,7 +92,17 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
foreach (var contentSegment in articleContent.Segments)
{
var segmentData = new ArticleContentSegmentData();
if (contentSegment.Body.IsValid())
{
segmentData.Body = new ArticleContentSegmentBodyData();
segmentData.Body.Html = contentSegment.Body.Html;
}
else if (contentSegment.Image.IsValid())
{
segmentData.Image = new ArticleContentSegmentImageData();
segmentData.Image.ItemImageId = SysId.ToInt(contentSegment.Image.ItemImageId);
segmentData.Image.ImageLink = GetArticleImageLink(contentSegment.Image.ItemImageId);
}
data.Content.Segments.Add(segmentData);
}
}
@@ -102,16 +124,14 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
AjaxResponse_ArticleList responseData = new AjaxResponse_ArticleList();
// 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);
if (!UserIsJournalist) return GetAjaxResult_GoHome(responseData);
SaxSessionData_Online sessionData = SessionData_Online;
// Item filter.
SaxJournalistArticle.Params prmArticle = new SaxJournalistArticle.Params();
prmArticle.UserAccountIdsJournalistIncluded.Add(SessionData.User.UserAccountId);
prmArticle.UserAccountIdsJournalistIncluded.Add(sessionData.User.UserAccountId);
prmArticle.ArticleFilter = model.Filter.Article;
prmArticle.StatusCat = SaxJournalistArticle.StatusCat.NotDeleted;
model.DataItemTotal = (ulong)ActivityMgr.GetJournalistArticleCount(prmArticle);
@@ -204,12 +224,144 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Delete upload images.
SaxItemImage.Params prmItemImage = new SaxItemImage.Params();
prmItemImage.ItemIdsIncluded.Add(new ItemId((short)Sax.DataItemType.JournalistArticle, articleId));
prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.ArticleUpload);
prmItemImage.StatusCat = SaxItemImage.StatusCat.NotDeleted;
foreach (SaxItemImage itemImage in ItemDataMgr.GetItemImageList(prmItemImage))
{
itemImage.SessionUid = 0;
itemImage.ImageUid = 0;
itemImage.Status = SaStatus.Deleted;
ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo);
}
// Construct response.
PopulateArticleResponseData(model, article, responseData.Article);
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
// Journalist - Upload Article Image.
//-------------------------------------------------------------------
public class AjaxResponse_UploadArticleImage : AjaxResponse_Data
{
public ArticleContentSegmentData Segment { get; set; }
public String UploadMsg { get; set; }
}
// Ajax request.
[HttpPost]
[Route("Journalist/Ajax/UploadArticleImage")]
public IActionResult UploadArticleImage(Model_Journalist model)
{
String fn = GetType().Name + ".UploadArticleImage";
AjaxResponse_UploadArticleImage responseData = new AjaxResponse_UploadArticleImage();
String messageTitle = Localiser["journalist.caption.article"];
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
SaxSessionData_Online sessionData = SessionData_Online;
// Validate number of images.
if (model.ArticleImage.IsEmpty())
{
SaLogger.Warn(fn + " No image file supplied for upload");
return Json(responseData);
}
if (model.ArticleImage.Count != 1)
{
SaLogger.Warn(fn + " Invalid number of image files uploaded: " + model.ArticleImage.Count);
return Json(responseData.SetControlError("ArticleImage", Localiser["msg.upload.image.single"]));
}
IFormFile file = model.ArticleImage[0];
// Image properties.
byte[] imageData = null;
using (MemoryStream fileStream = new MemoryStream())
{
file.CopyTo(fileStream);
imageData = fileStream.ToArray();
}
// Validate the image.
ImageUtils.ImageConfig imageConfig = ImageUtils.VerifyImageData(imageData);
if (!imageConfig.ValidImage)
return Json(responseData.SetControlError("ArticleImage", Localiser["msg.upload.image.invalid"]));
// 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 userItemId = new ItemId((short)Sax.DataItemType.UserAccount, sessionData.User.UserAccountId);
ItemId imageItemId = SysId.IsValid(articleId) ? articleItemId : userItemId;
// Store uploaded image as 'Upload' - awaiting confirmation that the article details are to be saved.
// NB Reuse any existing deleted article upload image to avoid creating new images unless necessary.
SaxItemImage.Params prmItemImage = new SaxItemImage.Params();
prmItemImage.ItemIdsIncluded.Add(imageItemId);
prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.Article);
prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.ArticleUpload);
prmItemImage.StatusCat = SaxItemImage.StatusCat.Deleted;
prmItemImage.ResultsPaging.PageLength = 1;
prmItemImage.ResultsPaging.PageNo = 1;
List<SaxItemImage> itemImages = ItemDataMgr.GetItemImageList(prmItemImage);
SaxItemImage itemImage = !itemImages.IsEmpty() ? itemImages[0] : null;
if (itemImage == null)
itemImage = ItemDataMgr.CreateItemImage(imageItemId, Sax.ImageType.ArticleUpload);
itemImage.ImageType = Sax.ImageType.ArticleUpload;
itemImage.Filename = file.FileName;
itemImage.Mime = SacsContentTypeHelper.GetMimeTypeFromContentType(file.ContentType).ToString().ToLower();
itemImage.ContentType = file.ContentType;
itemImage.Width = imageConfig.Width;
itemImage.Height = imageConfig.Height;
itemImage.ImageData = imageData;
itemImage.SessionUid = sessionData.SessionIdx;
itemImage.ImageUid = sessionData.NextItemIdx;
itemImage.Status = SaxItemImage.DefaultStatus;
if (!SysId.IsValid(itemImage.Id))
{
if (!ItemDataMgr.InsertItemImage(itemImage, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to insert uploaded image - " + ItemDataMgr.ErrorStateMessage);
return Json(responseData.SetControlError("ArticleImage", Localiser["msg.error.item.insert.failed"]));
}
}
else
{
if (!ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to update uploaded image - " + ItemDataMgr.ErrorStateMessage);
return Json(responseData.SetControlError("ArticleImage", Localiser["msg.error.item.insert.failed"]));
}
}
// Segment image info.
responseData.Segment = new ArticleContentSegmentData();
responseData.Segment.Image = new ArticleContentSegmentImageData();
responseData.Segment.Image.ImageLink = GetArticleImageLink(itemImage.Id);
responseData.Segment.Image.ImageIdx = itemImage.ImageUid;
// Complete response.
//responseData.SetNotification(messageTitle, "Image uploaded.");
responseData.Success = true;
return Json(responseData);
}
private String GetArticleImageLink(SysId itemImageId)
{
return GetArticleImageLink(this, itemImageId);
}
public static String GetArticleImageLink(SaxController_Online controller, SysId itemImageId)
{
String imageLink = "Image/Journalist/Article?";
NameValueCollection parameters = new NameValueCollection();
parameters.Add(ImageController.ParamName_ItemImageId, SysId.ToString(itemImageId));
return imageLink + ImageController.ParamName_JournalistArticleImageEncrypted + "=" + SaxController_Online.EncryptOnlineParams(controller, parameters);
}
//-------------------------------------------------------------------
// Store Article ajax request.
//-------------------------------------------------------------------
@@ -222,12 +374,10 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
AjaxResponse_Article responseData = new AjaxResponse_Article();
// 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);
if (!UserIsJournalist) return GetAjaxResult_GoHome(responseData);
SaxSessionData_Online sessionData = SessionData_Online;
// Validate item properties.
model.ValidateArticleData(responseData);
@@ -258,7 +408,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
// Create new item if required.
if (article == null)
article = ActivityMgr.CreateJournalistArticle(SessionData.User.UserAccountId);
article = ActivityMgr.CreateJournalistArticle(sessionData.User.UserAccountId);
// Populate item properties.
if (model.ArticleRegionId != null)
@@ -272,20 +422,18 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
if (model.ArticleStatusCode != null)
article.Status = model.ArticleStatus;
// Content.
if (model.ArticleContentSegments != null)
{
SaxJournalistArticle.ContentData articleContent = new SaxJournalistArticle.ContentData();
foreach (String contentSegment in model.ArticleContentSegments)
{
if (StringUtil.IsEmpty(contentSegment)) continue;
var segment = articleContent.AddSegment();
segment.Body.Html = contentSegment;
}
article.BodyData = SaxJournalistArticle.GetContentData(articleContent);
}
// Retrieve all article images - before new article is created as uploaded images are assigned to user first.
SaxItemImage.Params prmItemImage = new SaxItemImage.Params();
if (SysId.IsValid(article.Id))
prmItemImage.ItemIdsIncluded.Add(article.GetItemId());
else
prmItemImage.ItemIdsIncluded.Add(new ItemId((short)Sax.DataItemType.UserAccount, sessionData.User.UserAccountId));
prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.Article);
prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.ArticleUpload);
prmItemImage.StatusCat = SaxItemImage.StatusCat.NotDeleted;
List<SaxItemImage> itemImages = ItemDataMgr.GetItemImageList(prmItemImage);
// Store item.
// 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))
@@ -294,18 +442,76 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + ActivityMgr.ErrorStateMessage));
}
}
else
// Content.
if (model.ArticleContentSegmentBodies != null)
{
SaxJournalistArticle.ContentData articleContent = new SaxJournalistArticle.ContentData();
for (int segmentIdx = 0; segmentIdx < model.ArticleContentSegmentBodies.Count; segmentIdx++)
{
String segmentBody = model.ArticleContentSegmentBodies[segmentIdx];
String segmentItemImageId = model.ArticleContentSegmentItemImageIds.Count > segmentIdx ? model.ArticleContentSegmentItemImageIds[segmentIdx] : "";
String segmentImageIdx = model.ArticleContentSegmentImageIdxs.Count > segmentIdx ? model.ArticleContentSegmentImageIdxs[segmentIdx] : "";
if (!StringUtil.IsEmpty(segmentBody))
{
// HTML Body segment.
var segment = articleContent.AddSegment();
segment.Body.Html = segmentBody;
}
else if (!StringUtil.IsEmpty(segmentItemImageId) || !StringUtil.IsEmpty(segmentImageIdx))
{
SysId itemImageId = segmentItemImageId.ToSysId();
int imageIdx = StringUtil.ToInt(segmentImageIdx);
// Check for new image first.
SaxItemImage itemImage = itemImages.GetItemImageBySessionImage(sessionData.SessionIdx, imageIdx);
if (itemImage == null)
itemImage = itemImages.GetItemImageById(itemImageId);
if (itemImage != null)
{
// Ensure that the image is correctly identified for the Article.
itemImage.ItemId = article.GetItemId();
itemImage.ImageType = Sax.ImageType.Article;
itemImage.SessionUid = 0;
itemImage.ImageUid = 0;
itemImage.Status = SaxItemImage.DefaultStatus;
if (ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo))
{
// Assign the image segment to the article.
var segment = articleContent.AddSegment();
segment.Image.ItemImageId = itemImage.Id;
// Remove the image from the list as it's now been handled.
itemImages.Remove(itemImage);
}
else
SaLogger.Warn(fn + " Failed to update article image: " + ItemDataMgr.ErrorStateMessage);
}
else
SaLogger.Warn(fn + " Failed to identify article image. ItemImageId: " + itemImageId.ToInt() + ". SessionIdx: " + sessionData.SessionIdx + ". ImageIdx: " + imageIdx + ".");
}
}
article.BodyData = SaxJournalistArticle.GetContentData(articleContent);
}
// Update the Article.
if (!ActivityMgr.UpdateJournalistArticle(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"] + "\n\n" + ActivityMgr.ErrorStateMessage));
}
}
// Store Article Activity Index data.
ActivityConsole.StoreActivityIndex(article, DbUpdateInfo);
// Delete remaining images as they are no longer required.
foreach (SaxItemImage itemImage in itemImages)
{
itemImage.SessionUid = 0;
itemImage.ImageUid = 0;
itemImage.Status = SaStatus.Deleted;
ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo);
}
// Construct response.
PopulateArticleResponseData(model, article, responseData.Article);
responseData.Success = true;
@@ -15,6 +15,7 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
namespace Saxonite.Net.Core.Web.Online.Controllers
{
@@ -236,8 +237,27 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
return keepLoggedInParams;
}
//-------------------------------------------------------------------
// Parameter encryption, eg. for images.
//-------------------------------------------------------------------
// Encryption key is the same for all users but a different IV value is generated for each session so that the links/parameters cannot be shared.
public static String Base64Key_OnlineApp { get; } = SacsEncryptionHelper.EncodePlainKey("<Saxonite#Online+App@Encryption>", SacsEncryptionHelper.KeyLength);
protected String EncryptOnlineParams(NameValueCollection parameters)
{
return HttpUtility.UrlEncode(EncryptParameters(parameters, SessionData_Online.Base64IV_OnlineApp, Base64Key_OnlineApp));
}
public static String EncryptOnlineParams(SaxController_Online controller, NameValueCollection parameters)
{
return controller.EncryptOnlineParams(parameters);
}
protected NameValueCollection ExtractOnlineParams(String encryptedParams)
{
return DecryptParameters(encryptedParams, SessionData_Online.Base64IV_OnlineApp, Base64Key_OnlineApp);
}
//-------------------------------------------------------------------
// Logging.
//-------------------------------------------------------------------
protected String getLogSuffix()
{
List<String> logSuffix = new List<string>();
@@ -1,4 +1,5 @@
using Sarand.Net.Standard.Base.App;
using Microsoft.AspNetCore.Http;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils;
@@ -49,7 +50,11 @@ namespace Saxonite.Net.Core.Web.Online.Models
public String ArticleStatusCode { get; set; }
public SaStatus ArticleStatus { get { return SacsSystem.GetStatusForCode(ArticleStatusCode); } }
// Article content.
public List<String> ArticleContentSegments { get; set; }
public List<String> ArticleContentSegmentBodies { get; set; }
public List<String> ArticleContentSegmentItemImageIds { get; set; }
public List<String> ArticleContentSegmentImageIdxs { get; set; }
// Article images.
public List<IFormFile> ArticleImage { get; set; }
//-------------------------------------------------------------------
// Validation.
@@ -85,6 +85,9 @@ else
</div>
<div class="sax-panel-item ArticleContentSegment">
</div>
<div class="sax-panel-item ArticleContentSegmentImage center">
<img src="" alt="" title="" />
</div>
<div class="sax-panel-item Opportunity">
<div class="OpportunityOrganisation"></div>
<div class="OpportunityPosition"></div>
@@ -82,13 +82,30 @@
<div class="sax-panel-item-template">
<div class="sax-panel-item ArticleSegment">
<input type="hidden" name="ArticleContentSegments" class="ArticleContentSegment" value="" />
<div class="row">
<div class="col"><div class="sax-article-segment"></div></div>
@* Inputs with same name for every segment to ensure they are uploaded as a list. *@
<input type="hidden" name="ArticleContentSegmentBodies" class="ArticleContentSegmentBody" value="" />
<input type="hidden" name="ArticleContentSegmentItemImageIds" class="ArticleContentSegmentItemImageId" value="" />
<input type="hidden" name="ArticleContentSegmentImageIdxs" class="ArticleContentSegmentImageIdx" value="" />
@* Image drop panel *@
<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;" />
</div>
</div>
@* Segment details *@
<div class="row">
@* Segment body *@
<div class="col">
<div class="sax-article-segment-body"></div>
<div class="sax-article-segment-image hidden"><img src="" alt="" title="" /></div>
</div>
<div class="fixed sax-actions">
@* Segment actions *@
<div class="sax-action sax-add"><img src="~/img/action/add24.png" alt="" title="" /></div>
<div class="sax-action sax-up"><img src="~/img/action/prev24.png" alt="" title="" /></div>
<div class="sax-action sax-down"><img src="~/img/action/next24.png" alt="" title="" /></div>
<div class="sax-action sax-add-image"><img src="~/img/action/image-add-24.png" alt="" title="" /></div>
<div class="sax-action sax-up"><img src="~/img/action/upload24.png" alt="" title="" /></div>
<div class="sax-action sax-down"><img src="~/img/action/download24.png" alt="" title="" /></div>
<div class="sax-action sax-delete"><img src="~/img/action/delete24.png" alt="" title="" /></div>
</div>
</div>
@@ -101,6 +118,35 @@
}
<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" />
<div class="spacer4"></div>
<div class="sax-form-control ArticleImage">
<div class="row">
<div class="fixed"><div style="padding:0 12px;">@Localiser["label.image"]</div></div>
<div class="col"><input type="file" id="ifArticleImage" name="" class="fullwidth" style="" /></div>
</div>
<div class="sax-message"></div>
</div>
<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>
<div class="spacer2"></div>
}
</div>
<script type="text/javascript">
sax.dlg.title.imageUpload = '@Localiser.GetJavascriptText("account.caption.image.upload")';
sax.msg.uploadFileSelect = '@Localiser.GetJavascriptText("msg.upload.file.select")';
sax.msg.uploadImageSingle = '@Localiser.GetJavascriptText("msg.upload.image.single")';
sax.msg.uploadFileSizeMax = '@Localiser.GetJavascriptText("msg.upload.file.size.max","{0}")';
sax.msg.uploadFileTypeInvalid = '@Localiser.GetJavascriptText("msg.upload.file.type.invalid","{0}")';
sax.msg.uploadingFile = '@Localiser.GetJavascriptText("msg.upload.file.uploading","{0}")';
</script>
<partial name="~/Views/Common/SelectRegion.cshtml" />
<partial name="~/Views/Common/SelectSport.cshtml" />
@@ -74,6 +74,7 @@
sax.lbl.availableCharacters = '@Localiser.GetJavascriptText("label.characters.count", "{0}")';
sax.lbl.noneSelected = '@Localiser.GetJavascriptText("label.selected.none")';
sax.lbl.numberSelected = '@Localiser.GetJavascriptText("label.selected.count", "{0}")';
sax.msg.itemRemoveConfirm = '@Localiser.GetJavascriptText("msg.confirm.item.remove")';
sax.msg.signOutConfirm = '@Localiser.GetJavascriptText("security.msg.signout.confirm")';
sax.msg.somethingGoneWrong = '@Localiser.GetJavascriptText("msg.something.gone.wrong")';
sax.msg.dataRefreshing = '@Localiser.GetJavascriptText("msg.data.refreshing")';
@@ -89,7 +89,12 @@
border-radius: 4px;
}
.sax-profile #pnlContactImageDrop.sax-panel-drop.sax-dragging
.sax-profile #pnlContactImageDrop.sax-panel-drop *
{
pointer-events: none;
}
.sax-profile #pnlContactImageDrop.sax-panel-drop.sax-file-drag
{
border-color: var(--color-profile);
}
@@ -69,6 +69,16 @@
{
}
#dlgActivity .sax-panel-item.Article .ArticleContentSegment
{
}
#dlgActivity .sax-panel-item.Article .ArticleContentSegmentImage img
{
max-width:75%;
max-height:400px;
}
.ui-dialog.sax-dialog-activity button.ActivityReaction
{
min-width: 80px;
@@ -23,10 +23,10 @@
border-radius: 6px;
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-article-segment
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-article-segment-body
{
min-height: 160px;
max-height: 320px;
min-height: 150px;
max-height: 300px;
margin: 0;
padding: 4px;
background-color: #e0efff;
@@ -36,13 +36,13 @@
z-index: 1000;
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment:hover .sax-article-segment
/*,.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-article-segment:focus*/
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment:hover .sax-article-segment-body
/*,.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-article-segment-body:focus*/
{
border: 2px solid #c0d0ff;
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-article-segment.mce-edit-focus
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-article-segment-body.mce-edit-focus
{
margin-top: 48px;
}
@@ -52,4 +52,58 @@
z-index: 1000;
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment.sax-file-drag
{
border-color: var(--color-article);
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-actions
{
margin: 2px 0;
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-action
{
margin: 0 2px;
padding: 2px 2px;
border-radius: 4px;
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-action:hover
{
background-color: var(--color-article-pale);
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-action img
{
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-panel-file-drop
{
display: none;
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment.sax-file-drag .sax-panel-file-drop
{
display: block;
margin: 4px;
border: 1px dashed var(--color-article);
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment.ArticleImage .sax-article-segment-body
{
display: none;
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment.ArticleImage .sax-article-segment-image
{
display: block;
}
.sax-article.ArticleContent .sax-article-content .sax-panel-item.ArticleSegment .sax-article-segment-image img
{
max-width: 320px;
max-height: 160px;
}
/* The End */
Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -5,6 +5,7 @@
(function (win, doc, undef)
{
"use strict";
sax.classFileDrag = 'sax-file-drag';
sax.profile = { contact: {}, sports: {}, organisations: {} };
//--------------------------------------------------------------
@@ -106,7 +107,7 @@
}
sax.onDropContactImageFile = function (file, context)
{
//sax.debug('onDropContactImageFile', file);
//sax.debug('onDropContactImageFile', file, context);
if (file.size > sax.maxProfileImageSize) return sax.doAlert(sax.dlg.title.imageUpload, sax.msg.uploadFileSizeMax.format(sax.formatFileSize(sax.maxProfileImageSize)));
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));
@@ -123,7 +124,7 @@
sax.handleContactImageUploadResponse = function (response)
{
let context = sax.data.contactImageUploadContext;
sax.debug('handleContactImageUploadResponse', response, context);
//sax.debug('handleContactImageUploadResponse', response, context);
if (!response) return;
var $section = $('.sax-panel-section.ProfileContact');
sax.refreshControlValues(response.controlValues, context);
@@ -340,9 +341,9 @@
sax.$pnl.contactImageDrag = $('#pnlContactImageDrop')
.on("dragenter", function (evt) { sax.haltEvent(evt); })
.on("dragover", function (evt) { sax.haltEvent(evt); if (!sax.$pnl.contactImageDrag.hasClass('sax-dragging')) sax.$pnl.contactImageDrag.addClass('sax-dragging'); })
.on("dragleave", function (evt) { sax.haltEvent(evt); sax.$pnl.contactImageDrag.removeClass('sax-dragging'); })
.on("drop", function (evt) { sax.haltEvent(evt); sax.$pnl.contactImageDrag.removeClass('sax-dragging'); sax.onDropContactImage(evt); });
.on("dragover", function (evt) { sax.haltEvent(evt); if (!sax.$pnl.contactImageDrag.hasClass(sax.classFileDrag)) sax.$pnl.contactImageDrag.addClass(sax.classFileDrag); })
.on("dragleave", function (evt) { sax.haltEvent(evt); sax.$pnl.contactImageDrag.removeClass(sax.classFileDrag); })
.on("drop", function (evt) { sax.haltEvent(evt); sax.$pnl.contactImageDrag.removeClass(sax.classFileDrag); sax.onDropContactImage(evt); });
$('.sax-panel-section.ProfileSports .sax-action.sax-add').on('click', function (evt) { sax.addProfileSport(); });
var opt = sax.dlgOpts();
+12 -2
View File
@@ -23,7 +23,7 @@
}
sax.doRefreshResults = function (response)
{
sax.debug('doRefreshResults', response);
//sax.debug('doRefreshResults', response);
delete sax.awaitingRefreshResponse;
var $results = $('.sax-panel-results');
var $msgs = $('.sax-panel-messages', $results).hide().empty();
@@ -81,14 +81,24 @@
if (item = response.article)
{
let $itm = $('.sax-panel-item-template .sax-panel-item.Article').clone();
let $segs = $('.ArticleContentSegments', $itm);
$('.ArticleHeadline', $itm).text(item.headline);
$('.ArticleSummary', $itm).text(item.summary).toggle(!!item.summary);
let segs = item.content.segments;
for (let segIdx = 0; segIdx < segs.length; segIdx++)
{
let seg = segs[segIdx];
if (seg.body)
{
let $seg = $('.sax-panel-item-template .sax-panel-item.ArticleContentSegment').clone().html(seg.body.html);
$('.ArticleContentSegments', $itm).append($seg);
$seg.appendTo($segs);
}
if (seg.image)
{
let $seg = $('.sax-panel-item-template .sax-panel-item.ArticleContentSegmentImage').clone();
$('img', $seg).prop('src', seg.image.link);
$seg.appendTo($segs);
}
}
$act.append($itm);
}
+117 -20
View File
@@ -7,6 +7,7 @@
"use strict";
sax.itemIdPrefix = 'Itm_';
sax.segIdPrefix = 'Seg_';
sax.classFileDrag = 'sax-file-drag';
let ac = sax.articleContent = sax.articleContent || {};
//--------------------------------------------------------------
@@ -68,16 +69,16 @@
}
sax.populateArticleContent = function (content)
{
sax.debug('populateArticleContent', content);
//sax.debug('populateArticleContent', content);
ac.$segList.empty();
ac.segIdx = 0;
let segments = content.segments || [{}];
if (!segments.length) segments.push({});
let segments = content.segments || [];
if (!segments.length) segments.push({ body: {}});
for (let segIdx = 0; segIdx < segments.length; segIdx++)
sax.addContentSegment(segments[segIdx]);
}
sax.addContentSegment = function (seg)
sax.addContentSegment = function (seg, idxAfter, idxBefore)
{
let idx = ++ac.segIdx;
let segId = sax.segmentId(idx);
@@ -86,15 +87,33 @@
return;
}
let $seg = $('.sax-panel-item-template .sax-panel-item.ArticleSegment', ac.$content).clone().prop('id', segId)
let segBody = seg.body || {};
$('.sax-article-segment', $seg).html(segBody.html);
$('input.ArticleContentSegment', $seg).val(segBody.html);
ac.$segList.append($seg);
$('.sax-action.sax-add', $seg).on('click', function () { sax.addContentSegment({}, idx); });
if (seg.body)
{
$('.sax-article-segment-body', $seg).html(seg.body.html);
$('input.ArticleContentSegmentBody', $seg).val(seg.body.html);
}
else if (seg.image)
{
$seg.addClass("ArticleImage");
$('input.ArticleContentSegmentItemImageId', $seg).val(seg.image.itemImageId);
$('input.ArticleContentSegmentImageIdx', $seg).val(seg.image.imageIdx);
$('.sax-article-segment-image', $seg).show().find('img').prop('src', seg.image.imageLink);
$('.sax-action.sax-add-image', $seg).hide();
}
$('.sax-action.sax-add', $seg).on('click', function () { sax.addContentSegment({ body: {} }, idx); });
$('.sax-action.sax-add-image', $seg).on('click', function () { sax.selectArticleImage(idx); });
$('.sax-action.sax-up', $seg).on('click', function () { sax.moveUpContentSegment(idx); });
$('.sax-action.sax-down', $seg).on('click', function () { sax.moveDownContentSegment(idx); });
$('.sax-action.sax-delete', $seg).on('click', function () { sax.deleteContentSegment(idx); });
let $segAfter = $('#' + sax.segmentId(idxAfter));
let $segBefore = $('#' + sax.segmentId(idxBefore));
if ($segAfter.length) $seg.insertAfter($segAfter);
else if ($segBefore.length) $seg.insertBefore($segBefore);
else ac.$segList.append($seg);
if (seg.body)
{
tinymce.init({
branding: false,
elementpath: true,
@@ -102,27 +121,34 @@
inline: true,
//skin: 'small',
//icons: 'small',
selector: '#' + segId + ' .sax-article-segment',
selector: '#' + segId + ' .sax-article-segment-body',
setup: function (ed)
{
ed.on('focus', function (e)
{
ed.notificationManager.close();
});
ed.on('blur', function (e)
{
let ed = tinymce.get(e.target.id);
let $ed = $('#' + ed.id);
let $seg = $ed.closest('.sax-panel-item.ArticleSegment');
$(".sax-article-segment p", $seg).each(function (i,el) { if ($.trim($(el).text()) == "") { $(el).remove(); } });
let $inp = $seg.find('input.ArticleContentSegment').val(ed.getContent());
sax.debug('blur Id: ' + e.target.id + '. Val: ' + $inp.val());
$(".sax-article-segment-body p", $seg).each(function (i, el) { if ($.trim($(el).text()) == "") { $(el).remove(); } });
let $inp = $seg.find('input.ArticleContentSegmentBody').val(ed.getContent());
//sax.debug('blur Id: ' + e.target.id + '. Val: ' + $inp.val());
});
},
/*
plugins: [
//'paste image'
//'link',
'lists',
//'lists',
//'powerpaste',
//'autolink',
//'tinymcespellchecker'
],
//paste_block_drop: true,
//powerpaste_block_drop: true,
/*
//powerpaste_word_import: 'clean',
//powerpaste_html_import: 'clean',
*/
@@ -131,12 +157,20 @@
'forecolor backcolor | alignleft aligncenter alignright alignfull | numlist bullist outdent indent'
],
valid_elements: 'p[style],strong,em,span[style],a[href],ul,ol,li',
valid_styles: { '*': 'font-size,font-family,color,text-decoration,text-align' },
valid_styles: { '*': 'font-size,font-family,color,background-color,text-decoration,text-align' },
});
$seg.dragCount = 0;
$seg
.on("dragenter", function (evt) { $seg.dragCount++; sax.haltEvent(evt); })
.on("dragover", function (evt) { sax.haltEvent(evt); if (!$seg.hasClass(sax.classFileDrag)) $seg.addClass(sax.classFileDrag); })
.on("dragleave", function (evt) { $seg.dragCount--; sax.haltEvent(evt); if (!$seg.dragCount) $seg.removeClass(sax.classFileDrag); })
.on("drop", function (evt) { sax.haltEvent(evt); $seg.removeClass(sax.classFileDrag); sax.onDropArticleImage(evt, idx, $seg); });
}
}
sax.moveUpContentSegment = function (idx)
{
sax.debug('moveUpContentSegment(' + idx + ')');
//sax.debug('moveUpContentSegment(' + idx + ')');
let segId = sax.segmentId(idx);
let $segPrev;
$('.sax-panel-item.ArticleSegment', ac.$segList).detach().each(
@@ -154,7 +188,7 @@
}
sax.moveDownContentSegment = function (idx)
{
sax.debug('moveDownContentSegment(' + idx + ')');
//sax.debug('moveDownContentSegment(' + idx + ')');
let segId = sax.segmentId(idx);
let $segMove;
let $segs = $('.sax-panel-item.ArticleSegment', ac.$segList).detach();
@@ -169,13 +203,71 @@
}
ac.$segList.append($seg);
if ($segMove) $segMove.insertAfter($seg);
$segMove = null;
});
}
sax.deleteContentSegment = function (idx)
{
sax.debug('deleteContentSegment(' + idx + ')');
//sax.debug('deleteContentSegment(' + idx + ')');
if ($('.sax-panel-item.ArticleSegment', ac.$segList).length < 2) return;
$('#' + sax.segmentId(idx)).remove();
sax.confirmItemRemove(function () { $('#' + sax.segmentId(idx)).remove(); });
}
sax.selectArticleImage = function (idx)
{
let $dlg = sax.$dlg.selectArticleImage.dialog('option', { title: sax.dlg.title.imageUpload });
$('input.SegmentIdx', $dlg).val(idx);
$('#ifArticleImage', $dlg).val('');
sax.openDialog($dlg, 560, 240);
}
sax.uploadArticleImage = function ()
{
let $dlg = sax.$dlg.selectArticleImage;
let $fileCtrl = $('#ifArticleImage', $dlg);
if (!$fileCtrl.length || !$fileCtrl[0].files.length)
return sax.doAlert(sax.dlg.title.imageUpload, sax.msg.uploadFileSelect);
let file = $fileCtrl[0].files[0];
sax.onDropArticleImageFile(file, $('input.SegmentIdx', $dlg).val(), $dlg);
}
sax.onDropArticleImage = function (evt, idx, $seg)
{
//sax.debug('onDropArticleImage');
let files = evt.originalEvent.dataTransfer.files;
if (files.length < 1) return;
if (files.length > 1) return sax.doAlert(sax.dlg.title.imageUpload, sax.msg.uploadImageSingle);
sax.onDropArticleImageFile(files[0], idx, $('#frmArticle'));
}
sax.onDropArticleImageFile = function (file, idx, context)
{
//sax.debug('onDropArticleImageFile', file, context);
ac.segIdxAddImage = idx;
if (file.size > sax.maxProfileImageSize) return sax.doAlert(sax.dlg.title.imageUpload, sax.msg.uploadFileSizeMax.format(sax.formatFileSize(sax.maxProfileImageSize)));
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.data.contactImageUploadContext = context;
sax.ajax.uploadArticleImage = sax.ajax.uploadArticleImage || { url: sax.url.base + 'Journalist/Ajax/UploadArticleImage', 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("ArticleImage", file);
sax.doAjaxRequest(sax.ajax.uploadArticleImage, 50);
}
sax.handleArticleImageUploadResponse = function (response)
{
let context = sax.data.contactImageUploadContext;
//sax.debug('handleArticleImageUploadResponse', response, context);
if (!response) return;
sax.refreshControlValues(response.controlValues, context);
$(".UploadMessage", context).empty();
$('img.ArticleImageUploadProgress', context).hide();
if (response.success && response.segment)
{
sax.addContentSegment(response.segment, 0, ac.segIdxAddImage);
delete ac.segIdxAddImage;
sax.$dlg.selectArticleImage.dialog('close');
}
}
//--------------------------------------------------------------
@@ -313,6 +405,11 @@
ac.$content = $('.sax-article-panel.sax-article-content');
ac.$segList = $('.sax-article-segment-list', ac.$content);
var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.ok] = function () { sax.uploadArticleImage(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
sax.$dlg.selectArticleImage = $('#dlgSelectArticleImage').dialog(opt);
setTimeout(sax.refreshResults, 250);
});
+16 -11
View File
@@ -68,7 +68,7 @@
evt.preventDefault();
evt.stopPropagation();
}
sax.debug = sax.debugMode ? window.console.log.bind(window.console) : function () { };
sax.debug = sax.debugMode ? win.console.log.bind(win.console) : function () { };
//--------------------------------------------------------------
sax.setOddDataRowClass = function (rowSel, cName)
@@ -152,10 +152,11 @@
// Dialogs.
sax.openDialog = function ($dlg, width, height)
{
let $win = $(win);
$dlg.dialog(
{
minWidth: null, maxWidth: null, width: Math.min(width || 400, $(window).width() * .90),
minHeight: null, maxHeight: null, height: Math.min(height || 320, $(window).innerHeight() * .90)
minWidth: null, maxWidth: null, width: Math.min(width || 400, $win.width() * .90),
minHeight: null, maxHeight: null, height: Math.min(height || 320, $win.innerHeight() * .96)
}).dialog('open');
return $dlg;
}
@@ -205,6 +206,10 @@
$('#dlgConfirmMsg').html(msg);
sax.openDialog(sax.$dlg.confirm);
}
sax.confirmItemRemove = function (fn)
{
sax.doConfirm('', sax.msg.itemRemoveConfirm, fn);
}
sax.doProgress = function (title, msg, delay)
{
if (!msg)
@@ -235,8 +240,8 @@
// Notifications.
sax.showNotification = function (title, msg)
{
window.clearTimeout(sax.toNotification);
var $win = $(window);
win.clearTimeout(sax.toNotification);
var $win = $(win);
var $not = $('#sax-notification').hide();
if (!$not.length)
{
@@ -255,7 +260,7 @@
}
sax.hideNotification = function ()
{
window.clearTimeout(sax.toNotification);
win.clearTimeout(sax.toNotification);
$('#sax-notification').slideUp(500);
}
sax.doPleaseWait = function ()
@@ -272,13 +277,13 @@
// Ajax.
sax.doAjaxRequest = function (ajax, delay)
{
window.clearTimeout(ajax.timeout);
win.clearTimeout(ajax.timeout);
if (!ajax.noWaitIcon) sax.doPleaseWait();
ajax.timeout = setTimeout(function () { sax.execAjaxRequest(ajax); }, Math.max(50, parseInt(delay || 0, 10)));
}
sax.execAjaxRequest = function (ajax)
{
window.clearTimeout(ajax.timeout);
win.clearTimeout(ajax.timeout);
if (ajax.request) ajax.request.abort();
var cfgAjax =
{
@@ -360,7 +365,7 @@
{
sax.session = sax.session || { refresh: {} };
let ssr = sax.session.refresh;
window.clearTimeout(ssr.timeout);
win.clearTimeout(ssr.timeout);
ssr.timeout = setTimeout(function () { sax.refreshSession(); }, 150000);
}
sax.refreshSession = function ()
@@ -461,11 +466,11 @@
if (viewport.is('xs')) $body.addClass('mob');
else if (viewport.current() != 'unrecognized') $body.addClass('dsk');
}
sax.isAutoHeight = function () { return ($(window).width() < 360 || $(window).height() < 560 || sax.isMob()); }
sax.isAutoHeight = function () { return ($(win).width() < 360 || $(win).height() < 560 || sax.isMob()); }
sax.onWinResizePage = function () { };
sax.onWinResize = function ()
{
var winH = $(window).height();
var winH = $(win).height();
var $pageBody = $('#sax-page-body');
var $hdr = $('#sax-page-header');
var $ftr = $('#sax-page-footer');
+3 -1
View File
@@ -18,7 +18,7 @@ namespace Saxonite.Net.Standard.Base.App
//-------------------------------------------------------------------
public static class Version
{
private static String version { get; } = "1.0.8.1";
private static String version { get; } = "1.0.9.0";
// Retrieve version.
public static String GetFullVersion () { return version; }
public static String GetAppVersion ()
@@ -40,6 +40,8 @@ namespace Saxonite.Net.Standard.Base.App
//-------------------------------------------------------------------
// Version history.
//-------------------------------------------------------------------
// 1.0.9 ?-Jun-2021 Journalist Articles
// - Online Article Images.
// 1.0.8 15-Jun-2021 Online Article Content
// - Journalist Articles styled content.
// - Online home page click through activity for details with reaction.
+5 -1
View File
@@ -227,8 +227,12 @@ namespace Saxonite.Net.Standard.Base.App
Unknown,
/// <summary>User's profile image.</summary>
Avatar = 100,
/// <summary>User's new profile image awaiting confirmation.</summary>
/// <summary>User's profile image, uploaded awaiting confirmation.</summary>
AvatarUpload = 101,
/// <summary>Journalist Article image.</summary>
Article = 200,
/// <summary>Journalist Article image uploaded, awaiting confirmation.</summary>
ArticleUpload = 201,
}
//-------------------------------------------------------------------
@@ -6,7 +6,7 @@ using System.Collections.Generic;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Base.App
{
@@ -57,6 +57,8 @@ namespace Saxonite.Base.App
ItemImage_ItemId,
ItemImage_ImageType,
ItemImage_ImageSeq,
ItemImage_SessionUid,
ItemImage_ImageUid,
ItemImage_Filename,
ItemImage_Mime,
ItemImage_ContentType,
@@ -269,7 +271,7 @@ namespace Saxonite.Base.App
//-------------------------------------------------------------------
// Data members.
private static readonly int tableCount = 14;
private static readonly int columnCount = 226;
private static readonly int columnCount = 228;
private static ulong maxTextLen = 0;
//-------------------------------------------------------------------
@@ -474,6 +476,8 @@ namespace Saxonite.Base.App
new ColumnDfn(2,"ItemId",4,4,false,10),
new ColumnDfn(2,"ImageType",3,5,false,5),
new ColumnDfn(2,"ImageSeq",2,-6,false,3),
new ColumnDfn(2,"SessionUid",5,-5,false,19),
new ColumnDfn(2,"ImageUid",4,4,false,10),
new ColumnDfn(2,"Filename",0,-9,false,1024),
new ColumnDfn(2,"Mime",0,12,false,64),
new ColumnDfn(2,"ContentType",0,12,false,128),
@@ -10,6 +10,7 @@ using System.Text;
using System.Diagnostics;
using Sarand.Net.Standard.Base.Utils;
using Newtonsoft.Json.Converters;
using Sarand.Net.Standard.Base.Helpers;
namespace Saxonite.Net.Standard.Base.App
{
@@ -17,16 +18,15 @@ namespace Saxonite.Net.Standard.Base.App
public abstract class SaxSessionData
{
//-------------------------------------------------------------------
// Protected construction.
protected SaxSessionData()
{
}
private static long sessionIdxRoot = SacsRandomHelper.GetInt32(1000, 1999);
//-------------------------------------------------------------------
// Construction.
/// <summary>Hidden constructor for deserialisation only.</summary>
private SaxSessionData(SaxSessionContext sessionContext)
/// <summary>Protected constructor for deserialisation only.</summary>
protected SaxSessionData(long sessionIdx, int itemIdx, SaxSessionContext sessionContext)
{
SessionIdx = sessionIdx;
ItemIdx = itemIdx;
SessionContext = sessionContext;
userData = CreateUserData(SessionContext, null, null);
}
@@ -37,12 +37,20 @@ namespace Saxonite.Net.Standard.Base.App
/// </summary>
protected SaxSessionData(SaxSessionContext sessionContext, SaxUserAccount userAccount, List<SaxUserRole> userRoles)
{
SessionIdx = ++sessionIdxRoot;
ItemIdx = 1000;
SessionContext = sessionContext;
userData = CreateUserData(SessionContext, userAccount, userRoles);
}
//-------------------------------------------------------------------
// Properties.
// Session and Item indexers.
public long SessionIdx { get; }
public int ItemIdx { get; private set; }
[JsonIgnore]
public int NextItemIdx { get { return ++ItemIdx; } }
// Session context.
public SaxSessionContext SessionContext { get; }
[JsonIgnore]
public bool ValidUserSession { get { return SysId.IsValid(User.UserAccountId) && SysId.IsValid(User.UserAccountId); } }
@@ -98,6 +98,8 @@ namespace Saxonite.Net.Standard.Base.App
// Image types.
imageTypeCodes.Add(Sax.ImageType.Avatar, "Avatar", "Avatar");
imageTypeCodes.Add(Sax.ImageType.AvatarUpload, "AvatarUpload", "Avatar - upload");
imageTypeCodes.Add(Sax.ImageType.Article, "Article", "Article");
imageTypeCodes.Add(Sax.ImageType.ArticleUpload, "ArticleUpload", "Article - upload");
//---------------------------------------------------------------
// Organisation types.
+43 -2
View File
@@ -53,6 +53,8 @@ namespace Saxonite.Net.Standard.Base.Bus
public ItemId ItemId { get; set; }
public Sax.ImageType ImageType { get; set; }
public byte ImageSeq { get; set; }
public long SessionUid { get; set; }
public int ImageUid { get; set; }
public String Filename { get; set; }
public String Mime { get; set; }
public String ContentType { get; set; }
@@ -88,6 +90,16 @@ namespace Saxonite.Net.Standard.Base.Bus
get { return data.ImageSeq; }
set { CheckChanged(data.ImageSeq, value); data.ImageSeq = value; }
}
public long SessionUid
{
get { return data.SessionUid; }
set { CheckChanged(data.SessionUid, value); data.SessionUid = value; }
}
public int ImageUid
{
get { return data.ImageUid; }
set { CheckChanged(data.ImageUid, value); data.ImageUid = value; }
}
public String Filename
{
get { return data.Filename; }
@@ -124,6 +136,8 @@ namespace Saxonite.Net.Standard.Base.Bus
ItemId = data.ItemId;
ImageType = data.ImageType;
ImageSeq = data.ImageSeq;
SessionUid = data.SessionUid;
ImageUid = data.ImageUid;
Filename = data.Filename;
Mime = data.Mime;
ContentType = data.ContentType;
@@ -148,6 +162,8 @@ namespace Saxonite.Net.Standard.Base.Bus
public ValidValue ItemId { get; set; } = ValidValue.Valid;
public ValidValue ImageType { get; set; } = ValidValue.Valid;
public ValidValue ImageSeq { get; set; } = ValidValue.Valid;
public ValidValue SessionUid { get; set; } = ValidValue.Valid;
public ValidValue ImageUid { get; set; } = ValidValue.Valid;
public ValidValue Filename { get; set; } = ValidValue.Valid;
public ValidValue Mime { get; set; } = ValidValue.Valid;
public ValidValue ContentType { get; set; } = ValidValue.Valid;
@@ -213,18 +229,28 @@ namespace Saxonite.Net.Standard.Base.Bus
public ItemId ItemId
{
get { return data.ItemId; }
protected set { data.ItemId = value; }
set { data.ItemId = value; }
}
public Sax.ImageType ImageType
{
get { return data.ImageType; }
protected set { data.ImageType = value; }
set { data.ImageType = value; }
}
public byte ImageSeq
{
get { return data.ImageSeq; }
set { data.ImageSeq = value; }
}
public long SessionUid
{
get { return data.SessionUid; }
set { data.SessionUid = value; }
}
public int ImageUid
{
get { return data.ImageUid; }
set { data.ImageUid = value; }
}
public String Filename
{
get { return data.Filename; }
@@ -273,6 +299,7 @@ namespace Saxonite.Net.Standard.Base.Bus
NotDeleted,
ActiveOnly,
InctiveOnly,
Deleted,
}
/// <summary>
/// Item list parameters.
@@ -294,6 +321,20 @@ namespace Saxonite.Net.Standard.Base.Bus
// Item list extension methods.
public static class SaxItemImageList
{
//-------------------------------------------------------------------
public static SaxItemImage GetItemImageById(this List<SaxItemImage> values, SysId itemImageId)
{
if (!SysId.IsValid(itemImageId)) return null;
return values.Find(item => item.Id.Equals(itemImageId));
}
public static SaxItemImage GetItemImageBySessionImage(this List<SaxItemImage> values, long sessionUid, int imageUid)
{
if (sessionUid < 1 || imageUid < 1) return null;
return values.Find(item => item.SessionUid == sessionUid && item.ImageUid == imageUid);
}
//-------------------------------------------------------------------
}
//=======================================================================
@@ -22,22 +22,45 @@ namespace Saxonite.Net.Standard.Base.Bus
private static readonly String ElementName_Segment = "segment";
private static readonly String ElementName_Body = "body";
private static readonly String ElementName_Html = "html";
private static readonly String ElementName_Image = "image";
private static readonly String ElementName_ImageId = "imageId";
//-------------------------------------------------------------------
/// <summary>Article content.</summary>
public class ContentData
{
/// <summary>
/// Article Content Segment - either body content or image.
/// </summary>
public class SegmentData
{
// Segment body.
public class BodyData
{
public bool IsValid()
{
if (!StringUtil.IsEmpty(Html)) return true;
return false;
}
public String Html { get; set; } = String.Empty;
}
public BodyData Body { get; } = new BodyData();
// Segment image.
public class ImageData
{
public bool IsValid()
{
if (SysId.IsValid(ItemImageId)) return true;
return false;
}
public SysId ItemImageId { get; set; }
}
public ImageData Image { get; } = new ImageData();
// Validate.
public bool IsValid()
{
if (!StringUtil.IsEmpty(Body.Html)) return true;
if (Body.IsValid()) return true;
if (Image.IsValid()) return true;
return false;
}
}
@@ -59,6 +82,7 @@ namespace Saxonite.Net.Standard.Base.Bus
{
String fn = typeof(ContentData).FullName + ".ExtractContent";
ContentData content = new ContentData();
if (StringUtil.IsEmpty(contentData)) return content;
try
{
@@ -99,6 +123,22 @@ namespace Saxonite.Net.Standard.Base.Bus
else SaLogger.Warn(fn + " Unexpected 'Segment' child element: " + segmentChildElementName);
}
}
else if (segmentChildElementName.EqualsCI(ElementName_Image))
{
// Content segment image.
XElement imageElement = segmentChildElement;
foreach (XElement imageChildElement in imageElement.GetChildElements())
{
String imageChildElementName = imageChildElement.GetLocalName();
if (imageChildElementName.EqualsCI(ElementName_ImageId))
{
// Content segment image Id.
XElement imageIdElement = imageChildElement;
segment.Image.ItemImageId = imageIdElement.Value.ToSysId();
}
else SaLogger.Warn(fn + " Unexpected 'Segment' child element: " + segmentChildElementName);
}
}
else SaLogger.Warn(fn + " Unexpected 'Segment' child element: " + segmentChildElementName);
}
// Add this segment to the list.
@@ -136,10 +176,21 @@ namespace Saxonite.Net.Standard.Base.Bus
{
if (!segment.IsValid()) continue;
XElement segmentElement = segmentsElement.AppendElement(ElementName_Segment);
if (segment.Body.IsValid())
{
// Segment Body.
XElement bodyElement = segmentElement.AppendElement(ElementName_Body);
if (!StringUtil.IsEmpty(segment.Body.Html))
bodyElement.AppendElement(ElementName_Html, segment.Body.Html);
}
else if (segment.Image.IsValid())
{
// Segment Image.
XElement imageElement = segmentElement.AppendElement(ElementName_Image);
if (SysId.IsValid(segment.Image.ItemImageId))
imageElement.AppendElement(ElementName_ImageId, SysId.ToString(segment.Image.ItemImageId));
}
}
return doc.GetXml();
}
catch (Exception exc)
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -24,6 +24,8 @@ namespace Saxonite.Net.Standard.Dbas.Internal
public ColumnDataInt32 _ItemId { get; } = new ColumnDataInt32("ItemId");
public ColumnDataInt16 _ImageType { get; } = new ColumnDataInt16("ImageType");
public ColumnDataByte _ImageSeq { get; } = new ColumnDataByte("ImageSeq");
public ColumnDataInt64 _SessionUid { get; } = new ColumnDataInt64("SessionUid");
public ColumnDataInt32 _ImageUid { get; } = new ColumnDataInt32("ImageUid");
public ColumnDataString _Filename { get; } = new ColumnDataString("Filename");
public ColumnDataString _Mime { get; } = new ColumnDataString("Mime");
public ColumnDataString _ContentType { get; } = new ColumnDataString("ContentType");
@@ -50,6 +52,8 @@ namespace Saxonite.Net.Standard.Dbas.Internal
"ItemId",
"ImageType",
"ImageSeq",
"SessionUid",
"ImageUid",
"Filename",
"Mime",
"ContentType",
@@ -102,6 +106,8 @@ namespace Saxonite.Net.Standard.Dbas.Internal
public Int32 _ItemId { get { return Cols._ItemId.Value; } set { Cols._ItemId.Value = value; } }
public Int16 _ImageType { get { return Cols._ImageType.Value; } set { Cols._ImageType.Value = value; } }
public Byte _ImageSeq { get { return Cols._ImageSeq.Value; } set { Cols._ImageSeq.Value = value; } }
public Int64 _SessionUid { get { return Cols._SessionUid.Value; } set { Cols._SessionUid.Value = value; } }
public Int32 _ImageUid { get { return Cols._ImageUid.Value; } set { Cols._ImageUid.Value = value; } }
public String _Filename { get { return Cols._Filename.Value; } set { Cols._Filename.Value = value; } }
public String _Mime { get { return Cols._Mime.Value; } set { Cols._Mime.Value = value; } }
public String _ContentType { get { return Cols._ContentType.Value; } set { Cols._ContentType.Value = value; } }
@@ -143,6 +149,8 @@ namespace Saxonite.Net.Standard.Dbas.Internal
_ItemId = GetFieldInt32(dbDataReader, "ItemId", _ItemId);
_ImageType = GetFieldInt16(dbDataReader, "ImageType", _ImageType);
_ImageSeq = GetFieldByte(dbDataReader, "ImageSeq", _ImageSeq);
_SessionUid = GetFieldInt64(dbDataReader, "SessionUid", _SessionUid);
_ImageUid = GetFieldInt32(dbDataReader, "ImageUid", _ImageUid);
_Filename = GetFieldString(dbDataReader, "Filename", _Filename);
_Mime = GetFieldString(dbDataReader, "Mime", _Mime);
_ContentType = GetFieldString(dbDataReader, "ContentType", _ContentType);
@@ -183,6 +191,8 @@ namespace Saxonite.Net.Standard.Dbas.Internal
if (columnNames.ContainsCI("ItemId")) AddCommandParameter(dbCommand, "@ItemId", _ItemId);
if (columnNames.ContainsCI("ImageType")) AddCommandParameter(dbCommand, "@ImageType", _ImageType);
if (columnNames.ContainsCI("ImageSeq")) AddCommandParameter(dbCommand, "@ImageSeq", _ImageSeq);
if (columnNames.ContainsCI("SessionUid")) AddCommandParameter(dbCommand, "@SessionUid", _SessionUid);
if (columnNames.ContainsCI("ImageUid")) AddCommandParameter(dbCommand, "@ImageUid", _ImageUid);
if (columnNames.ContainsCI("Filename")) AddCommandParameter(dbCommand, "@Filename", _Filename);
if (columnNames.ContainsCI("Mime")) AddCommandParameter(dbCommand, "@Mime", _Mime);
if (columnNames.ContainsCI("ContentType")) AddCommandParameter(dbCommand, "@ContentType", _ContentType);
@@ -238,6 +248,8 @@ namespace Saxonite.Net.Standard.Dbas.Internal
if (columnNames.ContainsCI("ItemId")) AddCommandParameter(dbCommand, "@ItemId", _ItemId);
if (columnNames.ContainsCI("ImageType")) AddCommandParameter(dbCommand, "@ImageType", _ImageType);
if (columnNames.ContainsCI("ImageSeq")) AddCommandParameter(dbCommand, "@ImageSeq", _ImageSeq);
if (columnNames.ContainsCI("SessionUid")) AddCommandParameter(dbCommand, "@SessionUid", _SessionUid);
if (columnNames.ContainsCI("ImageUid")) AddCommandParameter(dbCommand, "@ImageUid", _ImageUid);
if (columnNames.ContainsCI("Filename")) AddCommandParameter(dbCommand, "@Filename", _Filename);
if (columnNames.ContainsCI("Mime")) AddCommandParameter(dbCommand, "@Mime", _Mime);
if (columnNames.ContainsCI("ContentType")) AddCommandParameter(dbCommand, "@ContentType", _ContentType);
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -9,7 +9,7 @@ using System.Data.Common;
using System.Linq;
//---------------------------------------------------------------------------
// Code generated by Sarand Database Utilities Fri 18-Jun-2021 11:08:40
// Code generated by Sarand Database Utilities Tue 22-Jun-2021 08:56:11
//---------------------------------------------------------------------------
namespace Saxonite.Net.Standard.Dbas.Internal
{
@@ -29,7 +29,7 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
return new List<StringPair>()
{
new StringPair("Id", SysId.ToString(itemImage.Id)),
new StringPair("ItemId", ItemId.ToString(itemImage.ItemId)),
new StringPair("ItemId", (Sax.DataItemType)itemImage.ItemId.Type + ": " + itemImage.ItemId.Id),
new StringPair("ImageType", itemImage.ImageType.ToString()),
new StringPair("Status", itemImage.StatusCode)
};
@@ -209,6 +209,8 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
dbItemImage._ItemId = SysId.ToInt(itemImage.ItemId.Id);
dbItemImage._ImageType = (short)itemImage.ImageType;
dbItemImage._ImageSeq = itemImage.ImageSeq;
dbItemImage._SessionUid = itemImage.SessionUid;
dbItemImage._ImageUid = itemImage.ImageUid;
dbItemImage._Filename = itemImage.Filename;
dbItemImage._Mime = itemImage.Mime;
dbItemImage._ContentType = itemImage.ContentType;
@@ -235,6 +237,8 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
//itemImage.ItemId = new ItemId(dbItemImage._ItemType, new SysId(dbItemImage._ItemId);
//itemImage.ImageType = (Sax.ImageType)dbItemImage._ImageType;
itemImage.ImageSeq = dbItemImage._ImageSeq;
itemImage.SessionUid = dbItemImage._SessionUid;
itemImage.ImageUid = dbItemImage._ImageUid;
itemImage.Filename = dbItemImage._Filename;
itemImage.Mime = dbItemImage._Mime;
itemImage.ContentType = dbItemImage._ContentType;
@@ -407,8 +411,12 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
// Status.
if (prm.StatusCat == SaxItemImage.StatusCat.ActiveOnly)
filter.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ItemImage_Status, aliasItemImage) + "='" + SacsSystem.GetStatusCode(SaStatus.Active) + "'");
else if (prm.StatusCat == SaxItemImage.StatusCat.InctiveOnly)
filter.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ItemImage_Status, aliasItemImage) + "='" + SacsSystem.GetStatusCode(SaStatus.Inactive) + "'");
else if (prm.StatusCat == SaxItemImage.StatusCat.NotDeleted)
filter.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ItemImage_Status, aliasItemImage) + "!='" + SacsSystem.GetStatusCode(SaStatus.Deleted) + "'");
else if (prm.StatusCat == SaxItemImage.StatusCat.Deleted)
filter.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ItemImage_Status, aliasItemImage) + "='" + SacsSystem.GetStatusCode(SaStatus.Deleted) + "'");
if (filter.Count < 1) filter.Add("1=1");
return filter;
@@ -28,7 +28,7 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
return new List<StringPair>()
{
new StringPair("Id",SysId.ToString(itemSport.Id)),
new StringPair("ItemId",ItemId.ToString(itemSport.ItemId)),
new StringPair("ItemId", (Sax.DataItemType)itemSport.ItemId.Type + ": " + itemSport.ItemId.Id),
new StringPair("Sport",SysId.ToString(itemSport.SportId)),
new StringPair("Status",itemSport.StatusCode)
};
@@ -437,6 +437,40 @@
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>6</Pos>
<Name>SessionUid</Name>
<DataType>BigInt</DataType>
<DataTypeName />
<DataTypeNative>-5</DataTypeNative>
<DataTypeNameNative>bigint</DataTypeNameNative>
<IsIdentity>false</IsIdentity>
<Size>19</Size>
<BufferLen>8</BufferLen>
<DecimalDigits>0</DecimalDigits>
<Nullable>NoNulls</Nullable>
<IsNullable>false</IsNullable>
<Remarks />
</DbDfnColumn>
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>7</Pos>
<Name>ImageUid</Name>
<DataType>Int</DataType>
<DataTypeName />
<DataTypeNative>4</DataTypeNative>
<DataTypeNameNative>int</DataTypeNameNative>
<IsIdentity>false</IsIdentity>
<Size>10</Size>
<BufferLen>4</BufferLen>
<DecimalDigits>0</DecimalDigits>
<Nullable>NoNulls</Nullable>
<IsNullable>false</IsNullable>
<Remarks />
</DbDfnColumn>
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>8</Pos>
<Name>Filename</Name>
<DataType>VarChar</DataType>
<DataTypeName />
@@ -453,7 +487,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>7</Pos>
<Pos>9</Pos>
<Name>Mime</Name>
<DataType>VarChar</DataType>
<DataTypeName />
@@ -470,7 +504,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>8</Pos>
<Pos>10</Pos>
<Name>ContentType</Name>
<DataType>VarChar</DataType>
<DataTypeName />
@@ -487,7 +521,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>9</Pos>
<Pos>11</Pos>
<Name>Width</Name>
<DataType>Int</DataType>
<DataTypeName />
@@ -504,7 +538,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>10</Pos>
<Pos>12</Pos>
<Name>Height</Name>
<DataType>Int</DataType>
<DataTypeName />
@@ -521,7 +555,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>11</Pos>
<Pos>13</Pos>
<Name>ImageData</Name>
<DataType>Binary</DataType>
<DataTypeName />
@@ -538,7 +572,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>12</Pos>
<Pos>14</Pos>
<Name>Notes</Name>
<DataType>VarChar</DataType>
<DataTypeName />
@@ -555,7 +589,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>13</Pos>
<Pos>15</Pos>
<Name>Flags</Name>
<DataType>SmallInt</DataType>
<DataTypeName />
@@ -572,7 +606,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>14</Pos>
<Pos>16</Pos>
<Name>Status</Name>
<DataType>VarChar</DataType>
<DataTypeName />
@@ -589,7 +623,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>15</Pos>
<Pos>17</Pos>
<Name>CreateOn</Name>
<DataType>DateTime</DataType>
<DataTypeName />
@@ -606,7 +640,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>16</Pos>
<Pos>18</Pos>
<Name>CreateBy</Name>
<DataType>Int</DataType>
<DataTypeName />
@@ -623,7 +657,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>17</Pos>
<Pos>19</Pos>
<Name>CreateHost</Name>
<DataType>VarChar</DataType>
<DataTypeName />
@@ -640,7 +674,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>18</Pos>
<Pos>20</Pos>
<Name>UpdateOn</Name>
<DataType>DateTime</DataType>
<DataTypeName />
@@ -657,7 +691,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>19</Pos>
<Pos>21</Pos>
<Name>UpdateBy</Name>
<DataType>Int</DataType>
<DataTypeName />
@@ -674,7 +708,7 @@
<DbDfnColumn>
<Schema>dbo</Schema>
<Table>ItemImage</Table>
<Pos>20</Pos>
<Pos>22</Pos>
<Name>UpdateHost</Name>
<DataType>VarChar</DataType>
<DataTypeName />
@@ -700,7 +734,7 @@
<Clustered>false</Clustered>
<Nullable>false</Nullable>
<Pages>1</Pages>
<UniqueValues>2</UniqueValues>
<UniqueValues>5</UniqueValues>
<HasColumns>false</HasColumns>
<Columns>
<DbDfnIndexColumn>
@@ -3816,8 +3850,8 @@
<Primary>false</Primary>
<Clustered>false</Clustered>
<Nullable>false</Nullable>
<Pages>0</Pages>
<UniqueValues>0</UniqueValues>
<Pages>1</Pages>
<UniqueValues>8</UniqueValues>
<HasColumns>false</HasColumns>
<Columns>
<DbDfnIndexColumn>