mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Initial bit of progress on the next rev of the global widget management UI.
--HG-- branch : dev
This commit is contained in:
@@ -4,14 +4,15 @@ using System.Web.Mvc;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.Core.Contents.Controllers;
|
using Orchard.Core.Contents.Controllers;
|
||||||
|
using Orchard.DisplayManagement;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
|
using Orchard.Mvc.Extensions;
|
||||||
using Orchard.UI.Admin;
|
using Orchard.UI.Admin;
|
||||||
using Orchard.UI.Notify;
|
using Orchard.UI.Notify;
|
||||||
using Orchard.Utility.Extensions;
|
using Orchard.Utility.Extensions;
|
||||||
using Orchard.Widgets.Models;
|
using Orchard.Widgets.Models;
|
||||||
using Orchard.Widgets.Services;
|
using Orchard.Widgets.Services;
|
||||||
using Orchard.Widgets.ViewModels;
|
|
||||||
|
|
||||||
namespace Orchard.Widgets.Controllers {
|
namespace Orchard.Widgets.Controllers {
|
||||||
|
|
||||||
@@ -24,57 +25,69 @@ namespace Orchard.Widgets.Controllers {
|
|||||||
|
|
||||||
public AdminController(
|
public AdminController(
|
||||||
IOrchardServices services,
|
IOrchardServices services,
|
||||||
IWidgetsService widgetsService) {
|
IWidgetsService widgetsService,
|
||||||
|
IShapeFactory shapeFactory) {
|
||||||
|
|
||||||
Services = services;
|
Services = services;
|
||||||
_widgetsService = widgetsService;
|
_widgetsService = widgetsService;
|
||||||
|
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
|
Shape = shapeFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IOrchardServices Services { get; set; }
|
private IOrchardServices Services { get; set; }
|
||||||
public Localizer T { get; set; }
|
public Localizer T { get; set; }
|
||||||
public ILogger Logger { get; set; }
|
public ILogger Logger { get; set; }
|
||||||
|
dynamic Shape { get; set; }
|
||||||
|
|
||||||
public ActionResult Index(int? id) {
|
public ActionResult Index(int? layerId) {
|
||||||
IEnumerable<LayerPart> layers = _widgetsService.GetLayers();
|
IEnumerable<LayerPart> layers = _widgetsService.GetLayers();
|
||||||
|
|
||||||
LayerPart currentLayer;
|
LayerPart currentLayer;
|
||||||
IEnumerable<WidgetPart> currentLayerWidgets;
|
IEnumerable<WidgetPart> widgets;
|
||||||
|
|
||||||
if (layers.Count() > 0) {
|
if (layers.Count() > 0) {
|
||||||
currentLayer = id == null ?
|
currentLayer = layerId == null ?
|
||||||
layers.First() :
|
layers.First() :
|
||||||
layers.FirstOrDefault(layer => layer.Id == id);
|
layers.FirstOrDefault(layer => layer.Id == layerId);
|
||||||
|
|
||||||
if (currentLayer == null &&
|
if (currentLayer == null &&
|
||||||
id != null) {
|
layerId != null) {
|
||||||
// Incorrect layer id passed
|
// Incorrect layer id passed
|
||||||
Services.Notifier.Error(T("Layer not found: {0}", id));
|
Services.Notifier.Error(T("Layer not found: {0}", layerId));
|
||||||
return RedirectToAction("Index");
|
return RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
|
|
||||||
currentLayerWidgets = _widgetsService.GetWidgets(currentLayer.Id);
|
widgets = _widgetsService.GetWidgets();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
currentLayer = null;
|
currentLayer = null;
|
||||||
currentLayerWidgets = new List<WidgetPart>();
|
widgets = new List<WidgetPart>();
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetsIndexViewModel widgetsIndexViewModel = new WidgetsIndexViewModel {
|
//WidgetsIndexViewModel widgetsIndexViewModel = new WidgetsIndexViewModel {
|
||||||
WidgetTypes = _widgetsService.GetWidgetTypes(),
|
// WidgetTypes = _widgetsService.GetWidgetTypes(),
|
||||||
Layers = layers,
|
// Layers = layers,
|
||||||
Zones = _widgetsService.GetZones(),
|
// Zones = _widgetsService.GetZones(),
|
||||||
CurrentLayer = currentLayer,
|
// CurrentLayer = currentLayer,
|
||||||
CurrentLayerWidgets = currentLayerWidgets
|
// CurrentLayerWidgets = currentLayerWidgets
|
||||||
};
|
//};
|
||||||
|
|
||||||
return View(widgetsIndexViewModel);
|
//return View(widgetsIndexViewModel);
|
||||||
|
|
||||||
|
dynamic viewModel = Shape.ViewModel()
|
||||||
|
.CurrentLayer(currentLayer)
|
||||||
|
.Layers(layers)
|
||||||
|
.Widgets(widgets)
|
||||||
|
.Zones(_widgetsService.GetZones());
|
||||||
|
|
||||||
|
// Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
|
||||||
|
return View((object)viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost, ActionName("Index")]
|
[HttpPost, ActionName("Index")]
|
||||||
public ActionResult IndexWidgetPOST(int? id) {
|
public ActionResult IndexWidgetPOST(int? id, string returnUrl) {
|
||||||
const string moveDownString = "submit.MoveDown.";
|
const string moveDownString = "submit.MoveDown.";
|
||||||
const string moveUpString = "submit.MoveUp.";
|
const string moveUpString = "submit.MoveUp.";
|
||||||
|
|
||||||
@@ -98,7 +111,7 @@ namespace Orchard.Widgets.Controllers {
|
|||||||
this.Error(exception, T("Moving widget failed: {0}", exception.Message), Logger, Services.Notifier);
|
this.Error(exception, T("Moving widget failed: {0}", exception.Message), Logger, Services.Notifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
return RedirectToAction("Index", "Admin", new { id });
|
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult AddWidget(int layerId, string widgetType) {
|
public ActionResult AddWidget(int layerId, string widgetType) {
|
||||||
@@ -216,7 +229,7 @@ namespace Orchard.Widgets.Controllers {
|
|||||||
|
|
||||||
[HttpPost, ActionName("EditLayer")]
|
[HttpPost, ActionName("EditLayer")]
|
||||||
[FormValueRequired("submit.Save")]
|
[FormValueRequired("submit.Save")]
|
||||||
public ActionResult EditLayerSavePOST(int id) {
|
public ActionResult EditLayerSavePOST(int id, string returnUrl) {
|
||||||
if (!Services.Authorizer.Authorize(Permissions.ManageWidgets, T(NotAuthorizedManageWidgetsLabel)))
|
if (!Services.Authorizer.Authorize(Permissions.ManageWidgets, T(NotAuthorizedManageWidgetsLabel)))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
@@ -238,7 +251,7 @@ namespace Orchard.Widgets.Controllers {
|
|||||||
this.Error(exception, T("Editing layer failed: {0}", exception.Message), Logger, Services.Notifier);
|
this.Error(exception, T("Editing layer failed: {0}", exception.Message), Logger, Services.Notifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
return RedirectToAction("Index", "Admin", new { id });
|
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost, ActionName("EditLayer")]
|
[HttpPost, ActionName("EditLayer")]
|
||||||
|
|||||||
@@ -71,7 +71,6 @@
|
|||||||
<Compile Include="Services\RuleContext.cs" />
|
<Compile Include="Services\RuleContext.cs" />
|
||||||
<Compile Include="Services\WidgetsService.cs" />
|
<Compile Include="Services\WidgetsService.cs" />
|
||||||
<Compile Include="Shapes.cs" />
|
<Compile Include="Shapes.cs" />
|
||||||
<Compile Include="ViewModels\WidgetsIndexViewModel.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Content\Admin\images\edit.png" />
|
<Content Include="Content\Admin\images\edit.png" />
|
||||||
|
|||||||
@@ -1,114 +1,57 @@
|
|||||||
#main #widgets h2 {
|
#layout-widgets-placement {
|
||||||
border-bottom:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4.widgets-layer-header, h4.widgets-zone-header {
|
|
||||||
font-weight:600;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4.widgets-layer-header {
|
|
||||||
float:left;
|
float:left;
|
||||||
width:40%;
|
width:65%;
|
||||||
}
|
}
|
||||||
|
#widgets-placement { }
|
||||||
|
#layout-widgets-assistance {
|
||||||
.widgetsbag-editor h5 {
|
|
||||||
color:#4c4c4c;
|
|
||||||
font-weight:600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widgets-availableWidgets {
|
|
||||||
float:right;
|
float:right;
|
||||||
float: left;
|
width:35%;
|
||||||
width: 30%;
|
}
|
||||||
margin: 0 0 0 2em;
|
.widgets-container {
|
||||||
|
padding:10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.widgets-availableWidgets table.items th
|
#widgets-layers-control {
|
||||||
{
|
margin-bottom:-20px;
|
||||||
background: #f1f1f1;
|
|
||||||
padding:.5em 0 .3em .2em;
|
|
||||||
}
|
}
|
||||||
|
#widgets-layers-control form, #widgets-layers-control fieldset {
|
||||||
.widgets-availableLayers {
|
display:inline;
|
||||||
float: left;
|
|
||||||
margin: 0 0 0 2em;
|
|
||||||
width: 60%;
|
|
||||||
min-width: 40%;
|
|
||||||
}
|
}
|
||||||
|
#widgets-layers-control select, #widgets-layers-control a {
|
||||||
.widgets-layerZones {
|
|
||||||
float: left;
|
|
||||||
float: right;
|
|
||||||
width: 60%;
|
|
||||||
border: 1px solid #eaeaea;
|
|
||||||
border:1px solid #ccc;
|
|
||||||
background: #fcfcfc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widgets-layerZones .widgets-zone {
|
|
||||||
background:#f5f5f5;
|
|
||||||
border: 1px solid #f1f1f1;
|
|
||||||
padding: 1em 2em 1em 2em;
|
|
||||||
margin: 0 0 .6em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widgets-layerZones .widgets-zoneWidget {
|
|
||||||
margin: .6em;
|
|
||||||
padding: 1em 2em 1em 3em;
|
|
||||||
background:#ffffff;
|
|
||||||
border: 1px solid #f1f1f1;
|
|
||||||
vertical-align:middle;
|
vertical-align:middle;
|
||||||
}
|
}
|
||||||
|
#widgets-layers-control a {
|
||||||
.widgets-availableLayers fieldset
|
margin-left:10px;
|
||||||
{
|
|
||||||
border: 1px solid #eaeaea;
|
|
||||||
background: #f1f1f1;
|
|
||||||
background: -moz-linear-gradient(center top, #f1f1f1, #fcfcfc);
|
|
||||||
padding: .6em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.widgets-availableWidgets fieldset {
|
#widgets-zones {
|
||||||
padding: 0;
|
background:#F3F4F5;
|
||||||
|
border:1px solid #E4E5E6;
|
||||||
|
padding:0 5px;
|
||||||
}
|
}
|
||||||
|
#widgets-zones ol {
|
||||||
.widgets-layers {
|
list-style:decimal inside;
|
||||||
border:1px solid #ccc;
|
|
||||||
border-right:none;
|
|
||||||
}
|
}
|
||||||
|
#widgets-zones li {
|
||||||
.widgets-layers ul {
|
background:#FFF;
|
||||||
background: #f5f5f5;
|
color:#AEC3CE;
|
||||||
border: 1px solid #f1f1f1;
|
border:1px solid #EAEAEA;
|
||||||
|
margin:5px 0;
|
||||||
|
padding:0 10px;
|
||||||
}
|
}
|
||||||
|
#widgets-zones h2 {
|
||||||
.widgets-layers ul li
|
font-size:1.077em;
|
||||||
{
|
|
||||||
padding: .6em .4em;
|
|
||||||
border:1px solid #F1F1F1;
|
|
||||||
}
|
}
|
||||||
|
#widgets-zones h2, #widgets-zones li li {
|
||||||
.widgets-layers .widgets-currentLayer {
|
|
||||||
background: #c3d9ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widgets-layers .widgets-currentLayer a {
|
|
||||||
color:#333;
|
color:#333;
|
||||||
font-weight: 600;
|
|
||||||
}
|
}
|
||||||
|
#widgets-zones li li {
|
||||||
.widgets-layerZones ul li ul {
|
background:#F3F4F5;
|
||||||
margin: 0;
|
border:0;
|
||||||
padding: 0;
|
margin:10px 0;
|
||||||
|
padding:5px 10px 5px 25px;
|
||||||
}
|
}
|
||||||
|
#widgets-zones .widgets-mover {
|
||||||
.new-layer {
|
margin-left:-18px;
|
||||||
padding: .6em;
|
vertical-align:-2px;
|
||||||
background: #F5F5F5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.new-layer a {
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Orchard.Widgets.Models;
|
|
||||||
|
|
||||||
namespace Orchard.Widgets.ViewModels
|
|
||||||
{
|
|
||||||
public class WidgetsIndexViewModel
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The available widget content types.
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<string> WidgetTypes { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The available layers.
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<LayerPart> Layers { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The available zones in the page.
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<string> Zones { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current layer.
|
|
||||||
/// </summary>
|
|
||||||
public LayerPart CurrentLayer { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current layer widgets.
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<WidgetPart> CurrentLayerWidgets { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +1,52 @@
|
|||||||
@model WidgetsIndexViewModel
|
@using Orchard.Utility.Extensions;
|
||||||
@using Orchard.Widgets.Models;
|
@using Orchard.Widgets.Models;
|
||||||
@using Orchard.Widgets.ViewModels;
|
|
||||||
@{
|
@{
|
||||||
Style.Require("WidgetsAdmin");
|
Style.Require("WidgetsAdmin");
|
||||||
|
|
||||||
Layout.Title = T("Manage Widgets").ToString();
|
Layout.Title = T("Manage Widgets").ToString();
|
||||||
|
IEnumerable<LayerPart> layers = Model.Layers;
|
||||||
|
IEnumerable<WidgetPart> widgets = Model.Widgets;
|
||||||
|
IEnumerable<string> zones = Model.Zones;
|
||||||
|
var returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@using(Html.BeginFormAntiForgeryPost()) {
|
|
||||||
Html.ValidationSummary();
|
|
||||||
|
|
||||||
|
|
||||||
<div id="widgets" class="group">
|
<div id="widgets" class="group">
|
||||||
|
<div id="widgets-layers-control" class="widgets-container">
|
||||||
<div class="widgets-availableLayers">
|
@if (layers.Count() > 0) {
|
||||||
<h2>Widgets</h2>
|
using (Html.BeginForm("index", "admin", FormMethod.Get, new {area = "Orchard.Widgets"})) {
|
||||||
|
<fieldset class="bulk-actions-auto">
|
||||||
<fieldset>
|
<label for="layerId">@T("Current Layer:")</label>
|
||||||
<h4 class="widgets-layer-header">Layers</h4>
|
<select id="layerId" name="layerId">
|
||||||
<h4 class="widgets-zone-header">Zones</h4>
|
@foreach (var layer in Model.Layers) {
|
||||||
<div>
|
@Html.SelectOption((int)Model.CurrentLayer.Id, (int)layer.Id, (string)layer.Name)
|
||||||
<ul class="widgets-layerZones">
|
}
|
||||||
@foreach (string zone in Model.Zones) {
|
</select>
|
||||||
|
<button type="submit" class="apply-bulk-actions-auto">@T("Show")</button>
|
||||||
|
@Html.Link(T("Edit").Text, Url.Action("EditLayer", "Admin", new { area = "Orchard.Widgets", id = Model.CurrentLayer.Id, returnUrl }), new { @class = "button" })
|
||||||
|
</fieldset>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Html.Link(T("Add a new layer...").Text, Url.Action("AddLayer", "Admin", new { area = "Orchard.Widgets", returnUrl }))
|
||||||
|
</div>
|
||||||
|
<div id="layout-widgets-placement">
|
||||||
|
<div id="widgets-placement">
|
||||||
|
<div id="widgets-layers" class="widgets-container">
|
||||||
|
<div id="widgets-zones">
|
||||||
|
<ol>
|
||||||
|
@foreach (string zone in zones) {
|
||||||
<li>
|
<li>
|
||||||
<div class="widgets-zone">@zone</div>
|
<h2>@zone</h2>
|
||||||
<ul>
|
<ul class="widgets-zone-widgets">
|
||||||
@{
|
@{
|
||||||
int count = Model.CurrentLayerWidgets.Where(widgetPart => widgetPart.Zone == zone).Count() - 1;
|
int count = widgets.Where(w => w.Zone == zone).Count() - 1;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
}
|
}
|
||||||
@foreach (WidgetPart widget in Model.CurrentLayerWidgets.Where(widgetPart => widgetPart.Zone == zone).OrderBy(widgetPart => widgetPart.Position, new Orchard.UI.FlatPositionComparer())) {
|
@foreach (WidgetPart widget in widgets.Where(w => w.Zone == zone).OrderBy(w => w.Position, new Orchard.UI.FlatPositionComparer())) {
|
||||||
<li class="widgets-zoneWidget">
|
<li>
|
||||||
@if (i > 0) {
|
@if (i > 0) {
|
||||||
<input type="image" name="submit.MoveUp.@widget.Id" src="@Url.Content("~/modules/orchard.widgets/Content/Admin/images/moveup.gif")" alt="Move up" value="@widget.Id" />
|
<input class="widgets-mover" type="image" name="submit.MoveUp.@widget.Id" src="@Url.Content("~/modules/orchard.widgets/Content/Admin/images/moveup.gif")" alt="Move up" value="@widget.Id" />
|
||||||
}
|
}
|
||||||
@if (i < count) {
|
@if (i < count) {
|
||||||
<input type="image" name="submit.MoveDown.@widget.Id" src="@Url.Content("~/modules/orchard.widgets/Content/Admin/images/movedown.gif")" alt="Move down" value="@widget.Id" />
|
<input class="widgets-mover" type="image" name="submit.MoveDown.@widget.Id" src="@Url.Content("~/modules/orchard.widgets/Content/Admin/images/movedown.gif")" alt="Move down" value="@widget.Id" />
|
||||||
}
|
}
|
||||||
@{
|
@{
|
||||||
i++;
|
i++;
|
||||||
@@ -46,56 +57,17 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
</ul>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="widgets-layers">
|
</div>
|
||||||
<ul>
|
</div>
|
||||||
@foreach (var layer in Model.Layers) {
|
<div id="layout-widgets-assistance">
|
||||||
var layerClass = "widgets-editLayer";
|
<div id="widgets-assistance">
|
||||||
if (layer.Id == Model.CurrentLayer.Id) {
|
<div class="widgets-container">
|
||||||
layerClass += " widgets-currentLayer";
|
<p>[theme preview image]</p>
|
||||||
}
|
<p>[layer visibility]</p>
|
||||||
<li class="@layerClass">
|
|
||||||
<a href="@Url.Action("EditLayer", new { @layer.Id })" title="@T("Edit {0} layer", layer.Name)">
|
|
||||||
<img width="15" height="15" src="@Url.Content("~/modules/orchard.widgets/Content/Admin/images/edit.png")" />
|
|
||||||
</a>
|
|
||||||
@Html.ActionLink(@layer.Name, "Index", new { @layer.Id })
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
<div class="new-layer">
|
|
||||||
@Html.ActionLink(T("+ Add a layer").ToString(), "AddLayer", new { })
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="widgets-availableWidgets">
|
|
||||||
<h2>Available Widgets</h2>
|
|
||||||
|
|
||||||
<fieldset>
|
|
||||||
<table class="items" summary="@T("This is a table of the widgets currently available for use in your application.")">
|
|
||||||
<colgroup>
|
|
||||||
<col id="Col1" />
|
|
||||||
<col id="Col2" />
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">@T("Name")</th>
|
|
||||||
<th scope="col"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
@foreach (string widget in Model.WidgetTypes) {
|
|
||||||
<tr>
|
|
||||||
<td>@widget</td>
|
|
||||||
<td>@Html.ActionLink(T("Add to zone").ToString(), "AddWidget", new { layerId = Model.CurrentLayer.Id, widgetType = widget })</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user