This commit is contained in:
Sipke Schoorstra 2018-10-28 15:34:00 +01:00
parent 3873284c08
commit ab9e038ca1
155 changed files with 2338 additions and 2129 deletions

View file

@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=BFA6473C_002D809D_002D42F6_002DADD3_002D80A3118B999C_002Fd_003AAssets_002Fd_003Anode_005Fmodules/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=src_005Cweb_005Cmodules_005CFlowsharp_002EWeb_002EViewComponents_005CClientApp_005Cnode_005Fmodules/@EntryIndexedValue"></s:String>
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=src_005Cweb_005Cmodules_005CFlowsharp_002EWeb_002EViewComponents_005CClientApp_005Cnode_005Fmodules/@EntryIndexRemoved">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=src_005Cweb_005Cmodules_005CFlowsharp_002EWeb_002EViewComponents_005CAssets_005Cnode_005Fmodules/@EntryIndexedValue">ExplicitlyExcluded</s:String></wpf:ResourceDictionary>

View file

@ -11,7 +11,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69230" />
</ItemGroup>
<ItemGroup>

View file

@ -10,7 +10,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69230" />
</ItemGroup>
</Project>

View file

@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OrchardCore.DisplayManagement" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.DisplayManagement" Version="1.0.0-beta3-69230" />
</ItemGroup>
<ItemGroup>

View file

@ -12,10 +12,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="OrchardCore.FileStorage.FileSystem" Version="1.0.0-beta2-67846" />
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.Mvc.Core" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.DisplayManagement" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.FileStorage.FileSystem" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.Mvc.Core" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.DisplayManagement" Version="1.0.0-beta3-69230" />
</ItemGroup>
<ItemGroup>

View file

@ -5,11 +5,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OrchardCore" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.DisplayManagement" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.ResourceManagement" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.Infrastructure" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.DisplayManagement" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.ResourceManagement" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.Infrastructure" Version="1.0.0-beta3-69230" />
</ItemGroup>
</Project>

View file

@ -5,8 +5,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.FileStorage.FileSystem" Version="1.0.0-beta2-67846" />
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.FileStorage.FileSystem" Version="1.0.0-beta3-69230" />
</ItemGroup>
<ItemGroup>

File diff suppressed because it is too large Load diff

View file

@ -1,35 +1,35 @@
{
"name": "flowsharp-components",
"name": "flowsharp-web-workflpw-editor-assets",
"private": true,
"version": "1.0.0",
"scripts": {
"build": "webpack"
},
"babel": {
"presets": [
"env",
"react"
]
"build:dev": "SET NODE_ENV=development && webpack -p --config webpack/config.dev.js",
"build:prod": "SET NODE_ENV=production && webpack -p --config webpack/config.prod.js",
"start": "SET NODE_ENV=development && webpack-dev-server --config webpack/config.dev.js"
},
"dependencies": {
"dotnetify": "~3.0.3",
"react": "~16.5.0",
"react-dom": "~16.5.0",
"jsplumb": "^2.8.0"
"jquery": "^3.3.1",
"jsplumb": "^2.8.2",
"lodash": "^4.17.11"
},
"devDependencies": {
"aspnet-webpack": "^3.0.0",
"babel-core": "~6.26.3",
"babel-loader": "~7.1.4",
"babel-preset-env": "~1.7.0",
"babel-preset-react": "~6.24.1",
"webpack": "^4.21.0",
"webpack-cli": "^3.1.0",
"webpack-dev-middleware": "^3.4.0",
"webpack-dev-server": "^3.1.9",
"webpack-hot-middleware": "^2.24.3",
"html-webpack-plugin": "^3.2.0",
"@babel/core": "^7.0.0",
"@babel/runtime-corejs2": "^7.0.0",
"autoprefixer": "^9.1.3",
"babel-loader": "^8.0.4",
"cross-env": "^5.2.0",
"css-loader": "^1.0.0",
"node-sass": "^4.9.4",
"extract-loader": "^2.0.1",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^2.0.0",
"style-loader": "^0.23.1",
"node-sass": "^4.9.3",
"postcss-cli": "^6.0.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1"
"webpack": "^4.23.1",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.10",
"webpack-merge": "^4.1.4"
}
}

