diff --git a/routes/timer.py b/routes/timer.py index 1d9a032..78d7d65 100644 --- a/routes/timer.py +++ b/routes/timer.py @@ -402,4 +402,41 @@ def logs(function_id): return render_block(environment, 'dashboard/timer_functions/logs.html', 'page', **args) return render_template('dashboard/timer_functions/logs.html', **args) +@timer.route('/history/') +@login_required +def history(function_id): + # Fetch the timer function to verify ownership + timer_function = db.execute(""" + SELECT id, name, code, version_number + FROM timer_functions + WHERE id = %s AND user_id = %s + """, [function_id, current_user.id], one=True) + + if not timer_function: + flash('Timer function not found', 'error') + return redirect(url_for('timer.overview')) + + # Fetch all versions + versions = db.execute(""" + SELECT version_number, script, versioned_at + FROM timer_function_versions + WHERE timer_function_id = %s + ORDER BY version_number DESC + """, [function_id]) + + # Convert datetime objects to ISO format strings + for version in versions: + version['versioned_at'] = version['versioned_at'].isoformat() if version['versioned_at'] else None + + args = { + 'user_id': current_user.id, + 'function_id': function_id, + 'timer_function': timer_function, + 'versions': versions + } + + if htmx: + return render_block(environment, 'dashboard/timer_functions/history.html', 'page', **args) + return render_template('dashboard/timer_functions/history.html', **args) + diff --git a/static/js/mithril/diffView.js b/static/js/mithril/diffView.js new file mode 100644 index 0000000..2df3c71 --- /dev/null +++ b/static/js/mithril/diffView.js @@ -0,0 +1,94 @@ +const DiffView = { + oninit: function(vnode) { + // Initialize indices in state + vnode.state.leftIndex = vnode.attrs.versions.length - 1; // Earliest + vnode.state.rightIndex = 0; // Latest + }, + view: function (vnode) { + const versions = vnode.attrs.versions; + return m("div", [ + m("div.flex.gap-4.mb-4", [ + m("div.flex-1", [ + m("label.block.text-sm.font-medium.text-gray-700", "Left Version"), + m("select.mt-1.block.w-full.rounded-md.border-gray-300.shadow-sm", { + onchange: (e) => { + vnode.state.leftIndex = parseInt(e.target.value); + vnode.state.leftVersion = versions[vnode.state.leftIndex]; + vnode.state.updateDiff(); + }, + value: vnode.state.leftIndex + }, versions.map((v, idx) => + m("option", { value: idx }, `Version ${v.version_number} (${new Date(v.versioned_at).toLocaleString()})`) + )) + ]), + m("div.flex-1", [ + m("label.block.text-sm.font-medium.text-gray-700", "Right Version"), + m("select.mt-1.block.w-full.rounded-md.border-gray-300.shadow-sm", { + onchange: (e) => { + vnode.state.rightIndex = parseInt(e.target.value); + vnode.state.rightVersion = versions[vnode.state.rightIndex]; + vnode.state.updateDiff(); + }, + value: vnode.state.rightIndex + }, versions.map((v, idx) => + m("option", { value: idx }, `Version ${v.version_number} (${new Date(v.versioned_at).toLocaleString()})`) + )) + ]) + ]), + m("div", { + id: "diff-container", + style: "height: 500px; position: relative;" + }) + ]); + }, + oncreate: function (vnode) { + const versions = vnode.attrs.versions; + // Initialize with the earliest and most recent versions if available + if (versions.length >= 2) { + vnode.state.leftVersion = versions[versions.length - 1]; // Earliest version + vnode.state.rightVersion = versions[0]; // Latest version + } else if (versions.length === 1) { + vnode.state.leftVersion = versions[0]; + vnode.state.rightVersion = versions[0]; + } + + vnode.state.updateDiff = function () { + if (vnode.state.aceDiffer) { + // Clean up previous instance + vnode.state.aceDiffer.destroy(); + } + + vnode.state.aceDiffer = new AceDiff({ + element: '#diff-container', + mode: "ace/mode/javascript", + left: { + content: vnode.state.leftVersion ? vnode.state.leftVersion.script : "", + editable: false, + }, + right: { + content: vnode.state.rightVersion ? vnode.state.rightVersion.script : "", + editable: false, + } + }); + + // Configure both editors + const editors = vnode.state.aceDiffer.getEditors(); + ['left', 'right'].forEach(side => { + editors[side].setOptions({ + maxLines: 20, + autoScrollEditorIntoView: true, + }); + editors[side].session.setOption("useWorker", false); + }); + }; + + // Initial diff setup + vnode.state.updateDiff(); + }, + onremove: function (vnode) { + // Clean up AceDiff when component is removed + if (vnode.state.aceDiffer) { + vnode.state.aceDiffer.destroy(); + } + } +}; \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index d78c9fa..6853461 100644 --- a/templates/base.html +++ b/templates/base.html @@ -26,7 +26,7 @@ - + diff --git a/templates/dashboard/http_functions/client.html b/templates/dashboard/http_functions/client.html index 79bd0bb..d3a7594 100644 --- a/templates/dashboard/http_functions/client.html +++ b/templates/dashboard/http_functions/client.html @@ -9,8 +9,9 @@ show_logs=True, show_client=True, show_history=True, edit_url=url_for('http_function_editor', function_id=function_id), -cancel_url=url_for('dashboard_http_functions', -logs_url=url_for('get_http_function_logs', function_id=function_id))) }} +cancel_url=url_for('dashboard_http_functions'), +logs_url=url_for('get_http_function_logs', function_id=function_id), +history_url=url_for('get_http_function_history', function_id=function_id)) }}
diff --git a/templates/dashboard/http_functions/editor.html b/templates/dashboard/http_functions/editor.html index 2dc23b6..9a09b16 100644 --- a/templates/dashboard/http_functions/editor.html +++ b/templates/dashboard/http_functions/editor.html @@ -10,7 +10,8 @@ show_client=True, show_history=True, edit_url=edit_url, cancel_url=cancel_url, -logs_url=url_for('get_http_function_logs', function_id=function_id)) }} +logs_url=url_for('get_http_function_logs', function_id=function_id), +history_url=url_for('get_http_function_history', function_id=function_id)) }}
diff --git a/templates/dashboard/http_functions/header.html b/templates/dashboard/http_functions/header.html index 69787c8..6ad139d 100644 --- a/templates/dashboard/http_functions/header.html +++ b/templates/dashboard/http_functions/header.html @@ -59,8 +59,7 @@ {% if show_history|default(false, true) %}