In Sitecore 8.1 why do my users need to click edit on an item before they can approve/reject it?

I'm using the sample workflow in 8.1 (rev. 160519) and users need to click the edit button before they can approve/reject changes. We don't have this issue in any other versions of Sitecore and the user is still able to approve from the workbox without having edited it first. Is there a setting somewhere that needs to be changed so that my users can just approve an item without first having to lock it?

  • In reply to Brian Heward:

    This was super helpful! Wondering if anyone also fixed that in the "gutter" workflow actions? In search of where that lives now. Thanks!
  • In reply to Michael Pontin:

    Michael,
    Any ideas on how to change this behavior for the submit and approve button in the left gutter?
    Thanks,
    David
  • In reply to Michael Pontin:

    i am having the same issue in 8.2 update 5 and i am not sure how to resolve it , is there any patch or details on how to that you can share
  • In reply to nour arab:

    I'm not sure if 8.2 changed this class, but the code I'm using is the following:

    namespace Sitecore.Shell.Applications.ContentManager.Panels
    {
        using Sitecore;
        using Sitecore.Configuration;
        using Sitecore.Data.Items;
        using Sitecore.Diagnostics;
        using Sitecore.Globalization;
        using Sitecore.Security.AccessControl;
        using Sitecore.Shell.Framework.CommandBuilders;
        using Sitecore.Shell.Framework.Commands;
        using Sitecore.Shell.Web.UI.WebControls;
        using Sitecore.Web.UI.WebControls.Ribbons;
        using Sitecore.Workflows;
        using System.Web.UI;
    
        public class WorkflowPanel : RibbonPanel
        {
            private Item checkInItem;
    
            public static bool CanShowCommands(Item item, WorkflowCommand[] commands)
            {
                Assert.ArgumentNotNull(item, "item");
                if ((item.Appearance.ReadOnly || (commands == null)) || (commands.Length <= 0))
                {
                    return false;
                }
                if (!Context.IsAdministrator && (!item.Access.CanWriteLanguage() || (!item.Locking.CanLock() && !item.Locking.HasLock())))
                {
                    return false;
                }
                return true;
            }
    
            private Item GetCheckInItem()
            {
                if (this.checkInItem == null)
                {
                    this.checkInItem = Context.Database.Items["/sitecore/system/Settings/Workflow/Check In"];
                }
                return this.checkInItem;
            }
    
            private static void GetCommands(Item[] items, out IWorkflow workflow, out WorkflowCommand[] commands)
            {
                Assert.ArgumentNotNull(items, "items");
                Item item = items[0];
                if (item != null)
                {
                    IWorkflowProvider workflowProvider = Context.ContentDatabase.WorkflowProvider;
                    if ((workflowProvider != null) && (workflowProvider.GetWorkflows().Length > 0))
                    {
                        workflow = workflowProvider.GetWorkflow(item);
                        if ((workflow != null) && (workflow.GetState(item) != null))
                        {
                            commands = WorkflowFilterer.FilterVisibleCommands(workflow.GetCommands(item), item);
                            return;
                        }
                    }
                }
                workflow = null;
                commands = null;
            }
    
            private static string GetText(Item[] items)
            {
                Assert.ArgumentNotNull(items, "items");
                if ((items.Length <= 0) || (items.Length != 1))
                {
                    return string.Empty;
                }
                Item entity = items[0];
                if (entity.Appearance.ReadOnly)
                {
                    return string.Empty;
                }
                if (AuthorizationManager.IsAllowed(entity, AccessRight.ItemWrite, Context.User))
                {
                    if (entity.Locking.HasLock())
                    {
                        return Translate.Text("<b>You</b> have locked this item.");
                    }
                    if (entity.Locking.IsLocked())
                    {
                        return Translate.Text("<b>\"{0}\"</b> has locked this item.", new object[] { StringUtil.GetString(new string[] { entity.Locking.GetOwnerWithoutDomain(), "?" }) });
                    }
                    if (entity.Locking.CanLock())
                    {
                        return Translate.Text("Click Edit to lock and edit this item.");
                    }
                    IWorkflow workflow = entity.State.GetWorkflow();
                    WorkflowState state = entity.State.GetWorkflowState();
                    if ((workflow == null) || (state == null))
                    {
                        return Translate.Text("You do not have permission to<br/>edit the content of this item.");
                    }
                    if (state.FinalState)
                    {
                        return Translate.Text("This item has been approved.");
                    }
                    return Translate.Text("The item is in the <b>{0}</b> state<br/>in the <b>{1}</b> workflow.", new object[] { StringUtil.GetString(new string[] { state.DisplayName, "?" }), StringUtil.GetString(new string[] { workflow.Appearance.DisplayName, "?" }) });
                }
                if (entity.Access.CanWrite())
                {
                    return Translate.Text("Click Edit to lock and edit this item.");
                }
                IWorkflow workflow2 = entity.State.GetWorkflow();
                WorkflowState workflowState = entity.State.GetWorkflowState();
                if ((workflow2 == null) || (workflowState == null))
                {
                    return Translate.Text("You do not have permission to<br/>edit the content of this item.");
                }
                if (workflowState.FinalState)
                {
                    return Translate.Text("This item has been approved.");
                }
                return Translate.Text("The item is in the <b>{0}</b> state<br/>in the <b>{1}</b> workflow.", new object[] { StringUtil.GetString(new string[] { workflowState.DisplayName, "?" }), StringUtil.GetString(new string[] { workflow2.Appearance.DisplayName, "?" }) });
            }
    
            private bool IsCommandEnabled(string command, Item item)
            {
                Assert.ArgumentNotNullOrEmpty(command, "command");
                Assert.ArgumentNotNull(item, "item");
                CommandState state = CommandManager.QueryState(command, item);
                if (state != CommandState.Down)
                {
                    return (state == CommandState.Enabled);
                }
                return true;
            }
    
            public override void Render(HtmlTextWriter output, Ribbon ribbon, Item button, CommandContext context)
            {
                Assert.ArgumentNotNull(output, "output");
                Assert.ArgumentNotNull(ribbon, "ribbon");
                Assert.ArgumentNotNull(button, "button");
                Assert.ArgumentNotNull(context, "context");
                if (context.Items.Length >= 1)
                {
                    Item item = context.Items[0];
                    if (base.HasField(item, FieldIDs.Workflow) && Settings.Workflows.Enabled)
                    {
                        IWorkflow workflow;
                        WorkflowCommand[] commandArray;
                        GetCommands(context.Items, out workflow, out commandArray);
                        bool flag = this.IsCommandEnabled("item:checkout", item);
                        bool flag2 = CanShowCommands(item, commandArray);
                        bool flag3 = this.IsCommandEnabled("item:checkin", item);
                        bool flag4 = Context.User.IsAdministrator || item.Locking.HasLock();
                        base.RenderText(output, GetText(context.Items));
                        if (((workflow != null) || flag) || (flag2 || flag3))
                        {
                            Context.ClientPage.ClientResponse.DisableOutput();
                            ribbon.BeginSmallButtons(output);
                            if (flag)
                            {
                                base.RenderSmallButton(output, ribbon, string.Empty, Translate.Text("Edit"), "Office/24x24/edit_in_workflow.png", Translate.Text("Start editing this item."), "item:checkout", base.Enabled, false);
                            }
                            if (flag3)
                            {
                                Item checkInItem = this.GetCheckInItem();
                                if (checkInItem != null)
                                {
                                    base.RenderSmallButton(output, ribbon, string.Empty, checkInItem["Header"], checkInItem["Icon"], Translate.Text("Check this item in."), "item:checkin", base.Enabled, false);
                                }
                            }
                            if (workflow != null)
                            {
                                base.RenderSmallButton(output, ribbon, Sitecore.Web.UI.HtmlControls.Control.GetUniqueID("B"), Translate.Text("History"), "Office/16x16/history.png", Translate.Text("Show the workflow history."), "item:workflowhistory", base.Enabled, false);
                            }
                            if (flag2)
                            {
                                foreach (WorkflowCommand command in commandArray)
                                {
                                    base.RenderSmallButton(output, ribbon, string.Empty, command.DisplayName, command.Icon, command.DisplayName, new WorkflowCommandBuilder(item, workflow, command).ToString(), base.Enabled, false);
                                }
                            }
                            ribbon.EndSmallButtons(output);
                            Context.ClientPage.ClientResponse.EnableOutput();
                        }
                    }
                }
            }
        }
    }
    

  • We recently ran into this somewhat frustrating issue recently when we upgraded to 8.2.7 (from 7). I wrote a few quick extension methods to revert the ability to execute workflow commands from both the Workflow Panel in the ribbon as well as using the Gutters. I threw a generic version of it up on GitHub in case anyone runs into this issue in the future and wants a starting point to modify to their environment and business needs: github.com/.../WorkflowCommandsWithoutEditLock

  • I was able to return my custom workflow back to the previous behavior simply by configuring the workflow in a specific way and adding a super-simple custom workflow action (which does nothing but lock the item):

    Both of the items in my example named "Lock item" use my custom action. Basically, setting your workflow up this way locks the item for your user at each non-Final workflow state.

    NOTE: Depending on how your workflow works, you may not even need to use an __OnSave command item. If not, you can just put the custom action (of type /System/Workflow/Action) as a direct child of your workflow state (like my "In Review" example workflow state). If you DO need to create it, make sure its "Next state" field value is set to point to the same workflow state that it's a child of. Otherwise, it throws an error.

    Here's the custom workflow action class:

    namespace MyCustomNamespace
    {
    public class LockItem
    {
    public void Process(Sitecore.Workflows.Simple.WorkflowPipelineArgs args)
    {
    Sitecore.Data.Items.Item item = args.DataItem;
    if (item == null)
    return;

    item.Editing.BeginEdit();
    item.Locking.Lock();
    item.Editing.EndEdit();
    }
    }
    }
  • Please check user role(reviewer), also see security settings for this role under workflow.