File: D:/HostingSpaces/RMourik/bassol.nl/wwwroot/CMSModules/Automation/Controls/AutomationMenu.ascx.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using CMS.Automation;
using CMS.Helpers;
using CMS.Base;
using CMS.WorkflowEngine;
using CMS.ExtendedControls.ActionsConfig;
using CMS.Controls;
using CMS.ExtendedControls;
using CMS.WorkflowEngine.Definitions;
using CMS.Membership;
using CMS.FormControls;
using CMS.DataEngine;
public partial class CMSModules_Automation_Controls_AutomationMenu : BaseEditMenu
{
#region "Variables"
// Actions
protected NextStepAction next = null;
protected PreviousStepAction previous = null;
protected HeaderAction delete = null;
protected HeaderAction start = null;
protected NextStepAction specific = null;
private WorkflowStepInfo mStep;
private CMSAutomationManager mAutomationManager;
private bool? mAllowSave;
private string originalClientId;
#endregion
#region "Public properties"
/// <summary>
/// Menu control
/// </summary>
public override HeaderActions HeaderActions
{
get
{
return menu;
}
}
/// <summary>
/// Indicates if Save action is allowed.
/// </summary>
public override bool AllowSave
{
get
{
if (mAllowSave == null)
{
return AutomationManager.AllowSave;
}
return mAllowSave.Value;
}
set
{
mAllowSave = value;
}
}
/// <summary>
/// Indicates if the menu is enabled
/// </summary>
public override bool Enabled
{
get
{
return menu.Enabled;
}
set
{
menu.Enabled = value;
}
}
/// <summary>
/// Object instance
/// </summary>
public BaseInfo InfoObject
{
get
{
return AutomationManager.InfoObject;
}
}
/// <summary>
/// State object
/// </summary>
public AutomationStateInfo StateObject
{
get
{
return AutomationManager.StateObject;
}
}
/// <summary>
/// Automation manager
/// </summary>
public AutomationManager Manager
{
get
{
return AutomationManager.Manager;
}
}
/// <summary>
/// Automation manager control
/// </summary>
public CMSAutomationManager AutomationManager
{
get
{
if (mAutomationManager == null)
{
mAutomationManager = ControlsHelper.GetChildControl(Page, typeof(CMSAutomationManager)) as CMSAutomationManager;
if (mAutomationManager == null)
{
throw new Exception("[AutomationMenu.AutomationManager]: Missing automation manager.");
}
}
return mAutomationManager;
}
}
/// <summary>
/// If true, the access permissions to the items are checked.
/// </summary>
public override bool CheckPermissions
{
get
{
return AutomationManager.CheckPermissions;
}
set
{
AutomationManager.CheckPermissions = value;
}
}
/// <summary>
/// Indicates if the control should perform the operations.
/// </summary>
public override bool StopProcessing
{
get
{
return AutomationManager.StopProcessing;
}
set
{
AutomationManager.StopProcessing = value;
}
}
/// <summary>
/// Current step
/// </summary>
protected WorkflowStepInfo Step
{
get
{
return mStep ?? (mStep = AutomationManager.Step);
}
}
#endregion
#region "Constructors"
/// <summary>
/// Constructor
/// </summary>
public CMSModules_Automation_Controls_AutomationMenu()
{
RefreshInterval = 500;
}
#endregion
#region "Page events"
protected override void OnInit(EventArgs e)
{
// Store client ID before replaced by short ID (original ID is needed when sending AJAX request to identify the control)
originalClientId = ClientID;
var parameters = Request.Form["params"];
if (parameters != null)
{
if (parameters.StartsWith(CALLBACK_ID + originalClientId))
{
string[] args = parameters.Split(new[] { CALLBACK_SEP }, StringSplitOptions.None);
AutomationManager.Mode = FormModeEnum.Update;
AutomationManager.ClearObject();
AutomationManager.ObjectType = ValidationHelper.GetString(args[1], null);
AutomationManager.ObjectID = ValidationHelper.GetInteger(args[2], 0);
Response.Clear();
if (Step != null)
{
Response.Write(CALLBACK_ID + AutomationManager.GetAutomationInfo() + CALLBACK_SEP + AutomationManager.RefreshActionContent.ToString().ToLowerCSafe() + CALLBACK_SEP + Step.StepID);
}
else
{
Response.Write(CALLBACK_ID + AutomationManager.GetAutomationInfo() + CALLBACK_SEP + "false" + CALLBACK_SEP + "0");
}
Response.End();
return;
}
}
base.OnInit(e);
// Perform full post-back if not in update panel
menu.PerformFullPostBack = !ControlsHelper.IsInUpdatePanel(this);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
ReloadMenu();
// Display information
AutomationManager.ShowAutomationInfo();
// Hide menu if no actions
plcMenu.Visible = menu.HasAnyVisibleAction() || !string.IsNullOrEmpty(pnlDoc.Label.Text) || lblInfo.Visible;
if (plcMenu.Visible)
{
RegisterActionScripts();
}
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
PostBackOptions opt = new PostBackOptions(this, null)
{
PerformValidation = false
};
Page.ClientScript.RegisterForEventValidation(opt);
}
/// <summary>
/// Registers action scripts
/// </summary>
private void RegisterActionScripts()
{
StringBuilder sb = new StringBuilder();
bool addComment = false;
sb.Append("function CheckConsistency_", ClientID, "() { ", AutomationManager.GetJSFunction("CONS", null, null), "; } \n");
if (next != null) { addComment = true; sb.Append("function MoveNext_", ClientID, "(stepId, comment) { ", next.OnClientClick, AutomationManager.GetJSFunction(next.EventName, "stepId", "comment"), "; } \n"); }
if (specific != null) { addComment = true; sb.Append("function MoveSpecific_", ClientID, "(stepId, comment) { ", specific.OnClientClick, AutomationManager.GetJSFunction(specific.EventName, "stepId", "comment"), "; } \n"); }
if (previous != null) { addComment = true; sb.Append("function MovePrevious_", ClientID, "(historyId, comment) { ", previous.OnClientClick, AutomationManager.GetJSFunction(previous.EventName, "historyId", "comment"), "; } \n"); }
if (addComment) { sb.Append("function AddComment_", ClientID, "(name, stateId, menuId) { ", AutomationManager.GetJSFunction(ComponentEvents.COMMENT, "name|stateId|menuId", null), "; } \n"); }
// Register the script
if (sb.Length > 0)
{
ControlsHelper.RegisterClientScriptBlock(this, Page, typeof(string), "AutoMenuActions" + ClientID, ScriptHelper.GetScript(sb.ToString()));
}
}
#endregion
#region "Methods"
private void ClearProperties()
{
// Clear actions
next = null;
specific = null;
previous = null;
delete = null;
start = null;
mStep = null;
// Clear security result
AutomationManager.ClearProperties();
}
private void ReloadMenu()
{
if (StopProcessing)
{
return;
}
// Handle several reloads
ClearProperties();
if (!HideStandardButtons)
{
// If content should be refreshed
if (AutomationManager.RefreshActionContent)
{
// Display action message
WorkflowActionInfo action = WorkflowActionInfoProvider.GetWorkflowActionInfo(Step.StepActionID);
string name = (action != null) ? action.ActionDisplayName : Step.StepDisplayName;
string str = (action != null) ? "workflow.actioninprogress" : "workflow.stepinprogress";
string text = string.Format(ResHelper.GetString(str, ResourceCulture), HTMLHelper.HTMLEncode(ResHelper.LocalizeString(name)));
text = ScriptHelper.GetLoaderInlineHtml(Page, text);
InformationText = text;
EnsureRefreshScript();
}
// Object update
if (AutomationManager.Mode == FormModeEnum.Update)
{
if (InfoObject != null)
{
// Get current process
WorkflowInfo process = AutomationManager.Process;
string objectName = HTMLHelper.HTMLEncode(InfoObject.TypeInfo.GetNiceObjectTypeName().ToLowerCSafe());
// Next step action
if (AutomationManager.IsActionAllowed(ComponentEvents.AUTOMATION_MOVE_NEXT))
{
next = new NextStepAction(Page)
{
Tooltip = string.Format(ResHelper.GetString("EditMenu.NextStep", ResourceCulture), objectName),
OnClientClick = RaiseGetClientValidationScript(ComponentEvents.AUTOMATION_MOVE_NEXT, null),
};
}
// Move to specific step action
if (AutomationManager.IsActionAllowed(ComponentEvents.AUTOMATION_MOVE_SPEC))
{
var steps = WorkflowStepInfoProvider.GetWorkflowSteps()
.Where("StepWorkflowID = " + process.WorkflowID + " AND StepType <> " + (int)WorkflowStepTypeEnum.Start)
.OrderBy("StepDisplayName");
specific = new NextStepAction(Page)
{
Text = GetString("AutoMenu.SpecificStepIcon"),
Tooltip = string.Format(ResHelper.GetString("AutoMenu.SpecificStepMultiple", ResourceCulture), objectName),
CommandName = ComponentEvents.AUTOMATION_MOVE_SPEC,
EventName = ComponentEvents.AUTOMATION_MOVE_SPEC,
// Make action inactive
OnClientClick = null,
Inactive = true
};
foreach (var s in steps)
{
string stepName = HTMLHelper.HTMLEncode(ResHelper.LocalizeString(s.StepDisplayName));
NextStepAction spc = new NextStepAction(Page)
{
Text = string.Format(ResHelper.GetString("AutoMenu.SpecificStepTo", ResourceCulture), stepName),
Tooltip = string.Format(ResHelper.GetString("AutoMenu.SpecificStep", ResourceCulture), objectName),
CommandName = ComponentEvents.AUTOMATION_MOVE_SPEC,
EventName = ComponentEvents.AUTOMATION_MOVE_SPEC,
CommandArgument = s.StepID.ToString(),
OnClientClick = RaiseGetClientValidationScript(ComponentEvents.AUTOMATION_MOVE_SPEC, "if(!confirm(" + ScriptHelper.GetString(string.Format(ResHelper.GetString("autoMenu.MoveSpecificConfirmation"), objectName, ResHelper.LocalizeString(s.StepDisplayName))) + ")) { return false; }"),
};
// Process action appearance
ProcessAction(spc, Step, s);
// Add step
specific.AlternativeActions.Add(spc);
}
// Add comment
AddCommentAction(ComponentEvents.AUTOMATION_MOVE_SPEC, specific, objectName);
}
// Previous step action
if (AutomationManager.IsActionAllowed(ComponentEvents.AUTOMATION_MOVE_PREVIOUS))
{
var prevSteps = Manager.GetPreviousSteps(InfoObject, StateObject);
int prevStepsCount = prevSteps.Count;
if (prevStepsCount > 0)
{
previous = new PreviousStepAction(Page)
{
Tooltip = string.Format(ResHelper.GetString("EditMenu.PreviousStep", ResourceCulture), objectName),
OnClientClick = RaiseGetClientValidationScript(ComponentEvents.AUTOMATION_MOVE_PREVIOUS, null)
};
// For managers allow move to specified step
if (WorkflowStepInfoProvider.CanUserManageAutomationProcesses(MembershipContext.AuthenticatedUser, InfoObject.Generalized.ObjectSiteName))
{
if (prevStepsCount > 1)
{
foreach (var s in prevSteps)
{
previous.AlternativeActions.Add(new PreviousStepAction(Page)
{
Text = string.Format(ResHelper.GetString("EditMenu.PreviousStepTo", ResourceCulture), HTMLHelper.HTMLEncode(ResHelper.LocalizeString(s.StepDisplayName))),
Tooltip = string.Format(ResHelper.GetString("EditMenu.PreviousStep", ResourceCulture), objectName),
OnClientClick = RaiseGetClientValidationScript(ComponentEvents.AUTOMATION_MOVE_PREVIOUS, null),
CommandArgument = s.RelatedHistoryID.ToString()
});
}
}
}
// Add comment
AddCommentAction(ComponentEvents.AUTOMATION_MOVE_PREVIOUS, previous, objectName);
}
}
if (AutomationManager.IsActionAllowed(ComponentEvents.AUTOMATION_REMOVE))
{
delete = new HeaderAction
{
CommandName = ComponentEvents.AUTOMATION_REMOVE,
EventName = ComponentEvents.AUTOMATION_REMOVE,
Text = ResHelper.GetString("autoMenu.RemoveState", ResourceCulture),
Tooltip = string.Format(ResHelper.GetString("autoMenu.RemoveStateDesc", ResourceCulture), objectName),
OnClientClick = RaiseGetClientValidationScript(ComponentEvents.AUTOMATION_REMOVE, "if(!confirm(" + ScriptHelper.GetString(string.Format(ResHelper.GetString("autoMenu.RemoveStateConfirmation"), objectName)) + ")) { return false; }"),
ButtonStyle = ButtonStyle.Default
};
}
// Handle multiple next steps
if (next != null)
{
// Get next step info
List<WorkflowStepInfo> steps = AutomationManager.NextSteps;
int stepsCount = steps.Count;
if (stepsCount > 0)
{
var nextS = steps[0];
// Only one next step
if (stepsCount == 1)
{
if (nextS.StepIsFinished)
{
next.Text = ResHelper.GetString("EditMenu.IconFinish", ResourceCulture);
next.Tooltip = string.Format(ResHelper.GetString("EditMenu.Finish", ResourceCulture), objectName);
}
// Process action appearance
ProcessAction(next, Step, nextS);
}
// Multiple next steps
else
{
// Check if not all steps finish steps
if (steps.Exists(s => !s.StepIsFinished))
{
next.Tooltip = string.Format(ResHelper.GetString("EditMenu.NextStepMultiple", ResourceCulture), objectName);
}
else
{
next.Text = ResHelper.GetString("EditMenu.IconFinish", ResourceCulture);
next.Tooltip = string.Format(ResHelper.GetString("EditMenu.NextStepMultiple", ResourceCulture), objectName);
}
// Make action inactive
next.OnClientClick = null;
next.Inactive = true;
// Process action appearance
ProcessAction(next, Step, null);
string itemText = "EditMenu.NextStepTo";
string itemDesc = "EditMenu.NextStep";
foreach (var s in steps)
{
NextStepAction nxt = new NextStepAction(Page)
{
Text = string.Format(ResHelper.GetString(itemText, ResourceCulture), HTMLHelper.HTMLEncode(ResHelper.LocalizeString(s.StepDisplayName))),
Tooltip = string.Format(ResHelper.GetString(itemDesc, ResourceCulture), objectName),
OnClientClick = RaiseGetClientValidationScript(ComponentEvents.AUTOMATION_MOVE_NEXT, null),
CommandArgument = s.StepID.ToString()
};
if (s.StepIsFinished)
{
nxt.Text = string.Format(ResHelper.GetString("EditMenu.FinishTo", ResourceCulture), HTMLHelper.HTMLEncode(ResHelper.LocalizeString(s.StepDisplayName)));
nxt.Tooltip = string.Format(ResHelper.GetString("EditMenu.Finish", ResourceCulture), objectName);
}
// Process action appearance
ProcessAction(nxt, Step, s);
// Add step
next.AlternativeActions.Add(nxt);
}
}
// Add comment
AddCommentAction(ComponentEvents.AUTOMATION_MOVE_NEXT, next, objectName);
}
else
{
bool displayAction = false;
if (!Step.StepAllowBranch)
{
// Transition exists, but condition doesn't match
var transitions = Manager.GetStepTransitions(Step);
if (transitions.Count > 0)
{
WorkflowStepInfo s = WorkflowStepInfoProvider.GetWorkflowStepInfo(transitions[0].TransitionEndStepID);
// Finish text
if (s.StepIsFinished)
{
next.Text = ResHelper.GetString("EditMenu.IconFinish", ResourceCulture);
next.Tooltip = string.Format(ResHelper.GetString("EditMenu.Finish", ResourceCulture), objectName);
}
// Inform user
displayAction = true;
next.Enabled = false;
// Process action appearance
ProcessAction(next, Step, null);
}
}
if (!displayAction)
{
// There is not next step
next = null;
}
}
}
// Handle start button
if (AutomationManager.IsActionAllowed(ComponentEvents.AUTOMATION_START) && (process.WorkflowRecurrenceType != ProcessRecurrenceTypeEnum.NonRecurring))
{
start = new HeaderAction
{
CommandName = ComponentEvents.AUTOMATION_START,
EventName = ComponentEvents.AUTOMATION_START,
Text = ResHelper.GetString("autoMenu.StartState", ResourceCulture),
Tooltip = process.WorkflowEnabled ? ResHelper.GetString("autoMenu.StartStateDesc", ResourceCulture) : ResHelper.GetString("autoMenu.DisabledStateDesc", ResourceCulture),
CommandArgument = process.WorkflowID.ToString(),
Enabled = process.WorkflowEnabled,
OnClientClick = RaiseGetClientValidationScript(ComponentEvents.AUTOMATION_START, "if(!confirm(" + ScriptHelper.GetString(string.Format(ResHelper.GetString("autoMenu.startSameProcessConfirmation", ResourceCulture), objectName)) + ")) { return false; }"),
ButtonStyle = ButtonStyle.Default
};
}
}
}
}
// Add actions in correct order
menu.ActionsList.Clear();
AddAction(previous);
AddAction(next);
AddAction(specific);
AddAction(delete);
AddAction(start);
// Set the information text
if (!String.IsNullOrEmpty(InformationText))
{
lblInfo.Text = InformationText;
lblInfo.CssClass = "LeftAlign EditMenuInfo";
lblInfo.Visible = true;
}
}
private void EnsureRefreshScript()
{
PostBackOptions options = new PostBackOptions(this)
{
PerformValidation = false
};
string postback = ControlsHelper.GetPostBackEventReference(menu, options, false, true);
string externalRefreshScript = null;
if (!string.IsNullOrEmpty(OnClientStepChanged))
{
externalRefreshScript = string.Format("clearInterval(refTimerId_{0}); {1};", ClientID, OnClientStepChanged);
}
const string commonScript = @"
String.prototype.startsWith = function (str) { return (this.match('^' + str) == str); };
function VerifyData(incomingData) {
if (incomingData.startsWith('" + CALLBACK_ID + @"')) {
return incomingData.replace('" + CALLBACK_ID + @"', '');
}
else {
data = null;
}
return data;
}
";
ScriptHelper.RegisterStartupScript(Page, typeof(string), "refCommon", commonScript, true);
StringBuilder sb = new StringBuilder();
sb.Append(@"
var refTimerId_", ClientID, @" = 0;
function RfMenu_DoPostBack_", ClientID, @"() {", postback, @"}
function RfMenu_Succ_", ClientID, @"(data, textStatus, jqXHR) {
if(data != null) {
var hdn = document.getElementById('", hdnParam.ClientID, @"');
var args = data.split('", CALLBACK_SEP, @"');
var stop = (args[1] == 'false');
var stepId = args[2];
if(stop) {
clearInterval(refTimerId_", ClientID, @");
setTimeout('RfMenu_DoPostBack_", ClientID, "()', ", RefreshInterval, @");
}
else {
// Step changed
if(hdn.value != stepId) {
var lbl = document.getElementById('", AutomationManager.AutomationInfoLabel.ClientID, @"');
if(lbl != null) {
lbl.innerHTML = args[0];
}",
externalRefreshScript, @"
}
}
hdn.value = stepId;
}
else {
clearInterval(refTimerId_", ClientID, @");
setTimeout('RfMenu_DoPostBack_", ClientID, "()', ", RefreshInterval, @");
}
}
function RfMenu_Err_", ClientID, @"(jqXHR, textStatus, errorThrown) {
var err = '';
if ((errorThrown != undefined) && (errorThrown != null) && (errorThrown != '')) {
err = ' (' + errorThrown + ')';
clearInterval(refTimerId_", ClientID, @");
alert(err);
}
}
function RfMenu_", ClientID, @"() {
$cmsj.ajax({
cache: false,
type: 'POST',
data: 'params=", CALLBACK_ID + originalClientId, CALLBACK_SEP, AutomationManager.ObjectType, CALLBACK_SEP, AutomationManager.ObjectID, CALLBACK_SEP, @"',
context: document.body,
success: RfMenu_Succ_" + ClientID, @",
error: RfMenu_Err_", ClientID, @",
dataType: 'text',
dataFilter: VerifyData
});
}
refTimerId_", ClientID, @" = setInterval('RfMenu_", ClientID, "()', 200);");
ScriptHelper.RegisterStartupScript(Page, typeof(string), "ref_" + ClientID, sb.ToString(), true);
}
private void ProcessAction(HeaderAction action, WorkflowStepInfo currentStep, WorkflowStepInfo nextStep)
{
if (action == null)
{
return;
}
string nextStepName = null;
SourcePoint def = null;
if (nextStep != null)
{
WorkflowTransitionInfo transition = nextStep.RelatedTransition;
if (transition != null)
{
def = currentStep.GetSourcePoint(transition.TransitionSourcePointGUID);
nextStepName = HTMLHelper.HTMLEncode(ResHelper.LocalizeString(nextStep.StepDisplayName));
}
}
else
{
def = currentStep.StepDefinition.DefinitionPoint;
}
if (def != null)
{
if (!string.IsNullOrEmpty(def.Text))
{
action.Text = string.Format(HTMLHelper.HTMLEncode(ResHelper.LocalizeString(def.Text)), nextStepName);
}
if (!string.IsNullOrEmpty(def.Tooltip))
{
action.Tooltip = string.Format(ResHelper.LocalizeString(def.Tooltip), action.Text);
}
}
}
/// <summary>
/// Adds menu action.
/// </summary>
/// <param name="action">Action</param>
protected void AddAction(HeaderAction action)
{
if (action != null)
{
// Action
menu.ActionsList.Add(action);
}
}
/// <summary>
/// Adds comment action.
/// </summary>
/// <param name="name">Action name</param>
/// <param name="action">Current action</param>
/// <param name="objectName">Object name</param>
private void AddCommentAction(string name, HeaderAction action, string objectName)
{
AutomationManager.RenderScript = true;
CommentAction comment = new CommentAction(Page, name)
{
Tooltip = string.Format(ResHelper.GetString("EditMenu.Comment" + name, ResourceCulture), objectName),
OnClientClick = string.Format("AddComment_{0}('{1}',{2},'{0}');", ClientID, name, StateObject.StateID),
};
action.AlternativeActions.Add(comment);
}
#endregion
}