Changing list management pick items ability to a new 'choose items' view.

--HG--
branch : dev
This commit is contained in:
Dave Reed
2011-03-22 17:48:26 -07:00
parent 4a404afd2d
commit 319134e237
7 changed files with 260 additions and 90 deletions

View File

@@ -60,47 +60,26 @@ namespace Lists.Controllers {
public ActionResult List(ListContentsViewModel model, PagerParameters pagerParameters) {
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var container = model.ContainerId.HasValue ? _contentManager.GetLatest((int)model.ContainerId) : null;
if (container == null && model.ContainerId.HasValue) {
if (container == null || !container.Has<ContainerPart>()) {
return HttpNotFound();
}
var restrictedContentType = container == null ? null : container.As<ContainerPart>().Record.ItemContentType;
var restrictedContentType = container.As<ContainerPart>().Record.ItemContentType;
var hasRestriction = !string.IsNullOrEmpty(restrictedContentType);
if (hasRestriction) {
model.FilterByContentType = restrictedContentType;
}
if (container != null) {
var metadata = container.ContentManager.GetItemMetadata(container);
model.ContainerDisplayName = metadata.DisplayText;
if (string.IsNullOrEmpty(model.ContainerDisplayName)) {
model.ContainerDisplayName = container.ContentType;
}
}
var query = _contentManager.Query<ContainablePart>(VersionOptions.Latest);
if (!string.IsNullOrEmpty(model.FilterByContentType)) {
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.FilterByContentType);
if (contentTypeDefinition == null)
return HttpNotFound();
query = query.ForType(model.FilterByContentType);
}
query = query.Join<CommonPartRecord>().Where(cr => cr.Container.Id == model.ContainerId);
switch (model.Options.OrderBy) {
case ContentsOrder.Modified:
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.ModifiedUtc);
break;
case ContentsOrder.Published:
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.PublishedUtc);
break;
case ContentsOrder.Created:
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.CreatedUtc);
break;
}
model.Options.SelectedFilter = model.FilterByContentType;
model.ContainerDisplayName = container.ContentManager.GetItemMetadata(container).DisplayText;
if (string.IsNullOrEmpty(model.ContainerDisplayName)) {
model.ContainerDisplayName = container.ContentType;
}
var query = GetListContentItemQuery(model);
if (query == null) {
return new HttpNotFoundResult();
}
if (!hasRestriction) {
model.Options.FilterOptions = GetContainableTypes()
.Select(ctd => new KeyValuePair<string, string>(ctd.Name, ctd.DisplayName))
@@ -120,7 +99,7 @@ namespace Lists.Controllers {
.Options(model.Options)
.HasRestriction(hasRestriction)
.ContainerDisplayName(model.ContainerDisplayName)
.ContainerContentType(container == null ? null : container.ContentType)
.ContainerContentType(container.ContentType)
.ContainerItemContentType(hasRestriction ? restrictedContentType : (model.FilterByContentType ?? ""))
.OtherLists(_contentManager.Query<ContainerPart>(VersionOptions.Latest).List()
.Select(part => part.ContentItem)
@@ -131,6 +110,32 @@ namespace Lists.Controllers {
return View((object)viewModel);
}
private IContentQuery<ContainablePart> GetListContentItemQuery(ListContentsViewModel model) {
var query = _contentManager.Query<ContainablePart>(VersionOptions.Latest);
if (!string.IsNullOrEmpty(model.FilterByContentType)) {
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.FilterByContentType);
if (contentTypeDefinition == null) {
return null;
}
query = query.ForType(model.FilterByContentType);
}
query = query.Join<CommonPartRecord>().Where(cr => cr.Container.Id == model.ContainerId);
switch (model.Options.OrderBy) {
case ContentsOrder.Modified:
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.ModifiedUtc);
break;
case ContentsOrder.Published:
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.PublishedUtc);
break;
case ContentsOrder.Created:
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.CreatedUtc);
break;
}
return query;
}
[HttpPost, ActionName("List")]
[FormValueRequired("submit.BulkEdit")]
public ActionResult ListPOST(ContentOptions options, IEnumerable<int> itemIds, int? targetContainerId, string returnUrl) {
@@ -172,6 +177,119 @@ namespace Lists.Controllers {
return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
}
[HttpPost, ActionName("List")]
[FormValueRequired("submit.Filter")]
public ActionResult ListFilterPOST(ContentOptions options) {
var routeValues = ControllerContext.RouteData.Values;
if (options != null) {
routeValues["Options.OrderBy"] = options.OrderBy;
if (GetContainableTypes().Any(ctd => string.Equals(ctd.Name, options.SelectedFilter, StringComparison.OrdinalIgnoreCase))) {
routeValues["filterByContentType"] = options.SelectedFilter;
}
else {
routeValues.Remove("filterByContentType");
}
}
return RedirectToAction("List", routeValues);
}
public ActionResult Choose(ChooseContentsViewModel model, PagerParameters pagerParameters) {
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var container = model.SourceContainerId == 0 ? null : _contentManager.GetLatest(model.SourceContainerId);
if (container == null && model.SourceContainerId != 0) {
return HttpNotFound();
}
var query = _contentManager.Query<ContainablePart>(VersionOptions.Latest);
if (!string.IsNullOrEmpty(model.FilterByContentType)) {
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.FilterByContentType);
if (contentTypeDefinition == null) {
return HttpNotFound();
}
query = query.ForType(model.FilterByContentType);
}
if (model.SourceContainerId == 0) {
query = query.Join<CommonPartRecord>().Where(cr => cr.Container == null);
}
else {
query = query.Join<CommonPartRecord>().Where(cr => cr.Container.Id == model.SourceContainerId);
}
switch (model.OrderBy) {
case ContentsOrder.Modified:
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.ModifiedUtc);
break;
case ContentsOrder.Published:
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.PublishedUtc);
break;
case ContentsOrder.Created:
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.CreatedUtc);
break;
}
model.SelectedFilter = model.FilterByContentType;
model.FilterOptions = GetContainableTypes()
.Select(ctd => new KeyValuePair<string, string>(ctd.Name, ctd.DisplayName))
.ToList().OrderBy(kvp => kvp.Key);
var pagerShape = Shape.Pager(pager).TotalItemCount(query.Count());
var pageOfContentItems = query.Slice(pager.GetStartIndex(), pager.PageSize).ToList();
var list = Shape.List();
list.AddRange(pageOfContentItems.Select(ci => _contentManager.BuildDisplay(ci, "SummaryAdmin")));
dynamic viewModel = Shape.ViewModel()
.ContentItems(list)
.Pager(pagerShape)
.SourceContainerId(model.SourceContainerId)
.TargetContainerId(model.TargetContainerId)
.SelectedFilter(model.SelectedFilter)
.FilterOptions(model.FilterOptions)
.OrderBy(model.OrderBy)
.Containers(_contentManager.Query<ContainerPart>(VersionOptions.Latest).List()
.Select(part => part.ContentItem)
.OrderBy(item => item.As<CommonPart>().VersionPublishedUtc));
// Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
return View((object)viewModel);
}
[HttpPost, ActionName("Choose")]
[FormValueRequired("submit.MoveTo")]
public ActionResult ChoosePOST(IEnumerable<int> itemIds, int targetContainerId, string returnUrl) {
if (itemIds != null && !BulkMoveToList(itemIds, targetContainerId)) {
return new HttpUnauthorizedResult();
}
return this.RedirectLocal(returnUrl, () => RedirectToAction("List", new { ContainerId = targetContainerId }));
}
[HttpPost, ActionName("Choose")]
[FormValueRequired("submit.Filter")]
public ActionResult ChooseFilterPOST(ChooseContentsViewModel model) {
var routeValues = ControllerContext.RouteData.Values;
if (GetContainableTypes().Any(ctd => string.Equals(ctd.Name, model.SelectedFilter, StringComparison.OrdinalIgnoreCase))) {
routeValues["filterByContentType"] = model.SelectedFilter;
}
else {
routeValues.Remove("filterByContentType");
}
if (model.SourceContainerId == 0) {
routeValues.Remove("SourceContainerId");
}
else {
routeValues["SourceContainerId"] = model.SourceContainerId;
}
routeValues["OrderBy"] = model.OrderBy;
routeValues["TargetContainerId"] = model.TargetContainerId;
return RedirectToAction("Choose", routeValues);
}
private bool BulkMoveToList(IEnumerable<int> itemIds, int? targetContainerId) {
if (!targetContainerId.HasValue) {
Services.Notifier.Information(T("Please select the list to move the items to."));
@@ -248,23 +366,5 @@ namespace Lists.Controllers {
return true;
}
[HttpPost, ActionName("List")]
[FormValueRequired("submit.Filter")]
public ActionResult ListFilterPOST(ContentOptions options) {
var routeValues = ControllerContext.RouteData.Values;
if (options != null) {
routeValues["Options.OrderBy"] = options.OrderBy;
if (GetContainableTypes().Any(ctd => string.Equals(ctd.Name, options.SelectedFilter, StringComparison.OrdinalIgnoreCase))) {
routeValues["filterByContentType"] = options.SelectedFilter;
}
else {
routeValues.Remove("filterByContentType");
}
}
return RedirectToAction("List", routeValues);
}
}
}