View file

@ -0,0 +1,9 @@
import * as flowsharp from './workflow-editor.js'
import $ from 'jquery';
import '../styles/index.scss';
$(function(){
$('.workflow-canvas').each((e, i) => {
const editor= new flowsharp.WorkflowEditor(e);
});
});

View file

@ -0,0 +1,165 @@
import $ from 'jquery';
import {jsPlumb} from "jsplumb";
import {WorkflowType, Activity, Endpoint, Transition} from "./workflow-models";
export class WorkflowEditor {
constructor(container) {
this.container = container;
this.readActivities();
this.plumber = this.createJsPlumbInstance();
this.initializeNodes();
}
readActivities() {
const activityElements = $(this.container).find('.activity');
const activities = [];
for (let index = 0; index < activityElements.length; index++) {
const activityElement = activityElements[index];
const activity = activityElement.data['activity-json'];
activities.push(activity);
}
this.activityElements = activityElements;
this.activities = activities;
}
createJsPlumbInstance() {
return jsPlumb.getInstance({
Anchor: "Continuous",
DragOptions: {cursor: 'pointer', zIndex: 2000},
EndpointStyles: [{fillStyle: '#225588'}],
Endpoints: [["Dot", {radius: 7}], ["Blank"]],
ConnectionOverlays: [
["Arrow", {width: 12, length: 12, location: -5}],
],
ConnectorZIndex: 5,
Container: this.container
});
};
initializeNodes() {
// Suspend drawing and initialize.
this.plumber.batch(() => {
let activityElements = this.activityElements;
for (let index = 0; index < activityElements.length; index++) {
const activityElement = activityElements[index];
const activity = this.activities[index];
const $activityElement = $(activityElement);
// Make the activity draggable.
this.plumber.draggable(activityElement, {
grid: [10, 10],
containment: true,
start: args => {
this.dragStart = {left: args.e.screenX, top: args.e.screenY};
},
stop: args => {
this.hasDragged = this.dragStart.left !== args.e.screenX || this.dragStart.top !== args.e.screenY;
}
});
// Configure the activity as a target.
this.plumber.makeTarget(activityElement, {
dropOptions: {hoverClass: 'hover'},
anchor: 'Continuous',
endpoint: ['Blank', {radius: 8}]
});
// Add source endpoints.
this.addSourceEndpoints(activity, activityElement);
}
// Connect activities.
this.updateConnections();
// Make all activity elements visible.
activityElements.show();
});
}
addSourceEndpoints(activity, activityElement){
for(let i = 0; i < activity.endpoints.length; i++)
{
const endpoint = activity.endpoints[i];
const sourceEndpointOptions = WorkflowEditor.getSourceEndpointOptions(activity.id, endpoint.name);
this.plumber.addEndpoint(activityElement, {
connectorOverlays: [['Label', {
label: endpoint.name,
cssClass: 'connection-label'
}]]
}, sourceEndpointOptions);
}
}
static getSourceEndpointOptions(activityId, endpointName) {
// The definition of source endpoints.
const paintColor = '#7ab02c';
return {
endpoint: 'Dot',
anchor: 'Continuous',
paintStyle: {
stroke: paintColor,
fill: paintColor,
radius: 7,
strokeWidth: 1
},
isSource: true,
connector: ['Flowchart', {stub: [40, 60], gap: 0, cornerRadius: 5, alwaysRespectStubs: true}],
connectorStyle: {
strokeWidth: 2,
stroke: '#999999',
joinstyle: 'round',
outlineStroke: 'white',
outlineWidth: 2
},
hoverPaintStyle: {
fill: '#216477',
stroke: '#216477'
},
connectorHoverStyle: {
strokeWidth: 3,
stroke: '#216477',
outlineWidth: 5,
outlineStroke: 'white'
},
connectorOverlays: [['Label', {location: [3, -1.5], cssClass: 'endpointSourceLabel'}]],
dragOptions: {},
uuid: `${activityId}-${endpointName}`
};
};
updateConnections() {
const workflowId = "";
// for (let transitionModel of this.workflowType.transitions) {
// const sourceEndpointUuid: string = `${transitionModel.sourceActivityId}-${transitionModel.sourceOutcomeName}`;
// const sourceEndpoint: Endpoint = plumber.getEndpoint(sourceEndpointUuid);
// const destinationElementId: string = `activity-${workflowId}-${transitionModel.destinationActivityId}`;
//
// plumber.connect({
// source: sourceEndpoint,
// target: destinationElementId
// });
// }
}
static areEqualOutcomes(outcomes1, outcomes2) {
if (outcomes1.length !== outcomes2.length) {
return false;
}
for (let i = 0; i < outcomes1.length; i++) {
const outcome1 = outcomes1[i];
const outcome2 = outcomes2[i];
if (outcome1.name !== outcome2.displayName || outcome1.displayName !== outcome2.displayName) {
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,36 @@
export class WorkflowType {
constructor(){
this.id = null;
this.activities = [];
this.transitions = [];
this.removedActivities = [];
}
}
export class Activity {
constructor(){
this.id = null;
this.x = 0;
this.y = 0;
this.isStart = false;
this.isBlocking = false;
this.isEvent = false;
this.endpoints = [];
}
}
export class Endpoint {
constructor(){
this.name = null;
this.displayName = null;
}
}
export class Transition {
constructor(){
this.sourceActivityId = null;
this.sourceOutcomeName = null;
this.destinationActivityId = null;
}
}

View file

@ -0,0 +1,2 @@
@import '~jsplumb/css/jsplumbtoolkit-defaults.css';
@import 'workflow-editor';

View file

@ -0,0 +1,5 @@
module.exports = {
plugins: {
'autoprefixer': {}
}
};

View file

@ -1,19 +1,3 @@
.workflow-container {
.workflow-canvas-container {
border: 1px solid #e4e5e6;
border-radius: 0.25em;
padding: 15px;
}
}
.modal-activities {
h4.card-title {
.fa {
margin-right: 0.5em;
}
}
}
.workflow-canvas {
overflow: auto !important;
position: relative;
@ -21,7 +5,7 @@
min-height: 400px;
.activity {
display: none;
//display: none;
border: 1px solid #346789;
box-shadow: 2px 2px 19px #aaa;
-o-box-shadow: 2px 2px 9px #aaa;

View file

@ -1,36 +0,0 @@
'use strict';
const webpack = require('webpack');
module.exports = {
mode: 'development',
entry: { main: './js/index.js' },
output: {
path: __dirname + '/../wwwroot',
publicPath: '/'
},
resolve: {
modules: [ 'src', 'node_modules' ]
},
module: {
rules: [
{ test: /\.js?$/, use: 'babel-loader', exclude: /node_modules/ },
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
{
loader: "style-loader" // creates style nodes from JS strings
},
{
loader: "css-loader" // translates CSS into CommonJS
},
{
loader: "sass-loader" // compiles Sass to CSS
}
]
}]
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};

View file

@ -0,0 +1,62 @@
const path = require('path');
const webpack = require('webpack');
const extractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
entry: [
'./src/scripts/index.js'
//'./src/styles/index.scss'
],
externals: {
jquery: 'jQuery'
},
output: {
path: path.join(__dirname, '../../wwwroot'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.scss$/,
use: [
{
// Adds CSS to the DOM by injecting a `<style>` tag
loader: 'style-loader'
},
{
// Interprets `@import` and `url()` like `import/require()` and will resolve them
loader: 'css-loader'
},
{
// Loader for webpack to process CSS with PostCSS
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('autoprefixer')
];
}
}
},
{
// Loads a SASS/SCSS file and compiles it to CSS
loader: 'sass-loader'
}
]
}
]
},
plugins: [
new webpack.EnvironmentPlugin([
'NODE_ENV',
])
]
};

