From c0970835ab95de71e3bb75ca3231de4d2c46fc74 Mon Sep 17 00:00:00 2001 From: Peter Stockings Date: Tue, 25 Nov 2025 15:43:12 +1100 Subject: [PATCH] Add feature to restore script content to a specific version on history page --- routes/http.py | 44 +++++++++++++++++++ routes/timer.py | 44 +++++++++++++++++++ static/js/mithril/FunctionHistory.js | 37 ++++++++++++++-- .../dashboard/http_functions/history.html | 6 ++- .../dashboard/timer_functions/history.html | 6 ++- 5 files changed, 131 insertions(+), 6 deletions(-) diff --git a/routes/http.py b/routes/http.py index d37462d..ca4cef1 100644 --- a/routes/http.py +++ b/routes/http.py @@ -393,3 +393,47 @@ def editor(function_id): ) return render_template("dashboard/http_functions/editor.html", **editor_data) + + +@http.route("/restore/", methods=["POST"]) +@login_required +def restore(function_id): + try: + user_id = current_user.id + version_number = request.json.get("version_number") + + if not version_number: + return jsonify({"status": "error", "message": "Version number is required"}), 400 + + # Verify ownership and existence of the function + http_function = db.execute( + "SELECT id FROM http_functions WHERE id = %s AND user_id = %s", + [function_id, user_id], + one=True + ) + if not http_function: + return jsonify({"status": "error", "message": "Function not found"}), 404 + + # Fetch the content of the selected version + version_data = db.execute( + "SELECT script_content FROM http_functions_versions WHERE http_function_id = %s AND version_number = %s", + [function_id, version_number], + one=True + ) + + if not version_data: + return jsonify({"status": "error", "message": "Version not found"}), 404 + + # Update the function with the old script content + # This will trigger the database function to create a new version entry + db.execute( + "UPDATE http_functions SET script_content = %s WHERE id = %s", + [version_data["script_content"], function_id], + commit=True + ) + + return jsonify({"status": "success", "message": f"Restored to version {version_number}"}) + + except Exception as e: + print(e) + return jsonify({"status": "error", "message": str(e)}), 500 diff --git a/routes/timer.py b/routes/timer.py index a62218a..c031e9b 100644 --- a/routes/timer.py +++ b/routes/timer.py @@ -465,3 +465,47 @@ def history(function_id): return render_block(environment, 'dashboard/timer_functions/history.html', 'page', **args) return render_template('dashboard/timer_functions/history.html', **args) + +@timer.route('/restore/', methods=['POST']) +@login_required +def restore(function_id): + try: + user_id = current_user.id + version_number = request.json.get('version_number') + + if not version_number: + return jsonify({"status": "error", "message": "Version number is required"}), 400 + + # Verify ownership and existence of the function + timer_function = db.execute( + "SELECT id FROM timer_functions WHERE id = %s AND user_id = %s", + [function_id, user_id], + one=True + ) + if not timer_function: + return jsonify({"status": "error", "message": "Timer function not found"}), 404 + + # Fetch the content of the selected version + version_data = db.execute( + "SELECT script FROM timer_function_versions WHERE timer_function_id = %s AND version_number = %s", + [function_id, version_number], + one=True + ) + + if not version_data: + return jsonify({"status": "error", "message": "Version not found"}), 404 + + # Update the function with the old script content + # This will trigger the database function to create a new version entry + db.execute( + "UPDATE timer_functions SET code = %s WHERE id = %s", + [version_data["script"], function_id], + commit=True + ) + + return jsonify({"status": "success", "message": f"Restored to version {version_number}"}) + + except Exception as e: + print(e) + return jsonify({"status": "error", "message": str(e)}), 500 + diff --git a/static/js/mithril/FunctionHistory.js b/static/js/mithril/FunctionHistory.js index f5e506b..247f4a0 100644 --- a/static/js/mithril/FunctionHistory.js +++ b/static/js/mithril/FunctionHistory.js @@ -74,10 +74,12 @@ const FunctionHistory = { m(".flex-1.p-4.bg-white.dark:bg-gray-900", [ mode === "view" ? m("div", [ - m( - "h3.text-lg.font-semibold.mb-2", - `Version ${selectedVersion.version_number}` - ), + m("div.flex.justify-between.items-center.mb-2", [ + m("h3.text-lg.font-semibold", `Version ${selectedVersion.version_number}`), + m("button.bg-blue-500.hover:bg-blue-600.text-white.px-3.py-1.rounded.text-sm", { + onclick: () => FunctionHistory.restoreVersion(vnode) + }, "Restore this Version") + ]), m("div#editor-history", { style: "height: 600px;" }), ]) : m("div", [ @@ -175,6 +177,33 @@ const FunctionHistory = { } }, + restoreVersion: async function (vnode) { + const { selectedVersion } = vnode.state; + const { restore_url } = vnode.attrs; + + if (!confirm(`Are you sure you want to restore version ${selectedVersion.version_number}? This will create a new version with this content.`)) { + return; + } + + try { + const response = await m.request({ + method: "POST", + url: restore_url, + body: { version_number: selectedVersion.version_number } + }); + + if (response.status === "success") { + Alert.show(response.message, "success"); + // Reload the page to show the new version + window.location.reload(); + } else { + Alert.show(response.message || "Error restoring version", "error"); + } + } catch (err) { + Alert.show(err.message || "Error restoring version", "error"); + } + }, + onremove: function (vnode) { if (vnode.state.editor) { vnode.state.editor.destroy(); diff --git a/templates/dashboard/http_functions/history.html b/templates/dashboard/http_functions/history.html index 85767a8..34fe41a 100644 --- a/templates/dashboard/http_functions/history.html +++ b/templates/dashboard/http_functions/history.html @@ -18,7 +18,11 @@ history_url=url_for('http.history', function_id=function_id)) }} {% endblock %} \ No newline at end of file diff --git a/templates/dashboard/timer_functions/history.html b/templates/dashboard/timer_functions/history.html index 7779d28..3bd0651 100644 --- a/templates/dashboard/timer_functions/history.html +++ b/templates/dashboard/timer_functions/history.html @@ -20,7 +20,11 @@ history_url=url_for('timer.history', function_id=function_id)) {% endblock %} \ No newline at end of file