mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Simplifying dashboard management.
This removes the ability to edit multiple dashboards in favor of a simplified way for users to edit the default dashboard.
This commit is contained in:
@@ -7,13 +7,8 @@ namespace Orchard.Dashboards {
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Settings"), settings => settings
|
||||
.Add(T("Dashboards"), "16", dashboard => dashboard
|
||||
.Add(T("Settings"), "5", dashboardSettings => dashboardSettings
|
||||
.Action("Index", "Settings", new { area = "Orchard.Dashboards" })
|
||||
.LocalNav())
|
||||
.Add(T("Manage Dashboards"), "6", manageDashboards => manageDashboards
|
||||
.Action("List", "Dashboard", new { area = "Orchard.Dashboards" })
|
||||
.LocalNav())));
|
||||
.Add(T("Dashboard"), "16", dashboard => dashboard
|
||||
.Action("Edit", "Dashboard", new { area = "Orchard.Dashboards" })));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,31 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Contents.ViewModels;
|
||||
using Orchard.Dashboards.Services;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Localization.Services;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.UI.Admin;
|
||||
using Orchard.UI.Navigation;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Dashboards.Controllers {
|
||||
[Admin]
|
||||
public class DashboardController : Controller {
|
||||
[ValidateInput(false)]
|
||||
public class DashboardController : Controller, IUpdateModel {
|
||||
private readonly IDashboardService _dashboardService;
|
||||
private readonly IOrchardServices _services;
|
||||
private readonly ICultureFilter _cultureFilter;
|
||||
private readonly ICultureManager _cultureManager;
|
||||
|
||||
public DashboardController(IDashboardService dashboardService, IOrchardServices services, ICultureFilter cultureFilter, ICultureManager cultureManager) {
|
||||
public DashboardController(IDashboardService dashboardService, IOrchardServices services) {
|
||||
_dashboardService = dashboardService;
|
||||
_services = services;
|
||||
_cultureFilter = cultureFilter;
|
||||
_cultureManager = cultureManager;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
@@ -36,123 +27,52 @@ namespace Orchard.Dashboards.Controllers {
|
||||
return new ShapeResult(this, shape);
|
||||
}
|
||||
|
||||
public ActionResult List(ListContentsViewModel model, PagerParameters pagerParameters) {
|
||||
var pager = new Pager(_services.WorkContext.CurrentSite, pagerParameters);
|
||||
VersionOptions versionOptions;
|
||||
|
||||
switch (model.Options.ContentsStatus) {
|
||||
case ContentsStatus.Published:
|
||||
versionOptions = VersionOptions.Published;
|
||||
break;
|
||||
case ContentsStatus.Draft:
|
||||
versionOptions = VersionOptions.Draft;
|
||||
break;
|
||||
case ContentsStatus.AllVersions:
|
||||
versionOptions = VersionOptions.AllVersions;
|
||||
break;
|
||||
default:
|
||||
versionOptions = VersionOptions.Latest;
|
||||
break;
|
||||
}
|
||||
|
||||
var query = _services.ContentManager.Query(versionOptions, "Dashboard");
|
||||
|
||||
switch (model.Options.OrderBy) {
|
||||
case ContentsOrder.Modified:
|
||||
query = query.OrderByDescending<CommonPartRecord>(cr => cr.ModifiedUtc);
|
||||
break;
|
||||
case ContentsOrder.Published:
|
||||
query = query.OrderByDescending<CommonPartRecord>(cr => cr.PublishedUtc);
|
||||
break;
|
||||
case ContentsOrder.Created:
|
||||
query = query.OrderByDescending<CommonPartRecord>(cr => cr.CreatedUtc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(model.Options.SelectedCulture)) {
|
||||
query = _cultureFilter.FilterCulture(query, model.Options.SelectedCulture);
|
||||
}
|
||||
|
||||
model.Options.Cultures = _cultureManager.ListCultures();
|
||||
|
||||
var maxPagedCount = _services.WorkContext.CurrentSite.MaxPagedCount;
|
||||
if (maxPagedCount > 0 && pager.PageSize > maxPagedCount)
|
||||
pager.PageSize = maxPagedCount;
|
||||
var pagerShape = _services.New.Pager(pager).TotalItemCount(maxPagedCount > 0 ? maxPagedCount : query.Count());
|
||||
var pageOfContentItems = query.Slice(pager.GetStartIndex(), pager.PageSize).ToList();
|
||||
|
||||
var list = _services.New.List();
|
||||
list.AddRange(pageOfContentItems.Select(ci => _services.ContentManager.BuildDisplay(ci, "SummaryAdmin")));
|
||||
|
||||
var viewModel = _services.New.ViewModel()
|
||||
.ContentItems(list)
|
||||
.Pager(pagerShape)
|
||||
.Options(model.Options)
|
||||
.TypeDisplayName(model.TypeDisplayName ?? "");
|
||||
|
||||
return View(viewModel);
|
||||
public ActionResult Edit() {
|
||||
var dashboard = _dashboardService.GetDashboardDescriptor();
|
||||
var editor = dashboard.Editor(_services.New);
|
||||
return View(editor);
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("List")]
|
||||
[FormValueRequired("submit.Filter")]
|
||||
public ActionResult ListFilterPOST(ContentOptions options) {
|
||||
var routeValues = ControllerContext.RouteData.Values;
|
||||
if (options != null) {
|
||||
routeValues["Options.SelectedCulture"] = options.SelectedCulture; //todo: don't hard-code the key
|
||||
routeValues["Options.OrderBy"] = options.OrderBy; //todo: don't hard-code the key
|
||||
routeValues["Options.ContentsStatus"] = options.ContentsStatus; //todo: don't hard-code the key
|
||||
}
|
||||
|
||||
return RedirectToAction("List", routeValues);
|
||||
[ActionName("Edit")]
|
||||
[HttpPost]
|
||||
[FormValueRequired("submit.Save")]
|
||||
public ActionResult Save() {
|
||||
return UpdateDashboard(dashboard => _services.Notifier.Information(T("Your dashboard has been saved.")));
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("List")]
|
||||
[FormValueRequired("submit.BulkEdit")]
|
||||
public ActionResult ListPOST(ContentOptions options, IEnumerable<int> itemIds, string returnUrl) {
|
||||
if (itemIds != null) {
|
||||
var checkedContentItems = _services.ContentManager.GetMany<ContentItem>(itemIds, VersionOptions.Latest, QueryHints.Empty);
|
||||
switch (options.BulkAction) {
|
||||
case ContentsBulkAction.None:
|
||||
break;
|
||||
case ContentsBulkAction.PublishNow:
|
||||
foreach (var item in checkedContentItems) {
|
||||
if (!_services.Authorizer.Authorize(Core.Contents.Permissions.PublishContent, item, T("Couldn't publish selected content."))) {
|
||||
_services.TransactionManager.Cancel();
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
[ActionName("Edit")]
|
||||
[HttpPost]
|
||||
[FormValueRequired("submit.Publish")]
|
||||
public ActionResult Publish() {
|
||||
return UpdateDashboard(dashboard => {
|
||||
_services.Notifier.Information(T("Your dashboard has been published."));
|
||||
_services.ContentManager.Publish(dashboard);
|
||||
});
|
||||
}
|
||||
|
||||
_services.ContentManager.Publish(item);
|
||||
}
|
||||
_services.Notifier.Information(T("Content successfully published."));
|
||||
break;
|
||||
case ContentsBulkAction.Unpublish:
|
||||
foreach (var item in checkedContentItems) {
|
||||
if (!_services.Authorizer.Authorize(Core.Contents.Permissions.PublishContent, item, T("Couldn't unpublish selected content."))) {
|
||||
_services.TransactionManager.Cancel();
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
private ActionResult UpdateDashboard(Action<ContentItem> conditonallyPublish) {
|
||||
var dashboard = _dashboardService.GetDashboardDescriptor();
|
||||
var editor = dashboard.UpdateEditor(_services.New, this);
|
||||
|
||||
_services.ContentManager.Unpublish(item);
|
||||
}
|
||||
_services.Notifier.Information(T("Content successfully unpublished."));
|
||||
break;
|
||||
case ContentsBulkAction.Remove:
|
||||
foreach (var item in checkedContentItems) {
|
||||
if (!_services.Authorizer.Authorize(Core.Contents.Permissions.DeleteContent, item, T("Couldn't remove selected content."))) {
|
||||
_services.TransactionManager.Cancel();
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
_services.ContentManager.Remove(item);
|
||||
}
|
||||
_services.Notifier.Information(T("Content successfully removed."));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
if (!ModelState.IsValid) {
|
||||
_services.TransactionManager.Cancel();
|
||||
return View(editor);
|
||||
}
|
||||
|
||||
return RedirectToAction("List");
|
||||
var contentItem = (ContentItem)editor.ContentItem;
|
||||
|
||||
if (contentItem != null)
|
||||
conditonallyPublish(contentItem);
|
||||
|
||||
return RedirectToAction("Edit");
|
||||
}
|
||||
|
||||
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
||||
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
|
||||
}
|
||||
|
||||
void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) {
|
||||
ModelState.AddModelError(key, errorMessage.ToString());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Dashboards.Models;
|
||||
using Orchard.Dashboards.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Admin;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Dashboards.Controllers {
|
||||
[Admin]
|
||||
public class SettingsController : Controller {
|
||||
private readonly IOrchardServices _services;
|
||||
|
||||
public SettingsController(IOrchardServices services) {
|
||||
_services = services;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public ActionResult Index() {
|
||||
var settings = _services.WorkContext.CurrentSite.As<DashboardSiteSettingsPart>();
|
||||
var viewModel = new DashboardSiteSettingsViewModel {
|
||||
SelectedDashboardId = settings.DefaultDashboardId.ToString(),
|
||||
SelectedDashboard = settings.DefaultDashboardId != null ? _services.ContentManager.Get(settings.DefaultDashboardId.Value) : default(ContentItem)
|
||||
};
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Index(DashboardSiteSettingsViewModel viewModel) {
|
||||
var settings = _services.WorkContext.CurrentSite.As<DashboardSiteSettingsPart>();
|
||||
|
||||
if (!ModelState.IsValid) {
|
||||
viewModel.SelectedDashboard = settings.DefaultDashboardId != null ? _services.ContentManager.Get(settings.DefaultDashboardId.Value) : default(ContentItem);
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
settings.DefaultDashboardId = ParseContentId(viewModel.SelectedDashboardId);
|
||||
_services.Notifier.Information(T("Dashboard settings updated."));
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
private static int? ParseContentId(string value) {
|
||||
if (String.IsNullOrWhiteSpace(value))
|
||||
return null;
|
||||
|
||||
var items = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (!items.Any())
|
||||
return null;
|
||||
|
||||
return XmlHelper.Parse<int>(items.First());
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
@@ -10,4 +10,4 @@ Features:
|
||||
Name: Dashboards
|
||||
Description: The Dashboards module enables administrators to customize the dashboard screen of the administration UI of the application.
|
||||
Category: Admin
|
||||
Dependencies: Orchard.Layouts, Orchard.ContentPicker
|
||||
Dependencies: Orchard.Layouts
|
@@ -81,11 +81,11 @@
|
||||
<Content Include="Views\Elements\Grid.Dashboard.cshtml" />
|
||||
<Content Include="Views\Elements\Column.Dashboard.cshtml" />
|
||||
<Content Include="Views\Parts\Layout.Dashboard.cshtml" />
|
||||
<Content Include="Views\Settings\Index.cshtml" />
|
||||
<Content Include="Views\Dashboard\List.cshtml">
|
||||
<SubType>
|
||||
</SubType>
|
||||
</Content>
|
||||
<Content Include="Views\Dashboard\Edit.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||
@@ -107,23 +107,20 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="AdminMenu.cs" />
|
||||
<Compile Include="Controllers\DashboardController.cs" />
|
||||
<Compile Include="Controllers\SettingsController.cs" />
|
||||
<Compile Include="Drivers\DashboardSiteSettingsPartDriver.cs" />
|
||||
<Compile Include="Handlers\DashboardSiteSettingsPartHandler.cs" />
|
||||
<Compile Include="Migrations.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="Services\DashboardService.cs" />
|
||||
<Compile Include="Services\IDashboardService.cs" />
|
||||
<Compile Include="Shapes\LayoutPartShape.cs" />
|
||||
<Compile Include="ViewModels\DashboardSiteSettingsViewModel.cs" />
|
||||
<Compile Include="Models\DashboardSiteSettingsPart.cs" />
|
||||
<Compile Include="Routes.cs" />
|
||||
<Compile Include="Services\DashboardDescriptor.cs" />
|
||||
<Compile Include="Services\DefaultDashboardSelector.cs" />
|
||||
<Compile Include="Services\IDashboardSelector.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Elements\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
@@ -1,8 +1,11 @@
|
||||
using System;
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Dashboards.Services {
|
||||
public class DashboardDescriptor {
|
||||
public int Priority { get; set; }
|
||||
public Func<dynamic, dynamic> DashboardFactory { get; set; }
|
||||
public Func<dynamic, dynamic> Display { get; set; }
|
||||
public Func<dynamic, dynamic> Editor { get; set; }
|
||||
public Func<dynamic, IUpdateModel, dynamic> UpdateEditor { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.DisplayManagement;
|
||||
|
||||
namespace Orchard.Dashboards.Services {
|
||||
public class DashboardService : IDashboardService {
|
||||
private readonly Lazy<IEnumerable<IDashboardSelector>> _selectors;
|
||||
private readonly IShapeFactory _shapeFactory;
|
||||
|
||||
public DashboardService(Lazy<IEnumerable<IDashboardSelector>> selectors, IShapeFactory shapeFactory) {
|
||||
_selectors = selectors;
|
||||
_shapeFactory = shapeFactory;
|
||||
}
|
||||
|
||||
public DashboardDescriptor GetDashboardDescriptor() {
|
||||
var selectorQuery =
|
||||
from selector in _selectors.Value
|
||||
let descriptor = selector.GetDashboardDescriptor()
|
||||
orderby descriptor.Priority descending
|
||||
select descriptor;
|
||||
|
||||
var result = selectorQuery.First();
|
||||
return result;
|
||||
}
|
||||
|
||||
public dynamic GetDashboardShape() {
|
||||
var result = GetDashboardDescriptor();
|
||||
var factory = result.Display ?? (shapeFactory => shapeFactory.StaticDashboard());
|
||||
var shape = factory(_shapeFactory);
|
||||
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
@@ -1,34 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.DisplayManagement;
|
||||
|
||||
namespace Orchard.Dashboards.Services {
|
||||
namespace Orchard.Dashboards.Services {
|
||||
public interface IDashboardService : IDependency {
|
||||
DashboardDescriptor GetDashboardDescriptor();
|
||||
dynamic GetDashboardShape();
|
||||
}
|
||||
|
||||
public class DashboardService : IDashboardService {
|
||||
private readonly Lazy<IEnumerable<IDashboardSelector>> _selectors;
|
||||
private readonly IShapeFactory _shapeFactory;
|
||||
|
||||
public DashboardService(Lazy<IEnumerable<IDashboardSelector>> selectors, IShapeFactory shapeFactory) {
|
||||
_selectors = selectors;
|
||||
_shapeFactory = shapeFactory;
|
||||
}
|
||||
|
||||
public dynamic GetDashboardShape() {
|
||||
var selectorQuery =
|
||||
from selector in _selectors.Value
|
||||
let descriptor = selector.GetDashboardDescriptor()
|
||||
orderby descriptor.Priority descending
|
||||
select descriptor;
|
||||
|
||||
var result = selectorQuery.First();
|
||||
var factory = result.DashboardFactory ?? (shapeFactory => shapeFactory.StaticDashboard());
|
||||
var shape = factory(_shapeFactory);
|
||||
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Dashboards.ViewModels {
|
||||
public class DashboardSiteSettingsViewModel {
|
||||
public string SelectedDashboardId { get; set; }
|
||||
public ContentItem SelectedDashboard { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
@{
|
||||
var pageTitle = T("Edit Dashboard");
|
||||
Layout.Title = pageTitle;
|
||||
}
|
||||
|
||||
@using (Html.BeginFormAntiForgeryPost(Url.Action("Edit"), FormMethod.Post, new { enctype = "multipart/form-data" })) {
|
||||
@Html.ValidationSummary()
|
||||
@Display(Model)
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
@using Orchard.ContentManagement
|
||||
@model Orchard.Dashboards.ViewModels.DashboardSiteSettingsViewModel
|
||||
@{
|
||||
Layout.Title = T("Dashboard Settings").ToString();
|
||||
}
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
<section>
|
||||
<div class="form-group">
|
||||
@Display.ContentPicker_Edit(
|
||||
DisplayName: T("Default Dashboard").Text,
|
||||
SelectedItemsFieldName: Html.FieldNameFor(m => m.SelectedDashboardId),
|
||||
ContentItems: Model.SelectedDashboard != null ? new[] {Model.SelectedDashboard} : Enumerable.Empty<ContentItem>(),
|
||||
Hint: T("Select the content item to use as the dashboard.").Text,
|
||||
Types: new[]{ "Dashboard" })
|
||||
</div>
|
||||
</section>
|
||||
<button>@T("Save")</button>
|
||||
}
|
Reference in New Issue
Block a user