View file

@ -0,0 +1,6 @@
const merge = require('webpack-merge');
const baseConfig = require('./config.base.js');
module.exports = merge(baseConfig, {
devtool: 'eval-source-map'
});

View file

@ -0,0 +1,5 @@
const merge = require('webpack-merge');
const baseConfig = require('./config.base.js');
module.exports = merge(baseConfig, {
});

View file

@ -5,28 +5,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69004" />
<PackageReference Include="OrchardCore.DisplayManagement" Version="1.0.0-beta3-69004" />
</ItemGroup>
<ItemGroup>
<Content Include="Assets\css\workflow-editor-canvas.scss" />
<Content Include="Assets\js\index.js" />
<Content Include="Views\Shared\Components\WorkflowEditor\Default.cshtml">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Pack>false</Pack>
</Content>
<Content Include="Views\_ViewImports.cshtml">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Pack>false</Pack>
</Content>
</ItemGroup>
<ItemGroup>
<None Include="Assets\package-lock.json" />
<None Include="Assets\package.json" />
<None Include="Assets\webpack.config.js" />
<None Include="Views\Activity.Design.cshtml" />
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.DisplayManagement" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.Resources" Version="1.0.0-beta3-69230" />
</ItemGroup>
<ItemGroup>
@ -35,4 +16,26 @@
<ProjectReference Include="..\..\..\core\Flowsharp.Persistence.Abstractions\Flowsharp.Persistence.Abstractions.csproj" />
</ItemGroup>
</Project>
<ItemGroup>
<Content Include="Assets\package.json" />
<Content Include="Assets\src\scripts\index.js" />
<Content Include="Assets\src\scripts\workflow-models.js" />
<Content Include="Assets\src\styles\index.scss" />
<Content Include="Assets\src\styles\postcss.config.js" />
<Content Include="Assets\webpack\config.base.js" />
<Content Include="Assets\webpack\config.dev.js" />
<Content Include="Assets\webpack\config.prod.js" />
</ItemGroup>
<ItemGroup>
<None Remove="Assets\scripts\workflow-editor.js" />
<None Include="Assets\src\scripts\workflow-editor.js" />
<None Remove="Assets\styles\workflow-editor.scss" />
<None Include="Assets\src\styles\workflow-editor.scss" />
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot" />
</ItemGroup>
</Project>

