Skip to content

Commit

Permalink
Add content workflow tab action buttons in edit mode dnnsoftware#6115
Browse files Browse the repository at this point in the history
  • Loading branch information
tvatavuk committed Oct 1, 2024
1 parent a26d998 commit 471a211
Show file tree
Hide file tree
Showing 15 changed files with 460 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ namespace DotNetNuke.Web.InternalServices
using System.Net.Http;
using System.Web.Http;

using DotNetNuke.Entities.Content.Common;
using DotNetNuke.Entities.Content.Workflow;
using DotNetNuke.Entities.Content.Workflow.Dto;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Framework;
using DotNetNuke.Internal.SourceGenerators;
using DotNetNuke.Services.Exceptions;
Expand Down Expand Up @@ -149,5 +151,91 @@ public partial HttpResponseMessage Review(NotificationDTO postData)

return this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "unable to process notification");
}

[HttpPost]
[ValidateAntiForgeryToken]
public HttpResponseMessage CompleteState()
{
try
{
this.workflowEngine.CompleteState(this.BuildStateTransaction());
return this.Request.CreateResponse(HttpStatusCode.OK, new { Result = "success" });
}
catch (Exception exc)
{
Exceptions.LogException(exc);
}

return this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "unable to process notification");
}

[HttpPost]
[ValidateAntiForgeryToken]
public HttpResponseMessage DiscardState()
{
try
{
this.workflowEngine.DiscardState(this.BuildStateTransaction());
return this.Request.CreateResponse(HttpStatusCode.OK, new { Result = "success" });
}
catch (Exception exc)
{
Exceptions.LogException(exc);
}

return this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "unable to process notification");
}

[HttpPost]
[ValidateAntiForgeryToken]
public HttpResponseMessage CompleteWorkflow()
{
try
{
this.workflowEngine.CompleteWorkflow(this.BuildStateTransaction());
return this.Request.CreateResponse(HttpStatusCode.OK, new { Result = "success" });
}
catch (Exception exc)
{
Exceptions.LogException(exc);
}

return this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "unable to process notification");
}

[HttpPost]
[ValidateAntiForgeryToken]
public HttpResponseMessage DiscardWorkflow()
{
try
{
this.workflowEngine.DiscardWorkflow(this.BuildStateTransaction());
return this.Request.CreateResponse(HttpStatusCode.OK, new { Result = "success" });
}
catch (Exception exc)
{
Exceptions.LogException(exc);
}

return this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "unable to process notification");
}

