Admin UI experience for Packaging

--HG--
branch : dev
This commit is contained in:
Sebastien Ros
2010-07-23 16:37:25 -07:00
parent 9a353040cd
commit a2e4618986
13 changed files with 166 additions and 27 deletions

View File

@@ -13,7 +13,7 @@ namespace Orchard.Packaging {
builder.Add(T("Gallery"), "5", menu => menu
.Add(T("Browse Gallery"), "1.0", item => item
.Action("Index", "Gallery", new { area = "Orchard.Packaging" }))
.Add(T("Manage Feeds"), "2.0", item => item
.Add(T("Gallery Feeds"), "2.0", item => item
.Action("Sources", "Gallery", new { area = "Orchard.Packaging" })));
}
}

View File

@@ -33,7 +33,7 @@ namespace Orchard.Packaging.Controllers {
Localizer T { get; set; }
public ActionResult Index() {
return Modules();
return Modules(Guid.Empty);
}
public ActionResult Sources() {
@@ -42,16 +42,59 @@ namespace Orchard.Packaging.Controllers {
});
}
public ActionResult AddSource(string url) {
_packagingSourceManager.AddSource(new PackagingSource { Id = Guid.NewGuid(), FeedUrl = url });
public ActionResult Remove(Guid id) {
_packagingSourceManager.RemoveSource(id);
_notifier.Information(T("The feed has been removed successfully."));
Update();
return RedirectToAction("Sources");
}
public ActionResult AddSource() {
return View(new PackagingAddSourceViewModel());
}
public ActionResult AddSourceViewResult(PackagingAddSourceViewModel model) {
return View("AddSource", model);
}
[HttpPost]
public ActionResult AddSource(string title, string url) {
try {
if ( !String.IsNullOrEmpty(url) ) {
if (!url.StartsWith("http")) {
ModelState.AddModelError("Url", T("The Url is a valid").Text);
}
}
else if ( String.IsNullOrWhiteSpace(url)) {
ModelState.AddModelError("Url", T("Url is required").Text);
}
if ( String.IsNullOrWhiteSpace(title) ) {
ModelState.AddModelError("Url", T("Title is required").Text);
}
if ( !ModelState.IsValid )
return AddSourceViewResult(new PackagingAddSourceViewModel(){Title = title, Url = url});
_packagingSourceManager.AddSource(new PackagingSource { Id = Guid.NewGuid(), FeedUrl = url, FeedTitle = title });
_notifier.Information(T("The feed has been added successfully."));
Update();
return RedirectToAction("Sources");
}
catch ( Exception exception ) {
_notifier.Error(T("Adding feed failed: {0}", exception.Message));
return AddSourceViewResult(new PackagingAddSourceViewModel() { Title = title, Url = url });
}
}
public ActionResult Modules(Guid? sourceId) {
var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault();
public ActionResult Modules() {
return View("Modules", new PackagingModulesViewModel {
Modules = _packagingSourceManager.GetModuleList()
Modules = _packagingSourceManager.GetModuleList(selectedSource),
Sources = _packagingSourceManager.GetSources().OrderBy(s => s.FeedTitle),
SelectedSource = selectedSource
});
}

View File

@@ -86,6 +86,7 @@
<Compile Include="Services\PackagingEntry.cs" />
<Compile Include="Services\PackagingSource.cs" />
<Compile Include="Services\PackagingSourceManager.cs" />
<Compile Include="ViewModels\PackagingAddSourceViewModel.cs" />
<Compile Include="ViewModels\PackagingHarvestViewModel.cs" />
<Compile Include="ViewModels\PackagingModulesViewModel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -93,6 +94,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="Module.txt" />
<Content Include="Views\Gallery\AddSource.ascx" />
<Content Include="Views\Gallery\Harvest.ascx" />
<Content Include="Views\Gallery\Modules.ascx" />
<Content Include="Views\Gallery\Sources.ascx" />

View File

@@ -8,6 +8,6 @@ namespace Orchard.Packaging.Services {
void RemoveSource(Guid id);
void UpdateLists();
IEnumerable<PackagingEntry> GetModuleList();
IEnumerable<PackagingEntry> GetModuleList(PackagingSource packagingSource = null);
}
}

View File

@@ -3,6 +3,7 @@ using System;
namespace Orchard.Packaging.Services {
public class PackagingSource {
public Guid Id { get; set; }
public string FeedTitle { get; set; }
public string FeedUrl { get; set; }
}
}

View File

@@ -46,8 +46,8 @@ namespace Orchard.Packaging.Services {
}
}
public IEnumerable<PackagingEntry> GetModuleList() {
IEnumerable<PackagingEntry> packageInfos = GetSources()
public IEnumerable<PackagingEntry> GetModuleList(PackagingSource packagingSource = null) {
IEnumerable<PackagingEntry> packageInfos = ( packagingSource == null ? GetSources() : new [] { packagingSource })
.SelectMany(
source =>
Bind(ParseFeed(_appDataFolder.ReadFile(GetFeedCachePath(source))),

View File

@@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
namespace Orchard.Packaging.ViewModels {
public class PackagingAddSourceViewModel {
[Required]
public string Url { get; set; }
[Required]
public string Title { get; set; }
}
}

View File

@@ -4,5 +4,7 @@ using Orchard.Packaging.Services;
namespace Orchard.Packaging.ViewModels {
public class PackagingModulesViewModel {
public IEnumerable<PackagingEntry> Modules { get; set; }
public IEnumerable<PackagingSource> Sources { get; set; }
public PackagingSource SelectedSource { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.Packaging.ViewModels.PackagingAddSourceViewModel>" %>
<h1>
<%: Html.TitleForPage(T("Add a Feed").ToString())%></h1>
<%using ( Html.BeginFormAntiForgeryPost(Url.Action("AddSource")) ) { %>
<%: Html.ValidationSummary() %>
<fieldset>
<label for="Title"><%: T("Feed Title") %></label>
<input id="Title" class="textMedium" name="Title" type="text" value="<%: Model.Title %>" />
<label for="Url"><%: T("Feed Url") %></label>
<input id="Url" class="textMedium" name="Url" type="text" value="<%: Model.Url %>"/>
</fieldset>
<fieldset>
<input type="submit" class="button primaryAction" value="<%: T("Add Feed") %>" />
</fieldset>
<% } %>

View File

@@ -2,13 +2,46 @@
<h1>
<%: Html.TitleForPage(T("Browse Gallery").ToString())%></h1>
<p><%:Html.ActionLink("Update List", "Update") %></p>
<div class="manage">
<%:Html.ActionLink("Update List", "Update", new object{}, new { @class = "button primaryAction" }) %>
</div>
<% using ( Html.BeginFormAntiForgeryPost(Url.Action("Modules", "Gallery")) ) {%>
<fieldset class="bulk-actions">
<label for="filterResults" class="bulk-filter"><%:T("Show only of feed")%></label>
<select id="sourceId" name="sourceId">
<%:Html.SelectOption("", Model.SelectedSource == null, T("Any (show all feeds)").ToString())%>
<%
foreach (var source in Model.Sources) {%>
<%:Html.SelectOption(source.Id, Model.SelectedSource != null && Model.SelectedSource.Id == source.Id, source.FeedTitle)%><%
}%>
</select>
<button type="submit"><%:T("Apply")%></button>
</fieldset>
<%
} %>
<ul>
<% if (Model.Modules.Count() > 0) { %>
<ul class="contentItems">
<%foreach (var item in Model.Modules) {%>
<li>
<a href="<%:item.PackageStreamUri%>"><%:item.SyndicationItem.Title.Text%></a>
[<%:Html.ActionLink("Install", "Install", new RouteValueDictionary {{"SyndicationId",item.SyndicationItem.Id}})%>]
</li>
<%}%>
<ul class="summary">
<div class="properties">
<h2><%: item.SyndicationItem.Title.Text %><span> - <%: T("Version: {0}", "1.0")%></span></h2>
<p><%:item.SyndicationItem.Summary.Text %></p>
<ul class="pageStatus" style="color:#666; margin:.6em 0 0 0;">
<li><%: T("Last Updated: {0}", item.SyndicationItem.LastUpdatedTime.ToLocalTime()) %></li>
<li>&nbsp;&#124;&nbsp;<%: T("Author: {0}", item.SyndicationItem.Authors.Any() ? String.Join(", ", item.SyndicationItem.Authors.Select(a => a.Name)) : T("Unknown").Text)%></li>
</ul>
</div>
<div class="related">
<%:Html.ActionLink("Install", "Install", new RouteValueDictionary {{"SyndicationId",item.SyndicationItem.Id}})%><%:T(" | ") %>
<a href="<%:item.PackageStreamUri%>">Download</a>
</div>
</ul>
</li><%
}%>
</ul><%
}%>

View File

@@ -1,13 +1,39 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.Packaging.ViewModels.PackagingSourcesViewModel>" %>
<h1>
<%: Html.TitleForPage(T("Manage Feeds").ToString())%></h1>
<%: Html.TitleForPage(T("Gallery Feeds").ToString())%></h1>
<ul>
<%foreach (var item in Model.Sources) {%><li>
<%:Html.Link(item.FeedUrl, item.FeedUrl)%></li>
<% }%>
</ul>
<div class="manage">
<%:Html.ActionLink(T("Add a Feed").Text, "AddSource", new { }, new { @class = "button primaryAction" }) %>
</div>
<%using (Html.BeginFormAntiForgeryPost(Url.Action("AddSource"))) {%>
Url: <%:Html.TextBox("url") %> <input type="submit" value="Add Source" />
<fieldset>
<table class="items" summary="<%: T("This is a table of the gallery feeds in your application") %>">
<colgroup>
<col id="Col1" />
<col id="Col2" />
<col id="Col3" />
</colgroup>
<thead>
<tr>
<th scope="col"><%: T("Title")%></th>
<th scope="col"><%: T("Url")%></th>
<th scope="col"></th>
</tr>
</thead>
<%
foreach ( var item in Model.Sources ) {
%>
<tr>
<td>
<%: item.FeedTitle %>
</td>
<td>
<%:Html.Link(item.FeedUrl, item.FeedUrl)%>
</td>
<td>
<%: Html.ActionLink(T("Remove").ToString(), "Remove", new { id = item.Id })%>
</td>
</tr>
<% } %>
</table>
</fieldset>

View File

@@ -90,7 +90,9 @@
</ItemGroup>
<ItemGroup>
<Content Include="Global.asax" />
<Content Include="Web.config" />
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</Content>

View File

@@ -13,6 +13,8 @@
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />