-
-
- {{ k }} |
- {{ v }} |
-
-
+
{{ capitalizedType }}*
+
+
+ Apply first!
+ URL: {{this.url}}
+
+
+
+ width |
+ {{ this.data.width }} |
+ px |
+
+
+ height |
+ {{ this.data.height }} |
+ px |
+
+
+ bitrate |
+ {{ this.data.bitrate }} |
+ kbps |
+
+
+
+
+ Target: {{ this.data.url }}
+
+
{
}
},
+ apiId: {
+ type: String,
+ default: null
+ },
options: {
type: Object,
default() {
@@ -155,6 +191,9 @@ export default {
}
},
mounted() {
+ if (this.apiId === null && this.type !== 'ingest') {
+ this.$nextTick(() => this.show.editor = true);
+ }
},
computed: {
nodeStyle() {
@@ -172,8 +211,16 @@ export default {
},
capitalizedType() {
return capitalize(this.type);
+ },
+ discardButtonLabel() {
+ if (this.type === 'ingest') {
+ return "CLOSE";
+ } else {
+ return "DISCARD";
+ }
}
},
+
methods: {
handleMousedown(e) {
const target = e.target || e.srcElement;
@@ -240,12 +287,18 @@ $portSize: 14;
.node-content {
font-size: 13px;
+ padding: 0.5em;
th {
width: 50%;
}
}
+
+ .node-content-long {
+ word-break: break-all;
+ }
+
}
.node-port {
diff --git a/src/simple-flowchart/components/SimpleFlowchart.vue b/src/simple-flowchart/components/SimpleFlowchart.vue
index f6c7283..6236f4f 100644
--- a/src/simple-flowchart/components/SimpleFlowchart.vue
+++ b/src/simple-flowchart/components/SimpleFlowchart.vue
@@ -152,7 +152,11 @@ export default {
const existed = this.scene.links.find((link) => {
return link.from === this.draggingLink.from && link.to === index;
})
- if (!existed) {
+ // check for conflicting
+ const conflicting = this.scene.links.find((link) => { // This makes sure that only one link can go towards a node
+ return link.to === index;
+ })
+ if (!existed && !conflicting) {
let maxID = Math.max(0, ...this.scene.links.map((link) => {
return link.id
}))
@@ -223,10 +227,16 @@ export default {
if (typeof target.className === 'string' && target.className.indexOf('node-delete') > -1) {
// console.log('delete2', this.action.dragging);
this.nodeDelete(this.action.dragging);
+ this.action.dragging = null;
}
}
+
+ if (this.action.dragging) {
+ this.$emit("nodeMoved", this.action.dragging);
+ this.action.dragging = null;
+ }
+
this.action.linking = false;
- this.action.dragging = null;
this.action.scrolling = false;
},
handleDown(e) {
diff --git a/src/views/Dashboard.vue b/src/views/Dashboard.vue
index 45a2cfb..adb5f74 100644
--- a/src/views/Dashboard.vue
+++ b/src/views/Dashboard.vue
@@ -2,7 +2,8 @@
-
+
@@ -11,7 +12,14 @@
-
+
@@ -24,7 +32,8 @@ import SimpleFlowchart from '@/simple-flowchart';
import ElementAdder from "@/components/ElementAdder";
import WorkspaceDrawerContent from "@/components/WorkspaceDrawerContent";
import Toolbar from "@/components/Toolbar";
-import {maxBy} from 'lodash';
+
+import {some} from 'lodash';
export default {
name: 'Dashboard',
@@ -36,7 +45,13 @@ export default {
},
data: () => ({
showDrawer: false,
- diagram: {
+ idGenerator: 1,
+ pendingChanges: {
+ created: [],
+ updated: [],
+ deleted: []
+ },
+ model: {
centerX: 0,
centerY: 0,
scale: 1,
@@ -51,40 +66,95 @@ export default {
let newNode = {
x: 10,
y: 10,
- type
+ type,
+ apiId: null
}
switch (type) {
case "ingest":
newNode.data = {
- "url": "https://videon.test.kmlabz.com/live"
+ url: "",
+ streamkey: "demokey"
}
break;
case "encoder":
newNode.data = {
- "bitrate": 8000,
- "width": 600,
- "height": 800
+ bitrate: 0,
+ width: 0,
+ height: 0
}
break;
case "restreamer":
newNode.data = {
- "url": "https://youtube.com/live",
- "streamkey": "testkey"
+ url: "",
+ streamkey: ""
}
break;
}
- if (this.diagram.nodes.length > 0) {
- const max_id = maxBy(this.diagram.nodes, 'id').id
+ newNode.id = this.idGenerator;
+ this.idGenerator++;
- newNode.id = max_id + 1;
+ this.model.nodes.push(newNode);
+ //this.pendingChanges.created.add(newNode.id);
+ this.enqueuePendingNodeCreation(newNode.id);
+
+ },
+ // Vuejs can not track changes of a set, so we do this magic hack to fix it
+ enqueuePendingNodeDeletion(id) {
+ let pending_deletes = new Set(this.pendingChanges.deleted);
+ let pending_updates = new Set(this.pendingChanges.updated);
+ let pending_creations = new Set(this.pendingChanges.created);
+
+ // This stuff is here to prevent the creation and deletion of an object in the same transaction
+ if (pending_creations.has(id)) {
+ pending_creations.delete(id);
} else {
- newNode.id = 1;
+ pending_deletes.add(id);
}
- this.diagram.nodes.push(newNode)
+ pending_updates.delete(id);
+ this.pendingChanges.deleted = Array.from(pending_deletes);
+ this.pendingChanges.updated = Array.from(pending_updates);
+ this.pendingChanges.created = Array.from(pending_creations);
+ },
+ enqueuePendingNodeUpdate(id) {
+ let pending_updates = new Set(this.pendingChanges.updated);
+ pending_updates.add(id);
+ this.pendingChanges.updated = Array.from(pending_updates);
+ },
+ enqueuePendingNodeCreation(id) {
+ let pending_creations = new Set(this.pendingChanges.created);
+ pending_creations.add(id);
+ this.pendingChanges.created = Array.from(pending_creations);
+ },
+ // --- end of magic hack
+ handleNodeMove() {
+ // TODO
+ },
+ handleLinkBreak({from,to}) {
+ this.enqueuePendingNodeUpdate(from);
+ this.enqueuePendingNodeUpdate(to);
+ },
+ handleLinkAdd({from, to}) {
+ this.enqueuePendingNodeUpdate(from);
+ this.enqueuePendingNodeUpdate(to);
+ },
+ performApply() {
+ this.pendingChanges.created.forEach((id) => {
+ this.model.nodes.find((n) => n.id === id).apiId = 'a';
+ });
+ this.pendingChanges = {
+ deleted: [],
+ created: [],
+ updated: []
+ }
+ }
+ },
+ computed: {
+ modelChanged() {
+ return some(this.pendingChanges, (o) => o.length > 0);
}
}