private StateTransaction BuildStateTransaction()
{
var portalId = this.PortalSettings.PortalId;
var tabId = this.Request.FindTabId();
var currentPage = TabController.Instance.GetTab(tabId, portalId);
var contentItemId = currentPage.ContentItemId;
var contentController = Util.GetContentController();
var contentItem = contentController.GetContentItem(contentItemId);
var stateTransaction = new StateTransaction
{
ContentItemId = contentItem.ContentItemId,
CurrentStateId = contentItem.StateID,
Message = new StateTransactionMessage(),
UserId = this.UserInfo.UserID,
};
return stateTransaction;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ namespace DotNetNuke.Entities.Content.Workflow
public class WorkflowSecurity : ServiceLocator<IWorkflowSecurity, WorkflowSecurity>, IWorkflowSecurity
{
private const string ReviewPermissionKey = "REVIEW";
private const string ReviewPermissionCode = "SYSTEM_CONTENTWORKFLOWSTATE";
private const string ReviewPermissionCode = "SYSTEM_CONTENTWORKFLOWSTATE";
private const string ContentManagers = "Content Managers";
private readonly IUserController userController = UserController.Instance;
private readonly IWorkflowManager workflowManager = WorkflowManager.Instance;
private readonly IWorkflowStatePermissionsRepository statePermissionsRepository = WorkflowStatePermissionsRepository.Instance;
Expand All @@ -27,8 +28,9 @@ public bool HasStateReviewerPermission(PortalSettings settings, UserInfo user, i
{
var permissions = this.statePermissionsRepository.GetWorkflowStatePermissionByState(stateId);

return user.IsSuperUser ||
PortalSecurity.IsInRoles(user, settings, settings.AdministratorRoleName) ||
return user.IsSuperUser ||
PortalSecurity.IsInRoles(user, settings, settings.AdministratorRoleName) ||
PortalSecurity.IsInRoles(user, settings, ContentManagers) ||
PortalSecurity.IsInRoles(user, settings, PermissionController.BuildPermissions(permissions.ToList(), ReviewPermissionKey));
}

Expand Down
12 changes: 12 additions & 0 deletions Dnn.AdminExperience/EditBar/Dnn.EditBar.UI/Dnn.EditBar.UI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@
<Compile Include="HttpModules\EditBarModule.cs" />
<Compile Include="Items\AddExistingModuleMenu.cs" />
<Compile Include="Items\AddModuleMenu.cs" />
<Compile Include="Items\CompleteWorkflowMenu.cs" />
<Compile Include="Items\DiscardWorkflowMenu.cs" />
<Compile Include="Items\DiscardStateMenu.cs" />
<Compile Include="Items\CompleteStateMenu.cs" />
<Compile Include="Items\QuickAddModuleMenu.cs" />
<Compile Include="Items\ExitEditModeMenu.cs" />
<Compile Include="Items\PageSettingsMenu.cs" />
Expand Down Expand Up @@ -123,9 +127,17 @@
<None Include="editBar\css\SourceCodePro-Regular.ttf.woff" />
<None Include="editBar\css\SourceCodePro-Semibold.ttf" />
<None Include="editBar\css\SourceCodePro-Semibold.ttf.woff" />
<Content Include="editBar\css\CompleteWorkflow.css" />
<Content Include="editBar\css\DiscardWorkflow.css" />
<Content Include="editBar\css\DiscardState.css" />
<Content Include="editBar\css\CompleteState.css" />
<Content Include="editBar\css\QuickAddModule.css" />
<Content Include="editBar\css\theme.css" />
<Content Include="editBar\QuickAddModule.html" />
<Content Include="editBar\scripts\CompleteWorkflow.js" />
<Content Include="editBar\scripts\DiscardWorkflow.js" />
<Content Include="editBar\scripts\DiscardState.js" />
<Content Include="editBar\scripts\CompleteState.js" />
<Content Include="editBar\scripts\QuickAddModule.js" />
<Content Include="Module.build">
<SubType>Designer</SubType>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information

namespace Dnn.EditBar.UI.Items
{
using System;

using Dnn.EditBar.Library;
using Dnn.EditBar.Library.Items;
using DotNetNuke.Application;
using DotNetNuke.Entities.Content.Common;
using DotNetNuke.Entities.Content.Workflow;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Security.Permissions;
using DotNetNuke.Services.Personalization;

[Serializable]
public class CompleteStateMenu : BaseMenuItem
{
/// <inheritdoc/>
public override string Name { get; } = "CompleteState";

/// <inheritdoc/>
public override string Text => "Submit";

/// <inheritdoc/>
public override string CssClass => string.Empty;

/// <inheritdoc/>
public override string Template { get; } = string.Empty;

/// <inheritdoc/>
public override string Parent { get; } = Constants.LeftMenu;

/// <inheritdoc/>
public override string Loader { get; } = "CompleteState";

/// <inheritdoc/>
public override int Order { get; } = 77;

/// <inheritdoc/>
public override bool Visible()
{
var contentItem = Util.GetContentController().GetContentItem(TabController.CurrentPage.ContentItemId);
return Personalization.GetUserMode() == PortalSettings.Mode.Edit
&& DotNetNukeContext.Current.Application.SKU == "DNN" // IsPlatform
&& TabWorkflowSettings.Instance.IsWorkflowEnabled(PortalSettings.Current.PortalId) // workflow is enabled
&& ((WorkflowEngine.Instance.IsWorkflowOnDraft(contentItem) && PermissionProvider.Instance().CanAddContentToPage(TabController.CurrentPage))
|| (!WorkflowEngine.Instance.IsWorkflowCompleted(contentItem) && WorkflowSecurity.Instance.HasStateReviewerPermission(contentItem.StateID)));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information

namespace Dnn.EditBar.UI.Items
{
using System;

using Dnn.EditBar.Library;
using Dnn.EditBar.Library.Items;
using DotNetNuke.Application;
using DotNetNuke.Entities.Content.Common;
using DotNetNuke.Entities.Content.Workflow;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Services.Personalization;

[Serializable]
public class CompleteWorkflowMenu : BaseMenuItem
{
/// <inheritdoc/>
public override string Name { get; } = "CompleteWorkflow";

/// <inheritdoc/>
public override string Text => "Approve";

/// <inheritdoc/>
public override string CssClass => string.Empty;

/// <inheritdoc/>
public override string Template { get; } = string.Empty;

/// <inheritdoc/>
public override string Parent { get; } = Constants.LeftMenu;

/// <inheritdoc/>
public override string Loader { get; } = "CompleteWorkflow";

/// <inheritdoc/>
public override int Order { get; } = 79;

/// <inheritdoc/>
public override bool Visible()
{
var contentItem = Util.GetContentController().GetContentItem(TabController.CurrentPage.ContentItemId);
return Personalization.GetUserMode() == PortalSettings.Mode.Edit
&& DotNetNukeContext.Current.Application.SKU == "DNN" // IsPlatform
&& TabWorkflowSettings.Instance.IsWorkflowEnabled(PortalSettings.Current.PortalId) // workflow is enabled
&& !WorkflowEngine.Instance.IsWorkflowCompleted(contentItem) // tab has new version that is not published
&& WorkflowSecurity.Instance.HasStateReviewerPermission(contentItem.StateID); // user has workflow approval permission
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information

namespace Dnn.EditBar.UI.Items
{
using System;

using Dnn.EditBar.Library;
using Dnn.EditBar.Library.Items;
using DotNetNuke.Application;
using DotNetNuke.Entities.Content.Common;
using DotNetNuke.Entities.Content.Workflow;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Security.Permissions;
using DotNetNuke.Services.Personalization;

[Serializable]
public class DiscardStateMenu : BaseMenuItem
{
/// <inheritdoc/>
public override string Name { get; } = "DiscardState";

/// <inheritdoc/>
public override string Text => "Discard";

/// <inheritdoc/>
public override string CssClass => string.Empty;

/// <inheritdoc/>
public override string Template { get; } = string.Empty;

/// <inheritdoc/>
public override string Parent { get; } = Constants.LeftMenu;

/// <inheritdoc/>
public override string Loader { get; } = "DiscardState";

/// <inheritdoc/>
public override int Order { get; } = 78;

/// <inheritdoc/>
public override bool Visible()
{
var contentItem = Util.GetContentController().GetContentItem(TabController.CurrentPage.ContentItemId);
return Personalization.GetUserMode() == PortalSettings.Mode.Edit
&& DotNetNukeContext.Current.Application.SKU == "DNN" // IsPlatform
&& TabWorkflowSettings.Instance.IsWorkflowEnabled(PortalSettings.Current.PortalId) // workflow is enabled
&& ((WorkflowEngine.Instance.IsWorkflowOnDraft(contentItem) && PermissionProvider.Instance().CanAddContentToPage(TabController.CurrentPage))
|| (!WorkflowEngine.Instance.IsWorkflowCompleted(contentItem) && WorkflowSecurity.Instance.HasStateReviewerPermission(contentItem.StateID)));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information

namespace Dnn.EditBar.UI.Items
{
using System;

using Dnn.EditBar.Library;
using Dnn.EditBar.Library.Items;
using DotNetNuke.Application;
using DotNetNuke.Entities.Content.Common;
using DotNetNuke.Entities.Content.Workflow;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Security.Permissions;
using DotNetNuke.Services.Personalization;

[Serializable]
public class DiscardWorkflowMenu : BaseMenuItem
{
/// <inheritdoc/>
public override string Name { get; } = "DiscardWorkflow";

/// <inheritdoc/>
public override string Text => "Reject";

/// <inheritdoc/>
public override string CssClass => string.Empty;

/// <inheritdoc/>
public override string Template { get; } = string.Empty;

/// <inheritdoc/>
public override string Parent { get; } = Constants.LeftMenu;

/// <inheritdoc/>
public override string Loader { get; } = "DiscardWorkflow";

/// <inheritdoc/>
public override int Order { get; } = 80;

/// <inheritdoc/>
public override bool Visible()
{
var contentItem = Util.GetContentController().GetContentItem(TabController.CurrentPage.ContentItemId);
return Personalization.GetUserMode() == PortalSettings.Mode.Edit
&& DotNetNukeContext.Current.Application.SKU == "DNN" // IsPlatform
&& TabWorkflowSettings.Instance.IsWorkflowEnabled(PortalSettings.Current.PortalId) // workflow is enabled
&& !WorkflowEngine.Instance.IsWorkflowCompleted(contentItem) // tab has new version that is not published
&& WorkflowSecurity.Instance.HasStateReviewerPermission(contentItem.StateID); // user has workflow approval permission
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#menu-CompleteState button {
width: auto;
-ms-border-radius: 3px;
border-radius: 3px;
background-color: transparent;
border-style: solid;
border-width: 1px;
text-indent: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#menu-CompleteWorkflow button {
width: auto;
-ms-border-radius: 3px;
border-radius: 3px;
background-color: transparent;
border-style: solid;
border-width: 1px;
text-indent: 0;
}
Loading

0 comments on commit 471a211

Please sign in to comment.