mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Adding workflow database storage and fixing editor glitches
--HG-- branch : 1.x extra : rebase_source : 003e226cae68e22d5d74633485b2a225674d08df
This commit is contained in:
@@ -46,7 +46,7 @@ namespace Orchard.Forms.Services {
|
|||||||
|
|
||||||
|
|
||||||
public static dynamic ToDynamic(string parameters) {
|
public static dynamic ToDynamic(string parameters) {
|
||||||
var result = Bag.New();
|
var result = new JObject();
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(parameters)) {
|
if (String.IsNullOrEmpty(parameters)) {
|
||||||
return result;
|
return result;
|
||||||
@@ -69,27 +69,25 @@ namespace Orchard.Forms.Services {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return JsonConvert.DeserializeObject(state);
|
return JsonConvert.DeserializeObject<dynamic>(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ToJsonString(FormCollection formCollection) {
|
public static string ToJsonString(FormCollection formCollection) {
|
||||||
var o = new JObject();
|
var o = new JObject();
|
||||||
|
|
||||||
foreach (var key in formCollection.AllKeys) {
|
foreach (var key in formCollection.AllKeys) {
|
||||||
|
if (key.StartsWith("_")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
o.Add(new JProperty(key, formCollection.Get(key)));
|
o.Add(new JProperty(key, formCollection.Get(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return JsonConvert.SerializeObject(o);
|
return JsonConvert.SerializeObject(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ToJsonString(IDictionary<string, object> dictionary) {
|
public static string ToJsonString(object item) {
|
||||||
var o = new JObject();
|
return JsonConvert.SerializeObject(item);
|
||||||
|
|
||||||
foreach (var entry in dictionary) {
|
|
||||||
o.Add(new JProperty(entry.Key, entry.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
return JsonConvert.SerializeObject(o);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.Core.Contents.Controllers;
|
using Orchard.Core.Contents.Controllers;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
@@ -13,6 +15,7 @@ using Orchard.Themes;
|
|||||||
using System;
|
using System;
|
||||||
using Orchard.Settings;
|
using Orchard.Settings;
|
||||||
using Orchard.UI.Navigation;
|
using Orchard.UI.Navigation;
|
||||||
|
using Orchard.UI.Notify;
|
||||||
using Orchard.Workflows.Models;
|
using Orchard.Workflows.Models;
|
||||||
using Orchard.Workflows.Services;
|
using Orchard.Workflows.Services;
|
||||||
using Orchard.Workflows.ViewModels;
|
using Orchard.Workflows.ViewModels;
|
||||||
@@ -20,7 +23,6 @@ using Orchard.Workflows.ViewModels;
|
|||||||
namespace Orchard.Workflows.Controllers {
|
namespace Orchard.Workflows.Controllers {
|
||||||
[ValidateInput(false)]
|
[ValidateInput(false)]
|
||||||
public class AdminController : Controller, IUpdateModel {
|
public class AdminController : Controller, IUpdateModel {
|
||||||
private readonly IOrchardServices _services;
|
|
||||||
private readonly ISiteService _siteService;
|
private readonly ISiteService _siteService;
|
||||||
private readonly IRepository<WorkflowDefinitionRecord> _workflowDefinitionRecords;
|
private readonly IRepository<WorkflowDefinitionRecord> _workflowDefinitionRecords;
|
||||||
private readonly IActivitiesManager _activitiesManager;
|
private readonly IActivitiesManager _activitiesManager;
|
||||||
@@ -34,7 +36,6 @@ namespace Orchard.Workflows.Controllers {
|
|||||||
IActivitiesManager activitiesManager,
|
IActivitiesManager activitiesManager,
|
||||||
IFormManager formManager
|
IFormManager formManager
|
||||||
) {
|
) {
|
||||||
_services = services;
|
|
||||||
_siteService = siteService;
|
_siteService = siteService;
|
||||||
_workflowDefinitionRecords = workflowDefinitionRecords;
|
_workflowDefinitionRecords = workflowDefinitionRecords;
|
||||||
_activitiesManager = activitiesManager;
|
_activitiesManager = activitiesManager;
|
||||||
@@ -133,48 +134,107 @@ namespace Orchard.Workflows.Controllers {
|
|||||||
|
|
||||||
// convert the workflow definition into its view model
|
// convert the workflow definition into its view model
|
||||||
var workflowDefinitionRecord = _workflowDefinitionRecords.Get(id);
|
var workflowDefinitionRecord = _workflowDefinitionRecords.Get(id);
|
||||||
var workflowDefinitionModel = new WorkflowDefinitionViewModel();
|
var workflowDefinitionViewModel = CreateWorkflowDefinitionViewModel(workflowDefinitionRecord);
|
||||||
|
|
||||||
if (workflowDefinitionRecord != null) {
|
|
||||||
workflowDefinitionModel.Id = workflowDefinitionRecord.Id;
|
|
||||||
|
|
||||||
foreach (var activityRecord in workflowDefinitionRecord.ActivityRecords) {
|
|
||||||
workflowDefinitionModel.Activities.Add(new ActivityViewModel {
|
|
||||||
Name = activityRecord.Type,
|
|
||||||
ClientId = activityRecord.Type + "_" + activityRecord.Id,
|
|
||||||
State = FormParametersHelper.FromString(activityRecord.State)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var transitionRecord in workflowDefinitionRecord.TransitionRecords) {
|
|
||||||
workflowDefinitionModel.Connections.Add(new ConnectionViewModel{
|
|
||||||
Id = transitionRecord.Id,
|
|
||||||
SourceClientId = transitionRecord.SourceActivityRecord.Type + "_" + transitionRecord.SourceActivityRecord.Id,
|
|
||||||
DestinationClientId = transitionRecord.DestinationActivityRecord.Type + "_" + transitionRecord.DestinationActivityRecord.Id,
|
|
||||||
Outcome = transitionRecord.DestinationEndpoint
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var viewModel = new AdminEditViewModel {
|
var viewModel = new AdminEditViewModel {
|
||||||
LocalId = Guid.NewGuid().ToString(),
|
LocalId = String.IsNullOrEmpty(localId) ? Guid.NewGuid().ToString() : localId,
|
||||||
WorkflowDefinition = workflowDefinitionModel,
|
IsLocal = !String.IsNullOrEmpty(localId),
|
||||||
|
WorkflowDefinition = workflowDefinitionViewModel,
|
||||||
AllActivities = _activitiesManager.GetActivities()
|
AllActivities = _activitiesManager.GetActivities()
|
||||||
};
|
};
|
||||||
|
|
||||||
return View(viewModel);
|
return View(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult EditLocal(string localId) {
|
private WorkflowDefinitionViewModel CreateWorkflowDefinitionViewModel(WorkflowDefinitionRecord workflowDefinitionRecord) {
|
||||||
|
if (workflowDefinitionRecord == null) {
|
||||||
|
throw new ArgumentNullException("workflowDefinitionRecord");
|
||||||
|
}
|
||||||
|
|
||||||
|
var workflowDefinitionModel = new WorkflowDefinitionViewModel {
|
||||||
|
Id = workflowDefinitionRecord.Id
|
||||||
|
};
|
||||||
|
|
||||||
|
dynamic workflow = new JObject();
|
||||||
|
workflow.Activities = new JArray(workflowDefinitionRecord.ActivityRecords.Select(x => {
|
||||||
|
dynamic activity = new JObject();
|
||||||
|
activity.Name = x.Name;
|
||||||
|
activity.ClientId = x.Name + "_" + x.Id;
|
||||||
|
activity.Left = x.X;
|
||||||
|
activity.Top = x.Y;
|
||||||
|
activity.State = FormParametersHelper.FromJsonString(x.State);
|
||||||
|
|
||||||
|
return activity;
|
||||||
|
}));
|
||||||
|
|
||||||
|
workflow.Connections = new JArray(workflowDefinitionRecord.TransitionRecords.Select(x => {
|
||||||
|
dynamic connection = new JObject();
|
||||||
|
connection.Id = x.Id;
|
||||||
|
connection.SourceId = x.SourceActivityRecord.Name + "_" + x.SourceActivityRecord.Id;
|
||||||
|
connection.TargetId = x.DestinationActivityRecord.Name + "_" + x.DestinationActivityRecord.Id;
|
||||||
|
connection.SourceEndpoint = x.SourceEndpoint;
|
||||||
|
return connection;
|
||||||
|
}));
|
||||||
|
|
||||||
|
workflowDefinitionModel.JsonData = FormParametersHelper.ToJsonString(workflow);
|
||||||
|
|
||||||
|
return workflowDefinitionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost, ActionName("Edit")]
|
||||||
|
[FormValueRequired("submit.Save")]
|
||||||
|
public ActionResult EditPost(int id, string localId, string data) {
|
||||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to edit workflows")))
|
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to edit workflows")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
var viewModel = new AdminEditViewModel {
|
var workflowDefinitionRecord = _workflowDefinitionRecords.Get(id);
|
||||||
LocalId = localId,
|
|
||||||
AllActivities = _activitiesManager.GetActivities(),
|
|
||||||
};
|
|
||||||
|
|
||||||
return View("Edit", viewModel);
|
if (workflowDefinitionRecord == null) {
|
||||||
|
return HttpNotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
var state = FormParametersHelper.FromJsonString(data);
|
||||||
|
var activitiesIndex = new Dictionary<string, ActivityRecord>();
|
||||||
|
|
||||||
|
workflowDefinitionRecord.ActivityRecords.Clear();
|
||||||
|
|
||||||
|
foreach (var activity in state.Activities) {
|
||||||
|
ActivityRecord activityRecord;
|
||||||
|
|
||||||
|
workflowDefinitionRecord.ActivityRecords.Add(activityRecord = new ActivityRecord {
|
||||||
|
Name = activity.Name,
|
||||||
|
X = activity.Left,
|
||||||
|
Y = activity.Top,
|
||||||
|
State = FormParametersHelper.ToJsonString(activity.State),
|
||||||
|
WorkflowDefinitionRecord = workflowDefinitionRecord
|
||||||
|
});
|
||||||
|
|
||||||
|
activitiesIndex.Add((string)activity.ClientId, activityRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
workflowDefinitionRecord.TransitionRecords.Clear();
|
||||||
|
|
||||||
|
foreach (var connection in state.Connections) {
|
||||||
|
workflowDefinitionRecord.TransitionRecords.Add(new TransitionRecord {
|
||||||
|
SourceActivityRecord = activitiesIndex[(string)connection.SourceId],
|
||||||
|
DestinationActivityRecord = activitiesIndex[(string)connection.TargetId],
|
||||||
|
SourceEndpoint = connection.SourceEndpoint,
|
||||||
|
WorkflowDefinitionRecord = workflowDefinitionRecord
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Services.Notifier.Information(T("Workflow saved successfully"));
|
||||||
|
|
||||||
|
return RedirectToAction("Edit", new { id, localId });
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost, ActionName("Edit")]
|
||||||
|
[FormValueRequired("submit.Cancel")]
|
||||||
|
public ActionResult EditPostCancel() {
|
||||||
|
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to edit workflows")))
|
||||||
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Themed(false)]
|
[Themed(false)]
|
||||||
@@ -215,14 +275,13 @@ namespace Orchard.Workflows.Controllers {
|
|||||||
var form = activity.Form == null ? null : _formManager.Build(activity.Form);
|
var form = activity.Form == null ? null : _formManager.Build(activity.Form);
|
||||||
|
|
||||||
// form is bound on client side
|
// form is bound on client side
|
||||||
|
|
||||||
var viewModel = New.ViewModel(LocalId: localId, ClientId: clientId, Form: form);
|
var viewModel = New.ViewModel(LocalId: localId, ClientId: clientId, Form: form);
|
||||||
|
|
||||||
return View(viewModel);
|
return View(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost, ActionName("EditActivity")]
|
[HttpPost, ActionName("EditActivity")]
|
||||||
[FormValueRequired("submit.Save")]
|
[FormValueRequired("_submit.Save")]
|
||||||
public ActionResult EditActivityPost(int id, string localId, string name, string clientId, FormCollection formValues) {
|
public ActionResult EditActivityPost(int id, string localId, string name, string clientId, FormCollection formValues) {
|
||||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to edit workflows")))
|
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to edit workflows")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
@@ -257,18 +316,19 @@ namespace Orchard.Workflows.Controllers {
|
|||||||
|
|
||||||
TempData["UpdatedViewModel"] = model;
|
TempData["UpdatedViewModel"] = model;
|
||||||
|
|
||||||
return RedirectToAction("EditLocal", new {
|
return RedirectToAction("Edit", new {
|
||||||
|
id,
|
||||||
localId
|
localId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost, ActionName("EditActivity")]
|
[HttpPost, ActionName("EditActivity")]
|
||||||
[FormValueRequired("submit.Cancel")]
|
[FormValueRequired("_submit.Cancel")]
|
||||||
public ActionResult EditActivityPostCancel(string localId, string name, string clientId, FormCollection formValues) {
|
public ActionResult EditActivityPostCancel(int id, string localId, string name, string clientId, FormCollection formValues) {
|
||||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to edit workflows")))
|
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to edit workflows")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
return RedirectToAction("EditLocal", new {localId });
|
return RedirectToAction("Edit", new {id, localId });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace Orchard.Workflows {
|
|||||||
|
|
||||||
public int Create() {
|
public int Create() {
|
||||||
// Creating table TransitionRecord
|
// Creating table TransitionRecord
|
||||||
SchemaBuilder.CreateTable("TransitionRecord", table => table
|
SchemaBuilder.CreateTable("TransitionRecord", table => table
|
||||||
.Column<int>("Id", column => column.PrimaryKey().Identity())
|
.Column<int>("Id", column => column.PrimaryKey().Identity())
|
||||||
.Column<string>("SourceEndpoint")
|
.Column<string>("SourceEndpoint")
|
||||||
.Column<string>("DestinationEndpoint")
|
.Column<string>("DestinationEndpoint")
|
||||||
@@ -37,7 +37,9 @@ namespace Orchard.Workflows {
|
|||||||
// Creating table ActivityRecord
|
// Creating table ActivityRecord
|
||||||
SchemaBuilder.CreateTable("ActivityRecord", table => table
|
SchemaBuilder.CreateTable("ActivityRecord", table => table
|
||||||
.Column<int>("Id", column => column.PrimaryKey().Identity())
|
.Column<int>("Id", column => column.PrimaryKey().Identity())
|
||||||
.Column<string>("Type")
|
.Column<string>("Name")
|
||||||
|
.Column<int>("X")
|
||||||
|
.Column<int>("Y")
|
||||||
.Column<string>("State", c => c.Unlimited())
|
.Column<string>("State", c => c.Unlimited())
|
||||||
.Column<int>("WorkflowDefinitionRecord_id")
|
.Column<int>("WorkflowDefinitionRecord_id")
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Orchard.Workflows.Models {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of the activity.
|
/// The type of the activity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual string Type { get; set; }
|
public virtual string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The serialized state of the activity.
|
/// The serialized state of the activity.
|
||||||
@@ -18,6 +18,16 @@ namespace Orchard.Workflows.Models {
|
|||||||
[StringLengthMax]
|
[StringLengthMax]
|
||||||
public virtual string State { get; set; }
|
public virtual string State { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The left coordinate of the activity.
|
||||||
|
/// </summary>
|
||||||
|
public virtual int X { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The top coordinate of the activity.
|
||||||
|
/// </summary>
|
||||||
|
public virtual int Y { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The parent <see cref="WorkflowDefinitionRecord"/>
|
/// The parent <see cref="WorkflowDefinitionRecord"/>
|
||||||
/// containing this activity.
|
/// containing this activity.
|
||||||
|
|||||||
@@ -46,6 +46,10 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\Orchard.Forms\bin\Newtonsoft.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.ComponentModel.DataAnnotations">
|
<Reference Include="System.ComponentModel.DataAnnotations">
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ namespace Orchard.Workflows.Providers {
|
|||||||
shape => Shape.Form(
|
shape => Shape.Form(
|
||||||
Id: "ActivityNotify",
|
Id: "ActivityNotify",
|
||||||
_Type: Shape.SelectList(
|
_Type: Shape.SelectList(
|
||||||
Id: "notification", Name: "notification",
|
Id: "notification", Name: "Notification",
|
||||||
Title: T("Notification type"),
|
Title: T("Notification type"),
|
||||||
Description: T("Select what type of notification should be displayed."))
|
Description: T("Select what type of notification should be displayed."))
|
||||||
.Add(new SelectListItem { Value = "Information", Text = T("Information").Text })
|
.Add(new SelectListItem { Value = "Information", Text = T("Information").Text })
|
||||||
.Add(new SelectListItem { Value = "Warning", Text = T("Warning").Text })
|
.Add(new SelectListItem { Value = "Warning", Text = T("Warning").Text })
|
||||||
.Add(new SelectListItem { Value = "Error", Text = T("Error").Text }),
|
.Add(new SelectListItem { Value = "Error", Text = T("Error").Text }),
|
||||||
_Message: Shape.Textbox(
|
_Message: Shape.Textbox(
|
||||||
Id: "message", Name: "message",
|
Id: "message", Name: "Message",
|
||||||
Title: T("Message"),
|
Title: T("Message"),
|
||||||
Description: T("The notification message to display."),
|
Description: T("The notification message to display."),
|
||||||
Classes: new[] { "textMedium", "tokenized" })
|
Classes: new[] { "textMedium", "tokenized" })
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
|
|
||||||
var saveLocal = function (localId) {
|
var saveLocal = function (localId) {
|
||||||
var wokflow = {
|
var workflow = {
|
||||||
activities: [],
|
Activities: [],
|
||||||
connections: []
|
Connections: []
|
||||||
};
|
};
|
||||||
|
|
||||||
var allActivities = $('.activity');
|
var allActivities = $('.activity');
|
||||||
for (var i = 0; i < allActivities.length; i++) {
|
for (var i = 0; i < allActivities.length; i++) {
|
||||||
var activity = allActivities[i];
|
var activity = allActivities[i];
|
||||||
|
|
||||||
wokflow.activities.push({
|
workflow.Activities.push({
|
||||||
name: activity.viewModel.name,
|
Name: activity.viewModel.name,
|
||||||
clientId: activity.viewModel.clientId,
|
ClientId: activity.viewModel.clientId,
|
||||||
state: activity.viewModel.state,
|
State: activity.viewModel.state,
|
||||||
left: $(activity).position().left,
|
Left: $(activity).position().left,
|
||||||
top: $(activity).position().top
|
Top: $(activity).position().top
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,15 +22,36 @@ var saveLocal = function (localId) {
|
|||||||
for (var i = 0; i < allConnections.length; i++) {
|
for (var i = 0; i < allConnections.length; i++) {
|
||||||
var connection = allConnections[i];
|
var connection = allConnections[i];
|
||||||
|
|
||||||
wokflow.connections.push({
|
workflow.Connections.push({
|
||||||
sourceId: connection.sourceId,
|
SourceId: connection.sourceId,
|
||||||
targetId: connection.targetId,
|
TargetId: connection.targetId,
|
||||||
sourceEndpoint: connection.endpoints[0].outcome,
|
SourceEndpoint: connection.endpoints[0].outcome,
|
||||||
//targetEndpoint: connection.targetEndpoint
|
//targetEndpoint: connection.targetEndpoint
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// serialize the object
|
// serialize the object
|
||||||
sessionStorage.setItem(localId, JSON.stringify(wokflow));
|
sessionStorage.setItem(localId, JSON.stringify(workflow));
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateActivities = function(localId) {
|
||||||
|
var workflow = loadWorkflow(localId);
|
||||||
|
if (workflow == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// activities
|
||||||
|
if (updatedActivityState != null) {
|
||||||
|
for (var i = 0; i < workflow.Activities.length; i++) {
|
||||||
|
var activity = workflow.Activities[i];
|
||||||
|
|
||||||
|
if (updatedActivityClientId == activity.ClientId) {
|
||||||
|
// if an activity has been modified, update it
|
||||||
|
activity.State = JSON.parse(updatedActivityState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionStorage.setItem(localId, JSON.stringify(workflow));
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadActivities = function (localId) {
|
var loadActivities = function (localId) {
|
||||||
@@ -40,32 +61,27 @@ var loadActivities = function (localId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// activities
|
// activities
|
||||||
for (var i = 0; i < workflow.activities.length; i++) {
|
for (var i = 0; i < workflow.Activities.length; i++) {
|
||||||
var activity = workflow.activities[i];
|
var activity = workflow.Activities[i];
|
||||||
|
renderActivity(activity.ClientId, activity.Name, activity.State, activity.Top, activity.Left);
|
||||||
// if an activity has been modified, update it
|
|
||||||
if (updatedActivityState != null && updatedActivityClientId == activity.clientId) {
|
|
||||||
activity.state = JSON.parse(updatedActivityState);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderActivity(activity.clientId, activity.name, activity.state, activity.top, activity.left);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// connections
|
// connections
|
||||||
for (var i = 0; i < workflow.connections.length; i++) {
|
for (var i = 0; i < workflow.Connections.length; i++) {
|
||||||
var connection = workflow.connections[i];
|
var connection = workflow.Connections[i];
|
||||||
|
|
||||||
var source = document.getElementById(connection.sourceId);
|
var source = document.getElementById(connection.SourceId);
|
||||||
var ep = source.endpoints[connection.sourceEndpoint];
|
var ep = source.endpoints[connection.SourceEndpoint];
|
||||||
|
|
||||||
jsPlumb.connect({
|
jsPlumb.connect({
|
||||||
source: ep,
|
source: ep,
|
||||||
target: connection.targetId,
|
target: connection.TargetId,
|
||||||
newConnection: true
|
newConnection: true
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return workflow;
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadWorkflow = function(localId) {
|
var loadWorkflow = function(localId) {
|
||||||
@@ -90,9 +106,9 @@ var getActivity = function(localId, clientId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var activity = null;
|
var activity = null;
|
||||||
for (var i = 0; i < workflow.activities.length; i++) {
|
for (var i = 0; i < workflow.Activities.length; i++) {
|
||||||
var a = workflow.activities[i];
|
var a = workflow.Activities[i];
|
||||||
if (a.clientId == clientId) {
|
if (a.ClientId == clientId) {
|
||||||
activity = a;
|
activity = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +121,7 @@ var loadForm = function(localId, clientId) {
|
|||||||
// bind state to form
|
// bind state to form
|
||||||
|
|
||||||
var activity = getActivity(localId, clientId);
|
var activity = getActivity(localId, clientId);
|
||||||
bindForm($('form'), activity.state);
|
bindForm($('form'), activity.State);
|
||||||
};
|
};
|
||||||
|
|
||||||
var bindForm = function(form, data) {
|
var bindForm = function(form, data) {
|
||||||
@@ -126,38 +142,3 @@ var bindForm = function(form, data) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
var serializeForm = function(form) {
|
|
||||||
var data = {};
|
|
||||||
|
|
||||||
$(form).find('select, input, textarea').each(function(index, el) {
|
|
||||||
var $el = $(el);
|
|
||||||
var name = $el.attr('name');
|
|
||||||
var type = $el.attr('type');
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case 'checkbox':
|
|
||||||
data[name] = $el.attr('checked') ? 'true' : false;
|
|
||||||
break;
|
|
||||||
case 'radio':
|
|
||||||
var value = $el.filter('checked').attr('value');
|
|
||||||
if (value) {
|
|
||||||
data[name] = value;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
data[name] = $el.val();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
var saveState = function(localId, clientId, data) {
|
|
||||||
var activity = getActivity(localId, clientId);
|
|
||||||
activity.state = data;
|
|
||||||
|
|
||||||
sessionStorage.setItem(localId, JSON.stringify(wokflow));
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
@@ -26,12 +26,13 @@
|
|||||||
jsPlumb.bind("ready", function () {
|
jsPlumb.bind("ready", function () {
|
||||||
|
|
||||||
jsPlumb.importDefaults({
|
jsPlumb.importDefaults({
|
||||||
|
Anchor : "Continuous",
|
||||||
// default drag options
|
// default drag options
|
||||||
DragOptions: { cursor: 'pointer', zIndex: 2000 },
|
DragOptions: { cursor: 'pointer', zIndex: 2000 },
|
||||||
// default to blue at one end and green at the other
|
// default to blue at one end and green at the other
|
||||||
EndpointStyles: [{ fillStyle: '#225588' }, { fillStyle: '#558822' }],
|
EndpointStyles: [{ fillStyle: '#225588' }],
|
||||||
// blue endpoints 7 px; green endpoints 11.
|
// blue endpoints 7 px; Blank endpoints.
|
||||||
Endpoints: [["Dot", { radius: 7 }], ["Dot", { radius: 7 }]],
|
Endpoints: [["Dot", { radius: 7 }], ["Blank"]],
|
||||||
// the overlays to decorate each connection with. note that the label overlay uses a function to generate the label text; in this
|
// the overlays to decorate each connection with. note that the label overlay uses a function to generate the label text; in this
|
||||||
// case it returns the 'labelText' member that we set on each connection in the 'init' method below.
|
// case it returns the 'labelText' member that we set on each connection in the 'init' method below.
|
||||||
ConnectionOverlays: [
|
ConnectionOverlays: [
|
||||||
@@ -41,6 +42,9 @@
|
|||||||
ConnectorZIndex: 5
|
ConnectorZIndex: 5
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// updates the state of any edited activity
|
||||||
|
updateActivities(localId);
|
||||||
|
|
||||||
// deserialize the previously locally saved workflow
|
// deserialize the previously locally saved workflow
|
||||||
loadActivities(localId);
|
loadActivities(localId);
|
||||||
|
|
||||||
@@ -127,7 +131,7 @@
|
|||||||
if (activities[name].hasForm) {
|
if (activities[name].hasForm) {
|
||||||
dom.dblclick(function() {
|
dom.dblclick(function() {
|
||||||
saveLocal(localId);
|
saveLocal(localId);
|
||||||
window.location.href = editActivityUrl + "/0?name=" + name + "&clientId=" + elt.viewModel.clientId + "&localId=" + localId;
|
window.location.href = editActivityUrl + "/" + $("#id").val() + "?name=" + name + "&clientId=" + elt.viewModel.clientId + "&localId=" + localId;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Orchard.Workflows.Models;
|
|
||||||
using Orchard.Workflows.Services;
|
using Orchard.Workflows.Services;
|
||||||
|
|
||||||
namespace Orchard.Workflows.ViewModels {
|
namespace Orchard.Workflows.ViewModels {
|
||||||
public class AdminEditViewModel {
|
public class AdminEditViewModel {
|
||||||
public string LocalId { get; set; }
|
public string LocalId { get; set; }
|
||||||
|
public bool IsLocal { get; set; }
|
||||||
public IEnumerable<IActivity> AllActivities { get; set; }
|
public IEnumerable<IActivity> AllActivities { get; set; }
|
||||||
public WorkflowDefinitionViewModel WorkflowDefinition { get; set; }
|
public WorkflowDefinitionViewModel WorkflowDefinition { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Orchard.Workflows.ViewModels {
|
namespace Orchard.Workflows.ViewModels {
|
||||||
public class WorkflowDefinitionViewModel {
|
public class WorkflowDefinitionViewModel {
|
||||||
public WorkflowDefinitionViewModel() {
|
|
||||||
Activities = new List<ActivityViewModel>();
|
|
||||||
Connections = new List<ConnectionViewModel>();
|
|
||||||
}
|
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
public string JsonData { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// Used to prevent client side LocalStorage conflicts
|
|
||||||
/// </summary>
|
|
||||||
public string Tenant { get; set; }
|
|
||||||
|
|
||||||
public List<ActivityViewModel> Activities { get; set; }
|
|
||||||
public List<ConnectionViewModel> Connections { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ActivityViewModel {
|
public class ActivityViewModel {
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
@model Orchard.Workflows.ViewModels.AdminEditViewModel
|
@model AdminEditViewModel
|
||||||
@using ClaySharp.Implementation
|
|
||||||
@using Orchard.ContentManagement
|
|
||||||
@using Orchard.Forms.Services
|
@using Orchard.Forms.Services
|
||||||
@using Orchard.Localization
|
|
||||||
@using Orchard.Utility.Extensions
|
|
||||||
@using Orchard.Workflows.Models;
|
|
||||||
@using Orchard.Workflows.ViewModels;
|
@using Orchard.Workflows.ViewModels;
|
||||||
@using Orchard.DisplayManagement;
|
|
||||||
|
|
||||||
@{
|
@{
|
||||||
Layout.Title = @T("Edit Workflow");
|
Layout.Title = @T("Edit Workflow");
|
||||||
@@ -23,14 +17,13 @@
|
|||||||
Script.Include("orchard-workflows-serialize.js").AtFoot();
|
Script.Include("orchard-workflows-serialize.js").AtFoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@using (Html.BeginFormAntiForgeryPost()) {
|
@using (Html.BeginFormAntiForgeryPost("Edit")) {
|
||||||
@Html.ValidationSummary()
|
@Html.ValidationSummary()
|
||||||
|
|
||||||
<div id="activity-editor">
|
<div id="activity-editor">
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
|
|
||||||
@using (Script.Head()) {
|
using (Script.Head()) {
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
//<![CDATA[
|
//<![CDATA[
|
||||||
var renderActivityUrl = '@Url.Action("RenderActivity", "Admin", new { area = "Orchard.Workflows" })';
|
var renderActivityUrl = '@Url.Action("RenderActivity", "Admin", new { area = "Orchard.Workflows" })';
|
||||||
@@ -43,12 +36,42 @@
|
|||||||
@if (TempData.ContainsKey("UpdatedViewModel")) {
|
@if (TempData.ContainsKey("UpdatedViewModel")) {
|
||||||
var model = TempData["UpdatedViewModel"] as UpdatedActivityModel;
|
var model = TempData["UpdatedViewModel"] as UpdatedActivityModel;
|
||||||
if (model != null) {
|
if (model != null) {
|
||||||
<text>
|
<text>
|
||||||
updatedActivityClientId = '@(model.ClientId)';
|
updatedActivityClientId = '@(model.ClientId)';
|
||||||
updatedActivityState = '@Html.Raw(FormParametersHelper.ToJsonString(model.Data))';
|
updatedActivityState = '@Html.Raw(FormParametersHelper.ToJsonString(model.Data))';
|
||||||
</text>
|
</text>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(!Model.IsLocal) {
|
||||||
|
<text>
|
||||||
|
var state = @Html.Raw(Model.WorkflowDefinition.JsonData);
|
||||||
|
sessionStorage.setItem(localId, JSON.stringify(state));
|
||||||
|
</text>
|
||||||
|
}
|
||||||
|
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|
||||||
|
@Html.Hidden("id", Model.WorkflowDefinition.Id)
|
||||||
|
@Html.Hidden("localId", Model.LocalId)
|
||||||
|
@Html.Hidden("data", String.Empty)
|
||||||
|
|
||||||
|
using (Script.Foot()) {
|
||||||
|
<script type="text/javascript">
|
||||||
|
//<![CDATA[
|
||||||
|
$("form").submit(function () {
|
||||||
|
saveLocal(localId);
|
||||||
|
var workflow = loadWorkflow(localId);
|
||||||
|
var data = JSON.stringify(workflow);
|
||||||
|
$("[name='data']").val(data);
|
||||||
|
});
|
||||||
//]]>
|
//]]>
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<button class="primaryAction" type="submit" name="submit.Save" value="@T("Save")">@T("Save")</button>
|
||||||
|
<button class="cancel" type="submit" name="submit.Cancel" value="@T("Cancel")">@T("Cancel")</button>
|
||||||
|
</fieldset>
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
@Display.TokenHint()
|
@Display.TokenHint()
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<button class="primaryAction" type="submit" name="submit.Save" value="@T("Save")">@T("Save")</button>
|
<button class="primaryAction" type="submit" name="_submit.Save" value="@T("Save")">@T("Save")</button>
|
||||||
<button class="cancel" type="submit" name="submit.Cancel" value="@T("Cancel")">@T("Cancel")</button>
|
<button class="cancel" type="submit" name="_submit.Cancel" value="@T("Cancel")">@T("Cancel")</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user