Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gutter addon #195

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/Unicorn.Tests/TestingTools/Attributes/AutoSubAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Ploeh.AutoFixture.AutoNSubstitute;
using Ploeh.AutoFixture.Xunit2;

namespace Unicorn.Tests.TestingTools.Attributes
{
public class AutoSubAttribute : AutoDataAttribute
{
public AutoSubAttribute()
{
Fixture.Customize(new AutoNSubstituteCustomization());
}
}
}
39 changes: 39 additions & 0 deletions src/Unicorn.Tests/UI/Gutter/TransparentSyncGutterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using FluentAssertions;
using Ploeh.AutoFixture.Xunit2;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Shell.Applications.ContentEditor.Gutters;
using Unicorn.Data.DataProvider;
using Unicorn.Tests.TestingTools.Attributes;
using Unicorn.UI.Gutter;
using Xunit;

namespace Unicorn.Tests.UI.Gutter
{
public class TransparentSyncGutterTests
{
[Theory, AutoSub]
public void GetIconDescriptor_WhenItemIsNull_ThrowArgumentNullException([Greedy]TestableTransparentSyncGutter sut)
{
Assert.Throws<ArgumentNullException>(() => sut.Public_GetIconDescriptor(null));
}

[Theory, AutoDbData]
public void GetIconDescriptor_WasLastUpdatedByTransparentSync_ReturnGutterIconDescriptor([Greedy]TestableTransparentSyncGutter sut, [Content] Item item)
{
using (new EditContext(item))
{
item[FieldIDs.UpdatedBy] = UnicornDataProvider.TransparentSyncUpdatedByValue;
sut.Public_GetIconDescriptor(item).Should().BeAssignableTo<GutterIconDescriptor>();
}
}
}
public class TestableTransparentSyncGutter : TransparentSyncGutter
{
public GutterIconDescriptor Public_GetIconDescriptor(Item item)
{
return GetIconDescriptor(item);
}
}
}
2 changes: 2 additions & 0 deletions src/Unicorn.Tests/Unicorn.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@
<Compile Include="Configuration\Dependencies\DepTestHelper.cs" />
<Compile Include="Configuration\Dependencies\InterconfigurationDependencyResolverTests.cs" />
<Compile Include="Configuration\MicroConfigurationTests.cs" />
<Compile Include="TestingTools\Attributes\AutoSubAttribute.cs" />
<Compile Include="UI\Gutter\TransparentSyncGutterTests.cs" />
<None Include="app.config" />
<Compile Include="ControlPanel\Security\SitecoreDatabaseChallengeStoreTests.cs" />
<Compile Include="Data\DataProvider\ItemChangeApplyingItemDataTests.cs" />
Expand Down
47 changes: 47 additions & 0 deletions src/Unicorn/ControlPanel/Controls/Addons.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.Web.UI;
using Unicorn.ControlPanel.Pipelines.UnicornControlPanelRequest;

