mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-22 03:37:25 +08:00
Refactoring
--HG-- branch : 1.x extra : rebase_source : 0a3659f94fbdb3fab2185bdf26c7f9838bd4995b
This commit is contained in:
@@ -160,9 +160,9 @@ namespace Orchard.Core.Navigation.Drivers {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
menuShape.MenuName(menuName);
|
||||
menuShape.ContentItem(menu);
|
||||
|
||||
NavigationHelper.PopulateMenu(shapeHelper, menuShape, menuShape, menuItems);
|
||||
|
||||
return shapeHelper.Parts_MenuWidget(Menu: menuShape);
|
||||
|
@@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
using Orchard.Workflows.Models;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Workflows.Activities {
|
||||
@@ -14,15 +14,15 @@ namespace Orchard.Workflows.Activities {
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public override bool CanExecute(ActivityContext context) {
|
||||
public override bool CanExecute(WorkflowContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context) {
|
||||
return GetBranches(context).Select(x => T(x));
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext context) {
|
||||
return GetBranches(context).Select(x => T(x));
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Orchard.Workflows.Activities {
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetBranches(ActivityContext context) {
|
||||
private IEnumerable<string> GetBranches(WorkflowContext context) {
|
||||
if (context.State == null) {
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
using Orchard.Workflows.Models;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Workflows.Activities {
|
||||
@@ -15,7 +15,7 @@ namespace Orchard.Workflows.Activities {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanExecute(ActivityContext context) {
|
||||
public override bool CanExecute(WorkflowContext context) {
|
||||
try {
|
||||
|
||||
string contentTypesState = context.State.ContentTypes;
|
||||
@@ -40,11 +40,11 @@ namespace Orchard.Workflows.Activities {
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context) {
|
||||
return new[] { T("Done") };
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext context) {
|
||||
yield return T("Done");
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
using Orchard.Workflows.Models;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Workflows.Activities {
|
||||
@@ -24,11 +24,11 @@ namespace Orchard.Workflows.Activities {
|
||||
get { return T("Evaluates an expression."); }
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context) {
|
||||
return new[] { T("True"), T("False") };
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext context) {
|
||||
yield return T("True");
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
using Orchard.Workflows.Models;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Workflows.Activities {
|
||||
@@ -33,15 +33,15 @@ namespace Orchard.Workflows.Activities {
|
||||
get { return "SelectRoles"; }
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context) {
|
||||
return new[] {T("Yes"), T("No")};
|
||||
}
|
||||
|
||||
public override bool CanExecute(ActivityContext context) {
|
||||
public override bool CanExecute(WorkflowContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext context) {
|
||||
|
||||
if (UserIsInRole(context)) {
|
||||
yield return T("Yes");
|
||||
@@ -50,7 +50,7 @@ namespace Orchard.Workflows.Activities {
|
||||
yield return T("No");
|
||||
}
|
||||
|
||||
private bool UserIsInRole(ActivityContext context) {
|
||||
private bool UserIsInRole(WorkflowContext context) {
|
||||
|
||||
// checking if user is in an accepted role
|
||||
var workContext = _workContextAccessor.GetContext();
|
||||
@@ -78,7 +78,7 @@ namespace Orchard.Workflows.Activities {
|
||||
return isInRole;
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetRoles(ActivityContext context) {
|
||||
private IEnumerable<string> GetRoles(WorkflowContext context) {
|
||||
if (context.State == null) {
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ using Orchard.Messaging.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
using Orchard.Workflows.Models;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Workflows.Activities {
|
||||
@@ -31,7 +31,7 @@ namespace Orchard.Workflows.Activities {
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context) {
|
||||
return new[] { T("Sent") };
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Orchard.Workflows.Activities {
|
||||
get { return T("Sends an e-mail to a specific user."); }
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext context) {
|
||||
string recipient = context.State.Recipient;
|
||||
|
||||
var properties = new Dictionary<string, string> {
|
||||
|
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Tokens;
|
||||
using Orchard.UI.Notify;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
using Orchard.Workflows.Models;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Workflows.Activities {
|
||||
@@ -35,11 +35,11 @@ namespace Orchard.Workflows.Activities {
|
||||
get { return "ActivityNotify"; }
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context) {
|
||||
yield return T("Done");
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext context) {
|
||||
string notification = context.State.Notification;
|
||||
string message = context.State.Message;
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
using Orchard.Workflows.Models;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Workflows.Activities {
|
||||
@@ -14,15 +14,15 @@ namespace Orchard.Workflows.Activities {
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public override bool CanExecute(ActivityContext context) {
|
||||
public override bool CanExecute(WorkflowContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context) {
|
||||
return new[] { T("Published") };
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext context) {
|
||||
_contentManager.Publish(context.Content.ContentItem);
|
||||
yield return T("Published");
|
||||
}
|
||||
|
@@ -8,19 +8,14 @@ using Orchard.Localization;
|
||||
using Orchard.Services;
|
||||
using Orchard.Tasks;
|
||||
using Orchard.Workflows.Models;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Workflows.Activities {
|
||||
public class TimerActivity : Event {
|
||||
private readonly IClock _clock;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
|
||||
public TimerActivity(
|
||||
IClock clock,
|
||||
IWorkContextAccessor workContextAccessor) {
|
||||
public TimerActivity(IClock clock) {
|
||||
_clock = clock;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
@@ -42,26 +37,26 @@ namespace Orchard.Workflows.Activities {
|
||||
get { return "ActivityTimer"; }
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context) {
|
||||
yield return T("Done");
|
||||
}
|
||||
|
||||
public override bool CanExecute(ActivityContext context) {
|
||||
public override bool CanExecute(WorkflowContext context) {
|
||||
|
||||
return _clock.UtcNow > When(context);
|
||||
}
|
||||
|
||||
public override void Touch(dynamic workflowState) {
|
||||
workflowState.TimerActivity_StartedUtc = _clock.UtcNow;
|
||||
public override void OnWorkflowStarted(WorkflowContext context) {
|
||||
context.WorkflowState.TimerActivity_StartedUtc = _clock.UtcNow;
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext context) {
|
||||
if(_clock.UtcNow > When(context)) {
|
||||
yield return T("Done");
|
||||
}
|
||||
}
|
||||
|
||||
public static DateTime When(ActivityContext context) {
|
||||
public static DateTime When(WorkflowContext context) {
|
||||
try {
|
||||
int amount = context.State.Amount;
|
||||
string type = context.State.Unity;
|
||||
@@ -122,10 +117,10 @@ namespace Orchard.Workflows.Activities {
|
||||
var contentItem = _contentManager.Get(x.ContentItemRecord.Id, VersionOptions.Latest);
|
||||
var state = FormParametersHelper.FromJsonString(x.ActivityRecord.State);
|
||||
var workflowState = FormParametersHelper.FromJsonString(x.WorkflowRecord.State);
|
||||
return _clock.UtcNow > TimerActivity.When(new ActivityContext {
|
||||
return _clock.UtcNow > TimerActivity.When(new WorkflowContext {
|
||||
State = state,
|
||||
WorkflowState = workflowState,
|
||||
Content = contentItem
|
||||
Content = contentItem,
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
using Orchard.Workflows.Models;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Workflows.Activities {
|
||||
@@ -33,24 +33,24 @@ namespace Orchard.Workflows.Activities {
|
||||
get { return "ActivityUserTask"; }
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context) {
|
||||
foreach (var action in GetActions(context)) {
|
||||
yield return T(action);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanExecute(ActivityContext context) {
|
||||
public override bool CanExecute(WorkflowContext context) {
|
||||
return ActionIsValid(context) && UserIsInRole(context);
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(ActivityContext context) {
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext context) {
|
||||
|
||||
if (ActionIsValid(context) && UserIsInRole(context)) {
|
||||
yield return T(context.Tokens["UserTask.Action"].ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private bool UserIsInRole(ActivityContext context) {
|
||||
private bool UserIsInRole(WorkflowContext context) {
|
||||
|
||||
// checking if user is in an accepted role
|
||||
var workContext = _workContextAccessor.GetContext();
|
||||
@@ -78,7 +78,7 @@ namespace Orchard.Workflows.Activities {
|
||||
return isInRole;
|
||||
}
|
||||
|
||||
private bool ActionIsValid(ActivityContext context) {
|
||||
private bool ActionIsValid(WorkflowContext context) {
|
||||
|
||||
// checking if user has triggered an accepted action
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace Orchard.Workflows.Activities {
|
||||
return isValidAction;
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetRoles(ActivityContext context) {
|
||||
private IEnumerable<string> GetRoles(WorkflowContext context) {
|
||||
if (context.State == null) {
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
@@ -105,7 +105,7 @@ namespace Orchard.Workflows.Activities {
|
||||
return roles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList();
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetActions(ActivityContext context) {
|
||||
private IEnumerable<string> GetActions(WorkflowContext context) {
|
||||
|
||||
if (context.State == null) {
|
||||
return Enumerable.Empty<string>();
|
||||
|
@@ -0,0 +1,6 @@
|
||||
namespace Orchard.Workflows.Models {
|
||||
public enum ActivityState {
|
||||
Excuted,
|
||||
Executing
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
namespace Orchard.Workflows.Models {
|
||||
public class CancellationToken {
|
||||
public void Cancel() {
|
||||
IsCancelled = true;
|
||||
}
|
||||
|
||||
public bool IsCancelled { get; private set; }
|
||||
}
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Workflows.Models.Descriptors {
|
||||
public class ActivityContext {
|
||||
public ActivityContext() {
|
||||
Tokens = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If set, represents the subject of the current workflow
|
||||
/// </summary>
|
||||
public IContent Content { get; set; }
|
||||
|
||||
public IDictionary<string, object> Tokens { get; set; }
|
||||
public dynamic State { get; set; }
|
||||
public dynamic WorkflowState { get; set; }
|
||||
}
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
using System;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Workflows.Models.Descriptors {
|
||||
public class ActivityDescriptor {
|
||||
public string Category { get; set; }
|
||||
public string Type { get; set; }
|
||||
public LocalizedString Name { get; set; }
|
||||
public LocalizedString Description { get; set; }
|
||||
public Func<ActivityContext, bool> Action { get; set; }
|
||||
public string Form { get; set; }
|
||||
public Func<ActivityContext, LocalizedString> Display { get; set; }
|
||||
}
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Workflows.Models.Descriptors {
|
||||
public class DescribeActivityContext {
|
||||
private readonly Dictionary<string, DescribeActivityFor> _describes = new Dictionary<string, DescribeActivityFor>();
|
||||
|
||||
public IEnumerable<TypeDescriptor<ActivityDescriptor>> Describe() {
|
||||
return _describes.Select(kp => new TypeDescriptor<ActivityDescriptor> {
|
||||
Category = kp.Key,
|
||||
Name = kp.Value.Name,
|
||||
Description = kp.Value.Description,
|
||||
Descriptors = kp.Value.Types
|
||||
});
|
||||
}
|
||||
|
||||
public DescribeActivityFor For(string category) {
|
||||
return For(category, null, null);
|
||||
}
|
||||
|
||||
public DescribeActivityFor For(string category, LocalizedString name, LocalizedString description) {
|
||||
DescribeActivityFor describeFor;
|
||||
if (!_describes.TryGetValue(category, out describeFor)) {
|
||||
describeFor = new DescribeActivityFor(category, name, description);
|
||||
_describes[category] = describeFor;
|
||||
}
|
||||
return describeFor;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Workflows.Models.Descriptors {
|
||||
public class DescribeActivityFor {
|
||||
private readonly string _category;
|
||||
|
||||
public DescribeActivityFor(string category, LocalizedString name, LocalizedString description) {
|
||||
Types = new List<ActivityDescriptor>();
|
||||
_category = category;
|
||||
Name = name;
|
||||
Description = description;
|
||||
}
|
||||
|
||||
public LocalizedString Name { get; private set; }
|
||||
public LocalizedString Description { get; private set; }
|
||||
public List<ActivityDescriptor> Types { get; private set; }
|
||||
|
||||
public DescribeActivityFor Element(string type, LocalizedString name, LocalizedString description, Func<ActivityContext, bool> action, Func<ActivityContext, LocalizedString> display, string form = null) {
|
||||
Types.Add(new ActivityDescriptor { Type = type, Name = name, Description = description, Category = _category, Action = action, Display = display, Form = form });
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Workflows.Models.Descriptors {
|
||||
public class TypeDescriptor<T> {
|
||||
public string Category { get; set; }
|
||||
public LocalizedString Name { get; set; }
|
||||
public LocalizedString Description { get; set; }
|
||||
public IEnumerable<T> Descriptors { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Workflows.Models {
|
||||
public class WorkflowContext {
|
||||
public WorkflowContext() {
|
||||
Tokens = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If set, represents the subject of the current workflow
|
||||
/// </summary>
|
||||
public IContent Content { get; set; }
|
||||
|
||||
public IDictionary<string, object> Tokens { get; set; }
|
||||
public dynamic State { get; set; }
|
||||
public dynamic WorkflowState { get; set; }
|
||||
|
||||
public IActivity Activity { get; set; }
|
||||
public ActivityRecord Record { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Schedules a specific
|
||||
/// </summary>
|
||||
public Action<ActivityRecord> Schedule { get; set; }
|
||||
public IEnumerable<TransitionRecord> GetInboundTransitions(ActivityRecord activityRecord) {
|
||||
return Record.WorkflowDefinitionRecord
|
||||
.TransitionRecords
|
||||
.Where(transition =>
|
||||
transition.DestinationActivityRecord == activityRecord
|
||||
).ToArray();
|
||||
}
|
||||
|
||||
public IEnumerable<TransitionRecord> GetOutboundTransitions(ActivityRecord activityRecord) {
|
||||
return Record.WorkflowDefinitionRecord
|
||||
.TransitionRecords
|
||||
.Where(transition =>
|
||||
transition.SourceActivityRecord == activityRecord
|
||||
).ToArray();
|
||||
}
|
||||
|
||||
public IEnumerable<TransitionRecord> GetOutboundTransitions(ActivityRecord activityRecord, LocalizedString outcome) {
|
||||
return Record.WorkflowDefinitionRecord
|
||||
.TransitionRecords
|
||||
.Where(transition =>
|
||||
transition.SourceActivityRecord == activityRecord
|
||||
&& transition.SourceEndpoint == outcome.TextHint
|
||||
).ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -133,14 +133,12 @@
|
||||
<Compile Include="Drivers\WorkflowDriver.cs" />
|
||||
<Compile Include="Handlers\ContentHandler.cs" />
|
||||
<Compile Include="Handlers\WorkflowHandler.cs" />
|
||||
<Compile Include="Models\ActivityState.cs" />
|
||||
<Compile Include="Models\AwaitingActivityRecord.cs" />
|
||||
<Compile Include="Models\Descriptors\ActivityContext.cs" />
|
||||
<Compile Include="Models\Descriptors\ActivityDescriptor.cs" />
|
||||
<Compile Include="Models\Descriptors\DescribeActivityContext.cs" />
|
||||
<Compile Include="Models\Descriptors\DescribeActivityFor.cs" />
|
||||
<Compile Include="Models\CancellationToken.cs" />
|
||||
<Compile Include="Models\WorkflowContext.cs" />
|
||||
<Compile Include="Models\ActivityRecord.cs" />
|
||||
<Compile Include="Models\TransitionRecord.cs" />
|
||||
<Compile Include="Models\Descriptors\TypeDescriptor.cs" />
|
||||
<Compile Include="Models\WorkflowRecord.cs" />
|
||||
<Compile Include="Migrations.cs" />
|
||||
<Compile Include="Models\WorkflowDefinitionRecord.cs" />
|
||||
@@ -149,10 +147,9 @@
|
||||
<Compile Include="Forms\UserTaskForms.cs" />
|
||||
<Compile Include="Forms\NotificationActivityForms.cs" />
|
||||
<Compile Include="ResourceManifest.cs" />
|
||||
<Compile Include="Services\BaseActivity.cs" />
|
||||
<Compile Include="Services\BlockingActivity.cs" />
|
||||
<Compile Include="Services\Task.cs" />
|
||||
<Compile Include="Services\Event.cs" />
|
||||
<Compile Include="Services\IActivity.cs" />
|
||||
<Compile Include="Services\IActivityProvider.cs" />
|
||||
<Compile Include="Services\ActivitiesManager.cs" />
|
||||
<Compile Include="Services\IActivitiesManager.cs" />
|
||||
<Compile Include="Services\IWorkflowManager.cs" />
|
||||
|
@@ -1,35 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
|
||||
namespace Orchard.Workflows.Services {
|
||||
public abstract class Task : IActivity {
|
||||
|
||||
public abstract string Name { get; }
|
||||
public abstract LocalizedString Category { get; }
|
||||
public abstract LocalizedString Description { get; }
|
||||
|
||||
public virtual bool IsEvent {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool CanStartWorkflow { get { return false; } }
|
||||
|
||||
public virtual string Form {
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public abstract IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context);
|
||||
|
||||
public virtual bool CanExecute(ActivityContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract IEnumerable<LocalizedString> Execute(ActivityContext context);
|
||||
|
||||
public virtual void Touch(dynamic state) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
|
||||
namespace Orchard.Workflows.Services {
|
||||
public abstract class Event : IActivity {
|
||||
|
||||
public abstract string Name { get; }
|
||||
public abstract LocalizedString Category { get; }
|
||||
public abstract LocalizedString Description { get; }
|
||||
|
||||
public virtual bool IsEvent {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public virtual string Form {
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public virtual bool CanStartWorkflow {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public abstract IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context);
|
||||
|
||||
public virtual bool CanExecute(ActivityContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract IEnumerable<LocalizedString> Execute(ActivityContext context);
|
||||
|
||||
public virtual void Touch(dynamic workflowState) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
50
src/Orchard.Web/Modules/Orchard.Workflows/Services/Event.cs
Normal file
50
src/Orchard.Web/Modules/Orchard.Workflows/Services/Event.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Workflows.Models;
|
||||
|
||||
namespace Orchard.Workflows.Services {
|
||||
public abstract class Event : IActivity {
|
||||
|
||||
public abstract string Name { get; }
|
||||
public abstract LocalizedString Category { get; }
|
||||
public abstract LocalizedString Description { get; }
|
||||
|
||||
public virtual bool IsEvent {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public virtual string Form {
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public virtual bool CanStartWorkflow {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public abstract IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context);
|
||||
|
||||
public virtual bool CanExecute(WorkflowContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract IEnumerable<LocalizedString> Execute(WorkflowContext context);
|
||||
|
||||
public virtual void OnWorkflowStarting(WorkflowContext context, CancellationToken cancellationToken) {
|
||||
}
|
||||
|
||||
public virtual void OnWorkflowStarted(WorkflowContext context) {
|
||||
}
|
||||
|
||||
public virtual void OnWorkflowResuming(WorkflowContext context, CancellationToken cancellationToken) {
|
||||
}
|
||||
|
||||
public virtual void OnWorkflowResumed(WorkflowContext context) {
|
||||
}
|
||||
|
||||
public virtual void OnActivityExecuting(WorkflowContext context, CancellationToken cancellationToken) {
|
||||
}
|
||||
|
||||
public virtual void OnActivityExecuted(WorkflowContext context) {
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
using Orchard.Workflows.Models;
|
||||
|
||||
namespace Orchard.Workflows.Services {
|
||||
public interface IActivity : IDependency {
|
||||
@@ -15,23 +15,49 @@ namespace Orchard.Workflows.Services {
|
||||
/// <summary>
|
||||
/// List of possible outcomes when the activity is executed.
|
||||
/// </summary>
|
||||
IEnumerable<LocalizedString> GetPossibleOutcomes(ActivityContext context);
|
||||
IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the activity can transition to the next outcome. Can prevent the activity from being transitioned
|
||||
/// because a condition is not valid.
|
||||
/// </summary>
|
||||
bool CanExecute(ActivityContext context);
|
||||
bool CanExecute(WorkflowContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Executes the current activity
|
||||
/// </summary>
|
||||
/// <returns>The names of the resulting outcomes.</returns>
|
||||
IEnumerable<LocalizedString> Execute(ActivityContext context);
|
||||
IEnumerable<LocalizedString> Execute(WorkflowContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called on blocking activities when they are reached
|
||||
/// Called on each activity when a workflow is about to start
|
||||
/// </summary>
|
||||
void Touch(dynamic workflowState);
|
||||
void OnWorkflowStarting(WorkflowContext context, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Called on each activity when a workflow has started
|
||||
/// </summary>
|
||||
void OnWorkflowStarted(WorkflowContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called on each activity when a workflow is about to be resumed
|
||||
/// </summary>
|
||||
void OnWorkflowResuming(WorkflowContext context, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Called on each activity when a workflow is resumed
|
||||
/// </summary>
|
||||
void OnWorkflowResumed(WorkflowContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called on each activity when an activity is about to be executed
|
||||
/// </summary>
|
||||
void OnActivityExecuting(WorkflowContext context, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Called on each activity when an activity has been executed
|
||||
/// </summary>
|
||||
void OnActivityExecuted(WorkflowContext context);
|
||||
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
using Orchard.Events;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
|
||||
namespace Orchard.Workflows.Services {
|
||||
public interface IActivityProvider : IEventHandler {
|
||||
void Describe(DescribeActivityContext describe);
|
||||
}
|
||||
}
|
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Events;
|
||||
using Orchard.Workflows.Models;
|
||||
|
||||
namespace Orchard.Workflows.Services {
|
||||
public interface IWorkflowManager : IEventHandler {
|
||||
@@ -14,8 +13,6 @@ namespace Orchard.Workflows.Services {
|
||||
/// <param name="target">The <see cref="IContent"/> content item the event is related to</param>
|
||||
/// <param name="tokensContext">An object containing the tokens context</param>
|
||||
void TriggerEvent(string name, IContent target, Func<Dictionary<string, object>> tokensContext);
|
||||
|
||||
IEnumerable<ActivityRecord> ExecuteWorkflow(WorkflowDefinitionRecord workflowDefinitionRecord, ActivityRecord activityRecord, IContent target, Dictionary<string, object> tokens, dynamic workflowState);
|
||||
}
|
||||
|
||||
}
|
48
src/Orchard.Web/Modules/Orchard.Workflows/Services/Task.cs
Normal file
48
src/Orchard.Web/Modules/Orchard.Workflows/Services/Task.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Workflows.Models;
|
||||
|
||||
namespace Orchard.Workflows.Services {
|
||||
public abstract class Task : IActivity {
|
||||
|
||||
public abstract string Name { get; }
|
||||
public abstract LocalizedString Category { get; }
|
||||
public abstract LocalizedString Description { get; }
|
||||
|
||||
public virtual bool IsEvent {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool CanStartWorkflow { get { return false; } }
|
||||
|
||||
public virtual string Form {
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public abstract IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext context);
|
||||
|
||||
public virtual bool CanExecute(WorkflowContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract IEnumerable<LocalizedString> Execute(WorkflowContext context);
|
||||
|
||||
public virtual void OnWorkflowStarting(WorkflowContext context, CancellationToken cancellationToken) {
|
||||
}
|
||||
|
||||
public virtual void OnWorkflowStarted(WorkflowContext context) {
|
||||
}
|
||||
|
||||
public virtual void OnWorkflowResuming(WorkflowContext context, CancellationToken cancellationToken) {
|
||||
}
|
||||
|
||||
public virtual void OnWorkflowResumed(WorkflowContext context) {
|
||||
}
|
||||
|
||||
public virtual void OnActivityExecuting(WorkflowContext context, CancellationToken cancellationToken) {
|
||||
}
|
||||
|
||||
public virtual void OnActivityExecuted(WorkflowContext context) {
|
||||
}
|
||||
}
|
||||
}
|
@@ -10,7 +10,6 @@ using Orchard.Workflows.Models;
|
||||
using Orchard.Data;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Tokens;
|
||||
using Orchard.Workflows.Models.Descriptors;
|
||||
|
||||
namespace Orchard.Workflows.Services {
|
||||
public class WorkflowManager : IWorkflowManager {
|
||||
@@ -83,7 +82,12 @@ namespace Orchard.Workflows.Services {
|
||||
var serialized = String.IsNullOrEmpty(tokenized) ? "{}" : JsonConvert.SerializeXNode(XElement.Parse(tokenized));
|
||||
var state = FormParametersHelper.FromJsonString(serialized);
|
||||
var workflowState = FormParametersHelper.FromJsonString(a.WorkflowRecord.State);
|
||||
var context = new ActivityContext { Tokens = tokens, State = state.Root, WorkflowState = workflowState, Content = target };
|
||||
var context = new WorkflowContext {
|
||||
Tokens = tokens,
|
||||
State = state.Root,
|
||||
WorkflowState = workflowState,
|
||||
Content = target,
|
||||
};
|
||||
|
||||
// check the condition
|
||||
try {
|
||||
@@ -102,7 +106,12 @@ namespace Orchard.Workflows.Services {
|
||||
var serialized = String.IsNullOrEmpty(tokenized) ? "{}" : JsonConvert.SerializeXNode(XElement.Parse(tokenized));
|
||||
var state = FormParametersHelper.FromJsonString(serialized);
|
||||
var workflowState = FormParametersHelper.FromJsonString("{}");
|
||||
var context = new ActivityContext { Tokens = tokens, State = state.Root, WorkflowState = workflowState, Content = target };
|
||||
var context = new WorkflowContext {
|
||||
Tokens = tokens,
|
||||
State = state.Root,
|
||||
WorkflowState = workflowState,
|
||||
Content = target,
|
||||
};
|
||||
|
||||
// check the condition
|
||||
try {
|
||||
@@ -125,29 +134,59 @@ namespace Orchard.Workflows.Services {
|
||||
.ToList();
|
||||
|
||||
// resume halted workflows
|
||||
foreach (var a in awaitingActivities) {
|
||||
ResumeWorkflow(a, target, tokens);
|
||||
foreach (var awaitingActivityRecord in awaitingActivities) {
|
||||
var context = new WorkflowContext {
|
||||
Activity = _activitiesManager.GetActivityByName(awaitingActivityRecord.ActivityRecord.Name),
|
||||
Content = target,
|
||||
Record = awaitingActivityRecord.ActivityRecord,
|
||||
Tokens = tokens,
|
||||
State = FormParametersHelper.FromJsonString(awaitingActivityRecord.ActivityRecord.State),
|
||||
WorkflowState = FormParametersHelper.FromJsonString(awaitingActivityRecord.WorkflowRecord.State)
|
||||
};
|
||||
|
||||
ResumeWorkflow(awaitingActivityRecord, context);
|
||||
}
|
||||
|
||||
// start new workflows
|
||||
foreach (var a in startedWorkflows) {
|
||||
StartWorkflow(a, target, tokens);
|
||||
foreach (var activityRecord in startedWorkflows) {
|
||||
var context = new WorkflowContext {
|
||||
Activity = _activitiesManager.GetActivityByName(activityRecord.Name),
|
||||
Content = target,
|
||||
Record = activityRecord,
|
||||
Tokens = tokens,
|
||||
State = FormParametersHelper.FromJsonString(activityRecord.State),
|
||||
WorkflowState = FormParametersHelper.FromJsonString("{}")
|
||||
};
|
||||
|
||||
StartWorkflow(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartWorkflow(ActivityRecord activityRecord, IContent target, Dictionary<string, object> tokens) {
|
||||
var workflowState = FormParametersHelper.FromJsonString("{}");
|
||||
IEnumerable<ActivityRecord> blockedOn = ExecuteWorkflow(activityRecord.WorkflowDefinitionRecord, activityRecord, target, tokens, workflowState);
|
||||
private void StartWorkflow(WorkflowContext context) {
|
||||
|
||||
// signal every activity that the workflow is about to start
|
||||
var cancellationToken = new CancellationToken();
|
||||
InvokeActivities(context.Record.WorkflowDefinitionRecord, context, ctx => ctx.Activity.OnWorkflowStarting(ctx, cancellationToken));
|
||||
|
||||
if (cancellationToken.IsCancelled) {
|
||||
// workflow is aborted
|
||||
return;
|
||||
}
|
||||
|
||||
// signal every activity that the workflow is has started
|
||||
InvokeActivities(context.Record.WorkflowDefinitionRecord, context, ctx => ctx.Activity.OnWorkflowStarted(ctx));
|
||||
|
||||
var blockedOn = ExecuteWorkflow(context).ToList();
|
||||
|
||||
// is the workflow halted on a blocking activity ?
|
||||
if (blockedOn == null || !blockedOn.Any()) {
|
||||
if (!blockedOn.Any()) {
|
||||
// no, nothing to do
|
||||
}
|
||||
else {
|
||||
// workflow halted, create a workflow state
|
||||
var workflow = new WorkflowRecord {
|
||||
WorkflowDefinitionRecord = activityRecord.WorkflowDefinitionRecord,
|
||||
State = FormParametersHelper.ToJsonString(workflowState)
|
||||
WorkflowDefinitionRecord = context.Record.WorkflowDefinitionRecord,
|
||||
State = FormParametersHelper.ToJsonString(context.WorkflowState)
|
||||
};
|
||||
|
||||
_workflowRepository.Create(workflow);
|
||||
@@ -155,54 +194,66 @@ namespace Orchard.Workflows.Services {
|
||||
foreach (var blocking in blockedOn) {
|
||||
workflow.AwaitingActivities.Add(new AwaitingActivityRecord {
|
||||
ActivityRecord = blocking,
|
||||
ContentItemRecord = target.ContentItem.Record
|
||||
ContentItemRecord = context.Content.ContentItem.Record
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ResumeWorkflow(AwaitingActivityRecord awaitingActivityRecord, IContent target, Dictionary<string, object> tokens) {
|
||||
var workflowState = FormParametersHelper.FromJsonString(awaitingActivityRecord.WorkflowRecord.State);
|
||||
IEnumerable<ActivityRecord> blockedOn = ExecuteWorkflow(awaitingActivityRecord.WorkflowRecord.WorkflowDefinitionRecord, awaitingActivityRecord.ActivityRecord, target, tokens, workflowState);
|
||||
private void ResumeWorkflow(AwaitingActivityRecord awaitingActivityRecord, WorkflowContext context) {
|
||||
// signal every activity that the workflow is about to be resumed
|
||||
var cancellationToken = new CancellationToken();
|
||||
InvokeActivities(context.Record.WorkflowDefinitionRecord, context, ctx => ctx.Activity.OnWorkflowResuming(ctx, cancellationToken));
|
||||
|
||||
if (cancellationToken.IsCancelled) {
|
||||
// workflow is aborted
|
||||
return;
|
||||
}
|
||||
|
||||
// signal every activity that the workflow is resumed
|
||||
InvokeActivities(context.Record.WorkflowDefinitionRecord, context, ctx => ctx.Activity.OnWorkflowResumed(ctx));
|
||||
|
||||
var blockedOn = ExecuteWorkflow(context).ToList();
|
||||
|
||||
// is the workflow halted on a blocking activity ?
|
||||
if (blockedOn == null || !blockedOn.Any()) {
|
||||
if (!blockedOn.Any()) {
|
||||
// no, delete the workflow
|
||||
_workflowRepository.Delete(awaitingActivityRecord.WorkflowRecord);
|
||||
}
|
||||
else {
|
||||
// remove all previous awaiting activities
|
||||
var workflow = awaitingActivityRecord.WorkflowRecord;
|
||||
workflow.State = FormParametersHelper.ToJsonString(workflowState);
|
||||
workflow.State = FormParametersHelper.ToJsonString(context.WorkflowState);
|
||||
workflow.AwaitingActivities.Clear();
|
||||
|
||||
// add the new ones
|
||||
foreach (var blocking in blockedOn) {
|
||||
workflow.AwaitingActivities.Add(new AwaitingActivityRecord {
|
||||
ActivityRecord = blocking,
|
||||
ContentItemRecord = target.ContentItem.Record
|
||||
ContentItemRecord = context.Content.ContentItem.Record
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<ActivityRecord> ExecuteWorkflow(WorkflowDefinitionRecord workflowDefinitionRecord, ActivityRecord activityRecord, IContent target, Dictionary<string, object> tokens, dynamic workflowState) {
|
||||
public IEnumerable<ActivityRecord> ExecuteWorkflow(WorkflowContext context) {
|
||||
var firstPass = true;
|
||||
var pending = new Stack<ActivityRecord>();
|
||||
pending.Push(activityRecord);
|
||||
var scheduled = new Stack<ActivityRecord>();
|
||||
var activityRecord = context.Record;
|
||||
|
||||
scheduled.Push(activityRecord);
|
||||
|
||||
var blocking = new List<ActivityRecord>();
|
||||
|
||||
while (pending.Any()) {
|
||||
while (scheduled.Any()) {
|
||||
|
||||
activityRecord = pending.Pop();
|
||||
activityRecord = scheduled.Pop();
|
||||
|
||||
// while there is an activity to process
|
||||
var activity = _activitiesManager.GetActivityByName(activityRecord.Name);
|
||||
|
||||
if (!firstPass){
|
||||
if(activity.IsEvent) {
|
||||
activity.Touch(workflowState);
|
||||
blocking.Add(activityRecord);
|
||||
continue;
|
||||
}
|
||||
@@ -211,17 +262,15 @@ namespace Orchard.Workflows.Services {
|
||||
firstPass = false;
|
||||
}
|
||||
|
||||
var state = FormParametersHelper.FromJsonString(activityRecord.State);
|
||||
var activityContext = new ActivityContext { Tokens = tokens, State = state, WorkflowState = workflowState, Content = target };
|
||||
var outcomes = activity.Execute(activityContext);
|
||||
var outcomes = activity.Execute(context);
|
||||
|
||||
if (outcomes != null) {
|
||||
foreach (var outcome in outcomes) {
|
||||
// look for next activity in the graph
|
||||
var transition = workflowDefinitionRecord.TransitionRecords.FirstOrDefault(x => x.SourceActivityRecord == activityRecord && x.SourceEndpoint == outcome.TextHint);
|
||||
var transition = context.Record.WorkflowDefinitionRecord.TransitionRecords.FirstOrDefault(x => x.SourceActivityRecord == activityRecord && x.SourceEndpoint == outcome.TextHint);
|
||||
|
||||
if (transition != null) {
|
||||
pending.Push(transition.DestinationActivityRecord);
|
||||
scheduled.Push(transition.DestinationActivityRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,5 +279,16 @@ namespace Orchard.Workflows.Services {
|
||||
// apply Distinct() as two paths could block on the same activity
|
||||
return blocking.Distinct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a specific action on all the activities of a workflow, using a specific context
|
||||
/// </summary>
|
||||
private void InvokeActivities(WorkflowDefinitionRecord workflowDefinitionRecord, WorkflowContext context, Action<WorkflowContext> action) {
|
||||
foreach (var item in workflowDefinitionRecord.ActivityRecords) {
|
||||
context.Activity = _activitiesManager.GetActivityByName(item.Name);
|
||||
context.Record = item;
|
||||
action(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
@using Orchard.DisplayManagement
|
||||
@using Orchard.UI.Resources
|
||||
@using Orchard.Utility.Extensions
|
||||
@using Orchard.Workflows.Models
|
||||
@using Orchard.Workflows.Models.Descriptors
|
||||
@using Orchard.Workflows.Services
|
||||
|
||||
@@ -29,7 +30,7 @@
|
||||
//<![CDATA[
|
||||
var activities = { @foreach (var activity in allActivities) { <text>
|
||||
'@activity.Name': {
|
||||
outcomes: [@Html.Raw(String.Join(",", activity.GetPossibleOutcomes(new ActivityContext()).Where(x => !String.IsNullOrEmpty(x.Text)).Select(x => "'" + HttpUtility.JavaScriptStringEncode(x.Text) + "'").ToArray()))],
|
||||
outcomes: [@Html.Raw(String.Join(",", activity.GetPossibleOutcomes(new WorkflowContext()).Where(x => !String.IsNullOrEmpty(x.Text)).Select(x => "'" + HttpUtility.JavaScriptStringEncode(x.Text) + "'").ToArray()))],
|
||||
category: '@HttpUtility.JavaScriptStringEncode(activity.Category.Text)',
|
||||
description: '@HttpUtility.JavaScriptStringEncode(activity.Description.Text)',
|
||||
IsEvent: @(activity.IsEvent ? "true" : "false"),
|
||||
|
Reference in New Issue
Block a user