Initial bit of progress on the next rev of the global widget management UI.

--HG--
branch : dev
This commit is contained in:
Nathan Heskew
2011-03-14 15:15:21 -07:00
parent fed8e1c610
commit c17cdf41a5
5 changed files with 128 additions and 234 deletions

View File

@@ -4,14 +4,15 @@ using System.Web.Mvc;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.Core.Contents.Controllers;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.Mvc.Extensions;
using Orchard.UI.Admin;
using Orchard.UI.Notify;
using Orchard.Utility.Extensions;
using Orchard.Widgets.Models;
using Orchard.Widgets.Services;
using Orchard.Widgets.ViewModels;
namespace Orchard.Widgets.Controllers {
@@ -24,57 +25,69 @@ namespace Orchard.Widgets.Controllers {
public AdminController(
IOrchardServices services,
IWidgetsService widgetsService) {
IWidgetsService widgetsService,
IShapeFactory shapeFactory) {
Services = services;
_widgetsService = widgetsService;
T = NullLocalizer.Instance;
Logger = NullLogger.Instance;
Shape = shapeFactory;
}
private IOrchardServices Services { get; set; }
public Localizer T { 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();
LayerPart currentLayer;
IEnumerable<WidgetPart> currentLayerWidgets;
IEnumerable<WidgetPart> widgets;
if (layers.Count() > 0) {
currentLayer = id == null ?
currentLayer = layerId == null ?
layers.First() :
layers.FirstOrDefault(layer => layer.Id == id);
layers.FirstOrDefault(layer => layer.Id == layerId);
if (currentLayer == null &&
id != null) {
layerId != null) {
// 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");
}
currentLayerWidgets = _widgetsService.GetWidgets(currentLayer.Id);
widgets = _widgetsService.GetWidgets();
}
else {
currentLayer = null;
currentLayerWidgets = new List<WidgetPart>();
widgets = new List<WidgetPart>();
}
WidgetsIndexViewModel widgetsIndexViewModel = new WidgetsIndexViewModel {
WidgetTypes = _widgetsService.GetWidgetTypes(),
Layers = layers,
Zones = _widgetsService.GetZones(),
CurrentLayer = currentLayer,
CurrentLayerWidgets = currentLayerWidgets
};
//WidgetsIndexViewModel widgetsIndexViewModel = new WidgetsIndexViewModel {
// WidgetTypes = _widgetsService.GetWidgetTypes(),
// Layers = layers,
// Zones = _widgetsService.GetZones(),
// CurrentLayer = currentLayer,
// 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")]
public ActionResult IndexWidgetPOST(int? id) {
public ActionResult IndexWidgetPOST(int? id, string returnUrl) {
const string moveDownString = "submit.MoveDown.";
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);
}
return RedirectToAction("Index", "Admin", new { id });
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
}
public ActionResult AddWidget(int layerId, string widgetType) {
@@ -216,7 +229,7 @@ namespace Orchard.Widgets.Controllers {
[HttpPost, ActionName("EditLayer")]
[FormValueRequired("submit.Save")]
public ActionResult EditLayerSavePOST(int id) {
public ActionResult EditLayerSavePOST(int id, string returnUrl) {
if (!Services.Authorizer.Authorize(Permissions.ManageWidgets, T(NotAuthorizedManageWidgetsLabel)))
return new HttpUnauthorizedResult();
@@ -238,7 +251,7 @@ namespace Orchard.Widgets.Controllers {
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")]

View File

@@ -71,7 +71,6 @@
<Compile Include="Services\RuleContext.cs" />
<Compile Include="Services\WidgetsService.cs" />
<Compile Include="Shapes.cs" />
<Compile Include="ViewModels\WidgetsIndexViewModel.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\Admin\images\edit.png" />

View File

@@ -1,114 +1,57 @@
#main #widgets h2 {
border-bottom:none;
#layout-widgets-placement {
float:left;
width:65%;
}
#widgets-placement { }
#layout-widgets-assistance {
float:right;
width:35%;
}
.widgets-container {
padding:10px;
}
h4.widgets-layer-header, h4.widgets-zone-header {
font-weight:600;
#widgets-layers-control {
margin-bottom:-20px;
}
#widgets-layers-control form, #widgets-layers-control fieldset {
display:inline;
}
#widgets-layers-control select, #widgets-layers-control a {
vertical-align:middle;
}
#widgets-layers-control a {
margin-left:10px;
}
h4.widgets-layer-header {
float:left;
width:40%;
#widgets-zones {
background:#F3F4F5;
border:1px solid #E4E5E6;
padding:0 5px;
}
.widgetsbag-editor h5 {
color:#4c4c4c;
font-weight:600;
#widgets-zones ol {
list-style:decimal inside;
}
.widgets-availableWidgets {
float: right;
float: left;
width: 30%;
margin: 0 0 0 2em;
#widgets-zones li {
background:#FFF;
color:#AEC3CE;
border:1px solid #EAEAEA;
margin:5px 0;
padding:0 10px;
}
.widgets-availableWidgets table.items th
{
background: #f1f1f1;
padding:.5em 0 .3em .2em;
#widgets-zones h2 {
font-size:1.077em;
}
.widgets-availableLayers {
float: left;
margin: 0 0 0 2em;
width: 60%;
min-width: 40%;
#widgets-zones h2, #widgets-zones li li {
color:#333;
}
.widgets-layerZones {
float: left;
float: right;
width: 60%;
border: 1px solid #eaeaea;
border:1px solid #ccc;
background: #fcfcfc;
#widgets-zones li li {
background:#F3F4F5;
border:0;
margin:10px 0;
padding:5px 10px 5px 25px;
}
.widgets-layerZones .widgets-zone {
background:#f5f5f5;
border: 1px solid #f1f1f1;
padding: 1em 2em 1em 2em;
margin: 0 0 .6em 0;
#widgets-zones .widgets-mover {
margin-left:-18px;
vertical-align:-2px;
}
.widgets-layerZones .widgets-zoneWidget {
margin: .6em;
padding: 1em 2em 1em 3em;
background:#ffffff;
border: 1px solid #f1f1f1;
vertical-align: middle;
}
.widgets-availableLayers fieldset
{
border: 1px solid #eaeaea;
background: #f1f1f1;
background: -moz-linear-gradient(center top, #f1f1f1, #fcfcfc);
padding: .6em;
}
.widgets-availableWidgets fieldset {
padding: 0;
}
.widgets-layers {
border:1px solid #ccc;
border-right:none;
}
.widgets-layers ul {
background: #f5f5f5;
border: 1px solid #f1f1f1;
}
.widgets-layers ul li
{
padding: .6em .4em;
border:1px solid #F1F1F1;
}
.widgets-layers .widgets-currentLayer {
background: #c3d9ff;
}
.widgets-layers .widgets-currentLayer a {
color: #333;
font-weight: 600;
}
.widgets-layerZones ul li ul {
margin: 0;
padding: 0;
}
.new-layer {
padding: .6em;
background: #F5F5F5;
}
.new-layer a {
text-decoration: none;
font-weight: 600;
}

View File

@@ -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; }
}
}

