diff --git a/src/components/WorkspaceDrawerContent.vue b/src/components/WorkspaceDrawerContent.vue index 17bbe15..9080a17 100644 --- a/src/components/WorkspaceDrawerContent.vue +++ b/src/components/WorkspaceDrawerContent.vue @@ -24,9 +24,18 @@ - - - + + + + + + + + + + + +
Creations:0
Updates:0
Deletions:0
Creations:{{ pendingChanges.created.length }}
Updates:{{ pendingChanges.updated.length }}
Deletions:{{ pendingChanges.deleted.length }}
diff --git a/src/views/Dashboard.vue b/src/views/Dashboard.vue index 3f46d8f..4fa76b9 100644 --- a/src/views/Dashboard.vue +++ b/src/views/Dashboard.vue @@ -4,7 +4,7 @@ @@ -36,7 +36,7 @@ import ElementAdder from "@/components/ElementAdder"; import WorkspaceDrawerContent from "@/components/WorkspaceDrawerContent"; import Toolbar from "@/components/Toolbar"; -import {some} from 'lodash'; +import {some, map, cloneDeep} from 'lodash'; export default { name: 'Dashboard', @@ -55,6 +55,7 @@ export default { deleted: [] // Stores apiId instead of localId }, pendingNodeMoves: 0, // count of inflight coord modifications + processingNodeChanges: false, model: { centerX: 0, centerY: 0, @@ -163,15 +164,141 @@ export default { this.enqueuePendingNodeUpdate(to); }, performApply() { - this.pendingChanges.created.forEach((id) => { - this.model.nodes.find((n) => n.id === id).apiId = 'a'; - }); + this.processingNodeChanges = true; + + const pendingChangesSnapshot = cloneDeep(this.pendingChanges); + const modelSnapshot = cloneDeep(this.model); this.pendingChanges = { - deleted: [], created: [], - updated: [] + updated: [], + deleted: [] } - } + + let creation_promises = [] + + // Perform creations + pendingChangesSnapshot.created.forEach((id) => { + const new_node = modelSnapshot.nodes.find((n) => n.id === id); + if (new_node) { + creation_promises.push(new Promise((resolve, reject) => { + + let data = { + x: new_node.x, + y: new_node.y + } + + let translated_type = new_node.type; + + switch (new_node.type) { + case "ingest": + data["outputNeighbours"] = []; + break; + case "restreamer": + data["inputNeighbour"] = null; + data["outputURLs"] = []; + translated_type = "restream"; + break; + case "encoder": + data["inputNeighbour"] = null; + data["outputNeighbours"] = [] + data["bitrate"] = 0; + data["width"] = 0; + data["height"] = 0; + translated_type = "encode"; + break; + } + + + this.$api.post(`objects/streamerobjects/${translated_type}`, data).then((resp) => { + new_node.apiId = resp.data.id; + return resolve(); + }).catch(reject); + + })); + + } + + }); + + // Perform Updates + Promise.all(creation_promises).then(() => { + + let update_promises = []; + pendingChangesSnapshot.created.forEach((id) => { + const changed_node = modelSnapshot.nodes.find((n) => n.id === id); + if (changed_node) { + update_promises.push(new Promise((resolve, reject) => { + + const api_id = changed_node.apiId; + let data = { + x: changed_node.x, + y: changed_node.y + } + // Find neighbors + + // Input first + let input_neighbor = null; + const input_link = modelSnapshot.links.find((link) => link.to === changed_node.id); + if (input_link) { + input_neighbor = modelSnapshot.nodes.find((node) => node.id === input_link.from); + } + + // Then output + let output_neighbors = []; + const output_links = modelSnapshot.links.filter((link) => link.from === changed_node.id); + if (output_links) { + output_neighbors = modelSnapshot.nodes.filter((node) => node.id === input_link.to); + } + + // Compile type specific attributes + let translated_type = changed_node.type; + switch (changed_node.type) { + case "ingest": + data["outputNeighbours"] = map(output_neighbors, 'apiId'); + break; + case "restreamer": + data["inputNeighbour"] = input_neighbor ? input_neighbor.apiId : null; + data["outputURLs"] = [changed_node.data.url]; + translated_type = "restream"; + break; + case "encoder": + data["inputNeighbour"] = input_neighbor ? input_neighbor.apiId : null; + data["outputNeighbours"] = map(output_neighbors, 'apiId'); + data["bitrate"] = changed_node.data.bitrate; + data["width"] = changed_node.data.width; + data["height"] = changed_node.data.height; + translated_type = "encode"; + break; + } + + // and then send it + this.$api.put(`objects/streamerobjects/${translated_type}/${api_id}`, data).then(() => { + return resolve(); + }).catch(reject); + + })); + } + }); + + // Perform deletions + Promise.all(update_promises).then(() => { + + let delete_promises = []; + pendingChangesSnapshot.deleted.forEach((apiId) => { + delete_promises.push( + this.$api.delete(`objects/streamerobjects/${apiId}`) + ); + }); + + Promise.all(delete_promises).then(() => { + this.processingNodeChanges = false; + }); + + }); + + }); + + }, }, computed: { modelChanged() {