Skip to content

Commit

Permalink
Improvement - Category picture - use localizable alternate text and t…
Browse files Browse the repository at this point in the history
…itle attributes for a picture
  • Loading branch information
KrzysztofPajak committed Aug 16, 2021
1 parent 7574ca4 commit 50334c7
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
@using Microsoft.AspNetCore.Mvc.Razor;

@model CategoryModel.PictureModel
@{
Layout = Grand.Web.Admin.Extensions.Constants.Layout_AdminPopup;
//page title
ViewBag.Title = Loc["Admin.Catalog.Categories.Picture"];
}
<form asp-area="@Constants.AreaAdmin" asp-controller="Category" asp-action="PicturePopup" enctype="multipart/form-data" method="post"
asp-route-CategoryId="@Context.Request.Query["CategoryId"]">


<!-- #region languages template -->
@{ Func<int, HelperResult> template = @<div class="form-body">
<div class="form-group">
<admin-label asp-for="@Model.Locales[item].AltAttribute" class="col-sm-3 control-label" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="@Model.Locales[item].AltAttribute" />
<span asp-validation-for="@Model.Locales[item].AltAttribute"></span>
</div>
</div>
<div class="form-group">
<admin-label asp-for="@Model.Locales[item].TitleAttribute" class="col-sm-3 control-label" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="@Model.Locales[item].TitleAttribute" />
<span asp-validation-for="@Model.Locales[item].TitleAttribute"></span>
</div>
</div>
<input asp-for="@Model.Locales[item].LanguageId" type="hidden" />
</div>;
}

<div asp-validation-summary="All"></div>
<input asp-for="CategoryId" type="hidden" />
<input asp-for="Id" type="hidden" />
<input asp-for="PictureUrl" type="hidden" />
<div class="row">
<div class="col-md-12">
<div class="x_panel light form-fit">
<div class="x_content form">
<div class="form-horizontal">
<div class="form-body">
<div class="form-group">
<admin-label asp-for="PictureUrl" />
<div class="col-md-9 col-sm-9">
<a href="@Model.PictureUrl" target="_blank"><img src="@Model.PictureUrl" width="150" /></a>
</div>
</div>
<localized-editor localized-template=template name="picturevalue-localized" language-ids=@Model.Locales.Select(c=>c.LanguageId).ToList()>
<div class="form-body">
<div class="form-group">
<admin-label asp-for="AltAttribute" class="col-sm-3 control-label" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="AltAttribute" />
<span asp-validation-for="AltAttribute"></span>
</div>
</div>
<div class="form-group">
<admin-label asp-for="TitleAttribute" class="col-sm-3 control-label" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="TitleAttribute" />
<span asp-validation-for="TitleAttribute"></span>
</div>
</div>
</div>
</localized-editor>
<div class="form-actions">
<div class="row">
<div class="offset-md-3 offset-sm-3 col-md-9 col-sm-9">
<button class="k-button" type="submit" name="save"><i class="fa fa-check"></i>@Loc["Admin.Common.Save"] </button>
</div>
</div>
</div>

</div>
</div>
</div>
</div>
</div>
</div>
@if (ViewBag.RefreshPage == true)
{
<script>
window.close();
</script>
}
</form>
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,38 @@


@{ Func<int, HelperResult>
template = @<div class="form-body">
<div class="form-group">
<admin-label asp-for="@Model.Locales[item].Name" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="@Model.Locales[item].Name" />
<span asp-validation-for="@Model.Locales[item].Name"></span>
</div>
template = @<div class="form-body">
<div class="form-group">
<admin-label asp-for="@Model.Locales[item].Name" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="@Model.Locales[item].Name" />
<span asp-validation-for="@Model.Locales[item].Name"></span>
</div>
<div class="form-group">
<admin-label asp-for="@Model.Locales[item].Description" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="@Model.Locales[item].Description" asp-template="Editor" />
<span asp-validation-for="@Model.Locales[item].Description"></span>
</div>
</div>
<div class="form-group">
<admin-label asp-for="@Model.Locales[item].Description" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="@Model.Locales[item].Description" asp-template="Editor" />
<span asp-validation-for="@Model.Locales[item].Description"></span>
</div>
<div class="form-group">
<admin-label asp-for="@Model.Locales[item].BottomDescription" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="@Model.Locales[item].BottomDescription" asp-template="Editor" />
<span asp-validation-for="@Model.Locales[item].BottomDescription"></span>
</div>
</div>
<div class="form-group">
<admin-label asp-for="@Model.Locales[item].BottomDescription" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="@Model.Locales[item].BottomDescription" asp-template="Editor" />
<span asp-validation-for="@Model.Locales[item].BottomDescription"></span>
</div>
<div class="form-group">
<admin-label asp-for="@Model.Locales[item].Flag" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="@Model.Locales[item].Flag" />
<span asp-validation-for="@Model.Locales[item].Flag"></span>
</div>
</div>
<div class="form-group">
<admin-label asp-for="@Model.Locales[item].Flag" />
<div class="col-md-9 col-sm-9">
<admin-input asp-for="@Model.Locales[item].Flag" />
<span asp-validation-for="@Model.Locales[item].Flag"></span>
</div>
<input type="hidden" asp-for="@Model.Locales[item].LanguageId" />
</div>;
}
</div>
<input type="hidden" asp-for="@Model.Locales[item].LanguageId" />
</div>;
}
<div class="form-horizontal">
<vc:admin-widget widget-zone="category_details_info_top" additional-data="Model" />
<localized-editor localized-template=@template name="category-info-localized" language-ids=@Model.Locales.Select(c=>c.LanguageId).ToList()>
Expand Down Expand Up @@ -141,6 +141,12 @@
<div class="col-md-9 col-sm-9">
<admin-input asp-for="PictureId" />
<span asp-validation-for="PictureId"></span>
@if (!string.IsNullOrEmpty(Model.PictureId))
{
<label class="control-label">
<a class='k-link' href='javascript:OpenWindow("@Url.Action("PicturePopup", "Category", new { area = Constants.AreaAdmin })/?categoryId=@(Model.Id)", 800, 600, true);'>@Loc["Admin.Common.Picture.Attributes"]</a>
</label>
}
</div>
</div>
<div class="form-group">
Expand Down
54 changes: 54 additions & 0 deletions src/Web/Grand.Web.Admin/Controllers/CategoryController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,60 @@ public async Task<IActionResult> Delete(string id)
}


