From be6f5739e7030be0b867b2071d39969fb369aa18 Mon Sep 17 00:00:00 2001 From: Hoang Nguyen Date: Thu, 28 Dec 2017 19:50:32 +0700 Subject: [PATCH] Add FE BE Info ViewModel --- src/Swastika.Cms.Lib/Readme.txt | 2 +- .../TagHelpers/ActiveMenuTagHelper.cs | 104 +++ .../TagHelpers/ActiveRouteTagHelper.cs | 105 +++ .../BackEnd/BEArticleModuleViewModel.cs | 117 +++ .../ViewModels/BackEnd/BEArticleViewModel.cs | 699 ++++++++++++++++++ .../ViewModels/BackEnd/BEModuleViewModel.cs | 172 +++++ .../ViewModels/BackEnd/_BlankViewModel.cs | 49 ++ .../FrontEnd/FEArticleModuleViewModel.cs | 63 ++ .../ViewModels/FrontEnd/FEArticleViewModel.cs | 162 ++++ .../ViewModels/FrontEnd/FEModuleViewModel.cs | 110 +++ .../Info/InfoArticleModuleViewModel.cs | 47 ++ .../ViewModels/Info/InfoArticleViewModel.cs | 288 ++++++++ .../Info/InfoModuleAttributeViewModel.cs | 49 ++ .../Info/InfoModuleDataViewModel.cs | 144 ++++ .../ViewModels/Info/InfoModuleViewModel.cs | 49 ++ .../ViewModels/_BlankViewModel.cs | 50 ++ 16 files changed, 2209 insertions(+), 1 deletion(-) create mode 100644 src/Swastika.Cms.Lib/TagHelpers/ActiveMenuTagHelper.cs create mode 100644 src/Swastika.Cms.Lib/TagHelpers/ActiveRouteTagHelper.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/BackEnd/BEArticleModuleViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/BackEnd/BEArticleViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/BackEnd/BEModuleViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/BackEnd/_BlankViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEArticleModuleViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEArticleViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEModuleViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/Info/InfoArticleModuleViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/Info/InfoArticleViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleAttributeViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleDataViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleViewModel.cs create mode 100644 src/Swastika.Cms.Lib/ViewModels/_BlankViewModel.cs diff --git a/src/Swastika.Cms.Lib/Readme.txt b/src/Swastika.Cms.Lib/Readme.txt index a47a22a3..a5bc8ea1 100644 --- a/src/Swastika.Cms.Lib/Readme.txt +++ b/src/Swastika.Cms.Lib/Readme.txt @@ -15,7 +15,7 @@ dotnet add package System.IdentityModel.Tokens.Jwt Add-Migration AddFirstName -Context ApplicationDbContext -Update-database -Context ApplicationDbContext +Update-database -Context SiocCmsContext Scaffold-DbContext "Server=115.77.190.113,4444;Database=Stag_swastika_io;UID=sa;Pwd=sqlP@ssw0rd;MultipleActiveResultSets=true" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -force diff --git a/src/Swastika.Cms.Lib/TagHelpers/ActiveMenuTagHelper.cs b/src/Swastika.Cms.Lib/TagHelpers/ActiveMenuTagHelper.cs new file mode 100644 index 00000000..2cca7fe3 --- /dev/null +++ b/src/Swastika.Cms.Lib/TagHelpers/ActiveMenuTagHelper.cs @@ -0,0 +1,104 @@ +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.AspNetCore.Routing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Swastika.Web.Start.TagHelpers +{ + [HtmlTargetElement(Attributes = "is-active-menu")] + public class ActiveMenuTagHelper : TagHelper + { + private IDictionary _routeValues; + + /// The name of the controller. + /// Must be null if is non-null. + [HtmlAttributeName("asp-controllers")] + public string Controllers { get; set; } + [HtmlAttributeName("asp-action")] + public string Actions { get; set; } + [HtmlAttributeName("asp-route-pagenames")] + public string PageNames { get; set; } + + [HtmlAttributeName("asp-route-id")] + public string Id { get; set; } + + /// + /// Gets or sets the for the current request. + /// + [HtmlAttributeNotBound] + [ViewContext] + public ViewContext ViewContext { get; set; } + public IDictionary RouteValues { get => _routeValues; set => _routeValues = value; } + + public override void Process(TagHelperContext context, TagHelperOutput output) + { + base.Process(context, output); + + if (ShouldBeActive()) + { + MakeActive(output); + } + + output.Attributes.RemoveAll("is-active-menu"); + } + + private bool ShouldBeActive() + { + bool rtn = false; + string currentController = ViewContext.RouteData.Values["Controller"].ToString(); + + string currentAction = ViewContext.RouteData.Values["Action"].ToString(); + string id = ViewContext.RouteData.Values["Id"] != null ? ViewContext.RouteData.Values["Id"].ToString() : string.Empty; + string currentPagename = ViewContext.RouteData.Values["pageName"] != null ? ViewContext.RouteData.Values["pageName"].ToString() : string.Empty; + + List activeControllers = string.IsNullOrEmpty(Controllers) ? new List() : Controllers.ToLower().Split(',').ToList(); + List activeActions = string.IsNullOrEmpty(Actions) ? new List() : Actions.ToLower().Split(',').ToList(); + List activePageNames = string.IsNullOrEmpty(PageNames) ? new List() : PageNames.ToLower().Split(',').ToList(); + if (!string.IsNullOrWhiteSpace(Controllers)) + { + rtn = (string.IsNullOrEmpty(Actions) && string.IsNullOrEmpty(PageNames) && activeControllers.Contains(currentController.ToLower())) + || ( + activeControllers.Contains(currentController.ToLower()) // Current Controller + && activeActions.Contains(currentAction.ToLower()) // Current Action + && (string.IsNullOrEmpty(Id) || id==Id) // Current Details + && (string.IsNullOrEmpty(PageNames) || activePageNames.Contains(currentPagename.ToLower())) + ); + } + + //if (!string.IsNullOrWhiteSpace(Controllers)) + //{ + // foreach (string controller in Controllers.Split(',')) + // { + // if (currentController.ToLower() == controller.ToLower()) + // { + // rtn = true; + // break; + // } + // } + + //} + + return rtn; + } + + private void MakeActive(TagHelperOutput output) + { + var classAttr = output.Attributes.FirstOrDefault(a => a.Name == "class"); + if (classAttr == null) + { + classAttr = new TagHelperAttribute("class", "active"); + output.Attributes.Add(classAttr); + } + else if (classAttr.Value == null || classAttr.Value.ToString().IndexOf("active") < 0) + { + output.Attributes.SetAttribute("class", classAttr.Value == null + ? "active" + : classAttr.Value.ToString() + " active"); + } + } + } +} diff --git a/src/Swastika.Cms.Lib/TagHelpers/ActiveRouteTagHelper.cs b/src/Swastika.Cms.Lib/TagHelpers/ActiveRouteTagHelper.cs new file mode 100644 index 00000000..a9ee0bde --- /dev/null +++ b/src/Swastika.Cms.Lib/TagHelpers/ActiveRouteTagHelper.cs @@ -0,0 +1,105 @@ +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.AspNetCore.Routing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Swastika.Cms.Mvc.TagHelpers +{ + [HtmlTargetElement(Attributes = "is-active-route")] + public class ActiveRouteTagHelper : TagHelper + { + private IDictionary _routeValues; + + /// The name of the action method. + /// Must be null if is non-null. + [HtmlAttributeName("asp-action")] + public string Action { get; set; } + + /// The name of the controller. + /// Must be null if is non-null. + [HtmlAttributeName("asp-controller")] + public string Controller { get; set; } + + /// Additional parameters for the route. + [HtmlAttributeName("asp-all-route-data", DictionaryAttributePrefix = "asp-route-")] + public IDictionary RouteValues + { + get + { + if (this._routeValues == null) + this._routeValues = (IDictionary)new Dictionary((IEqualityComparer)StringComparer.OrdinalIgnoreCase); + return this._routeValues; + } + set + { + this._routeValues = value; + } + } + + /// + /// Gets or sets the for the current request. + /// + [HtmlAttributeNotBound] + [ViewContext] + public ViewContext ViewContext { get; set; } + + public override void Process(TagHelperContext context, TagHelperOutput output) + { + base.Process(context, output); + + if (ShouldBeActive()) + { + MakeActive(output); + } + + output.Attributes.RemoveAll("is-active-route"); + } + + private bool ShouldBeActive() + { + string currentController = ViewContext.RouteData.Values["Controller"].ToString(); + string currentAction = ViewContext.RouteData.Values["Action"].ToString(); + + if (!string.IsNullOrWhiteSpace(Controller) && Controller.ToLower() != currentController.ToLower()) + { + return false; + } + + if (!string.IsNullOrWhiteSpace(Action) && Action.ToLower() != currentAction.ToLower()) + { + return false; + } + + foreach (KeyValuePair routeValue in RouteValues) + { + if (!ViewContext.RouteData.Values.ContainsKey(routeValue.Key) || + ViewContext.RouteData.Values[routeValue.Key].ToString() != routeValue.Value) + { + return false; + } + } + + return true; + } + + private void MakeActive(TagHelperOutput output) + { + var classAttr = output.Attributes.FirstOrDefault(a => a.Name == "class"); + if (classAttr == null) + { + classAttr = new TagHelperAttribute("class", "active"); + output.Attributes.Add(classAttr); + } + else if (classAttr.Value == null || classAttr.Value.ToString().IndexOf("active") < 0) + { + output.Attributes.SetAttribute("class", classAttr.Value == null + ? "active" + : classAttr.Value.ToString() + " active"); + } + } + } +} diff --git a/src/Swastika.Cms.Lib/ViewModels/BackEnd/BEArticleModuleViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/BackEnd/BEArticleModuleViewModel.cs new file mode 100644 index 00000000..179b8e84 --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/BackEnd/BEArticleModuleViewModel.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using Swastika.IO.Common.Helper; +using Swastika.IO.Domain.Core.ViewModels; +using Swastika.Cms.Lib.ViewModels.Info; +using System.Threading.Tasks; +using Swastika.Cms.Lib.ViewModels.FrontEnd; + +namespace Swastika.Cms.Lib.ViewModels.BackEnd +{ + public class BEArticleModuleViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("articleId")] + public string ArticleId { get; set; } + [JsonProperty("moduleId")] + public int ModuleId { get; set; } + [JsonProperty("isActived")] + public bool IsActived { get; set; } + [JsonProperty("description")] + public string Description { get; set; } + #endregion + + #region Views + [JsonProperty("module")] + public FEModuleViewModel Module { get; set; } + #endregion + + #endregion + + #region Contructors + + public BEArticleModuleViewModel() : base() + { + } + + public BEArticleModuleViewModel(SiocArticleModule model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + #region Overrides + public override void ExpandView(SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + var getModuleResult = FEModuleViewModel.Repository.GetSingleModel(m => m.Id == ModuleId && m.Specificulture == Specificulture); + if (getModuleResult.IsSucceed) + { + this.Module = getModuleResult.Data; + } + } + public override RepositoryResponse RemoveRelatedModels(BEArticleModuleViewModel view, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + return InfoModuleDataViewModel.Repository.RemoveListModel(d => d.ArticleId == view.ArticleId + && d.ModuleId == view.ModuleId && d.Specificulture == view.Specificulture, _context, _transaction); + } + + + + public override RepositoryResponse SaveSubModels(SiocArticleModule parent, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + RepositoryResponse result = new RepositoryResponse() { IsSucceed = true }; + foreach (var data in Module.Data.Items) + { + data.ArticleId = parent.ArticleId; + data.ModuleId = parent.ModuleId; + var saveResult = data.SaveModel(false, _context, _transaction); + if (!saveResult.IsSucceed) + { + result.Errors.AddRange(saveResult.Errors); + result.Exception = saveResult.Exception; + } + result.Data = result.IsSucceed = result.IsSucceed && saveResult.IsSucceed; + } + return result; + } + + #region Async + public override Task> RemoveRelatedModelsAsync(BEArticleModuleViewModel view, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + return InfoModuleDataViewModel.Repository.RemoveListModelAsync(d => d.ArticleId == view.ArticleId + && d.ModuleId == view.ModuleId && d.Specificulture == view.Specificulture, _context, _transaction); + } + public override async Task> SaveSubModelsAsync(SiocArticleModule parent, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + RepositoryResponse result = new RepositoryResponse() { IsSucceed = true }; + foreach (var data in Module.Data.Items) + { + data.ArticleId = parent.ArticleId; + data.ModuleId = parent.ModuleId; + var saveResult = await data.SaveModelAsync(false, _context, _transaction); + if (!saveResult.IsSucceed) + { + result.Errors.AddRange(saveResult.Errors); + result.Exception = saveResult.Exception; + } + result.Data = result.IsSucceed = result.IsSucceed && saveResult.IsSucceed; + } + return result; + } + #endregion + #endregion + + #region Expands + + #endregion + + } +} diff --git a/src/Swastika.Cms.Lib/ViewModels/BackEnd/BEArticleViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/BackEnd/BEArticleViewModel.cs new file mode 100644 index 00000000..3e6b258f --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/BackEnd/BEArticleViewModel.cs @@ -0,0 +1,699 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; +using Newtonsoft.Json.Linq; +using Swastika.Cms.Lib.Services; +using Swastika.Cms.Lib.Repositories; +using Swastika.IO.Domain.Core.ViewModels; +using Swastika.Common.Helper; +using System.Threading.Tasks; +using Swastika.Domain.Core.Models; +using Swastika.Cms.Lib.ViewModels.Info; + +namespace Swastika.Cms.Lib.ViewModels.BackEnd +{ + public class BEArticleViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("id")] + public string Id { get; set; } + [JsonProperty("template")] + public string Template { get; set; } + [JsonProperty("thumbnail")] + public string Thumbnail { get; set; } + [JsonProperty("image")] + public string Image { get; set; } + [JsonProperty("icon")] + public string Icon { get; set; } + [Required] + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("excerpt")] + public string Excerpt { get; set; } + [JsonProperty("content")] + public string Content { get; set; } + [JsonProperty("seoName")] + public string SeoName { get; set; } + [JsonProperty("seoTitle")] + public string SeoTitle { get; set; } + [JsonProperty("seoDescription")] + public string SeoDescription { get; set; } + [JsonProperty("seoKeywords")] + public string SeoKeywords { get; set; } + [JsonProperty("source")] + public string Source { get; set; } + [JsonProperty("views")] + public int? Views { get; set; } + [JsonProperty("type")] + public int Type { get; set; } + [JsonProperty("createdDateTime")] + public DateTime CreatedDateTime { get; set; } + [JsonProperty("updatedDateTime")] + public DateTime? UpdatedDateTime { get; set; } + [JsonProperty("createdBy")] + public string CreatedBy { get; set; } + [JsonProperty("updatedBy")] + public string UpdatedBy { get; set; } + [JsonProperty("isVisible")] + public bool IsVisible { get; set; } + [JsonProperty("isDeleted")] + public bool IsDeleted { get; set; } + [JsonProperty("tags")] + public string Tags { get; set; } + #endregion + + #region Views + [JsonProperty("categories")] + public List Categories { get; set; } + [JsonProperty("modules")] + public List Modules { get; set; } // Parent to Modules + [JsonProperty("moduleNavs")] + public List ModuleNavs { get; set; } // Children Modules + [JsonProperty("activedModules")] + public List ActivedModules { get; set; } // Children Modules + [JsonProperty("listTag")] + public JArray ListTag { get; set; } = new JArray(); + [JsonProperty("view")] + public TemplateViewModel View { get; set; } + [JsonProperty("templates")] + public List Templates { get; set; }// Article Templates + [JsonProperty("imageFileStream")] + public FileStreamViewModel ImageFileStream { get; set; } + [JsonProperty("thumbnailFileStream")] + public FileStreamViewModel ThumbnailFileStream { get; set; } + [JsonProperty("templateFolder")] + public string TemplateFolder + { + get + { + return SWCmsHelper.GetFullPath(new string[] + { + SWCmsConstants.Parameters.TemplatesFolder + , SWCmsConstants.TemplateFolder.Articles.ToString() + } + ); + } + } + [JsonProperty("domain")] + public string Domain { get; set; } = "/"; + [JsonProperty("imageUrl")] + public string ImageUrl + { + get + { + if (Image != null && Image.IndexOf("http") == -1) + { + return SWCmsHelper.GetFullPath(new string[] { + Domain, Image + }); + } + else + { + return Image; + } + + } + } + [JsonProperty("thumbnailUrl")] + public string ThumbnailUrl + { + get + { + if (Thumbnail != null && Thumbnail.IndexOf("http") == -1) + { + return SWCmsHelper.GetFullPath(new string[] { + Domain, Thumbnail + }); + } + else + { + return Thumbnail; + } + + } + } + + + #endregion + + #endregion + + #region Contructors + + public BEArticleViewModel() : base() + { + } + + public BEArticleViewModel(SiocArticle model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + #region Overrides + + public override void ExpandView(SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + IsClone = true; + ListSupportedCulture = ApplicationConfigService.ListSupportedCulture; + + if (!string.IsNullOrEmpty(this.Tags)) + { + ListTag = JArray.Parse(this.Tags); + } + + this.Templates = this.Templates ?? TemplateRepository.Instance.GetTemplates( + SWCmsConstants.TemplateFolder.Articles); + + this.View = Templates.FirstOrDefault(t => !string.IsNullOrEmpty(this.Template) && this.Template.Contains(t.Filename + t.Extension)); + if (this.View == null) + { + this.View = new TemplateViewModel() + { + Extension = SWCmsConstants.Parameters.TemplateExtension, + FileFolder = SWCmsConstants.TemplateFolder.Articles, + Filename = SWCmsConstants.Default.DefaultTemplate, + Content = "
" + }; + this.Template = SWCmsHelper.GetFullPath(new string[] + { + this.View?.FileFolder + , this.View?.Filename + }); + } + + var getCateArticle = CommonRepository.Instance.GetCategoryArticleNav(Id, Specificulture, _context, _transaction); + if (getCateArticle.IsSucceed) + { + this.Categories = getCateArticle.Data; + } + + var getModuleArticle = CommonRepository.Instance.GetModuleArticleNav(Id, Specificulture, _context, _transaction); + if (getModuleArticle.IsSucceed) + { + this.Modules = getModuleArticle.Data; + } + + var getArticleModule = CommonRepository.Instance.GetArticleModuleNav(Id, Specificulture, _context, _transaction); + if (getArticleModule.IsSucceed) + { + this.ModuleNavs = getArticleModule.Data; + } + + this.ListSupportedCulture.ForEach(c => c.IsSupported = + (string.IsNullOrEmpty(Id) && c.Specificulture == Specificulture) + || Repository.CheckIsExists(a => a.Id == Id && a.Specificulture == c.Specificulture, _context, _transaction) + ); + this.ActivedModules = new List(); + foreach (var module in this.ModuleNavs.Where(m => m.IsActived)) + { + var getModule = ModuleWithDataViewModel.Repository.GetSingleModel(m => m.Id == module.ModuleId && m.Specificulture == module.Specificulture, _context, _transaction); + if (getModule.IsSucceed) + { + this.ActivedModules.Add(getModule.Data); + this.ActivedModules.ForEach(m => m.LoadData(Id)); + } + } + } + + public override SiocArticle ParseModel() + { + if (string.IsNullOrEmpty(Id)) + { + Id = Guid.NewGuid().ToString(); //Common.Common.GetBase62(8); + CreatedDateTime = DateTime.UtcNow; + } + if (ThumbnailFileStream != null) + { + string folder = SWCmsHelper.GetFullPath(new string[] + { + SWCmsConstants.Parameters.UploadFolder, "Articles", DateTime.UtcNow.ToString("dd-MM-yyyy") + }); + string filename = SWCmsHelper.GetRandomName(ThumbnailFileStream.Name); + bool saveThumbnail = SWCmsHelper.SaveFileBase64(folder, filename, ThumbnailFileStream.Base64); + if (saveThumbnail) + { + SWCmsHelper.RemoveFile(Thumbnail); + Thumbnail = SWCmsHelper.GetFullPath(new string[] { folder, filename }); + } + } + if (ImageFileStream != null) + { + string folder = SWCmsHelper.GetFullPath(new string[] + { + SWCmsConstants.Parameters.UploadFolder, "Articles", DateTime.UtcNow.ToString("dd-MM-yyyy") + }); + string filename = SWCmsHelper.GetRandomName(ImageFileStream.Name); + bool saveImage = SWCmsHelper.SaveFileBase64(folder, filename, ImageFileStream.Base64); + if (saveImage) + { + SWCmsHelper.RemoveFile(Image); + Image = SWCmsHelper.GetFullPath(new string[] { folder, filename }); + } + } + + Tags = ListTag.ToString(Newtonsoft.Json.Formatting.None); + Template = View != null ? SWCmsHelper.GetFullPath(new string[] { View?.FileFolder, View?.Filename + View?.Extension }) : Template; + + GenerateSEO(); + + return base.ParseModel(); + } + + #region Async Methods + + public override async Task> SaveSubModelsAsync( + SiocArticle parent + , SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + bool result = true; + TemplateRepository.Instance.SaveTemplate(View); + try + { + + if (result) + { + foreach (var item in Categories) + { + item.ArticleId = Id; + if (item.IsActived) + { + var saveResult = await item.SaveModelAsync(false, _context, _transaction); + result = result && saveResult.IsSucceed; + if (!result) + { + Errors.AddRange(saveResult.Errors); + } + } + else + { + var saveResult = await item.RemoveModelAsync(false, _context, _transaction); + result = result && saveResult.IsSucceed; + if (!result) + { + Errors.AddRange(saveResult.Errors); + } + } + } + } + + if (result) + { + foreach (var item in Modules) + { + item.ArticleId = Id; + if (item.IsActived) + { + var saveResult = await item.SaveModelAsync(false, _context, _transaction); + result = result && saveResult.IsSucceed; + if (!result) + { + Errors.AddRange(saveResult.Errors); + } + } + else + { + var saveResult = await item.RemoveModelAsync(false, _context, _transaction); + result = result && saveResult.IsSucceed; + if (!result) + { + Errors.AddRange(saveResult.Errors); + } + } + } + } + + if (result) + { + foreach (var item in ModuleNavs) + { + item.ArticleId = Id; + if (item.IsActived) + { + var saveResult = await item.SaveModelAsync(false, _context, _transaction); + } + else + { + var saveResult = await item.RemoveModelAsync(true, _context, _transaction); + result = saveResult.IsSucceed; + if (!result) + { + Errors.AddRange(saveResult.Errors); + Ex = saveResult.Exception; + } + } + } + } + + // save submodules navs + if (result) + { + foreach (var item in Modules) + { + item.ArticleId = Id; + if (item.IsActived) + { + var saveResult = await item.SaveModelAsync(false, _context, _transaction); + result = result && saveResult.IsSucceed; + if (!result) + { + Errors.AddRange(saveResult.Errors); + } + } + else + { + var saveResult = await item.RemoveModelAsync(false, _context, _transaction); + result = result && saveResult.IsSucceed; + if (!result) + { + Errors.AddRange(saveResult.Errors); + } + } + } + } + + //save submodules data + if (result) + { + foreach (var module in ActivedModules) + { + module.Data.Items = new List(); + foreach (var data in module.Data.JsonItems) + { + + SiocModuleData model = new SiocModuleData() + { + Id = data.Value("id") ?? Guid.NewGuid().ToString(), + Specificulture = module.Specificulture, + ArticleId = Id, + ModuleId = module.Id, + Fields = module.Fields, + CreatedDateTime = DateTime.UtcNow, + UpdatedDateTime = DateTime.UtcNow + }; + + List cols = module.Columns; + JObject val = new JObject(); + + foreach (JProperty prop in data.Properties()) + { + var col = cols.FirstOrDefault(c => c.Name == prop.Name); + if (col != null) + { + + JObject fieldVal = new JObject + { + new JProperty("dataType", col.DataType), + new JProperty("value", prop.Value) + }; + val.Add(new JProperty(prop.Name, fieldVal)); + } + } + model.Value = val.ToString(Newtonsoft.Json.Formatting.None); + + var vmData = new ModuleContentViewmodel(model); + + var saveResult = await vmData.SaveModelAsync(false, _context, _transaction); + if (saveResult.IsSucceed) + { + module.Data.Items.Add(vmData); + } + else + { + Errors.AddRange(saveResult.Errors); + Ex = saveResult.Exception; + } + result = result && saveResult.IsSucceed; + } + } + } + + return new RepositoryResponse() + { + IsSucceed = result, + Data = result, + Errors = Errors, + Exception = Ex + }; + + } + catch (Exception ex) + { + result = false; + return new RepositoryResponse() + { + IsSucceed = false, + Data = false, + Exception = ex + }; + } + } + public override async Task> CloneSubModelsAsync(BEArticleViewModel parent, List cloneCultures, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + RepositoryResponse result = new RepositoryResponse() { }; + foreach (var module in ActivedModules) + { + module.ParseModel(); + var cloneModule = await module.CloneAsync(cloneCultures, _context, _transaction); + if (cloneModule.IsSucceed) + { + var moduleNav = ModuleNavs.FirstOrDefault(m => m.ModuleId == module.Id && + m.ArticleId == Id && m.Specificulture == module.Specificulture); + var cloneNav = await moduleNav.CloneAsync(cloneCultures, _context, _transaction); + if (cloneNav.IsSucceed) + { + result.IsSucceed = cloneNav.IsSucceed; + } + else + { + result.IsSucceed = cloneNav.IsSucceed; + result.Errors.AddRange(cloneNav.Errors); + result.Exception = cloneNav.Exception; + } + + } + else + { + result.Errors.AddRange(cloneModule.Errors); + result.Exception = cloneModule.Exception; + } + } + return result; + } + + + + public override async Task> RemoveRelatedModelsAsync(BEArticleViewModel view, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + RepositoryResponse result = new RepositoryResponse() + { + IsSucceed = true + }; + + if (result.IsSucceed) + { + foreach (var item in view.Categories.Where(m => m.IsActived)) + { + result = await item.RemoveModelAsync(false, _context, _transaction); + } + } + + if (result.IsSucceed) + { + foreach (var item in view.Modules.Where(m => m.IsActived)) + { + result = await item.RemoveModelAsync(false, _context, _transaction); + } + } + + if (result.IsSucceed) + { + foreach (var item in view.ModuleNavs.Where(m => m.IsActived)) + { + result = item.RemoveModel(false, _context, _transaction); + } + } + return result; + } + #endregion + + #region Sync Methods + + public override RepositoryResponse RemoveRelatedModels(BEArticleViewModel model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + RepositoryResponse result = new RepositoryResponse() + { + IsSucceed = true + }; + + if (result.IsSucceed) + { + foreach (var item in model.Categories) + { + result = item.RemoveModel(false, _context, _transaction); + } + } + + if (result.IsSucceed) + { + foreach (var item in model.Modules) + { + result = item.RemoveModel(false, _context, _transaction); + } + } + + if (result.IsSucceed) + { + foreach (var item in model.ModuleNavs) + { + result = item.RemoveModel(false, _context, _transaction); + } + } + return result; + } + + + public override RepositoryResponse SaveSubModels(SiocArticle parent, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + bool result = true; + TemplateRepository.Instance.SaveTemplate(View); + try + { + foreach (var supportedCulture in ListSupportedCulture.Where(c => c.Specificulture != Specificulture)) + { + + if (result) + { + + var getcloneArticle = BEArticleViewModel.Repository.GetSingleModel(b => b.Id == Id && b.Specificulture == supportedCulture.Specificulture + , _context, _transaction); + if (!getcloneArticle.IsSucceed && supportedCulture.IsSupported) + { + var cloneArticle = new BEArticleViewModel(this.Model, _context, _transaction) + { + Id = Id, + Specificulture = supportedCulture.Specificulture, + Categories = new List(), + Modules = new List(), + ModuleNavs = new List() + }; + foreach (var cateArticle in this.Categories.Where(p => p.IsActived)) + { + cloneArticle.Categories.Add(new CategoryArticleViewModel( + new SiocCategoryArticle() + { + ArticleId = cateArticle.ArticleId, + Specificulture = supportedCulture.Specificulture, + CategoryId = cateArticle.CategoryId, + }, + _context, _transaction) + { + + IsActived = cateArticle.IsActived, + Description = cateArticle.Description + }); + } + + foreach (var moduleArticle in this.Modules.Where(p => p.IsActived)) + { + cloneArticle.Modules.Add(new ModuleArticleViewModel( + new SiocModuleArticle() + { + ArticleId = moduleArticle.ArticleId, + Specificulture = supportedCulture.Specificulture, + ModuleId = moduleArticle.ModuleId + }, + _context, _transaction) + { + + IsActived = moduleArticle.IsActived, + Description = moduleArticle.Description + }); + } + + foreach (var moduleArticle in this.Modules.Where(p => p.IsActived)) + { + cloneArticle.Modules.Add(new ModuleArticleViewModel( + new SiocModuleArticle() + { + ArticleId = moduleArticle.ArticleId, + Specificulture = supportedCulture.Specificulture, + ModuleId = moduleArticle.ModuleId + }, + _context, _transaction) + { + + IsActived = moduleArticle.IsActived, + Description = moduleArticle.Description + }); + } + var cloneResult = BEArticleViewModel.Repository.SaveModel(cloneArticle, true); + result = result && cloneResult.IsSucceed; + } + else if (getcloneArticle.IsSucceed && !supportedCulture.IsSupported) + { + var delResult = BEArticleViewModel.Repository.RemoveModel(b => b.Id == getcloneArticle.Data.Id && b.Specificulture == supportedCulture.Specificulture); + result = result && delResult.IsSucceed; + } + } + else + { + break; + } + } + return new RepositoryResponse() + { + IsSucceed = result, + Data = result + }; + } + catch (Exception ex) + { + result = false; + return new RepositoryResponse() + { + IsSucceed = false, + Data = false, + Exception = ex + }; + } + } + #endregion + + #endregion + + #region Expands + void GenerateSEO() + { + if (string.IsNullOrEmpty(this.SeoName)) + { + this.SeoName = SEOHelper.GetSEOString(this.Title); + } + + if (string.IsNullOrEmpty(this.SeoTitle)) + { + this.SeoTitle = SEOHelper.GetSEOString(this.Title); + } + + if (string.IsNullOrEmpty(this.SeoDescription)) + { + this.SeoDescription = SEOHelper.GetSEOString(this.Title); + } + + if (string.IsNullOrEmpty(this.SeoKeywords)) + { + this.SeoKeywords = SEOHelper.GetSEOString(this.Title); + } + } + #endregion + + } +} diff --git a/src/Swastika.Cms.Lib/ViewModels/BackEnd/BEModuleViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/BackEnd/BEModuleViewModel.cs new file mode 100644 index 00000000..b77469fb --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/BackEnd/BEModuleViewModel.cs @@ -0,0 +1,172 @@ +using System.Collections.Generic; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using Swastika.IO.Domain.Core.ViewModels; +using Newtonsoft.Json.Linq; +using Swastika.IO.Common.Helper; +using Swastika.Cms.Lib.ViewModels.Info; +using Swastika.Cms.Lib.Repositories; +using Microsoft.Data.OData.Query; +using System.Linq; +using Swastika.Domain.Core.Models; +using System.Threading.Tasks; + +namespace Swastika.Cms.Lib.ViewModels.BackEnd +{ + public class BEModuleViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("id")] + public int Id { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("template")] + public string Template { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("description")] + public string Description { get; set; } + [JsonProperty("fields")] + public string Fields { get; set; } + [JsonProperty("type")] + public int Type { get; set; } + #endregion + + #region Views + + [JsonProperty("view")] + public TemplateViewModel View { get; set; } + [JsonProperty("data")] + public PaginationModel Data { get; set; } = new PaginationModel(); + [JsonProperty("columns")] + public List Columns { get; set; } + [JsonProperty("templates")] + public List Templates { get; set; } + [JsonProperty("articles")] + public PaginationModel Articles { get; set; } = new PaginationModel(); + + #endregion + + #endregion + + #region Contructors + + public BEModuleViewModel() : base() + { + } + + public BEModuleViewModel(SiocModule model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + #region Overrides + public override SiocModule ParseModel() + { + var arrField = Columns != null ? JArray.Parse( + Newtonsoft.Json.JsonConvert.SerializeObject(Columns.Where( + c => !string.IsNullOrEmpty(c.Name)))) : new JArray(); + Fields = arrField.ToString(Newtonsoft.Json.Formatting.None); + Template = View != null ? string.Format(@"{0}/{1}", View.FileFolder, View.Filename) : Template; + + return base.ParseModel(); + } + + + public override void ExpandView(SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + Columns = new List(); + JArray arrField = !string.IsNullOrEmpty(Fields) ? JArray.Parse(Fields) : new JArray(); + foreach (var field in arrField) + { + ModuleFieldViewModel thisField = new ModuleFieldViewModel() + { + Name = CommonHelper.ParseJsonPropertyName(field["Name"].ToString()), + DataType = (SWCmsConstants.DataType)(int)field["DataType"], + Width = field["Width"] != null ? field["Width"].Value() : 3, + IsDisplay = field["IsDisplay"] != null ? field["IsDisplay"].Value() : true + }; + Columns.Add(thisField); + } + + //Get Languages + this.Templates = Templates ?? TemplateRepository.Instance.GetTemplates(SWCmsConstants.TemplateFolder.Modules); + this.Template = string.IsNullOrEmpty(Template) ? "Modules/_Default" : Template; + this.View = TemplateRepository.Instance.GetTemplate(Template, Templates, SWCmsConstants.TemplateFolder.Modules); + + var getDataResult = InfoModuleDataViewModel.Repository + .GetModelListBy(m => m.ModuleId == Id && m.Specificulture == Specificulture + , "Priority", OrderByDirection.Ascending, null, null + , _context, _transaction); + if (getDataResult.IsSucceed) + { + getDataResult.Data.JsonItems = new List(); + getDataResult.Data.Items.ForEach(d => getDataResult.Data.JsonItems.Add(d.JItem)); + Data = getDataResult.Data; + } + var getArticles = InfoArticleViewModel.GetModelListByModule(Id, Specificulture, SWCmsConstants.Default.OrderBy, OrderByDirection.Ascending + , _context: _context, _transaction: _transaction + ); + if (getArticles.IsSucceed) + { + Articles = getArticles.Data; + } + } + + #region Async + + + public override async Task> CloneSubModelsAsync(BEModuleViewModel parent, List cloneCultures, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + RepositoryResponse result = new RepositoryResponse() { IsSucceed = true }; + foreach (var data in parent.Data.Items) + { + var cloneData = await data.CloneAsync(cloneCultures, _context, _transaction); + if (cloneData.IsSucceed) + { + result.IsSucceed = cloneData.IsSucceed; + } + else + { + result.IsSucceed = cloneData.IsSucceed; + result.Errors.AddRange(cloneData.Errors); + result.Exception = cloneData.Exception; + } + } + return result; + } + #endregion + + #region Sync + public override RepositoryResponse CloneSubModels(BEModuleViewModel parent, List cloneCultures, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + RepositoryResponse result = new RepositoryResponse() { IsSucceed = true }; + foreach (var data in parent.Data.Items) + { + var cloneData = data.Clone(cloneCultures, _context, _transaction); + if (cloneData.IsSucceed) + { + result.IsSucceed = cloneData.IsSucceed; + } + else + { + result.IsSucceed = cloneData.IsSucceed; + result.Errors.AddRange(cloneData.Errors); + result.Exception = cloneData.Exception; + } + } + return result; + } + #endregion + + + #endregion + } + +} diff --git a/src/Swastika.Cms.Lib/ViewModels/BackEnd/_BlankViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/BackEnd/_BlankViewModel.cs new file mode 100644 index 00000000..a8d25ae8 --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/BackEnd/_BlankViewModel.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using Swastika.IO.Common.Helper; + +namespace Swastika.Cms.Lib.ViewModels.Cms +{ + public class _BlankViewModel + : ViewModelBase + { + #region Properties + //[JsonProperty("id")] + + #region Models + + #endregion + + #region Views + + #endregion + + #endregion + + #region Contructors + + public _BlankViewModel() : base() + { + } + + public _BlankViewModel(SiocArticle model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + #region Overrides + + #endregion + + #region Expands + + #endregion + + } +} diff --git a/src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEArticleModuleViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEArticleModuleViewModel.cs new file mode 100644 index 00000000..7ea9b76c --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEArticleModuleViewModel.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using Swastika.IO.Common.Helper; + +namespace Swastika.Cms.Lib.ViewModels.FrontEnd +{ + public class FEArticleModuleViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("articleId")] + public string ArticleId { get; set; } + [JsonProperty("moduleId")] + public int ModuleId { get; set; } + [JsonProperty("isActived")] + public bool IsActived { get; set; } + [JsonProperty("description")] + public string Description { get; set; } + #endregion + + #region Views + [JsonProperty("module")] + public FEModuleViewModel Module { get; set; } + #endregion + + #endregion + + #region Contructors + + public FEArticleModuleViewModel() : base() + { + } + + public FEArticleModuleViewModel(SiocArticleModule model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + #region Overrides + public override void ExpandView(SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + var getModuleResult = FEModuleViewModel.Repository.GetSingleModel(m => m.Id == ModuleId && m.Specificulture == Specificulture); + if (getModuleResult.IsSucceed) + { + this.Module = getModuleResult.Data; + } + } + #endregion + + #region Expands + + #endregion + + } +} diff --git a/src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEArticleViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEArticleViewModel.cs new file mode 100644 index 00000000..717c0a19 --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEArticleViewModel.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; +using Swastika.Common.Helper; +using Swastika.Cms.Lib; + +namespace Swastika.Cms.Lib.ViewModels.FrontEnd +{ + + public class FEArticleViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("id")] + public string Id { get; set; } + [JsonProperty("template")] + public string Template { get; set; } + [JsonProperty("thumbnail")] + public string Thumbnail { get; set; } + [JsonProperty("image")] + public string Image { get; set; } + [Required] + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("excerpt")] + public string Excerpt { get; set; } + [JsonProperty("content")] + public string Content { get; set; } + [JsonProperty("seoName")] + public string SeoName { get; set; } + [JsonProperty("seoTitle")] + public string SeoTitle { get; set; } + [JsonProperty("seoDescription")] + public string SeoDescription { get; set; } + [JsonProperty("seoKeywords")] + public string SeoKeywords { get; set; } + [JsonProperty("source")] + public string Source { get; set; } + [JsonProperty("views")] + public int? Views { get; set; } + [JsonProperty("type")] + public int Type { get; set; } + [JsonProperty("createdDateTime")] + public DateTime CreatedDateTime { get; set; } + [JsonProperty("updatedDateTime")] + public DateTime? UpdatedDateTime { get; set; } + [JsonProperty("createdBy")] + public string CreatedBy { get; set; } + [JsonProperty("updatedBy")] + public string UpdatedBy { get; set; } + [JsonProperty("isVisible")] + public bool IsVisible { get; set; } + [JsonProperty("isDeleted")] + public bool IsDeleted { get; set; } + [JsonProperty("tags")] + public string Tags { get; set; } + #endregion + + #region Views + [JsonProperty("modules")] + public List Modules { get; set; } + [JsonProperty("domain")] + public string Domain { get; set; } = "/"; + [JsonProperty("imageUrl")] + public string ImageUrl + { + get + { + if (Image != null && Image.IndexOf("http") == -1) + { + return SWCmsHelper.GetFullPath(new string[] { + Domain, Image + }); + } + else + { + return Image; + } + + } + } + [JsonProperty("thumbnailUrl")] + public string ThumbnailUrl + { + get + { + if (Thumbnail != null && Thumbnail.IndexOf("http") == -1) + { + return SWCmsHelper.GetFullPath(new string[] { + Domain, Thumbnail + }); + } + else + { + return Thumbnail; + } + + } + } + + #endregion + + #endregion + + #region Contructors + + public FEArticleViewModel() : base() + { + } + + public FEArticleViewModel(SiocArticle model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + #region Overrides + + public override void ExpandView(SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + var getModulesResult = FEArticleModuleViewModel.Repository.GetModelListBy(m => m.ArticleId == Id && m.Specificulture == Specificulture, _context, _transaction); + if (getModulesResult.IsSucceed) + { + this.Modules = getModulesResult.Data; + } + } + + #endregion + + #region Expands + void GenerateSEO() + { + if (string.IsNullOrEmpty(this.SeoName)) + { + this.SeoName = SEOHelper.GetSEOString(this.Title); + } + + if (string.IsNullOrEmpty(this.SeoTitle)) + { + this.SeoTitle = SEOHelper.GetSEOString(this.Title); + } + + if (string.IsNullOrEmpty(this.SeoDescription)) + { + this.SeoDescription = SEOHelper.GetSEOString(this.Title); + } + + if (string.IsNullOrEmpty(this.SeoKeywords)) + { + this.SeoKeywords = SEOHelper.GetSEOString(this.Title); + } + } + #endregion + + } +} diff --git a/src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEModuleViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEModuleViewModel.cs new file mode 100644 index 00000000..a8e72af7 --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/FrontEnd/FEModuleViewModel.cs @@ -0,0 +1,110 @@ +using System.Collections.Generic; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using Swastika.Cms.Lib; +using Swastika.IO.Domain.Core.ViewModels; +using Newtonsoft.Json.Linq; +using Swastika.IO.Common.Helper; +using Swastika.Cms.Lib.ViewModels; +using Swastika.Cms.Lib.ViewModels.Info; +using Swastika.Cms.Lib.Repositories; +using Microsoft.Data.OData.Query; + +namespace Swastika.Cms.Lib.ViewModels.FrontEnd +{ + public class FEModuleViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("id")] + public int Id { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("template")] + public string Template { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("description")] + public string Description { get; set; } + [JsonProperty("fields")] + public string Fields { get; set; } + [JsonProperty("type")] + public int Type { get; set; } + #endregion + + #region Views + + [JsonProperty("view")] + public TemplateViewModel View { get; set; } + [JsonProperty("data")] + public PaginationModel Data { get; set; } = new PaginationModel(); + [JsonProperty("columns")] + public List Columns { get; set; } + [JsonProperty("templates")] + public List Templates { get; set; } + [JsonProperty("articles")] + public PaginationModel Articles { get; set; } = new PaginationModel(); + + #endregion + + #endregion + + #region Contructors + + public FEModuleViewModel() : base() + { + } + + public FEModuleViewModel(SiocModule model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + #region Overrides + + public override void ExpandView(SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + Columns = new List(); + JArray arrField = !string.IsNullOrEmpty(Fields) ? JArray.Parse(Fields) : new JArray(); + foreach (var field in arrField) + { + ModuleFieldViewModel thisField = new ModuleFieldViewModel() + { + Name = CommonHelper.ParseJsonPropertyName(field["Name"].ToString()), + DataType = (SWCmsConstants.DataType)(int)field["DataType"], + Width = field["Width"] != null ? field["Width"].Value() : 3, + IsDisplay = field["IsDisplay"] != null ? field["IsDisplay"].Value() : true + }; + Columns.Add(thisField); + } + + this.Templates = Templates ?? TemplateRepository.Instance.GetTemplates(SWCmsConstants.TemplateFolder.Modules); + + var getDataResult = InfoModuleDataViewModel.Repository + .GetModelListBy(m => m.ModuleId == Id && m.Specificulture == Specificulture + , "Priority", OrderByDirection.Ascending, null, null + , _context, _transaction); + if (getDataResult.IsSucceed) + { + getDataResult.Data.JsonItems = new List(); + getDataResult.Data.Items.ForEach(d => getDataResult.Data.JsonItems.Add(d.JItem)); + Data = getDataResult.Data; + } + var getArticles = InfoArticleViewModel.GetModelListByModule(Id, Specificulture, SWCmsConstants.Default.OrderBy, OrderByDirection.Ascending + , _context: _context, _transaction: _transaction + ); + if (getArticles.IsSucceed) + { + Articles = getArticles.Data; + } + } + + #endregion + } + +} diff --git a/src/Swastika.Cms.Lib/ViewModels/Info/InfoArticleModuleViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/Info/InfoArticleModuleViewModel.cs new file mode 100644 index 00000000..7bbf86f9 --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/Info/InfoArticleModuleViewModel.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; +using Swastika.Cms.Lib; + +namespace Swastika.Cms.Lib.ViewModels.Info +{ + public class InfoArticleModuleViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("articleId")] + public string ArticleId { get; set; } + [JsonProperty("moduleId")] + public int ModuleId { get; set; } + [JsonProperty("isActived")] + public bool IsActived { get; set; } + [JsonProperty("description")] + public string Description { get; set; } + #endregion + + #region Views + + #endregion + + #endregion + + #region Contructors + + public InfoArticleModuleViewModel() : base() + { + } + + public InfoArticleModuleViewModel(SiocArticleModule model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + } +} diff --git a/src/Swastika.Cms.Lib/ViewModels/Info/InfoArticleViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/Info/InfoArticleViewModel.cs new file mode 100644 index 00000000..7689d81a --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/Info/InfoArticleViewModel.cs @@ -0,0 +1,288 @@ +using System; +using System.Collections.Generic; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; +using Swastika.Cms.Lib; +using Swastika.IO.Domain.Core.ViewModels; +using System.Threading.Tasks; +using Microsoft.Data.OData.Query; +using Microsoft.EntityFrameworkCore; +using System.Linq; + +namespace Swastika.Cms.Lib.ViewModels.Info +{ + public class InfoArticleViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("id")] + public string Id { get; set; } + [JsonProperty("template")] + public string Template { get; set; } + [JsonProperty("thumbnail")] + public string Thumbnail { get; set; } + [JsonProperty("image")] + public string Image { get; set; } + [Required] + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("excerpt")] + public string Excerpt { get; set; } + [JsonProperty("content")] + public string Content { get; set; } + [JsonProperty("seoName")] + public string SeoName { get; set; } + [JsonProperty("seoTitle")] + public string SeoTitle { get; set; } + [JsonProperty("seoDescription")] + public string SeoDescription { get; set; } + [JsonProperty("seoKeywords")] + public string SeoKeywords { get; set; } + [JsonProperty("source")] + public string Source { get; set; } + [JsonProperty("views")] + public int? Views { get; set; } + [JsonProperty("type")] + public int Type { get; set; } + [JsonProperty("createdDateTime")] + public DateTime CreatedDateTime { get; set; } + [JsonProperty("updatedDateTime")] + public DateTime? UpdatedDateTime { get; set; } + [JsonProperty("createdBy")] + public string CreatedBy { get; set; } + [JsonProperty("updatedBy")] + public string UpdatedBy { get; set; } + [JsonProperty("isVisible")] + public bool IsVisible { get; set; } + [JsonProperty("isDeleted")] + public bool IsDeleted { get; set; } + [JsonProperty("tags")] + public string Tags { get; set; } + #endregion + + #region Views + [JsonProperty("domain")] + public string Domain { get; set; } = "/"; + [JsonProperty("imageUrl")] + public string ImageUrl + { + get + { + if (Image != null && Image.IndexOf("http") == -1) + { + return SWCmsHelper.GetFullPath(new string[] { + Domain, Image + }); + } + else + { + return Image; + } + + } + } + [JsonProperty("thumbnailUrl")] + public string ThumbnailUrl + { + get + { + if (Thumbnail != null && Thumbnail.IndexOf("http") == -1) + { + return SWCmsHelper.GetFullPath(new string[] { + Domain, Thumbnail + }); + } + else + { + return Thumbnail; + } + + } + } + + #endregion + + #endregion + + #region Contructors + + public InfoArticleViewModel() : base() + { + } + + public InfoArticleViewModel(SiocArticle model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + #region Expands + + public static async Task>> GetModelListByCategoryAsync( + int categoryId, string specificulture + , string orderByPropertyName, OrderByDirection direction + , int? pageSize = 1, int? pageIndex = 0 + , SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + SiocCmsContext context = _context ?? new SiocCmsContext(); + var transaction = _transaction ?? context.Database.BeginTransaction(); + try + { + var query = context.SiocCategoryArticle.Include(ac => ac.SiocArticle) + .Where(ac => + ac.CategoryId == categoryId && ac.Specificulture == specificulture + && !ac.SiocArticle.IsDeleted && ac.SiocArticle.IsVisible).Select(ac => ac.SiocArticle); + PaginationModel result = await Repository.ParsePagingQueryAsync( + query, orderByPropertyName + , direction, + pageSize, pageIndex, context, transaction + ); + return new RepositoryResponse>() + { + IsSucceed = true, + Data = result + }; + } + // TODO: Add more specific exeption types instead of Exception only + catch (Exception ex) + { + Repository.LogErrorMessage(ex); + if (_transaction == null) + { + //if current transaction is root transaction + transaction.Rollback(); + } + + return new RepositoryResponse>() + { + IsSucceed = false, + Data = null, + Exception = ex + }; + } + finally + { + if (_context == null) + { + //if current Context is Root + context.Dispose(); + } + } + + } + + #region Sync + public static RepositoryResponse> GetModelListByCategory( + int categoryId, string specificulture + , string orderByPropertyName, OrderByDirection direction + , int? pageSize = 1, int? pageIndex = 0 + , SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + SiocCmsContext context = _context ?? new SiocCmsContext(); + var transaction = _transaction ?? context.Database.BeginTransaction(); + try + { + var query = context.SiocCategoryArticle.Include(ac => ac.SiocArticle) + .Where(ac => + ac.CategoryId == categoryId && ac.Specificulture == specificulture + && !ac.SiocArticle.IsDeleted && ac.SiocArticle.IsVisible).Select(ac => ac.SiocArticle); + PaginationModel result = Repository.ParsePagingQuery( + query, orderByPropertyName + , direction, + pageSize, pageIndex, context, transaction + ); + return new RepositoryResponse>() + { + IsSucceed = true, + Data = result + }; + } + // TODO: Add more specific exeption types instead of Exception only + catch (Exception ex) + { + Repository.LogErrorMessage(ex); + if (_transaction == null) + { + //if current transaction is root transaction + transaction.Rollback(); + } + + return new RepositoryResponse>() + { + IsSucceed = false, + Data = null, + Exception = ex + }; + } + finally + { + if (_context == null) + { + //if current Context is Root + context.Dispose(); + } + } + + } + + public static RepositoryResponse> GetModelListByModule( + int ModuleId, string specificulture + , string orderByPropertyName, OrderByDirection direction + , int? pageSize = 1, int? pageIndex = 0 + , SiocCmsContext _context = null, IDbContextTransaction _transaction = null) + { + SiocCmsContext context = _context ?? new SiocCmsContext(); + var transaction = _transaction ?? context.Database.BeginTransaction(); + try + { + var query = context.SiocModuleArticle.Include(ac => ac.SiocArticle) + .Where(ac => + ac.ModuleId == ModuleId && ac.Specificulture == specificulture + && !ac.SiocArticle.IsDeleted && ac.SiocArticle.IsVisible).Select(ac => ac.SiocArticle); + PaginationModel result = Repository.ParsePagingQuery( + query, orderByPropertyName + , direction, + pageSize, pageIndex, context, transaction + ); + return new RepositoryResponse>() + { + IsSucceed = true, + Data = result + }; + } + // TODO: Add more specific exeption types instead of Exception only + catch (Exception ex) + { + Repository.LogErrorMessage(ex); + if (_transaction == null) + { + //if current transaction is root transaction + transaction.Rollback(); + } + + return new RepositoryResponse>() + { + IsSucceed = false, + Data = null, + Exception = ex + }; + } + finally + { + if (_context == null) + { + //if current Context is Root + context.Dispose(); + } + } + + } + #endregion + #endregion + } +} diff --git a/src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleAttributeViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleAttributeViewModel.cs new file mode 100644 index 00000000..bb556d5c --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleAttributeViewModel.cs @@ -0,0 +1,49 @@ +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Swastika.IO.Domain.Core.ViewModels; + +namespace Swastika.Cms.Lib.ViewModels.Info +{ + public class InfoModuleAttributeViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("moduleId")] + public int ModuleId { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("dataType")] + public int DataType { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("width")] + public int Width { get; set; } + [JsonProperty("defaultValue")] + public string DefaultValue { get; set; } + + #endregion + + #region Views + + #endregion + + #endregion + + #region Contructors + + public InfoModuleAttributeViewModel() : base() + { + } + + public InfoModuleAttributeViewModel(SiocModuleAttributeValue model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + } + +} diff --git a/src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleDataViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleDataViewModel.cs new file mode 100644 index 00000000..0b9d8a20 --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleDataViewModel.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; +using Swastika.Cms.Lib; +using Newtonsoft.Json.Linq; +using Swastika.IO.Common.Helper; +using System.Linq; +using Swastika.Cms.Lib.ViewModels; + +namespace Swastika.Cms.Lib.ViewModels.Info +{ + public class InfoModuleDataViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("id")] + public string Id { get; set; } + [JsonProperty("moduleId")] + public int ModuleId { get; set; } + [JsonProperty("fields")] + public string Fields { get; set; } = "[]"; + [JsonProperty("value")] + public string Value { get; set; } + [JsonProperty("articleId")] + public string ArticleId { get; set; } + [JsonProperty("categoryId")] + public int? CategoryId { get; set; } + [JsonProperty("createdDateTime")] + public DateTime CreatedDateTime { get; set; } + [JsonProperty("updatedDateTime")] + public DateTime? UpdatedDateTime { get; set; } + + #endregion + + #region Views + public List DataProperties { get; set; } + public List Columns { get; set; } + public JObject JItem { get { return ParseJson(); } } + #endregion + + #endregion + + #region Contructors + + public InfoModuleDataViewModel() : base() + { + } + + public InfoModuleDataViewModel(SiocModuleData model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + #region Overrides + + + public override SiocModuleData ParseModel() + { + if (string.IsNullOrEmpty(Id)) + { + Id = Guid.NewGuid().ToString(); + CreatedDateTime = DateTime.UtcNow; + } + return base.ParseModel(); + } + + #endregion + + + #region Expands + + public string GetStringValue(string name) + { + var prop = DataProperties.FirstOrDefault(p => p.Name == name); + return prop != null && prop.Value != null ? prop.Value.ToString() : string.Empty; + } + + public T GetValue(string name) where T : IConvertible + { + var prop = DataProperties.FirstOrDefault(p => p.Name == name); + return prop != null && prop.Value != null ? (T)prop.Value : default(T); + } + + public ModuleDataValueViewModel GetDataProperty(string name) + { + return DataProperties.FirstOrDefault(p => p.Name == name); + } + + public JObject ParseJson() + { + JObject result = new JObject + { + new JProperty("id", Id) + }; + foreach (var prop in DataProperties) + { + result.Add(new JProperty(CommonHelper.ParseJsonPropertyName(prop.Name), prop.Value)); + } + JObject model = new JObject + { + new JProperty("id", Id), + new JProperty("moduleId", ModuleId), + new JProperty("specificulture", Specificulture), + new JProperty("fields", Fields), + new JProperty("value", Value), + new JProperty("articleId", ArticleId), + new JProperty("priority", Priority), + new JProperty("categoryId", CategoryId), + new JProperty("createdDateTime", CreatedDateTime) + }; + result.Add(new JProperty("model", model)); + return result; + + } + + + #endregion + + } + + public class ModuleDataValueViewModel + { + public int ModuleId { get; set; } + public string Name { get; set; } + public SWCmsConstants.DataType DataType { get; set; } + public IConvertible Value { get; set; } + + public string StringValue { get; set; } + + public T GetValue() + { + return this.Value != null ? (T)Value : default(T); + } + + } + +} diff --git a/src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleViewModel.cs new file mode 100644 index 00000000..d22fe8f0 --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/Info/InfoModuleViewModel.cs @@ -0,0 +1,49 @@ +using Swastika.Cms.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; + +namespace Swastika.Cms.Lib.ViewModels.Info +{ + public class InfoModuleViewModel + : ViewModelBase + { + #region Properties + + #region Models + [JsonProperty("id")] + public int Id { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("template")] + public string Template { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("description")] + public string Description { get; set; } + [JsonProperty("fields")] + public string Fields { get; set; } + [JsonProperty("type")] + public int Type { get; set; } + #endregion + + #region Views + + #endregion + + #endregion + + #region Contructors + + public InfoModuleViewModel() : base() + { + } + + public InfoModuleViewModel(SiocModule model, SiocCmsContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + } +} diff --git a/src/Swastika.Cms.Lib/ViewModels/_BlankViewModel.cs b/src/Swastika.Cms.Lib/ViewModels/_BlankViewModel.cs new file mode 100644 index 00000000..b36196b4 --- /dev/null +++ b/src/Swastika.Cms.Lib/ViewModels/_BlankViewModel.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Swastika.Messenger.Lib.Models; +using Swastika.Domain.Data.ViewModels; +using Microsoft.EntityFrameworkCore.Storage; +using Newtonsoft.Json; +using Swastika.IO.Common.Helper; +using ChatRoom.Lib.Helpers; + +namespace Swastika.Messenger.Lib.ViewModels.Messenger +{ + public class BlankViewModel + : ViewModelBase + { + #region Properties + [JsonProperty("id")] + + #region Models + + #endregion + + #region Views + + #endregion + + #endregion + + #region Contructors + + public BlankViewModel() : base() + { + } + + public BlankViewModel(Blank model, MessengerContext _context = null, IDbContextTransaction _transaction = null) : base(model, _context, _transaction) + { + } + + #endregion + + #region Overrides + + #endregion + + #region Expands + + #endregion + + } +}