diff --git a/Content/localization.en-US.xml b/Content/localization.en-US.xml index de80ebf..1b1449c 100644 --- a/Content/localization.en-US.xml +++ b/Content/localization.en-US.xml @@ -156,6 +156,9 @@ Picture + + Name + Start date @@ -239,6 +242,9 @@ Picture + + Name + Start date @@ -402,4 +408,45 @@ Put here HTML content to override original slide HTML content. Keep empty if you're don't want to chnage content. + + + Name + + + Name + + + Slide search name. This property is using only for search purposes. + + + + Slide name + + + Put here part of searchable slide name. + + + Widget zone + + + Select searchable widnget zone + + + Start date + + + Put slide start publication date + + + Finish date + + + Put slide finish publication date + + + Published + + + Select searchable slide publication state. + diff --git a/Controllers/qBoSlideController.cs b/Controllers/qBoSlideController.cs index 77f942d..0be2841 100644 --- a/Controllers/qBoSlideController.cs +++ b/Controllers/qBoSlideController.cs @@ -52,6 +52,7 @@ public class qBoSlideController : BasePluginController private readonly INotificationService _notificationService; private readonly IPermissionService _permissionService; private readonly IPictureService _pictureService; + private readonly ISearchModelFactory _searchModelFactory; private readonly ISettingService _settingService; private readonly ISlideModelFactory _slideModelFactory; private readonly ISlideWidgetZoneModelFactory _slideWidgetZoneModelFactory; @@ -75,6 +76,7 @@ public qBoSlideController(IAclService aclService, INotificationService notificationService, IPermissionService permissionService, IPictureService pictureService, + ISearchModelFactory searchModelFactory, ISettingService settingService, ISlideModelFactory slideModelFactory, ISlideWidgetZoneModelFactory slideWidgetZoneModelFactory, @@ -94,6 +96,7 @@ public qBoSlideController(IAclService aclService, this._localizedEntityService = localizedEntityService; this._notificationService = notificationService; this._permissionService = permissionService; + _searchModelFactory = searchModelFactory; this._pictureService = pictureService; this._settingService = settingService; this._slideModelFactory = slideModelFactory; @@ -197,10 +200,10 @@ protected virtual async Task SaveCustomerRolesAclAsync(Slide slide, SlideModel m #region Slides List / Create / Update / Delete - public virtual IActionResult List() + public virtual async Task List() { var model = new SlideSearchModel(); - model.SetGridPageSize(); + await _searchModelFactory.PrepareSlideSearchModelAsync(model); return View("~/Plugins/Widgets.qBoSlider/Views/Admin/Slide/List.cshtml", model); } @@ -248,6 +251,7 @@ public virtual async Task Create(SlideModel model, bool continueE var slide = new Slide() { + Name = model.Name, Description = model.Description, HyperlinkAddress = model.Hyperlink, PictureId = model.PictureId, @@ -324,6 +328,7 @@ public virtual async Task Edit(SlideModel model, bool continueEdi } //set values + slide.Name = model.Name; slide.Description = model.Description; slide.HyperlinkAddress = model.Hyperlink; slide.PictureId = model.PictureId; diff --git a/Controllers/qBoWidgetZoneController.cs b/Controllers/qBoWidgetZoneController.cs index 059997f..557bdd5 100644 --- a/Controllers/qBoWidgetZoneController.cs +++ b/Controllers/qBoWidgetZoneController.cs @@ -49,6 +49,7 @@ public class qBoWidgetZoneController : BasePluginController private readonly ILocalizedEntityService _localizedEntityService; private readonly INotificationService _notificationService; private readonly IPermissionService _permissionService; + private readonly ISearchModelFactory _searchModelFactory; private readonly ISettingService _settingService; private readonly IStaticCacheManager _staticCacheManager; private readonly IStoreMappingService _storeMappingService; @@ -68,6 +69,7 @@ public qBoWidgetZoneController(IAclService aclService, ILocalizedEntityService localizedEntityService, INotificationService notificationService, IPermissionService permissionService, + ISearchModelFactory searchModelFactory, ISettingService settingService, IStoreMappingService storeMappingService, IStoreService storeService, @@ -82,6 +84,7 @@ public qBoWidgetZoneController(IAclService aclService, _localizedEntityService = localizedEntityService; _notificationService = notificationService; _permissionService = permissionService; + _searchModelFactory = searchModelFactory; _settingService = settingService; _storeMappingService = storeMappingService; _storeService = storeService; @@ -478,8 +481,7 @@ public virtual async Task AddWidgetZoneSlidePopup(int widgetZoneI { WidgetZoneId = widgetZoneId }; - - model.SetPopupGridPageSize(); + await _searchModelFactory.PrepareSlideSearchModelAsync(model); return View("~/Plugins/Widgets.qBoSlider/Views/Admin/WidgetZone/AddWidgetZoneSlidePopup.cshtml", model); } diff --git a/Factories/Admin/ISearchModelFactory.cs b/Factories/Admin/ISearchModelFactory.cs new file mode 100644 index 0000000..65550f2 --- /dev/null +++ b/Factories/Admin/ISearchModelFactory.cs @@ -0,0 +1,35 @@ +//Copyright 2020 Alexey Prokhorov + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. + +using Nop.Plugin.Widgets.qBoSlider.Models.Admin; +using Nop.Web.Framework.Models; +using System.Threading.Tasks; + +namespace Nop.Plugin.Widgets.qBoSlider.Factories.Admin +{ + /// + /// Represents search model factory interface. + /// Stores methods which prepares common search box properties + /// + public interface ISearchModelFactory + { + /// + /// Prepares slide search box model + /// + /// Slide search model + /// Search box model instance + /// Model instance + Task PrepareSlideSearchModelAsync(TModel searchModel) where TModel : BaseSearchModel, ISlideSearchModel; + } +} diff --git a/Factories/Admin/SearchModelFactory.cs b/Factories/Admin/SearchModelFactory.cs new file mode 100644 index 0000000..607aa25 --- /dev/null +++ b/Factories/Admin/SearchModelFactory.cs @@ -0,0 +1,79 @@ +//Copyright 2020 Alexey Prokhorov + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. + +using Microsoft.AspNetCore.Mvc.Rendering; +using Nop.Plugin.Widgets.qBoSlider.Models.Admin; +using Nop.Plugin.Widgets.qBoSlider.Service; +using Nop.Services; +using Nop.Services.Localization; +using Nop.Web.Framework.Models; +using System.Linq; +using System.Threading.Tasks; + +namespace Nop.Plugin.Widgets.qBoSlider.Factories.Admin +{ + /// + /// Represents search boxes model factory + /// + public class SearchModelFactory : ISearchModelFactory + { + #region Fields + + private readonly ILocalizationService _localizationService; + private readonly IWidgetZoneService _widgetZoneService; + + #endregion + + #region Constructor + + public SearchModelFactory( + ILocalizationService localizationService, + IWidgetZoneService widgetZoneService) + { + _localizationService = localizationService; + _widgetZoneService = widgetZoneService; + } + + #endregion + + #region Methods + + /// + /// Prepares slide search model + /// + /// Slide search model + /// Slide search model + public virtual async Task PrepareSlideSearchModelAsync(TModel model) where TModel : BaseSearchModel, ISlideSearchModel + { + model.AvailableWidgetZones = _widgetZoneService.GetWidgetZones().Select(x => + { + return new SelectListItem() + { + Value = x.Id.ToString(), + Text = $"{x.Name} ({x.SystemName})" + }; + }).ToList(); + model.AvailablePublicationStates = (await PublicationState.All.ToSelectListAsync(useLocalization: true)).ToList(); + model.SetGridPageSize(); + model.AvailableWidgetZones.Insert(0, + new SelectListItem() + { + Value = "0", + Text = await _localizationService.GetResourceAsync("admin.common.all") + }); + } + + #endregion + } +} diff --git a/Factories/Admin/SlideModelFactory.cs b/Factories/Admin/SlideModelFactory.cs index 251d04c..c474fbd 100644 --- a/Factories/Admin/SlideModelFactory.cs +++ b/Factories/Admin/SlideModelFactory.cs @@ -151,7 +151,12 @@ public virtual async Task PrepareAclModelAsync(SlideModel model, Slide slide, bo /// Slide paged list model public virtual async Task PrepareSlideListPagedModelAsync(SlideSearchModel searchModel) { - var slides = await _slideService.GetAllSlidesAsync(showHidden: true, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); + var slides = await _slideService.GetAllSlidesAsync(searchModel.SearchName, + searchModel.SearchWidgetZoneId > 0 ? new int[1] { searchModel.SearchWidgetZoneId } : null, + searchModel.SearchStartDateOnUtc, + searchModel.SearchFinishDateOnUtc, + (PublicationState)searchModel.SearchPublicationStateId, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); + var gridModel = await new SlideSearchModel.SlidePagedListModel().PrepareToGridAsync(searchModel, slides, () => { return slides.SelectAwait(async slide => @@ -160,6 +165,7 @@ public virtual async Task PrepareAclModelAsync(SlideModel model, Slide slide, bo return new SlideSearchModel.SlideListItemModel() { Id = slide.Id, + Name = slide.Name, Picture = await _pictureService.GetPictureUrlAsync(pictureId, 300), Hyperlink = slide.HyperlinkAddress, StartDateUtc = slide.StartDateUtc, @@ -186,6 +192,7 @@ public virtual async Task PrepareSlideModelAsync(SlideModel model, S if(slide != null) { model.Id = slide.Id; + model.Name = slide.Name; model.Hyperlink = slide.HyperlinkAddress; model.PictureId = slide.PictureId.GetValueOrDefault(0); model.Description = slide.Description; diff --git a/Factories/Admin/WidgetZoneSlideModelFactory.cs b/Factories/Admin/WidgetZoneSlideModelFactory.cs index 6ec8d37..9e2dbc5 100644 --- a/Factories/Admin/WidgetZoneSlideModelFactory.cs +++ b/Factories/Admin/WidgetZoneSlideModelFactory.cs @@ -81,6 +81,7 @@ public WidgetZoneSlideModelFactory(ILanguageService languageService, { Id = widgetZoneSlide.Id, PictureUrl = pictureUrl, + Name = slide.Name, StartDateUtc = slide.StartDateUtc, EndDateUtc = slide.EndDateUtc, Published = slide.Published, @@ -99,7 +100,14 @@ public WidgetZoneSlideModelFactory(ILanguageService languageService, /// Add widget zone slide model public virtual async Task PrepareAddWidgetZoneSlideModelAsync(AddWidgetZoneSlideModel searchModel) { - var slides = await _slideService.GetAllSlidesAsync(showHidden: true, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); + var slides = await _slideService.GetAllSlidesAsync(name: searchModel.SearchName, + widgetZoneIds: searchModel.SearchWidgetZoneId > 0 ? new int[1] { searchModel.SearchWidgetZoneId } : null, + startDate: searchModel.SearchStartDateOnUtc, + endDate: searchModel.SearchFinishDateOnUtc, + publicationState: (PublicationState)searchModel.SearchPublicationStateId, + pageIndex: searchModel.Page - 1, + pageSize: searchModel.PageSize); + var gridModel = await new AddWidgetZoneSlideModel.SlidePagedListModel().PrepareToGridAsync(searchModel, slides, () => { return slides.SelectAwait(async slide => @@ -110,6 +118,7 @@ public WidgetZoneSlideModelFactory(ILanguageService languageService, return new AddWidgetZoneSlideModel.SlideModel() { Id = slide.Id, + Name = slide.Name, PictureUrl = pictureUrl, StartDateUtc = slide.StartDateUtc, EndDateUtc = slide.EndDateUtc, diff --git a/Infrastructure/NopStartup.cs b/Infrastructure/NopStartup.cs index f38de0a..6da3123 100644 --- a/Infrastructure/NopStartup.cs +++ b/Infrastructure/NopStartup.cs @@ -41,6 +41,7 @@ public void ConfigureServices(IServiceCollection services, IConfiguration config services.AddScoped(); //factories + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/Models/Admin/ISlideSearchModel.cs b/Models/Admin/ISlideSearchModel.cs new file mode 100644 index 0000000..8acafbb --- /dev/null +++ b/Models/Admin/ISlideSearchModel.cs @@ -0,0 +1,70 @@ +//Copyright 2020 Alexey Prokhorov + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. + +using Microsoft.AspNetCore.Mvc.Rendering; +using Nop.Web.Framework.Mvc.ModelBinding; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Nop.Plugin.Widgets.qBoSlider.Models.Admin +{ + /// + /// Represents slide search model + /// + public interface ISlideSearchModel + { + /// + /// Gets or sets slide search name + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchName")] + string SearchName { get; set; } + + /// + /// Gets or sets search slide widget zone + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchWidgetZoneId")] + int SearchWidgetZoneId { get; set; } + + /// + /// Gets or sets available widget zones + /// + IList AvailableWidgetZones { get; set; } + + /// + /// Gets or sets slide search start date + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchStartDateOnUtc")] + [UIHint("DateTimeNullable")] + DateTime? SearchStartDateOnUtc { get; set; } + + /// + /// Gets or sets slide search finish date + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchFinishDateOnUtc")] + [UIHint("DateTimeNullable")] + DateTime? SearchFinishDateOnUtc { get; set; } + + /// + /// Gets or sets slide search publication status + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.PublicationStateId")] + int SearchPublicationStateId { get; set; } + + /// + /// Gets or sets list of available publication states + /// + IList AvailablePublicationStates { get; set; } + } +} diff --git a/Models/Admin/Slides/SlideModel.cs b/Models/Admin/Slides/SlideModel.cs index 4785443..6523ee8 100644 --- a/Models/Admin/Slides/SlideModel.cs +++ b/Models/Admin/Slides/SlideModel.cs @@ -16,6 +16,9 @@ public record SlideModel : BaseNopEntityModel, ILocalizedModel /// Represent slide search model /// - public record SlideSearchModel : BaseSearchModel + public record SlideSearchModel : BaseSearchModel, ISlideSearchModel { + /// + /// Gets or sets slide search name + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchName")] + public string SearchName { get; set; } + + /// + /// Gets or sets search slide widget zone + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchWidgetZoneId")] + public int SearchWidgetZoneId { get; set; } + + /// + /// Gets or sets available widget zones + /// + public IList AvailableWidgetZones { get; set; } = new List(); + + /// + /// Gets or sets slide search start date + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchStartDateOnUtc")] + [UIHint("DateTimeNullable")] + public DateTime? SearchStartDateOnUtc { get; set; } + + /// + /// Gets or sets slide search finish date + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchFinishDateOnUtc")] + [UIHint("DateTimeNullable")] + public DateTime? SearchFinishDateOnUtc { get; set; } + + /// + /// Gets or sets slide search publication status + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.PublicationStateId")] + public int SearchPublicationStateId { get; set; } + + /// + /// Gets or sets list of available publication states + /// + public IList AvailablePublicationStates { get; set; } = new List(); + /// /// Represent slide page list model /// @@ -41,6 +87,11 @@ public record SlideListItemModel : BaseNopEntityModel /// public string Picture { get; set; } + /// + /// Gets or sets slide name + /// + public string Name { get; set; } + /// /// Gets or sets slide hyperlink /// diff --git a/Models/Admin/WidgetZones/AddWidgetZoneSlideModel.cs b/Models/Admin/WidgetZones/AddWidgetZoneSlideModel.cs index 7cae897..049e861 100644 --- a/Models/Admin/WidgetZones/AddWidgetZoneSlideModel.cs +++ b/Models/Admin/WidgetZones/AddWidgetZoneSlideModel.cs @@ -1,14 +1,16 @@ -using Nop.Web.Framework.Models; +using Microsoft.AspNetCore.Mvc.Rendering; +using Nop.Web.Framework.Models; using Nop.Web.Framework.Mvc.ModelBinding; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; namespace Nop.Plugin.Widgets.qBoSlider.Models.Admin.WidgetZones { /// /// Represents add widget zone slide model /// - public record AddWidgetZoneSlideModel : BaseSearchModel + public record AddWidgetZoneSlideModel : BaseSearchModel, ISlideSearchModel { /// /// Gets or sets widget zone unique id number @@ -20,6 +22,48 @@ public record AddWidgetZoneSlideModel : BaseSearchModel /// public IList SelecetedSlideIds { get; set; } = new List(); + /// + /// Gets or sets slide search name + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchName")] + public string SearchName { get; set; } + + /// + /// Gets or sets search slide widget zone + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchWidgetZoneId")] + public int SearchWidgetZoneId { get; set; } + + /// + /// Gets or sets available widget zones + /// + public IList AvailableWidgetZones { get; set; } = new List(); + + /// + /// Gets or sets slide search start date + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchStartDateOnUtc")] + [UIHint("DateTimeNullable")] + public DateTime? SearchStartDateOnUtc { get; set; } + + /// + /// Gets or sets slide search finish date + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.SearchFinishDateOnUtc")] + [UIHint("DateTimeNullable")] + public DateTime? SearchFinishDateOnUtc { get; set; } + + /// + /// Gets or sets slide search publication status + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.SlideSearch.PublicationStateId")] + public int SearchPublicationStateId { get; set; } + + /// + /// Gets or sets list of available publication states + /// + public IList AvailablePublicationStates { get; set; } = new List(); + /// /// Represents slide list model /// @@ -39,6 +83,12 @@ public record SlideModel : BaseNopEntityModel [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.AddWidgetZoneSlide.Fields.PictureUrl")] public string PictureUrl { get; set; } + /// + /// Gets or sets slide search name + /// + [NopResourceDisplayName("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.AddWidgetZoneSlide.Fields.Name")] + public string Name { get; set; } + /// /// Gets or sets slide publishing start date /// diff --git a/Models/Admin/WidgetZones/WidgetZoneSlideSearchModel.cs b/Models/Admin/WidgetZones/WidgetZoneSlideSearchModel.cs index 57972b0..de23463 100644 --- a/Models/Admin/WidgetZones/WidgetZoneSlideSearchModel.cs +++ b/Models/Admin/WidgetZones/WidgetZoneSlideSearchModel.cs @@ -31,6 +31,11 @@ public record SlideListItem : BaseNopEntityModel /// public string PictureUrl { get; set; } + /// + /// Gets or sets slide search name + /// + public string Name { get; set; } + /// /// Gets or sets slide displaying start date /// diff --git a/Nop.Plugin.Widgets.qBoSlider.csproj b/Nop.Plugin.Widgets.qBoSlider.csproj index 0c4390d..205b950 100644 --- a/Nop.Plugin.Widgets.qBoSlider.csproj +++ b/Nop.Plugin.Widgets.qBoSlider.csproj @@ -153,6 +153,9 @@ Always + + Always + Always diff --git a/Service/ISlideService.cs b/Service/ISlideService.cs index 78d88d9..f232b49 100644 --- a/Service/ISlideService.cs +++ b/Service/ISlideService.cs @@ -33,14 +33,23 @@ public interface ISlideService /// /// Get all slides for current store /// + /// Searching slider name + /// Slides for widget zones /// Publication start date /// Publication end date - /// Show unpublished slides too + /// Searching slides publication state /// Page index /// Page sizer /// Store id number - /// - Task> GetAllSlidesAsync(DateTime? startDate = null, DateTime? endDate = null, bool showHidden = false, int pageIndex = 0, int pageSize = int.MaxValue, int storeId = 0); + /// Paged slides list + Task> GetAllSlidesAsync(string name = null, + int[] widgetZoneIds = null, + DateTime? startDate = null, + DateTime? endDate = null, + PublicationState publicationState = 0, + int pageIndex = 0, + int pageSize = int.MaxValue, + int storeId = 0); /// /// Insert slide diff --git a/Service/SlideService.cs b/Service/SlideService.cs index cc696cf..0c66829 100644 --- a/Service/SlideService.cs +++ b/Service/SlideService.cs @@ -31,7 +31,7 @@ public partial class SlideService : ISlideService #region Fields private readonly IRepository _slideRepository; - + private readonly IRepository _widgetZoneSlideRepository; private readonly IStoreMappingService _storeMappingService; #endregion @@ -39,11 +39,12 @@ public partial class SlideService : ISlideService #region Constructor public SlideService(IRepository slideRepository, + IRepository widgetZoneSlideRepository, IStoreMappingService storeMappingService) { - this._slideRepository = slideRepository; - - this._storeMappingService = storeMappingService; + _slideRepository = slideRepository; + _widgetZoneSlideRepository = widgetZoneSlideRepository; + _storeMappingService = storeMappingService; } #endregion @@ -63,36 +64,59 @@ public virtual async Task GetSlideByIdAsync(int id) /// /// Get all slides for current store /// + /// Searching slider name + /// Slides for widget zones /// Publication start date /// Publication end date - /// Show unpublished slides too + /// Searching slides publication state /// Page index /// Page sizer /// Store id number - /// - public virtual async Task> GetAllSlidesAsync(DateTime? startDate = null, DateTime? endDate = null, bool showHidden = false, int pageIndex = 0, int pageSize = int.MaxValue, int storeId = 0) + /// Paged slides list + public virtual async Task> GetAllSlidesAsync(string name = null, + int[] widgetZoneIds = null, + DateTime? startDate = null, + DateTime? endDate = null, + PublicationState publicationState = 0, + int pageIndex = 0, + int pageSize = int.MaxValue, + int storeId = 0) { - var query = _slideRepository.Table; + var result = await _slideRepository.GetAllPagedAsync(async query => + { + //filter slides, which contains part of searchable slide name + if (!string.IsNullOrEmpty(name)) + query = query.Where(x => x.Name.Contains(name)); + + //filter by widget zones + if (widgetZoneIds != null && widgetZoneIds.Any()) + query = from slide in query + join widgetZoneSlide in _widgetZoneSlideRepository.Table on slide.Id equals widgetZoneSlide.SlideId + where widgetZoneIds.Contains(widgetZoneSlide.WidgetZoneId) + select slide; + + //filter by start date + if (startDate.HasValue) + query = query.Where(x => !x.StartDateUtc.HasValue || x.StartDateUtc >= startDate.Value); - //filter unpublished slides - if (!showHidden) - query = query.Where(x => x.Published); + //filter by end publishing date + if (endDate.HasValue) + query = query.Where(x => !x.EndDateUtc.HasValue || x.EndDateUtc <= endDate.Value); - //filter by start date - if (startDate.HasValue) - query = query.Where(x => x.StartDateUtc <= DateTime.UtcNow); + //filter unpublished slides + if (publicationState == PublicationState.Published) + query = query.Where(x => x.Published); - //filter by end publishing date - if (endDate.HasValue) - query = query.Where(x => x.EndDateUtc >= DateTime.UtcNow); + if (publicationState == PublicationState.Unpublished) + query = query.Where(x => !x.Published); - var result = new List(); + if (storeId > 0) + query = await _storeMappingService.ApplyStoreMapping(query, storeId); - foreach (var s in query) - if (await _storeMappingService.AuthorizeAsync(s, storeId)) - result.Add(s); + return query; + }); - return new PagedList(result, pageIndex, pageSize); + return result; } /// diff --git a/Views/Admin/Slide/List.cshtml b/Views/Admin/Slide/List.cshtml index d73bf36..9f8548b 100644 --- a/Views/Admin/Slide/List.cshtml +++ b/Views/Admin/Slide/List.cshtml @@ -26,6 +26,7 @@
+ @await Html.PartialAsync("~/Plugins/Widgets.qBoSlider/Views/Admin/_SlideSearch.cshtml", Model)
@await Html.PartialAsync("Table", new DataTablesModel @@ -44,6 +45,12 @@ Visible = true, Render = new RenderPicture() }, + new ColumnProperty(nameof(SlideSearchModel.SlideListItemModel.Name)) + { + Title = T("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.Slide.List.Name").Text, + Width = "300", + Visible = true + }, new ColumnProperty(nameof(SlideSearchModel.SlideListItemModel.StartDateUtc)) { Title = T("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.Slide.List.StartDateUtc").Text, diff --git a/Views/Admin/Slide/_CreateOrUpdate.Info.cshtml b/Views/Admin/Slide/_CreateOrUpdate.Info.cshtml index 374dc7b..5a38a55 100644 --- a/Views/Admin/Slide/_CreateOrUpdate.Info.cshtml +++ b/Views/Admin/Slide/_CreateOrUpdate.Info.cshtml @@ -59,6 +59,15 @@
)) +
+
+ +
+
+ + +
+
diff --git a/Views/Admin/WidgetZone/AddWidgetZoneSlidePopup.cshtml b/Views/Admin/WidgetZone/AddWidgetZoneSlidePopup.cshtml index c5c8346..ce858bd 100644 --- a/Views/Admin/WidgetZone/AddWidgetZoneSlidePopup.cshtml +++ b/Views/Admin/WidgetZone/AddWidgetZoneSlidePopup.cshtml @@ -34,6 +34,7 @@ else
+ @await Html.PartialAsync("~/Plugins/Widgets.qBoSlider/Views/Admin/_SlideSearch.cshtml", Model)
@await Html.PartialAsync("Table", new DataTablesModel @@ -58,6 +59,10 @@ else Title = T("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.AddWidgetZoneSlide.Fields.PictureUrl").Text, Width = "300" }, + new ColumnProperty(nameof(AddWidgetZoneSlideModel.SlideModel.Name)) + { + Title = T("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.AddWidgetZoneSlide.Fields.Name").Text + }, new ColumnProperty(nameof(AddWidgetZoneSlideModel.SlideModel.StartDateUtc)) { Title = T("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.AddWidgetZoneSlide.Fields.StartDateUtc").Text, diff --git a/Views/Admin/WidgetZone/_CreateOrUpdate.Slides.cshtml b/Views/Admin/WidgetZone/_CreateOrUpdate.Slides.cshtml index 902ff4b..2b49a2b 100644 --- a/Views/Admin/WidgetZone/_CreateOrUpdate.Slides.cshtml +++ b/Views/Admin/WidgetZone/_CreateOrUpdate.Slides.cshtml @@ -18,6 +18,10 @@ Title = T("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.WidgetZone.SlideList.PictureUrl").Text, Render = new RenderPicture() }, + new ColumnProperty(nameof(WidgetZoneSlideSearchModel.SlideListItem.Name)) + { + Title = T("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.WidgetZone.SlideList.Name").Text + }, new ColumnProperty(nameof(WidgetZoneSlideSearchModel.SlideListItem.StartDateUtc)) { Title = T("Nop.Plugin.Baroque.Widgets.qBoSlider.Admin.WidgetZone.SlideList.StartDateUtc").Text, diff --git a/Views/Admin/_SlideSearch.cshtml b/Views/Admin/_SlideSearch.cshtml new file mode 100644 index 0000000..9ec78dc --- /dev/null +++ b/Views/Admin/_SlideSearch.cshtml @@ -0,0 +1,70 @@ +@model ISlideSearchModel +@{ + const string hideSearchBlockAttributeName = "Baroque.qBoSlider.Slide.HideSearchBlock"; + var hideSearchBlock = await genericAttributeService.GetAttributeAsync(await workContext.GetCurrentCustomerAsync(), hideSearchBlockAttributeName); +} + + \ No newline at end of file diff --git a/plugin.json b/plugin.json index 2ec1577..49ce518 100644 --- a/plugin.json +++ b/plugin.json @@ -2,7 +2,7 @@ "Group": "Widgets", "FriendlyName": "qBoSlider", "SystemName": "Widgets.qBoSlider", - "Version": "1.3.1", + "Version": "1.4.1", "SupportedVersions": [ "4.50" ], "Author": "Baroque team", "DisplayOrder": 1, diff --git a/qBoOptions.cs b/qBoOptions.cs index bed9a88..6bc8ba8 100644 --- a/qBoOptions.cs +++ b/qBoOptions.cs @@ -46,4 +46,14 @@ public enum DragOrientation : int Vertical = 2, Both = 3 } + + /// + /// Represents entity publication state variants + /// + public enum PublicationState : int + { + All = 0, + Published = 5, + Unpublished = 10 + } } diff --git a/qBoSliderPlugin.cs b/qBoSliderPlugin.cs index 83e92c9..8ab303a 100644 --- a/qBoSliderPlugin.cs +++ b/qBoSliderPlugin.cs @@ -111,7 +111,7 @@ public async Task> GetWidgetZonesAsync() activeWidgetZones = await activeWidgetZones //process only authorized by ACL widget zones .WhereAwait(async widgetZone => await _aclService.AuthorizeAsync(widgetZone)).ToListAsync(); - //prepare of store mapped widget zones + //prepare of store mapped widget zones var widgetZoneSystemNames = await activeWidgetZones .WhereAwait(async widgetZone => await _storeMappingService.AuthorizeAsync(widgetZone)) .Select(x => x.SystemName).Distinct().ToListAsync(); @@ -218,36 +218,39 @@ public override async Task InstallAsync() //get sample pictures path var sampleImagesPath = CommonHelper.DefaultFileProvider.MapPath("~/Plugins/Widgets.qBoSlider/Content/sample-images/"); - var picture1 = (await _pictureService.InsertPictureAsync(File.ReadAllBytes(string.Format("{0}banner1.jpg", sampleImagesPath)), "image/pjpeg", "qboslide-1")).Id; + var picture1Id = (await _pictureService.InsertPictureAsync(File.ReadAllBytes(string.Format("{0}banner1.jpg", sampleImagesPath)), "image/pjpeg", "qboslide-1")).Id; var slide1 = new Slide() { + Name = "New comfort mouse", Description = "
" + "

NEW COMFORT MOUSE

" + "

CHOOSE FROM HUNDREDS

" + "

OF MODELS

" + "

FROM ONLY $59.00

" + "

SHOP NOW

", - PictureId = picture1, + PictureId = picture1Id, Published = true }; await _slideService.InsertSlideAsync(slide1); - var picture2 = _pictureService.InsertPictureAsync(File.ReadAllBytes(string.Format("{0}banner2.jpg", sampleImagesPath)), "image/pjpeg", "qboslide-2").GetAwaiter().GetResult().Id; + var picture2Id = (await _pictureService.InsertPictureAsync(File.ReadAllBytes(string.Format("{0}banner2.jpg", sampleImagesPath)), "image/pjpeg", "qboslide-2")).Id; var slide2 = new Slide() { + Name = "HD PRO WEBCAM H320", Description = "
" + "

HD PRO WEBCAM H320

" + "

720P FOR TRUE HD-QUALITY
VIDEO CHAT

" + "

ONLY $79.00

" + "

SHOP NOW

", - PictureId = picture2, + PictureId = picture2Id, Published = true, }; await _slideService.InsertSlideAsync(slide2); - var picture3 = _pictureService.InsertPictureAsync(File.ReadAllBytes(string.Format("{0}banner3.jpg", sampleImagesPath)), "image/pjpeg", "qboslide-3").GetAwaiter().GetResult().Id; + var picture3Id = (await _pictureService.InsertPictureAsync(File.ReadAllBytes(string.Format("{0}banner3.jpg", sampleImagesPath)), "image/pjpeg", "qboslide-3")).Id; var slide3 = new Slide() { + Name = "Compact camera SP120", Description = "
" + "

COMPACT CAMERA SP120

" + "

20X WIDE ZOOM, 2.5 LCD,

" + @@ -255,7 +258,7 @@ public override async Task InstallAsync() "

ONLY $159.00

" + "

SHOP NOW

" + "
", - PictureId = picture3, + PictureId = picture3Id, Published = true }; await _slideService.InsertSlideAsync(slide3);