View File

@@ -1,41 +1,52 @@
@model WidgetsIndexViewModel
@using Orchard.Utility.Extensions;
@using Orchard.Widgets.Models;
@using Orchard.Widgets.ViewModels;
@{
Style.Require("WidgetsAdmin");
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 class="widgets-availableLayers">
<h2>Widgets</h2>
<fieldset>
<h4 class="widgets-layer-header">Layers</h4>
<h4 class="widgets-zone-header">Zones</h4>
<div>
<ul class="widgets-layerZones">
@foreach (string zone in Model.Zones) {
<div id="widgets" class="group">
<div id="widgets-layers-control" class="widgets-container">
@if (layers.Count() > 0) {
using (Html.BeginForm("index", "admin", FormMethod.Get, new {area = "Orchard.Widgets"})) {
<fieldset class="bulk-actions-auto">
<label for="layerId">@T("Current Layer:")</label>
<select id="layerId" name="layerId">
@foreach (var layer in Model.Layers) {
@Html.SelectOption((int)Model.CurrentLayer.Id, (int)layer.Id, (string)layer.Name)
}
</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>
<div class="widgets-zone">@zone</div>
<ul>
<h2>@zone</h2>
<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;
}
@foreach (WidgetPart widget in Model.CurrentLayerWidgets.Where(widgetPart => widgetPart.Zone == zone).OrderBy(widgetPart => widgetPart.Position, new Orchard.UI.FlatPositionComparer())) {
<li class="widgets-zoneWidget">
@foreach (WidgetPart widget in widgets.Where(w => w.Zone == zone).OrderBy(w => w.Position, new Orchard.UI.FlatPositionComparer())) {
<li>
@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) {
<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++;
@@ -46,56 +57,17 @@
</ul>
</li>
}
</ul>
</ol>
</div>
<div class="widgets-layers">
<ul>
@foreach (var layer in Model.Layers) {
var layerClass = "widgets-editLayer";
if (layer.Id == Model.CurrentLayer.Id) {
layerClass += " widgets-currentLayer";
}
<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>
</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 id="layout-widgets-assistance">
<div id="widgets-assistance">
<div class="widgets-container">
<p>[theme preview image]</p>
<p>[layer visibility]</p>
</div>
</div>
</div>
</div>