#endregion

#region Picture

[PermissionAuthorizeAction(PermissionActionName.Preview)]
public async Task<IActionResult> PicturePopup(string categoryId)
{
var category = await _categoryService.GetCategoryById(categoryId);
if (category == null)
return Content("Category not exist");

if (string.IsNullOrEmpty(category.PictureId))
return Content("Picture not exist");

var permission = await CheckAccessToCategory(category);
if (!permission.allow)
return Content(permission.message);


var (model, picture) = await _categoryViewModelService.PreparePictureModel(category);
//locales
await AddLocales(_languageService, model.Locales, (locale, languageId) =>
{
locale.AltAttribute = picture?.GetTranslation(x => x.AltAttribute, languageId, false);
locale.TitleAttribute = picture?.GetTranslation(x => x.TitleAttribute, languageId, false);
});

return View(model);
}

[PermissionAuthorizeAction(PermissionActionName.Edit)]
[HttpPost]
public async Task<IActionResult> PicturePopup(CategoryModel.PictureModel model)
{
if (ModelState.IsValid)
{
var category = await _categoryService.GetCategoryById(model.CategoryId);
if (category == null)
throw new ArgumentException("No category found with the specified id");

if (string.IsNullOrEmpty(category.PictureId))
throw new ArgumentException("No picture found with the specified id");

await _categoryViewModelService.UpdateCategoryPicture(model);

ViewBag.RefreshPage = true;
return View(model);
}

Error(ModelState);

return View(model);
}

#endregion

#region Export / Import
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Grand.Domain.Catalog;
using Grand.Domain.Media;
using Grand.Web.Admin.Models.Catalog;
using System.Collections.Generic;
using System.Threading.Tasks;
Expand All @@ -14,6 +15,8 @@ public interface ICategoryViewModelService
Task<Category> InsertCategoryModel(CategoryModel model);
Task<Category> UpdateCategoryModel(Category category, CategoryModel model);
Task DeleteCategory(Category category);
Task<(CategoryModel.PictureModel model, Picture Picture)> PreparePictureModel(Category category);
Task UpdateCategoryPicture(CategoryModel.PictureModel model);
Task<(IEnumerable<CategoryModel.CategoryProductModel> categoryProductModels, int totalCount)> PrepareCategoryProductModel(string categoryId, int pageIndex, int pageSize);
Task<ProductCategory> UpdateProductCategoryModel(CategoryModel.CategoryProductModel model);
Task DeleteProductCategoryModel(string id, string productId);
Expand Down
31 changes: 31 additions & 0 deletions src/Web/Grand.Web.Admin/Models/Catalog/CategoryModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,37 @@ public partial class ActivityLogModel : BaseEntityModel
public string CustomerEmail { get; set; }
}

public partial class PictureModel : BaseEntityModel, ILocalizedModel<PictureModel.PictureLocalizedModel>
{
public PictureModel()
{
Locales = new List<PictureLocalizedModel>();
}

public string CategoryId { get; set; }

[GrandResourceDisplayName("Admin.Catalog.Categories.Picture")]
public string PictureUrl { get; set; }

[GrandResourceDisplayName("Admin.Catalog.Categories.Picture.Fields.AltAttribute")]
public string AltAttribute { get; set; }

[GrandResourceDisplayName("Admin.Catalog.Categories.Picture.Fields.TitleAttribute")]
public string TitleAttribute { get; set; }

public IList<PictureLocalizedModel> Locales { get; set; }

public partial class PictureLocalizedModel : ILocalizedModelLocal
{
public string LanguageId { get; set; }

[GrandResourceDisplayName("Admin.Catalog.Categories.Picture.Fields.AltAttribute")]
public string AltAttribute { get; set; }

[GrandResourceDisplayName("Admin.Catalog.Categories.Picture.Fields.TitleAttribute")]
public string TitleAttribute { get; set; }
}
}

