diff --git a/angular.json b/angular.json
index cc6bb425e..f2f5a0297 100644
--- a/angular.json
+++ b/angular.json
@@ -108,7 +108,9 @@
"dist/common/assets/fonts/material-design-icons/material-icons.css",
"node_modules/codemirror/lib/codemirror.css",
"node_modules/ol/ol.css",
- "./node_modules/vis-timeline/dist/vis-timeline-graph2d.min.css"
+ "./node_modules/vis-timeline/dist/vis-timeline-graph2d.min.css",
+ "node_modules/workflow-editor/src/workflow_editor/static/widget.css",
+ "node_modules/@fortawesome/fontawesome-free/css/all.min.css"
],
"scripts": ["node_modules/vis-timeline/peer/esm/vis-timeline-graph2d.min.js"],
"vendorChunk": true,
diff --git a/package-lock.json b/package-lock.json
index eb4b0c611..b24a711ec 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,6 +20,7 @@
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/router": "^17.3.0",
"@egjs/hammerjs": "^2.0.17",
+ "@fortawesome/fontawesome-free": "^5.15.4",
"@geoengine/openapi-client": "0.0.10",
"codemirror": "~5.65.16",
"d3": "~7.9.0",
@@ -43,6 +44,7 @@
"vis-data": "7.1.9",
"vis-timeline": "7.7.3",
"vis-util": "5.0.7",
+ "workflow-editor": "git+https://github.com/1lutz/workflow-editor.git",
"xss": "1.0.15",
"zone.js": "~0.14.4"
},
@@ -2964,6 +2966,22 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
+ "node_modules/@dagrejs/dagre": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@dagrejs/dagre/-/dagre-1.1.4.tgz",
+ "integrity": "sha512-QUTc54Cg/wvmlEUxB+uvoPVKFazM1H18kVHBQNmK2NbrDR5ihOCR6CXLnDSZzMcSQKJtabPUWridBOlJM3WkDg==",
+ "dependencies": {
+ "@dagrejs/graphlib": "2.2.4"
+ }
+ },
+ "node_modules/@dagrejs/graphlib": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-2.2.4.tgz",
+ "integrity": "sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw==",
+ "engines": {
+ "node": ">17.0.0"
+ }
+ },
"node_modules/@discoveryjs/json-ext": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -3489,6 +3507,15 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
+ "node_modules/@fortawesome/fontawesome-free": {
+ "version": "5.15.4",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz",
+ "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==",
+ "hasInstallScript": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@geoengine/openapi-client": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/@geoengine/openapi-client/-/openapi-client-0.0.10.tgz",
@@ -3718,6 +3745,17 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@json-editor/json-editor": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/@json-editor/json-editor/-/json-editor-2.15.1.tgz",
+ "integrity": "sha512-Z4KFXpL7I9wrKD94c1PcIwFfCvUzYhwM0jH2ihP2OSH8wut0FnqzCfKCL0gdNHG3A2UVsyVJBoU9Iwsc0xB6zQ==",
+ "dependencies": {
+ "core-js": "^3.27.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
"node_modules/@leichtgewicht/ip-codec": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz",
@@ -5093,6 +5131,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
"node_modules/@puppeteer/browsers": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.0.tgz",
@@ -8052,6 +8100,24 @@
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"dev": true
},
+ "node_modules/bootstrap": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
+ "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ }
+ ],
+ "peerDependencies": {
+ "@popperjs/core": "^2.11.8"
+ }
+ },
"node_modules/bplist-parser": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
@@ -8343,6 +8409,11 @@
}
]
},
+ "node_modules/capability": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/capability/-/capability-0.2.5.tgz",
+ "integrity": "sha512-rsJZYVCgXd08sPqwmaIqjAd5SUTfonV0z/gDJ8D6cN8wQphky1kkAYEqQ+hmDxTw7UihvBfjUVUSY+DBEe44jg=="
+ },
"node_modules/caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -8815,6 +8886,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/core-js": {
+ "version": "3.38.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz",
+ "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==",
+ "hasInstallScript": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
"node_modules/core-js-compat": {
"version": "3.36.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz",
@@ -10623,6 +10704,16 @@
"is-arrayish": "^0.2.1"
}
},
+ "node_modules/error-polyfill": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/error-polyfill/-/error-polyfill-0.1.3.tgz",
+ "integrity": "sha512-XHJk60ufE+TG/ydwp4lilOog549iiQF2OAPhkk9DdiYWMrltz5yhDz/xnKuenNwP7gy3dsibssO5QpVhkrSzzg==",
+ "dependencies": {
+ "capability": "^0.2.5",
+ "o3": "^1.0.3",
+ "u3": "^0.1.1"
+ }
+ },
"node_modules/es-abstract": {
"version": "1.22.3",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz",
@@ -14159,6 +14250,14 @@
"node >= 0.2.0"
]
},
+ "node_modules/jsonschema": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz",
+ "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/jsprim": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
@@ -14590,6 +14689,11 @@
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
+ "node_modules/litegraph.js": {
+ "version": "0.7.18",
+ "resolved": "https://registry.npmjs.org/litegraph.js/-/litegraph.js-0.7.18.tgz",
+ "integrity": "sha512-1WEwjOO58j4FcLX8DvsuMXM371MEq4Y+8pBr3q2pBhJ9nDkwBtBd9Gj6bxArBKhW6i42bSOyv9ybeuez6NAxoQ=="
+ },
"node_modules/loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
@@ -16369,6 +16473,14 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
+ "node_modules/o3": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/o3/-/o3-1.0.3.tgz",
+ "integrity": "sha512-f+4n+vC6s4ysy7YO7O2gslWZBUu8Qj2i2OUJOvjRxQva7jVjYjB29jrr9NCjmxZQR0gzrOcv1RnqoYOeMs5VRQ==",
+ "dependencies": {
+ "capability": "^0.2.5"
+ }
+ },
"node_modules/oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@@ -20195,6 +20307,11 @@
"node": ">=14.17"
}
},
+ "node_modules/u3": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/u3/-/u3-0.1.1.tgz",
+ "integrity": "sha512-+J5D5ir763y+Am/QY6hXNRlwljIeRMZMGs0cT6qqZVVzzT3X3nFPXVyPOFRMOR4kupB0T8JnCdpWdp6Q/iXn3w=="
+ },
"node_modules/ua-parser-js": {
"version": "0.7.35",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz",
@@ -21571,6 +21688,28 @@
"resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.3.3.tgz",
"integrity": "sha512-ZnV3yH8/k58ZPACOXeiHaMuXIiaTk1t0hSUVisbO0t4RjA5wPpUytcxeyiN2h+LZRrmuHIh/1UlrR9e7DHDvTw=="
},
+ "node_modules/workflow-editor": {
+ "version": "1.0.0",
+ "resolved": "git+ssh://git@github.com/1lutz/workflow-editor.git#af6d7d29e2da77c9f123d253c3672ba0135b8ad8",
+ "dependencies": {
+ "@dagrejs/dagre": "^1.1.3",
+ "@json-editor/json-editor": "^2.14.0",
+ "bootstrap": "^5.3.2",
+ "error-polyfill": "^0.1.3",
+ "jsonschema": "^1.4.1",
+ "litegraph.js": "^0.7.18",
+ "yaml": "^2.4.5",
+ "zod": "^3.23.4"
+ }
+ },
+ "node_modules/workflow-editor/node_modules/zod": {
+ "version": "3.23.8",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
+ "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
"node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
@@ -21756,6 +21895,17 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true
},
+ "node_modules/yaml": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz",
+ "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
@@ -23736,6 +23886,19 @@
}
}
},
+ "@dagrejs/dagre": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@dagrejs/dagre/-/dagre-1.1.4.tgz",
+ "integrity": "sha512-QUTc54Cg/wvmlEUxB+uvoPVKFazM1H18kVHBQNmK2NbrDR5ihOCR6CXLnDSZzMcSQKJtabPUWridBOlJM3WkDg==",
+ "requires": {
+ "@dagrejs/graphlib": "2.2.4"
+ }
+ },
+ "@dagrejs/graphlib": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-2.2.4.tgz",
+ "integrity": "sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw=="
+ },
"@discoveryjs/json-ext": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -24010,6 +24173,11 @@
"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
"dev": true
},
+ "@fortawesome/fontawesome-free": {
+ "version": "5.15.4",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz",
+ "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg=="
+ },
"@geoengine/openapi-client": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/@geoengine/openapi-client/-/openapi-client-0.0.10.tgz",
@@ -24180,6 +24348,14 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "@json-editor/json-editor": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/@json-editor/json-editor/-/json-editor-2.15.1.tgz",
+ "integrity": "sha512-Z4KFXpL7I9wrKD94c1PcIwFfCvUzYhwM0jH2ihP2OSH8wut0FnqzCfKCL0gdNHG3A2UVsyVJBoU9Iwsc0xB6zQ==",
+ "requires": {
+ "core-js": "^3.27.2"
+ }
+ },
"@leichtgewicht/ip-codec": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz",
@@ -25350,6 +25526,12 @@
}
}
},
+ "@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "peer": true
+ },
"@puppeteer/browsers": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.0.tgz",
@@ -27705,6 +27887,12 @@
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"dev": true
},
+ "bootstrap": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
+ "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
+ "requires": {}
+ },
"bplist-parser": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
@@ -27901,6 +28089,11 @@
"integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==",
"dev": true
},
+ "capability": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/capability/-/capability-0.2.5.tgz",
+ "integrity": "sha512-rsJZYVCgXd08sPqwmaIqjAd5SUTfonV0z/gDJ8D6cN8wQphky1kkAYEqQ+hmDxTw7UihvBfjUVUSY+DBEe44jg=="
+ },
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -28277,6 +28470,11 @@
}
}
},
+ "core-js": {
+ "version": "3.38.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz",
+ "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw=="
+ },
"core-js-compat": {
"version": "3.36.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz",
@@ -29647,6 +29845,16 @@
"is-arrayish": "^0.2.1"
}
},
+ "error-polyfill": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/error-polyfill/-/error-polyfill-0.1.3.tgz",
+ "integrity": "sha512-XHJk60ufE+TG/ydwp4lilOog549iiQF2OAPhkk9DdiYWMrltz5yhDz/xnKuenNwP7gy3dsibssO5QpVhkrSzzg==",
+ "requires": {
+ "capability": "^0.2.5",
+ "o3": "^1.0.3",
+ "u3": "^0.1.1"
+ }
+ },
"es-abstract": {
"version": "1.22.3",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz",
@@ -32272,6 +32480,11 @@
"integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
"dev": true
},
+ "jsonschema": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz",
+ "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ=="
+ },
"jsprim": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
@@ -32616,6 +32829,11 @@
"integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==",
"dev": true
},
+ "litegraph.js": {
+ "version": "0.7.18",
+ "resolved": "https://registry.npmjs.org/litegraph.js/-/litegraph.js-0.7.18.tgz",
+ "integrity": "sha512-1WEwjOO58j4FcLX8DvsuMXM371MEq4Y+8pBr3q2pBhJ9nDkwBtBd9Gj6bxArBKhW6i42bSOyv9ybeuez6NAxoQ=="
+ },
"loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
@@ -33848,6 +34066,14 @@
}
}
},
+ "o3": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/o3/-/o3-1.0.3.tgz",
+ "integrity": "sha512-f+4n+vC6s4ysy7YO7O2gslWZBUu8Qj2i2OUJOvjRxQva7jVjYjB29jrr9NCjmxZQR0gzrOcv1RnqoYOeMs5VRQ==",
+ "requires": {
+ "capability": "^0.2.5"
+ }
+ },
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@@ -36720,6 +36946,11 @@
"integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
"dev": true
},
+ "u3": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/u3/-/u3-0.1.1.tgz",
+ "integrity": "sha512-+J5D5ir763y+Am/QY6hXNRlwljIeRMZMGs0cT6qqZVVzzT3X3nFPXVyPOFRMOR4kupB0T8JnCdpWdp6Q/iXn3w=="
+ },
"ua-parser-js": {
"version": "0.7.35",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz",
@@ -37766,6 +37997,27 @@
"resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.3.3.tgz",
"integrity": "sha512-ZnV3yH8/k58ZPACOXeiHaMuXIiaTk1t0hSUVisbO0t4RjA5wPpUytcxeyiN2h+LZRrmuHIh/1UlrR9e7DHDvTw=="
},
+ "workflow-editor": {
+ "version": "git+ssh://git@github.com/1lutz/workflow-editor.git#af6d7d29e2da77c9f123d253c3672ba0135b8ad8",
+ "from": "workflow-editor@git+https://github.com/1lutz/workflow-editor.git",
+ "requires": {
+ "@dagrejs/dagre": "^1.1.3",
+ "@json-editor/json-editor": "^2.14.0",
+ "bootstrap": "^5.3.2",
+ "error-polyfill": "^0.1.3",
+ "jsonschema": "^1.4.1",
+ "litegraph.js": "^0.7.18",
+ "yaml": "^2.4.5",
+ "zod": "^3.23.4"
+ },
+ "dependencies": {
+ "zod": {
+ "version": "3.23.8",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
+ "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="
+ }
+ }
+ },
"wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
@@ -37897,6 +38149,11 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true
},
+ "yaml": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz",
+ "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q=="
+ },
"yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
diff --git a/package.json b/package.json
index 290de086a..96a3263fb 100644
--- a/package.json
+++ b/package.json
@@ -53,6 +53,7 @@
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/router": "^17.3.0",
"@egjs/hammerjs": "^2.0.17",
+ "@fortawesome/fontawesome-free": "^5.15.4",
"@geoengine/openapi-client": "0.0.10",
"codemirror": "~5.65.16",
"d3": "~7.9.0",
@@ -76,6 +77,7 @@
"vis-data": "7.1.9",
"vis-timeline": "7.7.3",
"vis-util": "5.0.7",
+ "workflow-editor": "git+https://github.com/1lutz/workflow-editor.git",
"xss": "1.0.15",
"zone.js": "~0.14.4"
},
diff --git a/projects/core/src/lib/core.module.ts b/projects/core/src/lib/core.module.ts
index 78dc199d4..f95e53a83 100644
--- a/projects/core/src/lib/core.module.ts
+++ b/projects/core/src/lib/core.module.ts
@@ -148,6 +148,8 @@ import {MapResolutionExtentOverlayComponent} from './map/map-info/map-resolution
import {DownloadLayerComponent} from './download-layer/download-layer.component';
import {BandwiseExpressionOperatorComponent} from './operators/dialogs/bandwise-expression-operator/bandwise-expression-operator.component';
import {BandNeighborhoodAggregateComponent} from './operators/dialogs/band-neighborhood-aggregate/band-neighborhood-aggregate.component';
+import {WorkflowEditorComponent} from "./workflow-editor/workflow-editor.component";
+import {CreateWorkflowComponent} from "./datasets/create-workflow/create-workflow.component";
export const MATERIAL_MODULES = [
MatAutocompleteModule,
@@ -195,6 +197,7 @@ const CORE_PIPES = [
const CORE_COMPONENTS = [
AddDataComponent,
AddWorkflowComponent,
+ CreateWorkflowComponent,
AutocompleteSelectDirective,
BackendStatusPageComponent,
BoxPlotOperatorComponent,
@@ -232,7 +235,6 @@ const CORE_COMPONENTS = [
LayerListMenuComponent,
LayerSelectionComponent,
LineageGraphComponent,
- LineageGraphComponent,
LineSimplificationComponent,
LoadProjectComponent,
LoginComponent,
@@ -301,6 +303,7 @@ const CORE_COMPONENTS = [
WorkspaceSettingsComponent,
ZoomHandlesComponent,
+ WorkflowEditorComponent
];
@NgModule({
diff --git a/projects/core/src/lib/datasets/add-data/add-data.component.ts b/projects/core/src/lib/datasets/add-data/add-data.component.ts
index 20ed4a2db..026efc0cc 100644
--- a/projects/core/src/lib/datasets/add-data/add-data.component.ts
+++ b/projects/core/src/lib/datasets/add-data/add-data.component.ts
@@ -6,6 +6,7 @@ import {LayoutService, SidenavConfig} from '../../layout.service';
import {AddWorkflowComponent} from '../add-workflow/add-workflow.component';
import {DrawFeaturesComponent} from '../draw-features/draw-features.component';
import {UploadComponent} from '../upload/upload.component';
+import {CreateWorkflowComponent} from "../create-workflow/create-workflow.component";
export interface AddDataButton {
name: string;
@@ -98,4 +99,16 @@ export class AddDataComponent {
sidenavConfig: {component: AddWorkflowComponent, keepParent: true},
};
}
+
+ /**
+ * Create workflow dialog
+ */
+ static createWorkflowEditorButton(): AddDataButton {
+ return {
+ name: 'Create Workflow using Editor',
+ description: 'Add a new workflow by graph editor',
+ icon: 'build',
+ sidenavConfig: {component: CreateWorkflowComponent, keepParent: true},
+ };
+ }
}
diff --git a/projects/core/src/lib/datasets/add-workflow/add-workflow.component.ts b/projects/core/src/lib/datasets/add-workflow/add-workflow.component.ts
index 2602b16b4..fbf15dcd3 100644
--- a/projects/core/src/lib/datasets/add-workflow/add-workflow.component.ts
+++ b/projects/core/src/lib/datasets/add-workflow/add-workflow.component.ts
@@ -1,10 +1,11 @@
import {Component, ChangeDetectionStrategy} from '@angular/core';
import {UntypedFormGroup, UntypedFormControl, Validators} from '@angular/forms';
-import {GeoEngineErrorDict, RasterResultDescriptorDict, UUID, VectorResultDescriptorDict} from '../../backend/backend.model';
+import {UUID} from '../../backend/backend.model';
import {NotificationService} from '../../notification.service';
import {ProjectService} from '../../project/project.service';
import {RandomColorService} from '../../util/services/random-color.service';
-import {RasterLayer, RasterSymbology, VectorLayer, createVectorSymbology, isValidUuid} from '@geoengine/common';
+import {isValidUuid} from '@geoengine/common';
+import {DatasetService} from "../dataset.service";
@Component({
selector: 'geoengine-add-workflow',
@@ -19,6 +20,7 @@ export class AddWorkflowComponent {
protected readonly projectService: ProjectService,
protected readonly notificationService: NotificationService,
protected readonly randomColorService: RandomColorService,
+ protected readonly datasetService: DatasetService,
) {
this.form = new UntypedFormGroup({
layerName: new UntypedFormControl('New Layer', Validators.required),
@@ -30,71 +32,22 @@ export class AddWorkflowComponent {
const layerName: string = this.form.controls.layerName.value;
const workflowId: UUID = this.form.controls.workflowId.value;
- this.projectService.getWorkflowMetaData(workflowId).subscribe(
- (resultDescriptorDict) => {
- const keys = Object.keys(resultDescriptorDict);
+ this.datasetService.createLayerFromWorkflow(layerName, workflowId).subscribe(
+ layer => {
+ this.projectService.addLayer(layer);
+ },
+ error => {
+ let errorMessage = `No workflow found for id: ${workflowId}`;
- if (keys.includes('columns')) {
- this.addVectorLayer(layerName, workflowId, resultDescriptorDict as VectorResultDescriptorDict);
- } else if (keys.includes('bands')) {
- this.addRasterLayer(layerName, workflowId, resultDescriptorDict as RasterResultDescriptorDict);
+ if ("error" in error) {
+ if (error.error !== 'NoWorkflowForGivenId') {
+ errorMessage = `Unknown error -> ${error.error}: ${error.message}`;
+ }
} else {
- // TODO: implement plots, etc.
- this.notificationService.error('Adding this workflow type is unimplemented, yet');
+ errorMessage = error.message;
}
- },
- (requestError) => this.handleError(requestError.error, workflowId),
+ this.notificationService.error(errorMessage);
+ }
);
}
-
- private addVectorLayer(layerName: string, workflowId: UUID, resultDescriptor: VectorResultDescriptorDict): void {
- const layer = new VectorLayer({
- name: layerName,
- workflowId,
- isVisible: true,
- isLegendVisible: false,
- symbology: createVectorSymbology(resultDescriptor.dataType, this.randomColorService.getRandomColorRgba()),
- });
-
- this.projectService.addLayer(layer);
- }
-
- private addRasterLayer(layerName: string, workflowId: UUID, _resultDescriptor: RasterResultDescriptorDict): void {
- const layer = new RasterLayer({
- name: layerName,
- workflowId,
- isVisible: true,
- isLegendVisible: false,
- symbology: RasterSymbology.fromRasterSymbologyDict({
- type: 'raster',
- opacity: 1.0,
- rasterColorizer: {
- type: 'singleBand',
- band: 0,
- bandColorizer: {
- type: 'linearGradient',
- breakpoints: [
- {value: 1, color: [0, 0, 0, 255]},
- {value: 255, color: [255, 255, 255, 255]},
- ],
- overColor: [255, 255, 255, 127],
- underColor: [0, 0, 0, 127],
- noDataColor: [0, 0, 0, 0],
- },
- },
- }),
- });
-
- this.projectService.addLayer(layer);
- }
-
- private handleError(error: GeoEngineErrorDict, workflowId: UUID): void {
- let errorMessage = `No workflow found for id: ${workflowId}`;
-
- if (error.error !== 'NoWorkflowForGivenId') {
- errorMessage = `Unknown error -> ${error.error}: ${error.message}`;
- }
-
- this.notificationService.error(errorMessage);
- }
}
diff --git a/projects/core/src/lib/datasets/create-workflow/create-workflow.component.html b/projects/core/src/lib/datasets/create-workflow/create-workflow.component.html
new file mode 100644
index 000000000..8a918b969
--- /dev/null
+++ b/projects/core/src/lib/datasets/create-workflow/create-workflow.component.html
@@ -0,0 +1,21 @@
+
+ Here you can add a new layer by creating a new workflow using an interactive graph-based editor.
+