Closed cewebdesigner closed 1 year ago
Complete example of #31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.css"
/>
<script src="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.js"></script>
<style>
#drawflow {
position: relative;
width: 100%;
height: 800px;
border: 1px solid red;
}
</style>
</head>
<body>
<div>
<div id="drawflow"></div>
<button onclick="undo()">Undo</button>
<button onclick="redo()">Redo</button>
</div>
<script>
var id = document.getElementById("drawflow");
const editor = new Drawflow(id);
const history = [];
let historyStatus = null;
let historyActive = false;
let historyStop = false;
function undo() {
if(historyStatus == 1) {
return;
}
if(historyStatus === null) {
historyStatus = history.length;
}
if(historyStatus === history.length) {
historyActive = true;
history.push(editor.export())
history.splice(-1); // Fix editor export two events;
}
historyStatus = historyStatus-1;
historyActive = true;
editor.import(JSON.parse(history[historyStatus]));
editor.drawflow = new Proxy(editor.drawflow, handler);
}
function redo() {
if(historyStatus !== null && historyStatus < history.length-1) {
historyStatus = historyStatus+1;
historyActive = true;
editor.import(JSON.parse(history[historyStatus]));
editor.drawflow = new Proxy(editor.drawflow, handler);
}
}
editor.on("click", () => {
historyStop = true;
})
editor.on("mouseUp", () => {
historyStop = false;
historyActive = true;
history.push(editor.export())
history.splice(-1);
if(history.at(-2) === history.at(-1)) {
console.log("delete");
history.splice(-1);
} else {
/// ??? DELETE History at restore point????
historyStatus = history.length-1
}
})
const handler = {
get: function(target, property, receiver) {
console.log(JSON.stringify(target));
if(!historyActive && !historyStop) {
history.push(JSON.stringify(target));
}
historyActive = false;
return Reflect.get(...arguments)
},
}
editor.drawflow = new Proxy(editor.drawflow, handler);
editor.start();
history.splice(-2); // Fix history
editor.addNode('aaa', 0, 1, 100, 300, 'aaa', {}, 'aaa' );
editor.addNode('bbb', 1, 0, 200, 400, 'bbb', {}, 'bbb' );
editor.addNode('ccc', 1, 0, 500, 500, 'ccc', {}, 'ccc' );
</script>
</body>
</html>
Likewise as discussed in #31. It's an idea.
so i have this example however it does not work when i import json
when I remove the json import, then yes it works
Following the previous example, try this.
...
editor.addNode('bbb', 1, 0, 200, 400, 'bbb', {}, 'bbb' );
editor.addNode('ccc', 1, 0, 500, 500, 'ccc', {}, 'ccc' );
historyActive = true;
history.push(JSON.stringify(editor.export()));
history.splice(-1);
const dataToImport = {"drawflow":{"Home":{"data":{"1":{"id":1,"name":"welcome","data":{},"class":"welcome","html":"\n <div>\n <div class=\"title-box\">π Welcome!!</div>\n <div class=\"box\">\n <p>Simple flow library <b>demo</b>\n <a href=\"https://github.com/jerosoler/Drawflow\" target=\"_blank\">Drawflow</a> by <b>Jero Soler</b></p><br>\n\n <p>Multiple input / outputs<br>\n Data sync nodes<br>\n Import / export<br>\n Modules support<br>\n Simple use<br>\n Type: Fixed or Edit<br>\n Events: view console<br>\n Pure Javascript<br>\n </p>\n <br>\n <p><b><u>Shortkeys:</u></b></p>\n <p>πΉ <b>Delete</b> for remove selected<br>\n π Mouse Left Click == Move<br>\n β Mouse Right == Delete Option<br>\n π Ctrl + Wheel == Zoom<br>\n π± Mobile support<br>\n ...</p>\n </div>\n </div>\n ","typenode": false, "inputs":{},"outputs":{},"pos_x":50,"pos_y":50},"2":{"id":2,"name":"slack","data":{},"class":"slack","html":"\n <div>\n <div class=\"title-box\"><i class=\"fab fa-slack\"></i> Slack chat message</div>\n </div>\n ","typenode": false, "inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"pos_x":1028,"pos_y":87},"3":{"id":3,"name":"telegram","data":{"channel":"channel_2"},"class":"telegram","html":"\n <div>\n <div class=\"title-box\"><i class=\"fab fa-telegram-plane\"></i> Telegram bot</div>\n <div class=\"box\">\n <p>Send to telegram</p>\n <p>select channel</p>\n <select df-channel>\n <option value=\"channel_1\">Channel 1</option>\n <option value=\"channel_2\">Channel 2</option>\n <option value=\"channel_3\">Channel 3</option>\n <option value=\"channel_4\">Channel 4</option>\n </select>\n </div>\n </div>\n ","typenode": false, "inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"pos_x":1032,"pos_y":184},"4":{"id":4,"name":"email","data":{},"class":"email","html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-at\"></i> Send Email </div>\n </div>\n ","typenode": false, "inputs":{"input_1":{"connections":[{"node":"5","input":"output_1"}]}},"outputs":{},"pos_x":1033,"pos_y":439},"5":{"id":5,"name":"template","data":{"template":"Write your template"},"class":"template","html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-code\"></i> Template</div>\n <div class=\"box\">\n Ger Vars\n <textarea df-template></textarea>\n Output template with vars\n </div>\n </div>\n ","typenode": false, "inputs":{"input_1":{"connections":[{"node":"6","input":"output_1"}]}},"outputs":{"output_1":{"connections":[{"node":"4","output":"input_1"},{"node":"11","output":"input_1"}]}},"pos_x":607,"pos_y":304},"6":{"id":6,"name":"github","data":{"name":"https://github.com/jerosoler/Drawflow"},"class":"github","html":"\n <div>\n <div class=\"title-box\"><i class=\"fab fa-github \"></i> Github Stars</div>\n <div class=\"box\">\n <p>Enter repository url</p>\n <input type=\"text\" df-name>\n </div>\n </div>\n ","typenode": false, "inputs":{},"outputs":{"output_1":{"connections":[{"node":"5","output":"input_1"}]}},"pos_x":341,"pos_y":191},"7":{"id":7,"name":"facebook","data":{},"class":"facebook","html":"\n <div>\n <div class=\"title-box\"><i class=\"fab fa-facebook\"></i> Facebook Message</div>\n </div>\n ","typenode": false, "inputs":{},"outputs":{"output_1":{"connections":[{"node":"2","output":"input_1"},{"node":"3","output":"input_1"},{"node":"11","output":"input_1"}]}},"pos_x":347,"pos_y":87},"11":{"id":11,"name":"log","data":{},"class":"log","html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-file-signature\"></i> Save log file </div>\n </div>\n ","typenode": false, "inputs":{"input_1":{"connections":[{"node":"5","input":"output_1"},{"node":"7","input":"output_1"}]}},"outputs":{},"pos_x":1031,"pos_y":363}}},"Other":{"data":{"8":{"id":8,"name":"personalized","data":{},"class":"personalized","html":"\n <div>\n Personalized\n </div>\n ","typenode": false, "inputs":{"input_1":{"connections":[{"node":"12","input":"output_1"},{"node":"12","input":"output_2"},{"node":"12","input":"output_3"},{"node":"12","input":"output_4"}]}},"outputs":{"output_1":{"connections":[{"node":"9","output":"input_1"}]}},"pos_x":764,"pos_y":227},"9":{"id":9,"name":"dbclick","data":{"name":"Hello World!!"},"class":"dbclick","html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-mouse\"></i> Db Click</div>\n <div class=\"box dbclickbox\" ondblclick=\"showpopup(event)\">\n Db Click here\n <div class=\"modal\" style=\"display:none\">\n <div class=\"modal-content\">\n <span class=\"close\" onclick=\"closemodal(event)\">×</span>\n Change your variable {name} !\n <input type=\"text\" df-name>\n </div>\n\n </div>\n </div>\n </div>\n ","typenode": false, "inputs":{"input_1":{"connections":[{"node":"8","input":"output_1"}]}},"outputs":{"output_1":{"connections":[{"node":"12","output":"input_2"}]}},"pos_x":209,"pos_y":38},"12":{"id":12,"name":"multiple","data":{},"class":"multiple","html":"\n <div>\n <div class=\"box\">\n Multiple!\n </div>\n </div>\n ","typenode": false, "inputs":{"input_1":{"connections":[]},"input_2":{"connections":[{"node":"9","input":"output_1"}]},"input_3":{"connections":[]}},"outputs":{"output_1":{"connections":[{"node":"8","output":"input_1"}]},"output_2":{"connections":[{"node":"8","output":"input_1"}]},"output_3":{"connections":[{"node":"8","output":"input_1"}]},"output_4":{"connections":[{"node":"8","output":"input_1"}]}},"pos_x":179,"pos_y":272}}}}}
editor.import(dataToImport);
editor.drawflow = new Proxy(editor.drawflow, handler);
historyActive = false;
I'm implementing this solution, and I noticed that when I use editor.import json, this undo and redo solution doesn't work, it only works if I remove code from editor.import
31