mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Implementing inline audit trail on content editor view.
This commit is contained in:
@@ -1,20 +1,72 @@
|
||||
using Orchard.AuditTrail.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Orchard.AuditTrail.Models;
|
||||
using Orchard.AuditTrail.Services;
|
||||
using Orchard.AuditTrail.Settings;
|
||||
using Orchard.AuditTrail.ViewModels;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.AuditTrail.Drivers {
|
||||
public class AuditTrailPartDriver : ContentPartDriver<AuditTrailPart> {
|
||||
private readonly IOrchardServices _services;
|
||||
private readonly IAuditTrailManager _auditTrailManager;
|
||||
private readonly IAuditTrailEventDisplayBuilder _displayBuilder;
|
||||
|
||||
public AuditTrailPartDriver(IOrchardServices services, IAuditTrailManager auditTrailManager, IAuditTrailEventDisplayBuilder displayBuilder) {
|
||||
_services = services;
|
||||
_auditTrailManager = auditTrailManager;
|
||||
_displayBuilder = displayBuilder;
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(AuditTrailPart part, dynamic shapeHelper) {
|
||||
return Editor(part, null, shapeHelper);
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(AuditTrailPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
return ContentShape("Parts_AuditTrail_Edit", () => {
|
||||
if (updater != null) {
|
||||
updater.TryUpdateModel(part, Prefix, null, null);
|
||||
}
|
||||
return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrail", Prefix: Prefix);
|
||||
});
|
||||
var settings = part.Settings.GetModel<AuditTrailPartSettings>();
|
||||
var results = new List<DriverResult>();
|
||||
|
||||
if (settings.ShowAuditTrailCommentInput) {
|
||||
results.Add(ContentShape("Parts_AuditTrail_Comment", () => {
|
||||
if (updater != null) {
|
||||
updater.TryUpdateModel(part, Prefix, null, null);
|
||||
}
|
||||
return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrail.Comment", Prefix: Prefix);
|
||||
}));
|
||||
}
|
||||
|
||||
if (settings.ShowAuditTrailLink) {
|
||||
results.Add(ContentShape("Parts_AuditTrail_Link", () => shapeHelper.Parts_AuditTrail_Link()));
|
||||
}
|
||||
|
||||
if (settings.ShowAuditTrail) {
|
||||
results.Add(ContentShape("Parts_AuditTrail", () => {
|
||||
var pager = new Pager(_services.WorkContext.CurrentSite, null, null);
|
||||
var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, new AuditTrailFilterParameters {
|
||||
FilterKey = "content",
|
||||
FilterValue = part.Id.ToString(CultureInfo.InvariantCulture)
|
||||
});
|
||||
var pagerShape = shapeHelper.Pager(pager).TotalItemCount(pageOfData.TotalItemCount);
|
||||
var eventDescriptors = from c in _auditTrailManager.Describe()
|
||||
from e in c.Events
|
||||
select e;
|
||||
var recordViewModels = from record in pageOfData
|
||||
let descriptor = eventDescriptors.FirstOrDefault(x => x.Event == record.Event)
|
||||
where descriptor != null
|
||||
select new AuditTrailEventSummaryViewModel {
|
||||
Record = record,
|
||||
EventDescriptor = descriptor,
|
||||
CategoryDescriptor = descriptor.CategoryDescriptor,
|
||||
SummaryShape = _displayBuilder.BuildDisplay(record, "SummaryAdmin")
|
||||
};
|
||||
return shapeHelper.Parts_AuditTrail(Records: recordViewModels, Pager: pagerShape);
|
||||
}));
|
||||
}
|
||||
|
||||
return Combined(results.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
@@ -83,6 +83,8 @@
|
||||
<Content Include="Module.txt" />
|
||||
<Content Include="Views\Parts.Contents.AuditTrail.SummaryAdmin.cshtml" />
|
||||
<Content Include="Views\DefinitionTemplates\AuditTrailPartSettings.cshtml" />
|
||||
<Content Include="Views\Parts.AuditTrail.Link.cshtml" />
|
||||
<Content Include="Views\Parts.AuditTrail.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||
@@ -151,7 +153,7 @@
|
||||
<Content Include="Views\AuditTrailEvent-Content.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\EditorTemplates\Parts.AuditTrail.cshtml" />
|
||||
<Content Include="Views\EditorTemplates\Parts.AuditTrail.Comment.cshtml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
|
@@ -1,5 +1,8 @@
|
||||
<Placement>
|
||||
<Place Parts_AuditTrail_Edit="Content:after" />
|
||||
<Place Parts_AuditTrail_Comment="Content:after.1"
|
||||
Parts_AuditTrail_Link="Content:after.2"
|
||||
Parts_AuditTrail="Content:after.3"/>
|
||||
|
||||
<Match DisplayType="SummaryAdmin">
|
||||
<Place Parts_Contents_AuditTrail_SummaryAdmin="Actions:7"/>
|
||||
</Match>
|
||||
|
@@ -0,0 +1,10 @@
|
||||
(function($) {
|
||||
// Initialize Expando control
|
||||
$(".expando-wrapper legend").expandoControl(
|
||||
function (controller) {
|
||||
return controller.nextAll(".expando");
|
||||
}, {
|
||||
collapse: true,
|
||||
remember: true
|
||||
});
|
||||
})(jQuery);
|
@@ -9,6 +9,8 @@
|
||||
new SelectListItem {Text = T("Date (desc)").Text, Value = AuditTrailOrderBy.DateDescending.ToString(), Selected = Model.Filter.OrderBy == AuditTrailOrderBy.DateDescending},
|
||||
new SelectListItem {Text = T("Event (asc)").Text, Value = AuditTrailOrderBy.EventAscending.ToString(), Selected = Model.Filter.OrderBy == AuditTrailOrderBy.EventAscending},
|
||||
};
|
||||
|
||||
Layout.Title = T("Audit Trail");
|
||||
}
|
||||
<section class="audit-trail-filter">
|
||||
@using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) {
|
||||
@@ -17,9 +19,9 @@
|
||||
@Html.Hidden("filtervalue", Model.Filter.FilterValue)
|
||||
@Html.Label("username", T("User:").Text)
|
||||
@Html.TextBox("username", Model.Filter.UserName, new { @class = "text" })
|
||||
@Html.LabelFor(m => from, T("Between:"))
|
||||
@Html.LabelFor(m => from, T("From:"))
|
||||
@Html.EditorFor(m => from)
|
||||
@Html.LabelFor(m => to, T("And:"))
|
||||
@Html.LabelFor(m => to, T("To:"))
|
||||
@Html.EditorFor(m => to)
|
||||
@Html.LabelFor(m => orderBy, T("Ordered by:"))
|
||||
@Html.DropDownListFor(m => orderBy, orderByItems)
|
||||
|
@@ -1,8 +1,7 @@
|
||||
@model Orchard.AuditTrail.Models.AuditTrailPart
|
||||
<fieldset>
|
||||
<legend>@T("Audit Trail")</legend>
|
||||
<div>
|
||||
@Html.LabelFor(m => m.Comment)
|
||||
@Html.LabelFor(m => m.Comment, T("Audit Trail Comment"))
|
||||
@Html.TextBoxFor(m => m.Comment, new { @class = "text large" })
|
||||
<span class="hint">@T("Optionally provide a comment about this change. This comment will be stored as part of an audit trail event.")</span>
|
||||
</div>
|
@@ -0,0 +1,8 @@
|
||||
@{
|
||||
var contentId = (int)Model.ContentPart.Id;
|
||||
}
|
||||
@if (contentId > 0) {
|
||||
<fieldset>
|
||||
@Html.ActionLink(T("View Audit Trail").Text, "Index", "Admin", new { filterkey = "content", filtervalue = contentId, area = "Orchard.AuditTrail" }, null)
|
||||
</fieldset>
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
@using Orchard.AuditTrail.Models
|
||||
@using Orchard.AuditTrail.ViewModels
|
||||
@{
|
||||
Script.Require("ShapesBase");
|
||||
Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot();
|
||||
Script.Include("audit-trail-admin.js").AtFoot();
|
||||
}
|
||||
@{
|
||||
var records = (IEnumerable<AuditTrailEventSummaryViewModel>)Model.Records;
|
||||
var auditTrailPart = (AuditTrailPart)Model.ContentPart;
|
||||
}
|
||||
@if (auditTrailPart.Id > 0) {
|
||||
|
||||
<fieldset class="expando-wrapper">
|
||||
<legend>@T("Audit Trail")</legend>
|
||||
<div class="expando">
|
||||
<section class="audit-trail-list">
|
||||
@if (!records.Any()) {
|
||||
<p class="info">@T("There are no audit trail events to display.")</p>
|
||||
}
|
||||
else {
|
||||
<table class="items">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>@T("Event")</th>
|
||||
<th>@T("Category")</th>
|
||||
<th>@T("User")</th>
|
||||
<th>@T("Timestamp")</th>
|
||||
<th>@T("Comment")</th>
|
||||
<th>@T("Event Data")</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var record in records) {
|
||||
<tr>
|
||||
<td>@record.EventDescriptor.Name</td>
|
||||
<td>@record.CategoryDescriptor.Name</td>
|
||||
<td>@record.Record.UserName</td>
|
||||
<td>@Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))</td>
|
||||
<td>@record.Record.Comment</td>
|
||||
<td>@Display(record.SummaryShape)</td>
|
||||
<td>@Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
@if (Model.Pager.TotalItemCount > Model.Pager.PageSize) {
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
@Html.ActionLink(T("Show more events").Text, "Index", "Admin", new { filterKey = "content", filterValue = auditTrailPart.Id, page = 2, area = "Orchard.AuditTrail" }, null)
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
}
|
||||
</table>
|
||||
}
|
||||
</section>
|
||||
</div>
|
||||
</fieldset>
|
||||
}
|
Reference in New Issue
Block a user