namespace Unicorn.ControlPanel.Controls
{
/// <summary>
/// Addons section
/// </summary>
internal class Addons : IControlPanelControl
{
public void Render(HtmlTextWriter writer)
{
writer.Write(@"
<article>");
writer.Write(@"
<h2>Addons</h2>");

writer.Write("<section>");
writer.Write("<table><tbody><tr>");

writer.Write("<td>");
writer.Write("<h3>Gutter Addon</h3>");
writer.Write("<p>Adds a gutter icon to any items that are included in a Unicorn Transparent Sync configuration</p>");
writer.Write(@"<p class=""help"">Note: if you have upgraded Unicorn and see a ""Verb Not Found"" message when clicking this button, make sure the following entries are present in your <strong>unicornControlPanelRequest</strong> pipeline:");
writer.Write(@"<pre class=""help"">
&lt;processor type=""Unicorn.ControlPanel.Pipelines.UnicornControlPanelRequest.InstallGutterVerb, Unicorn"" /&gt;
&lt;processor type=""Unicorn.ControlPanel.Pipelines.UnicornControlPanelRequest.RemoveGutterVerb, Unicorn"" /&gt;
</pre>");
writer.Write("</td>");
writer.Write(@"<td class=""controls"">");

if (GutterVerbBase.GetGutterItem() != null)
{
writer.Write(@"<a class=""button"" data-basehref=""?verb=RemoveGutter"" href=""?verb=RemoveGutter"">Remove Gutter Addon</a>");
}
else
{
writer.Write(@"<a class=""button"" data-basehref=""?verb=InstallGutter"" href=""?verb=InstallGutter"">Install Gutter Addon</a>");
}
writer.Write("</td>");
writer.Write("</tbody></table>");
writer.Write("</section>");
writer.Write(@"
</article>");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Kamsar.WebConsole;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Data.Managers;
using Unicorn.ControlPanel.Headings;
using Unicorn.ControlPanel.Responses;
using Unicorn.Logging;

namespace Unicorn.ControlPanel.Pipelines.UnicornControlPanelRequest
{
public abstract class GutterVerbBase : UnicornControlPanelRequestPipelineProcessor
{
private readonly string _consoleTitle;
protected const string GutterItemId = "{82496AF6-123F-4724-B7B6-746ED49A7747}";

protected GutterVerbBase(string verbHandled, string consoleTitle) : base(verbHandled)
{
_consoleTitle = consoleTitle;
}

protected override IResponse CreateResponse(UnicornControlPanelRequestPipelineArgs args)
{
return new WebConsoleResponse(_consoleTitle, args.SecurityState.IsAutomatedTool, new HeadingService(), progress => Process(progress, new WebConsoleLogger(progress, args.Context.Request.QueryString["log"])));
}

protected abstract void Process(IProgressStatus process, ILogger logger);

public static Item GetGutterItem()
{
Database coredb = Factory.GetDatabase("core");
return coredb.DataManager.DataEngine.GetItem(new ID(GutterItemId), LanguageManager.DefaultLanguage, Version.Latest);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using Kamsar.WebConsole;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Data.Managers;
using Sitecore.SecurityModel;
using Unicorn.Logging;
using Version = Sitecore.Data.Version;

namespace Unicorn.ControlPanel.Pipelines.UnicornControlPanelRequest
{
public class InstallGutterVerb : GutterVerbBase
{
public const string VerbName = "InstallGutter";
private const string GutterFolderId = "{59F37069-3118-4151-8C01-5DA0EF12CB4E}";
private const string GutterRendererTemplateId = "{F5D247E0-80E6-4F31-9921-D30D00B61B3C}";
public InstallGutterVerb() : base(VerbName, "Install Gutter")
{
}

protected override void Process(IProgressStatus progress, ILogger logger)
{
Item gutterItem = GetGutterItem();
Database coredb = Factory.GetDatabase("core");

if (gutterItem != null)
{
logger.Warn("JOB COMPLETE. Gutter icon exists. Aborting...");
WebConsoleUtility.SetTaskProgress(progress, 1, 1, 100);
return;
}

using (new SecurityDisabler())
{
Item gutterFolder = coredb.DataManager.DataEngine.GetItem(new ID(GutterFolderId), LanguageManager.DefaultLanguage,
Version.Latest);

logger.Info("Creating item");
try
{
gutterItem = ItemManager.CreateItem("Transparent Sync", gutterFolder, new ID(GutterRendererTemplateId),
new ID(GutterItemId));


gutterItem.Editing.BeginEdit();
gutterItem[FieldIDs.DisplayName] = "Transparent Sync";
gutterItem["Header"] = "Transparent Sync";
gutterItem["Type"] = "Unicorn.UI.Gutter.TransparentSyncGutter, Unicorn";
gutterItem.Editing.EndEdit(true, false);

logger.Info("JOB COMPLETE. Gutter item created successfully!");
WebConsoleUtility.SetTaskProgress(progress, 1, 1, 100);
}
catch (Exception ex)
{
logger.Error(ex);
logger.Error("JOB FAILED. An error has occurred. See above stack trace for details.");
WebConsoleUtility.SetTaskProgress(progress, 1, 1, 100);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using Kamsar.WebConsole;
using Sitecore.Data.Items;
using Sitecore.SecurityModel;
using Unicorn.Logging;

namespace Unicorn.ControlPanel.Pipelines.UnicornControlPanelRequest
{
public class RemoveGutterVerb : GutterVerbBase
{
public const string VerbName = "RemoveGutter";
public RemoveGutterVerb() : base(VerbName, "Remove Gutter Addon")
{
}
protected override void Process(IProgressStatus progress, ILogger additionalLogger)
{
Item gutterItem = GetGutterItem();

if (gutterItem == null)
{
additionalLogger.Warn("JOB COMPLETE. Gutter icon does not exist. Aborting...");
WebConsoleUtility.SetTaskProgress(progress, 1, 1, 100);
return;
}
using (new SecurityDisabler())
{
try
{
gutterItem.Delete();
additionalLogger.Info("JOB COMPLETE. Gutter item deleted successfully!");
WebConsoleUtility.SetTaskProgress(progress, 1, 1, 100);
}
catch (Exception ex)
{
additionalLogger.Error(ex);
additionalLogger.Error("JOB FAILED. An error has occurred. See above stack trace for details.");
WebConsoleUtility.SetTaskProgress(progress, 1, 1, 100);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ protected virtual IEnumerable<IControlPanelControl> CreateBodyControls(UnicornCo
</table>
</article>");

yield return new Addons();

yield return new QuickReference();
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public virtual void ProcessRequest(HttpContext context)

if (pipelineArgs.Response == null)
{
pipelineArgs.Response = new PlainTextResponse("Not Found", HttpStatusCode.NotFound);
pipelineArgs.Response = new PlainTextResponse("Verb not found. Please check your unicornControlPanelRequest pipeline and compare it against the standard Unicorn.UI.config.", HttpStatusCode.NotFound);
}

if (securityState.IsAllowed)
Expand Down
22 changes: 22 additions & 0 deletions src/Unicorn/UI/Gutter/TransparentSyncGutter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Shell.Applications.ContentEditor.Gutters;
using Unicorn.Data.DataProvider;

namespace Unicorn.UI.Gutter
{
public class TransparentSyncGutter : GutterRenderer
{
protected override GutterIconDescriptor GetIconDescriptor(Item item)
{
Assert.ArgumentNotNull(item, "item");
if (item.Statistics.UpdatedBy != UnicornDataProvider.TransparentSyncUpdatedByValue) return null;
var gutterIconDescriptor = new GutterIconDescriptor
{
Icon = "Office/32x32/arrow_circle2.png",
Tooltip = "This item is included by Unicorn Transparent Sync."
};
return gutterIconDescriptor;
}
}
}
5 changes: 5 additions & 0 deletions src/Unicorn/Unicorn.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,12 @@
<Compile Include="ControlPanel\Controls\BatchProcessingControls.cs" />
<Compile Include="ControlPanel\Controls\ConfigurationInfo.cs" />
<Compile Include="ControlPanel\Controls\GlobalWarnings.cs" />
<Compile Include="ControlPanel\Controls\Addons.cs" />
<Compile Include="ControlPanel\Controls\QuickReference.cs" />
<Compile Include="ControlPanel\Controls\NoConfigurations.cs" />
<Compile Include="ControlPanel\Pipelines\UnicornControlPanelRequest\GutterVerbBase.cs" />
<Compile Include="ControlPanel\Pipelines\UnicornControlPanelRequest\RemoveGutterVerb.cs" />
<Compile Include="ControlPanel\Pipelines\UnicornControlPanelRequest\InstallGutterVerb.cs" />
<Compile Include="ControlPanel\Security\ChallengeStoreSitecoreLogger.cs" />
<Compile Include="ControlPanel\Security\ChapServerSitecoreLogger.cs" />
<Compile Include="ControlPanel\UnicornStringConsole.cs" />
Expand Down Expand Up @@ -219,6 +223,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Publishing\ManualPublishQueueHandler.cs" />
<Compile Include="TransparentSyncDisabler.cs" />
<Compile Include="UI\Gutter\TransparentSyncGutter.cs" />
<Compile Include="UI\Pipelines\GetContentEditorWarnings\SerializedWarning.cs" />
<Compile Include="UI\Pipelines\GetContentEditorWarnings\Warning.cs" />
<Compile Include="UI\Pipelines\SaveUi\SaveUiConfirmProcessor.cs" />
Expand Down