View file

@ -2,5 +2,6 @@
[assembly: Module(
Name = "Flowsharp View Components",
Description = "Provides a set of reusable view components such as the Workflow Editor."
)]
Description = "Provides a set of reusable view components such as the Workflow Editor.",
Dependencies = new[] { "OrchardCore.Resources" }
)]

View file

@ -1,7 +1,13 @@
@using System.Drawing
@using Flowsharp.Activities
@using Newtonsoft.Json
@using Newtonsoft.Json.Serialization
@model dynamic
@{
var activity = (IActivity)Model.Activity;
var activityJson = JsonConvert.SerializeObject(activity, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver()});
var position = new Point(50, 50);
}
<div class="activity" style="left:@(position.X)px; top:@(position.Y)px;" id="@($"activity-1")" data-activity-id="1" >
<div class="activity" style="left:@(position.X)px; top:@(position.Y)px;" id="@($"activity-1")" data-activity-id="1" data-activity-json="@activityJson">
@await DisplayAsync(Model.Content)
</div>

View file

@ -1,12 +1,11 @@
@model WorkflowEditorViewModel
<div>
<h2>Workflow Editor</h2>
<div class="flowsharp-canvas">
<div class="workflow-canvas">
@foreach (var activityShape in Model.ActivityShapes)
{
@await DisplayAsync(activityShape)
}
</div>
</div>
<script src="~/main.js" charset="UTF-8"></script>
<script asp-name="flowsharpeditor" asp-src="~/Flowsharp.Web.ViewComponents/bundle.js" depends-on="jQuery" at="Foot"></script>

View file

@ -1,4 +1,6 @@
@using Flowsharp.Web.ViewComponents.ViewModels
@inherits OrchardCore.DisplayManagement.Razor.RazorPage<TModel>
@namespace Flowsharp.Web.ViewComponents.Views
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, OrchardCore.DisplayManagement
@addTagHelper *, OrchardCore.ResourceManagement

View file

@ -5,9 +5,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="OrchardCore.Application.Mvc.Targets">
<Version>1.0.0-beta3-69004</Version>
</PackageReference>
<PackageReference Include="OrchardCore.Application.Mvc.Targets" Version="1.0.0-beta3-69230" />
<PackageReference Include="OrchardCore.Resources" Version="1.0.0-beta3-69230" />
</ItemGroup>
<ItemGroup>

Some files were not shown because too many files have changed in this diff Show more