#endregion
}
Expand Down
30 changes: 27 additions & 3 deletions src/Web/Grand.Web.Admin/Services/CategoryViewModelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Grand.Domain.Media;

namespace Grand.Web.Admin.Services
{
Expand All @@ -34,7 +35,6 @@ public partial class CategoryViewModelService : ICategoryViewModelService
private readonly ITranslationService _translationService;
private readonly IStoreService _storeService;
private readonly ICustomerService _customerService;
private readonly IGroupService _groupService;
private readonly ISlugService _slugService;
private readonly IPictureService _pictureService;
private readonly ICustomerActivityService _customerActivityService;
Expand All @@ -46,7 +46,7 @@ public partial class CategoryViewModelService : ICategoryViewModelService
private readonly SeoSettings _seoSettings;

public CategoryViewModelService(ICategoryService categoryService, IProductCategoryService productCategoryService, ICategoryLayoutService categoryLayoutService, IDiscountService discountService,
ITranslationService translationService, IStoreService storeService, ICustomerService customerService, IGroupService groupService, IPictureService pictureService,
ITranslationService translationService, IStoreService storeService, ICustomerService customerService, IPictureService pictureService,
ISlugService slugService, ICustomerActivityService customerActivityService, IProductService productService,
IVendorService vendorService, IDateTimeService dateTimeService, ILanguageService languageService, CatalogSettings catalogSettings, SeoSettings seoSettings)
{
Expand All @@ -57,7 +57,6 @@ public CategoryViewModelService(ICategoryService categoryService, IProductCatego
_translationService = translationService;
_storeService = storeService;
_customerService = customerService;
_groupService = groupService;
_slugService = slugService;
_customerActivityService = customerActivityService;
_productService = productService;
Expand Down Expand Up @@ -248,6 +247,31 @@ public virtual async Task DeleteCategory(Category category)
//activity log
await _customerActivityService.InsertActivity("DeleteCategory", category.Id, _translationService.GetResource("ActivityLog.DeleteCategory"), category.Name);
}

public virtual async Task<(CategoryModel.PictureModel model, Picture Picture)> PreparePictureModel(Category category)
{
var picture = await _pictureService.GetPictureById(category.PictureId);
var model = new CategoryModel.PictureModel {
Id = picture.Id,
CategoryId = category.Id,
PictureUrl = picture != null ? await _pictureService.GetPictureUrl(picture) : null,
AltAttribute = picture?.AltAttribute,
TitleAttribute = picture?.TitleAttribute,
};
return (model, picture);
}
public virtual async Task UpdateCategoryPicture(CategoryModel.PictureModel model)
{
var picture = await _pictureService.GetPictureById(model.Id);
if (picture == null)
throw new ArgumentException("No picture found with the specified id");

//Update picture fields
await _pictureService.UpdatField(picture, x => x.AltAttribute, model.AltAttribute);
await _pictureService.UpdatField(picture, x => x.TitleAttribute, model.TitleAttribute);
await _pictureService.UpdatField(picture, x => x.Locales, model.Locales.ToTranslationProperty());

}
public virtual async Task<(IEnumerable<CategoryModel.CategoryProductModel> categoryProductModels, int totalCount)> PrepareCategoryProductModel(string categoryId, int pageIndex, int pageSize)
{
var productCategories = await _productCategoryService.GetProductCategoriesByCategoryId(categoryId,
Expand Down
12 changes: 12 additions & 0 deletions src/Web/Grand.Web/App_Data/Resources/DefaultLanguage.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2301,6 +2301,15 @@
<Resource Name="Admin.Catalog.Categories.Permisions">
<Value>You can't edit this category, because it can be used in many stores.</Value>
</Resource>
<Resource Name="Admin.Catalog.Categories.Picture">
<Value>Picture</Value>
</Resource>
<Resource Name="Admin.Catalog.Categories.Picture.Fields.AltAttribute">
<Value>Picture alternate text</Value>
</Resource>
<Resource Name="Admin.Catalog.Categories.Picture.Fields.TitleAttribute">
<Value>Picture title</Value>
</Resource>
<Resource Name="Admin.Catalog.Categories.Products">
<Value>Products</Value>
</Resource>
Expand Down Expand Up @@ -3906,6 +3915,9 @@
<Resource Name="Admin.Common.NoCancel">
<Value>No, cancel</Value>
</Resource>
<Resource Name="Admin.Common.Picture.Attributes">
<Value>Picture attributes</Value>
</Resource>
<Resource Name="Admin.Common.Preview">
<Value>Show in the shop page</Value>
</Resource>
Expand Down
Loading

0 comments on commit 50334c7

Please sign in to comment.