mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
#18951: Adding bulk feature operations to Features screen.
Work Item: 18951 --HG-- branch : 1.x
This commit is contained in:
@@ -14,13 +14,14 @@ using Orchard.Modules.Events;
|
|||||||
using Orchard.Modules.Models;
|
using Orchard.Modules.Models;
|
||||||
using Orchard.Modules.Services;
|
using Orchard.Modules.Services;
|
||||||
using Orchard.Modules.ViewModels;
|
using Orchard.Modules.ViewModels;
|
||||||
|
using Orchard.Mvc;
|
||||||
|
using Orchard.Mvc.Extensions;
|
||||||
using Orchard.Recipes.Models;
|
using Orchard.Recipes.Models;
|
||||||
using Orchard.Recipes.Services;
|
using Orchard.Recipes.Services;
|
||||||
using Orchard.Reports.Services;
|
using Orchard.Reports.Services;
|
||||||
using Orchard.Security;
|
using Orchard.Security;
|
||||||
using Orchard.UI.Navigation;
|
using Orchard.UI.Navigation;
|
||||||
using Orchard.UI.Notify;
|
using Orchard.UI.Notify;
|
||||||
using Orchard.Utility.Extensions;
|
|
||||||
|
|
||||||
namespace Orchard.Modules.Controllers {
|
namespace Orchard.Modules.Controllers {
|
||||||
public class AdminController : Controller {
|
public class AdminController : Controller {
|
||||||
@@ -178,46 +179,52 @@ namespace Orchard.Modules.Controllers {
|
|||||||
return View(new FeaturesViewModel { Features = features });
|
return View(new FeaturesViewModel { Features = features });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost, ActionName("Features")]
|
||||||
public ActionResult Enable(string id, bool? force) {
|
[FormValueRequired("submit.BulkExecute")]
|
||||||
|
public ActionResult FeaturesPOST(FeaturesBulkAction bulkAction, IList<string> featureIds, bool? force) {
|
||||||
|
|
||||||
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features")))
|
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(id))
|
if (featureIds == null || !featureIds.Any()) {
|
||||||
return HttpNotFound();
|
ModelState.AddModelError("featureIds", T("Please select one or more features."));
|
||||||
|
}
|
||||||
|
|
||||||
_moduleService.EnableFeatures(new[] { id }, force != null && (bool)force);
|
if (ModelState.IsValid) {
|
||||||
|
var availableFeatures = _moduleService.GetAvailableFeatures().ToList();
|
||||||
|
var selectedFeatures = availableFeatures.Where(x => featureIds.Contains(x.Descriptor.Id)).ToList();
|
||||||
|
var enabledFeatures = availableFeatures.Where(x => x.IsEnabled && featureIds.Contains(x.Descriptor.Id)).Select(x => x.Descriptor.Id).ToList();
|
||||||
|
var disabledFeatures = availableFeatures.Where(x => !x.IsEnabled && featureIds.Contains(x.Descriptor.Id)).Select(x => x.Descriptor.Id).ToList();
|
||||||
|
|
||||||
return RedirectToAction("Features");
|
switch (bulkAction) {
|
||||||
}
|
case FeaturesBulkAction.None:
|
||||||
|
break;
|
||||||
[HttpPost]
|
case FeaturesBulkAction.Enable:
|
||||||
public ActionResult Disable(string id, bool? force) {
|
_moduleService.EnableFeatures(disabledFeatures, force == true);
|
||||||
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features")))
|
break;
|
||||||
return new HttpUnauthorizedResult();
|
case FeaturesBulkAction.Disable:
|
||||||
|
_moduleService.DisableFeatures(enabledFeatures, force == true);
|
||||||
if (string.IsNullOrEmpty(id))
|
break;
|
||||||
return HttpNotFound();
|
case FeaturesBulkAction.Toggle:
|
||||||
|
_moduleService.EnableFeatures(disabledFeatures, force == true);
|
||||||
_moduleService.DisableFeatures(new[] { id }, force != null && (bool)force);
|
_moduleService.DisableFeatures(enabledFeatures, force == true);
|
||||||
|
break;
|
||||||
return RedirectToAction("Features");
|
case FeaturesBulkAction.Update:
|
||||||
}
|
foreach (var feature in selectedFeatures.Where(x => x.NeedsUpdate)) {
|
||||||
|
var id = feature.Descriptor.Id;
|
||||||
[HttpPost]
|
try {
|
||||||
public ActionResult Update(string id) {
|
_reportsCoordinator.Register("Data Migration", "Upgrade " + id, "Orchard installation");
|
||||||
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features")))
|
_dataMigrationManager.Update(id);
|
||||||
return new HttpUnauthorizedResult();
|
Services.Notifier.Information(T("The feature {0} was updated successfully", id));
|
||||||
|
}
|
||||||
if (string.IsNullOrEmpty(id))
|
catch (Exception exception) {
|
||||||
return HttpNotFound();
|
Services.Notifier.Error(T("An error occured while updating the feature {0}: {1}", id, exception.Message));
|
||||||
|
}
|
||||||
try {
|
}
|
||||||
_reportsCoordinator.Register("Data Migration", "Upgrade " + id, "Orchard installation");
|
break;
|
||||||
_dataMigrationManager.Update(id);
|
default:
|
||||||
Services.Notifier.Information(T("The feature {0} was updated successfully", id));
|
throw new ArgumentOutOfRangeException();
|
||||||
} catch (Exception exception) {
|
}
|
||||||
Services.Notifier.Error(T("An error occured while updating the feature {0}: {1}", id, exception.Message));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return RedirectToAction("Features");
|
return RedirectToAction("Features");
|
||||||
|
@@ -79,6 +79,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Module.txt" />
|
<Content Include="Module.txt" />
|
||||||
|
<Content Include="Scripts\features.admin.min.js">
|
||||||
|
<DependentUpon>features.admin.js</DependentUpon>
|
||||||
|
</Content>
|
||||||
<Content Include="Styles\images\menu.modules.png" />
|
<Content Include="Styles\images\menu.modules.png" />
|
||||||
<Content Include="Styles\images\new.gif" />
|
<Content Include="Styles\images\new.gif" />
|
||||||
<Content Include="Styles\images\update.gif" />
|
<Content Include="Styles\images\update.gif" />
|
||||||
@@ -117,6 +120,19 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Views\Admin\Recipes.cshtml" />
|
<Content Include="Views\Admin\Recipes.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Scripts\features.admin.js" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Scripts\features.admin.min.js.map">
|
||||||
|
<DependentUpon>features.admin.js</DependentUpon>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Scripts\Web.config">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
25
src/Orchard.Web/Modules/Orchard.Modules/Scripts/Web.config
Normal file
25
src/Orchard.Web/Modules/Orchard.Modules/Scripts/Web.config
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appSettings>
|
||||||
|
<add key="webpages:Enabled" value="false" />
|
||||||
|
</appSettings>
|
||||||
|
<system.web>
|
||||||
|
<httpHandlers>
|
||||||
|
<!-- iis6 - for any request in this location, return via managed static file handler -->
|
||||||
|
<add path="*" verb="*" type="System.Web.StaticFileHandler" />
|
||||||
|
</httpHandlers>
|
||||||
|
</system.web>
|
||||||
|
<system.webServer>
|
||||||
|
<staticContent>
|
||||||
|
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
|
||||||
|
</staticContent>
|
||||||
|
|
||||||
|
<handlers accessPolicy="Script,Read">
|
||||||
|
<!--
|
||||||
|
iis7 - for any request to a file exists on disk, return it via native http module.
|
||||||
|
accessPolicy 'Script' is to allow for a managed 404 page.
|
||||||
|
-->
|
||||||
|
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
|
||||||
|
</handlers>
|
||||||
|
</system.webServer>
|
||||||
|
</configuration>
|
@@ -0,0 +1,58 @@
|
|||||||
|
$(function() {
|
||||||
|
|
||||||
|
var initializeFeaturesUI = function() {
|
||||||
|
var bulkActions = $(".bulk-actions-wrapper").addClass("visible");
|
||||||
|
var theSwitch = $(".switch-for-switchable");
|
||||||
|
theSwitch.prepend(bulkActions);
|
||||||
|
$("#search-box").focus().keyup(function() {
|
||||||
|
var text = $(this).val();
|
||||||
|
|
||||||
|
if (text == '') {
|
||||||
|
$("li.category").show();
|
||||||
|
$("li.feature:hidden").show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("li.feature").each(function() {
|
||||||
|
var elt = $(this);
|
||||||
|
var value = elt.find('h3:first').text();
|
||||||
|
if (value.toLowerCase().indexOf(text.toLowerCase()) >= 0)
|
||||||
|
elt.show();
|
||||||
|
else
|
||||||
|
elt.hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("li.category:hidden").show();
|
||||||
|
var toHide = $("li.category:not(:has(li.feature:visible))").hide();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var initializeSelectionBehavior = function() {
|
||||||
|
$("li.feature h3").on("change", "input[type='checkbox']", function() {
|
||||||
|
var checked = $(this).is(":checked");
|
||||||
|
var wrapper = $(this).parents("li.feature:first");
|
||||||
|
wrapper.toggleClass("selected", checked);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var initializeActionLinks = function() {
|
||||||
|
$("li.feature .actions").on("click", "a[data-feature-action]", function(e) {
|
||||||
|
var actionLink = $(this);
|
||||||
|
var featureId = actionLink.data("feature-id");
|
||||||
|
var action = actionLink.data("feature-action");
|
||||||
|
var force = actionLink.data("feature-force");
|
||||||
|
|
||||||
|
$("[name='submit.BulkExecute']").val("yes");
|
||||||
|
$("[name='featureIds']").val(featureId);
|
||||||
|
$("[name='bulkAction']").val(action);
|
||||||
|
$("[name='force']").val(force);
|
||||||
|
|
||||||
|
actionLink.parents("form:first").submit();
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
initializeFeaturesUI();
|
||||||
|
initializeSelectionBehavior();
|
||||||
|
initializeActionLinks();
|
||||||
|
});
|
2
src/Orchard.Web/Modules/Orchard.Modules/Scripts/features.admin.min.js
vendored
Normal file
2
src/Orchard.Web/Modules/Orchard.Modules/Scripts/features.admin.min.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
$(function(){var n=function(){var n=$(".bulk-actions-wrapper").addClass("visible"),t=$(".switch-for-switchable");t.prepend(n),$("#search-box").focus().keyup(function(){var n=$(this).val(),t;if(n==""){$("li.category").show(),$("li.feature:hidden").show();return}$("li.feature").each(function(){var t=$(this),i=t.find("h3:first").text();i.toLowerCase().indexOf(n.toLowerCase())>=0?t.show():t.hide()}),$("li.category:hidden").show(),t=$("li.category:not(:has(li.feature:visible))").hide()})},t=function(){$("li.feature h3").on("change","input[type='checkbox']",function(){var n=$(this).is(":checked"),t=$(this).parents("li.feature:first");t.toggleClass("selected",n)})},i=function(){$("li.feature .actions").on("click","a[data-feature-action]",function(n){var t=$(this),i=t.data("feature-id"),r=t.data("feature-action"),u=t.data("feature-force");$("[name='submit.BulkExecute']").val("yes"),$("[name='featureIds']").val(i),$("[name='bulkAction']").val(r),$("[name='force']").val(u),t.parents("form:first").submit(),n.preventDefault()})};n(),t(),i()});
|
||||||
|
//@ sourceMappingURL=features.admin.min.js.map
|
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"version":3,
|
||||||
|
"file":"features.admin.min.js",
|
||||||
|
"lineCount":1,
|
||||||
|
"mappings":"AAAAA,CAAC,CAAC,QAAQ,CAAA,CAAG,CAET,IAAIC,EAAuBA,QAAQ,CAAA,CAAG,CAClC,IAAIC,EAAcF,CAAC,CAAC,uBAAD,CAAyBG,SAAS,CAAC,SAAD,EACjDC,EAAYJ,CAAC,CAAC,wBAAD,CAD+C,CAEhEI,CAASC,QAAQ,CAACH,CAAD,CAAa,CAC9BF,CAAC,CAAC,aAAD,CAAeM,MAAM,CAAA,CAAEC,MAAM,CAAC,QAAQ,CAAA,CAAG,CACtC,IAAIC,EAAOR,CAAC,CAAC,IAAD,CAAMS,IAAI,CAAA,EAkBlBC,CAlBoB,CAExB,GAAIF,CAAK,EAAG,GAAI,CACZR,CAAC,CAAC,aAAD,CAAeW,KAAK,CAAA,CAAE,CACvBX,CAAC,CAAC,mBAAD,CAAqBW,KAAK,CAAA,CAAE,CAC7B,MAHY,CAMhBX,CAAC,CAAC,YAAD,CAAcY,KAAK,CAAC,QAAQ,CAAA,CAAG,CAC5B,IAAIC,EAAMb,CAAC,CAAC,IAAD,EACPc,EAAQD,CAAGE,KAAK,CAAC,UAAD,CAAYP,KAAK,CAAA,CADpB,CAEbM,CAAKE,YAAY,CAAA,CAAEC,QAAQ,CAACT,CAAIQ,YAAY,CAAA,CAAjB,CAAqB,EAAG,CAAvD,CACIH,CAAGF,KAAK,CAAA,CADZ,CAGIE,CAAGK,KAAK,CAAA,CANgB,CAAZ,CAOlB,CAEFlB,CAAC,CAAC,oBAAD,CAAsBW,KAAK,CAAA,CAAE,CAC1BD,CAAO,CAAEV,CAAC,CAAC,2CAAD,CAA6CkB,KAAK,CAAA,CAnB1B,CAAZ,CAJI,EA2BlCC,EAA8BA,QAAQ,CAAA,CAAG,CACzCnB,CAAC,CAAC,eAAD,CAAiBoB,GAAG,CAAC,QAAQ,CAAE,wBAAwB,CAAE,QAAQ,CAAA,CAAG,CACjE,IAAIC,EAAUrB,CAAC,CAAC,IAAD,CAAMsB,GAAG,CAAC,UAAD,EACpBC,EAAUvB,CAAC,CAAC,IAAD,CAAMwB,QAAQ,CAAC,kBAAD,CADO,CAEpCD,CAAOE,YAAY,CAAC,UAAU,CAAEJ,CAAb,CAH8C,CAAhD,CADoB,EAQzCK,EAAwBA,QAAQ,CAAA,CAAG,CACnC1B,CAAC,CAAC,qBAAD,CAAuBoB,GAAG,CAAC,OAAO,CAAE,wBAAwB,CAAE,QAAQ,CAACO,CAAD,CAAI,CACvE,IAAIC,EAAa5B,CAAC,CAAC,IAAD,EACd6B,EAAYD,CAAUE,KAAK,CAAC,YAAD,EAC3BC,EAASH,CAAUE,KAAK,CAAC,gBAAD,EACxBE,EAAQJ,CAAUE,KAAK,CAAC,eAAD,CAHH,CAKxB9B,CAAC,CAAC,6BAAD,CAA+BS,IAAI,CAAC,KAAD,CAAO,CAC3CT,CAAC,CAAC,qBAAD,CAAuBS,IAAI,CAACoB,CAAD,CAAW,CACvC7B,CAAC,CAAC,qBAAD,CAAuBS,IAAI,CAACsB,CAAD,CAAQ,CACpC/B,CAAC,CAAC,gBAAD,CAAkBS,IAAI,CAACuB,CAAD,CAAO,CAE9BJ,CAAUJ,QAAQ,CAAC,YAAD,CAAcS,OAAO,CAAA,CAAE,CACzCN,CAACO,eAAe,CAAA,CAZuD,CAAhD,CADQ,CAVtC,CA2BDjC,CAAoB,CAAA,CAAE,CACtBkB,CAA2B,CAAA,CAAE,CAC7BO,CAAqB,CAAA,CAxDZ,CAAZ,CAyDC",
|
||||||
|
"sources":["features.admin.js"],
|
||||||
|
"names":["$","initializeFeaturesUI","bulkActions","addClass","theSwitch","prepend","focus","keyup","text","val","toHide","show","each","elt","value","find","toLowerCase","indexOf","hide","initializeSelectionBehavior","on","checked","is","wrapper","parents","toggleClass","initializeActionLinks","e","actionLink","featureId","data","action","force","submit","preventDefault"]
|
||||||
|
}
|
@@ -4,5 +4,14 @@ using Orchard.Modules.Models;
|
|||||||
namespace Orchard.Modules.ViewModels {
|
namespace Orchard.Modules.ViewModels {
|
||||||
public class FeaturesViewModel {
|
public class FeaturesViewModel {
|
||||||
public IEnumerable<ModuleFeature> Features { get; set; }
|
public IEnumerable<ModuleFeature> Features { get; set; }
|
||||||
|
public FeaturesBulkAction BulkAction { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum FeaturesBulkAction {
|
||||||
|
None,
|
||||||
|
Enable,
|
||||||
|
Disable,
|
||||||
|
Update,
|
||||||
|
Toggle
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -9,25 +9,46 @@
|
|||||||
Style.Require("ModulesAdmin");
|
Style.Require("ModulesAdmin");
|
||||||
Style.Require("Switchable");
|
Style.Require("Switchable");
|
||||||
Script.Require("Switchable");
|
Script.Require("Switchable");
|
||||||
|
Script.Include("features.admin.js", "features.admin.min.js").AtFoot();
|
||||||
|
|
||||||
Layout.Title = T("Modules").ToString();
|
Layout.Title = T("Modules").ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Model.Features.Count() > 0) {
|
@if (Model.Features.Any()) {
|
||||||
<ul class="features summary-view switchable">@{
|
using (Html.BeginFormAntiForgeryPost()) {
|
||||||
var featureGroups = Model.Features.OrderBy(f => f.Descriptor.Category, new DoghouseComparer("Core")).GroupBy(f => f.Descriptor.Category);
|
@Html.Hidden("submit.BulkExecute")
|
||||||
foreach (var featureGroup in featureGroups) {
|
@Html.Hidden("force", true)
|
||||||
var categoryName = LocalizedString.TextOrDefault(featureGroup.First().Descriptor.Category, T("Uncategorized"));
|
@Html.Hidden("featureIds")
|
||||||
var categoryClassName = string.Format("category {0}", Html.Encode(categoryName.ToString().HtmlClassify()));
|
<div class="bulk-actions-wrapper">
|
||||||
if (featureGroup == featureGroups.First()) {
|
<fieldset class="bulk-actions">
|
||||||
categoryClassName += " first";
|
<label for="search-box">@T("Filter:")</label>
|
||||||
}
|
<input id="search-box" class="text-box" type="text" />
|
||||||
if (featureGroup == featureGroups.Last()) {
|
</fieldset>
|
||||||
categoryClassName += " last";
|
<fieldset class="bulk-actions">
|
||||||
}
|
<label for="publishActions">@T("Actions:")</label>
|
||||||
|
<select id="publishActions" name="bulkAction">
|
||||||
|
@Html.SelectOption(Model.BulkAction, FeaturesBulkAction.None, T("Choose action...").ToString())
|
||||||
|
@Html.SelectOption(Model.BulkAction, FeaturesBulkAction.Enable, T("Enable").ToString())
|
||||||
|
@Html.SelectOption(Model.BulkAction, FeaturesBulkAction.Disable, T("Disable").ToString())
|
||||||
|
@Html.SelectOption(Model.BulkAction, FeaturesBulkAction.Toggle, T("Toggle").ToString())
|
||||||
|
</select>
|
||||||
|
<button type="submit" name="submit.BulkExecute" value="yes">@T("Execute")</button>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="features summary-view switchable">@{
|
||||||
|
var featureGroups = Model.Features.OrderBy(f => f.Descriptor.Category, new DoghouseComparer("Core")).GroupBy(f => f.Descriptor.Category).ToList();
|
||||||
|
foreach (var featureGroup in featureGroups) {
|
||||||
|
var categoryName = LocalizedString.TextOrDefault(featureGroup.First().Descriptor.Category, T("Uncategorized"));
|
||||||
|
var categoryClassName = string.Format("category {0}", Html.Encode(categoryName.ToString().HtmlClassify()));
|
||||||
|
if (featureGroup == featureGroups.First()) {
|
||||||
|
categoryClassName += " first";
|
||||||
|
}
|
||||||
|
if (featureGroup == featureGroups.Last()) {
|
||||||
|
categoryClassName += " last";
|
||||||
|
}
|
||||||
|
|
||||||
bool showEnable, showDisable;
|
<li class="@categoryClassName">
|
||||||
<li class="@categoryClassName">
|
|
||||||
<h2>@categoryName</h2>
|
<h2>@categoryName</h2>
|
||||||
<ul>@{
|
<ul>@{
|
||||||
var features = featureGroup.OrderBy(f => f.Descriptor.Name);
|
var features = featureGroup.OrderBy(f => f.Descriptor.Name);
|
||||||
@@ -52,12 +73,17 @@
|
|||||||
select (from f in Model.Features where f.Descriptor.Id.Equals(d, StringComparison.OrdinalIgnoreCase) select f).SingleOrDefault()).Where(f => f != null).OrderBy(f => f.Descriptor.Name);
|
select (from f in Model.Features where f.Descriptor.Id.Equals(d, StringComparison.OrdinalIgnoreCase) select f).SingleOrDefault()).Where(f => f != null).OrderBy(f => f.Descriptor.Name);
|
||||||
var missingDependencies = feature.Descriptor.Dependencies
|
var missingDependencies = feature.Descriptor.Dependencies
|
||||||
.Where(d => !Model.Features.Any(f => f.Descriptor.Id.Equals(d, StringComparison.OrdinalIgnoreCase)));
|
.Where(d => !Model.Features.Any(f => f.Descriptor.Id.Equals(d, StringComparison.OrdinalIgnoreCase)));
|
||||||
showDisable = categoryName.ToString() != "Core";
|
var showDisable = categoryName.ToString() != "Core";
|
||||||
showEnable = !missingDependencies.Any() && feature.Descriptor.Id != "Orchard.Setup";
|
var showEnable = !missingDependencies.Any() && feature.Descriptor.Id != "Orchard.Setup";
|
||||||
<li class="@featureClassName" id="@featureId" title="@T("{0} is {1}", Html.AttributeEncode(featureName), featureState)">
|
<li class="@featureClassName" id="@featureId" title="@T("{0} is {1}", Html.AttributeEncode(featureName), featureState)">
|
||||||
<div class="summary">
|
<div class="summary">
|
||||||
<div class="properties">
|
<div class="properties">
|
||||||
<h3>@featureName</h3>
|
<h3>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="featureIds" value="@feature.Descriptor.Id"/>
|
||||||
|
@featureName
|
||||||
|
</label>
|
||||||
|
</h3>
|
||||||
<p class="description" title="@feature.Descriptor.Description">@feature.Descriptor.Description</p>
|
<p class="description" title="@feature.Descriptor.Description">@feature.Descriptor.Description</p>
|
||||||
@if (feature.Descriptor.Dependencies != null && feature.Descriptor.Dependencies.Any()) {
|
@if (feature.Descriptor.Dependencies != null && feature.Descriptor.Dependencies.Any()) {
|
||||||
<div class="dependencies">
|
<div class="dependencies">
|
||||||
@@ -76,26 +102,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
@if (showDisable && feature.IsEnabled) {
|
@if (showDisable && feature.IsEnabled) {
|
||||||
using (Html.BeginFormAntiForgeryPost(string.Format("{0}", Url.Action("Disable", new { area = "Orchard.Modules" })), FormMethod.Post, new {@class = "inline link"})) {
|
<a href="#" data-feature-id="@feature.Descriptor.Id" data-feature-action="@FeaturesBulkAction.Disable" data-feature-force="true">@T("Disable")</a>
|
||||||
@Html.Hidden("id", feature.Descriptor.Id, new {id = ""})
|
|
||||||
@Html.Hidden("force", true)
|
|
||||||
<button type="submit">@T("Disable")</button>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@if(showEnable && !feature.IsEnabled) {
|
@if (showEnable && !feature.IsEnabled) {
|
||||||
using (Html.BeginFormAntiForgeryPost(string.Format("{0}", Url.Action("Enable", new { area = "Orchard.Modules" })), FormMethod.Post, new {@class = "inline link"})) {
|
<a href="#" data-feature-id="@feature.Descriptor.Id" data-feature-action="@FeaturesBulkAction.Enable" data-feature-force="true">@T("Enable")</a>
|
||||||
@Html.Hidden("id", feature.Descriptor.Id, new { id = "" })
|
|
||||||
@Html.Hidden("force", true)
|
|
||||||
<button type="submit">@T("Enable")</button>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@if(feature.NeedsUpdate){
|
@if (feature.NeedsUpdate) {
|
||||||
using (Html.BeginFormAntiForgeryPost(string.Format("{0}", Url.Action("Update", new { area = "Orchard.Modules" })), FormMethod.Post, new {@class = "inline link"})) {
|
<a href="#" data-feature-id="@feature.Descriptor.Id" data-feature-action="@FeaturesBulkAction.Update" data-feature-force="false">@T("Update")</a>
|
||||||
@Html.Hidden("id", feature.Descriptor.Id, new { id = "" })
|
|
||||||
<button type="submit" class="update">@T("Update")</button>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -103,36 +118,4 @@
|
|||||||
}</ul>
|
}</ul>
|
||||||
</li>}
|
</li>}
|
||||||
}</ul>}
|
}</ul>}
|
||||||
|
|
||||||
@using(Script.Foot()) {
|
|
||||||
<script type="text/javascript">
|
|
||||||
//<![CDATA[
|
|
||||||
$(function () {
|
|
||||||
var searchBox = $("<fieldset class=\"bulk-actions\"><label for=\"search-box\">@T("Filter:")</label> <input id=\"search-box\" class=\"text-box\" type=\"text\" /></fieldset>");
|
|
||||||
var theSwitch = $(".switch-for-switchable");
|
|
||||||
theSwitch.prepend(searchBox);
|
|
||||||
$("#search-box").focus().keyup(function () {
|
|
||||||
var text = $(this).val();
|
|
||||||
|
|
||||||
if (text == '') {
|
|
||||||
$("li.category").show();
|
|
||||||
$("li.feature:hidden").show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$("li.feature").each(function () {
|
|
||||||
var elt = $(this);
|
|
||||||
var value = elt.find('h3:first').text();
|
|
||||||
if (value.toLowerCase().indexOf(text.toLowerCase()) >= 0)
|
|
||||||
elt.show();
|
|
||||||
else
|
|
||||||
elt.hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
$("li.category:hidden").show();
|
|
||||||
var toHide = $("li.category:not(:has(li.feature:visible))").hide();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
//]]>
|
|
||||||
</script>
|
|
||||||
}
|
}
|
@@ -1,9 +1,6 @@
|
|||||||
@model Orchard.Modules.ViewModels.ModulesIndexViewModel
|
@model Orchard.Modules.ViewModels.ModulesIndexViewModel
|
||||||
@using Orchard.Localization;
|
|
||||||
@using Orchard.Modules.Models;
|
@using Orchard.Modules.Models;
|
||||||
@using Orchard.Modules.Extensions;
|
|
||||||
@using Orchard.Mvc.Html;
|
@using Orchard.Mvc.Html;
|
||||||
@using Orchard.Utility.Extensions;
|
|
||||||
|
|
||||||
@{
|
@{
|
||||||
Style.Require("ModulesAdmin");
|
Style.Require("ModulesAdmin");
|
||||||
@@ -23,7 +20,7 @@
|
|||||||
<span>@Html.ActionLink(T("Install a module from your computer").ToString(), "AddModule", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl }, null)</span>
|
<span>@Html.ActionLink(T("Install a module from your computer").ToString(), "AddModule", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl }, null)</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Model.Modules.Count() > 0) {
|
if (Model.Modules.Any()) {
|
||||||
<ul class="contentItems">
|
<ul class="contentItems">
|
||||||
@foreach (ModuleEntry module in Model.Modules.OrderBy(m => m.Descriptor.Name)) {
|
@foreach (ModuleEntry module in Model.Modules.OrderBy(m => m.Descriptor.Name)) {
|
||||||
<li>@Display.ModuleEntry(ContentPart: module)</li>
|
<li>@Display.ModuleEntry(ContentPart: module)</li>
|
||||||
|
@@ -36,6 +36,7 @@ html.dyn #main ul.features button { display:none; }
|
|||||||
|
|
||||||
.features.detail-view .feature {
|
.features.detail-view .feature {
|
||||||
padding:.25em 0;
|
padding:.25em 0;
|
||||||
|
border-bottom:1px solid #CCC;
|
||||||
}
|
}
|
||||||
.features .enabled.feature {
|
.features .enabled.feature {
|
||||||
background:#FFF;
|
background:#FFF;
|
||||||
@@ -44,6 +45,9 @@ html.dyn #main ul.features button { display:none; }
|
|||||||
border-color:#cfe493;
|
border-color:#cfe493;
|
||||||
overflow:hidden;
|
overflow:hidden;
|
||||||
}
|
}
|
||||||
|
.features.summary-view .enabled.selected.feature, .features.summary-view .disabled.selected.feature {
|
||||||
|
border-color:rgb(60,130,46);
|
||||||
|
}
|
||||||
.features .disabled.feature {
|
.features .disabled.feature {
|
||||||
background:#f3f3f3;
|
background:#f3f3f3;
|
||||||
}
|
}
|
||||||
@@ -56,17 +60,22 @@ html.dyn #main ul.features button { display:none; }
|
|||||||
.features.summary-view .update.feature {
|
.features.summary-view .update.feature {
|
||||||
border-color:#E77;
|
border-color:#E77;
|
||||||
}
|
}
|
||||||
.features.detail-view .feature {
|
|
||||||
border-bottom:1px solid #CCC;
|
|
||||||
}
|
|
||||||
.features.detail-view .last.feature {
|
.features.detail-view .last.feature {
|
||||||
border:0;
|
border:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.features .feature .summary {
|
.features .feature .summary {
|
||||||
overflow:hidden;
|
overflow: hidden;
|
||||||
padding:.4em .5em;
|
padding: .4em .5em;
|
||||||
position:relative;
|
position: relative;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.features .feature .summary .properties h3 label {
|
||||||
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.features .feature .summary .properties h3 label input {
|
||||||
|
vertical-align: 5%;
|
||||||
}
|
}
|
||||||
.features.detail-view .feature .summary {
|
.features.detail-view .feature .summary {
|
||||||
overflow:visible;
|
overflow:visible;
|
||||||
@@ -154,4 +163,10 @@ h2.recentlyInstalledModule {padding:0 0 0 40px;}
|
|||||||
|
|
||||||
.manage {
|
.manage {
|
||||||
float: right;
|
float: right;
|
||||||
|
}
|
||||||
|
.orchard-modules .bulk-actions-wrapper {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.orchard-modules .bulk-actions-wrapper.visible {
|
||||||
|
display: inline;
|
||||||
}
|
}
|
Reference in New Issue
Block a user