Add feature to restore script content to a specific version on history page

This commit is contained in:
Peter Stockings
2025-11-25 15:43:12 +11:00
parent 17518c3fcc
commit c0970835ab
5 changed files with 131 additions and 6 deletions

View File

@@ -393,3 +393,47 @@ def editor(function_id):
)
return render_template("dashboard/http_functions/editor.html", **editor_data)
@http.route("/restore/<int:function_id>", 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

View File

@@ -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/<int:function_id>', 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

View File

@@ -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();

View File

@@ -18,7 +18,11 @@ history_url=url_for('http.history', function_id=function_id)) }}
<script>
// Mount the Mithril component with versions as an attribute
m.mount(document.getElementById("history-view"), {
view: () => m(FunctionHistory, { versions: {{ versions| tojson | safe }} })
view: () => m(FunctionHistory, {
versions: {{ versions| tojson | safe }},
function_id: {{ function_id }},
restore_url: "{{ url_for('http.restore', function_id=function_id) }}"
})
});
</script>
{% endblock %}

View File

@@ -20,7 +20,11 @@ history_url=url_for('timer.history', function_id=function_id))
<script>
// Mount the Mithril component with versions as an attribute
m.mount(document.getElementById("history-view"), {
view: () => m(FunctionHistory, { versions: {{ versions| tojson | safe }} })
view: () => m(FunctionHistory, {
versions: {{ versions| tojson | safe }},
function_id: {{ function_id }},
restore_url: "{{ url_for('timer.restore', function_id=function_id) }}"
})
});
</script>
{% endblock %}