View File

@@ -52,6 +52,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Routes.cs" />
<Content Include="Scripts\orchard-lists-admin.js" />
<Compile Include="ViewModels\ChooseContentsViewModel.cs" />
<Compile Include="ViewModels\ListContentsViewModel.cs" />
<Content Include="Module.txt" />
</ItemGroup>
@@ -98,6 +99,9 @@
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Views\Admin\Choose.cshtml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@@ -24,24 +24,7 @@ namespace Orchard.Lists {
{"filterByContentType", ""}
},
new RouteValueDictionary{
{"filterByContentType", @"\w+"},
{"containerId", @"\d+"}
},
new RouteValueDictionary {
{"area", "Orchard.Lists"}
},
new MvcRouteHandler())
},
new RouteDescriptor {
Priority = 5,
Route = new Route(
"Admin/Lists/{containerId}",
new RouteValueDictionary {
{"area", "Orchard.Lists"},
{"controller", "Admin"},
{"action", "List"}
},
new RouteValueDictionary {
{"filterByContentType", @"\w*"},
{"containerId", @"\d+"}
},
new RouteValueDictionary {
@@ -53,15 +36,17 @@ namespace Orchard.Lists {
new RouteDescriptor {
Priority = 5,
Route = new Route(
"Admin/Lists/Orphaned/{filterByContentType}",
"Admin/Lists/Choose/From/Orphaned/To/{targetContainerId}/{filterByContentType}",
new RouteValueDictionary {
{"area", "Orchard.Lists"},
{"controller", "Admin"},
{"action", "List"},
{"action", "Choose"},
{"filterByContentType", ""},
{"sourceContainerId", "0"}
},
new RouteValueDictionary{
{"filterByContentType", @"\w+"},
{"filterByContentType", @"\w*"},
{"targetContainerId", @"\d+"},
},
new RouteValueDictionary {
{"area", "Orchard.Lists"}
@@ -71,19 +56,23 @@ namespace Orchard.Lists {
new RouteDescriptor {
Priority = 5,
Route = new Route(
"Admin/Lists/Orphaned",
"Admin/Lists/Choose/From/{sourceContainerId}/To/{targetContainerId}/{filterByContentType}",
new RouteValueDictionary {
{"area", "Orchard.Lists"},
{"controller", "Admin"},
{"action", "List"},
{"action", "Choose"},
{"filterByContentType", ""}
},
new RouteValueDictionary{
{"filterByContentType", @"\w*"},
{"sourceContainerId", @"\d+"},
{"targetContainerId", @"\d+"},
},
null,
new RouteValueDictionary {
{"area", "Orchard.Lists"}
},
new MvcRouteHandler())
},
};
}
}

View File

@@ -0,0 +1,21 @@
using System.Collections.Generic;
using Orchard.ContentManagement;
namespace Orchard.Lists.ViewModels {
public class ChooseContentsViewModel {
public ChooseContentsViewModel() {
OrderBy = ContentsOrder.Modified;
}
public string FilterByContentType { get; set; }
public int SourceContainerId { get; set; }
public int TargetContainerId { get; set; }
public int? Page { get; set; }
public string SelectedFilter { get; set; }
public IEnumerable<KeyValuePair<string, string>> FilterOptions { get; set; }
public ContentsOrder OrderBy { get; set; }
}
}

View File

@@ -0,0 +1,62 @@
@using Orchard.Lists.ViewModels;
@using Orchard.ContentManagement;
@{
var sourceContainerId = (int)Model.SourceContainerId;
var targetContainerId = (int)Model.TargetContainerId;
Layout.Title = T("Choose Items");
var targetContainers = ((IEnumerable<ContentItem>)Model.Containers).Select(
contentItem => new SelectListItem {
Text = T("Move to {0}", contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText).ToString(),
Value = contentItem.Id.ToString(System.Globalization.CultureInfo.InvariantCulture),
Selected = contentItem.Id == targetContainerId
}).ToList();
var sourceContainers = ((IEnumerable<ContentItem>)Model.Containers).Select(
contentItem => new SelectListItem {
Text = contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText,
Value = contentItem.Id.ToString(System.Globalization.CultureInfo.InvariantCulture),
Selected = contentItem.Id == sourceContainerId
}).ToList();
sourceContainers.Insert(0, new SelectListItem { Text = T("Orphan items").ToString(), Value = "" });
}
@using (Html.BeginFormAntiForgeryPost()) {
<fieldset class="bulk-actions">
<label for="filterResults">@T("Show")</label>
<select id="filterResults" name="SelectedFilter">
@Html.SelectOption((string)Model.SelectedFilter, "", T("any (show all)").ToString())
@foreach(var filterOption in Model.FilterOptions) {
@Html.SelectOption((string)Model.SelectedFilter, (string)filterOption.Key, (string)filterOption.Value)
}
</select>
<label for="SourceContainerId">@T("from")</label>
@Html.DropDownList("SourceContainerId", sourceContainers, new { id = "SourceContainerId" })
<label for="orderResults" class="bulk-order">@T("Ordered by")</label>
<select id="orderResults" name="OrderBy">
@Html.SelectOption((ContentsOrder)Model.OrderBy, ContentsOrder.Created, T("recently created").ToString())
@Html.SelectOption((ContentsOrder)Model.OrderBy, ContentsOrder.Modified, T("recently modified").ToString())
@Html.SelectOption((ContentsOrder)Model.OrderBy, ContentsOrder.Published, T("recently published").ToString())
</select>
<button type="submit" name="submit.Filter" value="yes">@T("Apply")</button>
</fieldset>
<div class="manage">
@Html.DropDownList("TargetContainerId", targetContainers)
<button type="submit" name="submit.MoveTo" value="yes">@T("Apply")</button>
</div>
<fieldset class="contentItems bulk-items">
@if ((int)Model.ContentItems.Items.Count == 0) {
@T("There are no content items.")
}
else {
@Display(Model.ContentItems)
}
</fieldset>
@Display(Model.Pager)
}

View File

@@ -3,11 +3,11 @@
@{
Script.Include("orchard-lists-admin.js");
int? containerId = (int?)Model.ContainerId;
int containerId = ((int?)Model.ContainerId).GetValueOrDefault();
string createLinkText = string.IsNullOrEmpty(Model.ContainerItemContentType) ? T("Create New Content").ToString() : T("Create New {0}", Model.ContainerItemContentType).ToString();
Layout.Title = containerId.HasValue ? T("Manage Content for {0}", Model.ContainerDisplayName) : T("Orphaned Content Items");
Layout.Title = T("Manage Content for {0}", Model.ContainerDisplayName);
var lists = ((IEnumerable<ContentItem>)Model.OtherLists).Select(
contentItem => new SelectListItem {
@@ -24,22 +24,19 @@
<div>&nbsp;</div>
@Display.Parts_Container_Manage(ContainerDisplayName: Model.ContainerDisplayName, ContainerContentType: Model.ContainerContentType, ContainerId: containerId)
@if (containerId.HasValue) {
<div class="manage">
@Html.ActionLink(createLinkText, "Create", new { Area = "Contents", Id = (string)Model.Options.SelectedFilter, ContainerId = (int)containerId, ReturnUrl = Url.Action("List", "Admin", new { Area = "Orchard.Lists", ContainerId = (int)containerId }) }, new { @class = "button primaryAction" })
@Html.ActionLink(createLinkText, "Create", new { Area = "Contents", Id = (string)Model.Options.SelectedFilter, ContainerId = containerId, ReturnUrl = Url.Action("List", "Admin", new { Area = "Orchard.Lists", ContainerId = containerId }) }, new { @class = "button primaryAction" })
</div>
}
@using (Html.BeginFormAntiForgeryPost()) {
<fieldset class="bulk-actions">
<label for="publishActions">@T("Actions:")</label>
<select id="publishActions" name="Options.BulkAction">
@if (containerId.HasValue) {
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.None, T("Choose action...").ToString())
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.PublishNow, T("Publish Now").ToString())
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.Unpublish, T("Unpublish").ToString())
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.Remove, T("Delete").ToString())
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.RemoveFromList, T("Remove from List").ToString())
}
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.MoveToList, T("Move to List...").ToString())
</select>
@Html.DropDownList("TargetContainerId", lists, new { id = "TargetContainerId" })

View File

@@ -1,10 +1,7 @@
<div class="item-properties actions">
<p>
@Html.ActionLink(T("Show Other Lists").ToString(), "List", new { Area = "Contents", Id = Model.ContainerContentType }) |
@Html.ActionLink(T("Show Orphaned Content Items").ToString(), "Orphaned", new { Area = "Orchard.Lists" })
@if (((int?)Model.ContainerId).HasValue) {
<text>|</text>
@Html.ActionLink(T("{0} Properties", (string)Model.ContainerContentType).ToString(), "Edit", new { Area = "Contents", Id = (int)Model.ContainerId })
}
@Html.ActionLink(T("Choose Items").ToString(), "Choose", new { TargetContainerId = (int)Model.ContainerId, Area = "Orchard.Lists" })
<text>|</text>
@Html.ActionLink(T("{0} Properties", (string)Model.ContainerContentType).ToString(), "Edit", new { Area = "Contents", Id = (int)Model.ContainerId, ReturnUrl = Html.ViewContext.HttpContext.Request.RawUrl })
</p>
</div>