From ed39c71a0e0bb14af762866e2be41e5be0e76cd0 Mon Sep 17 00:00:00 2001 From: usmannasir Date: Sat, 12 Apr 2025 13:58:23 +0500 Subject: [PATCH] fix issue with design on n8n page --- websiteFunctions/dockerviews.py | 65 ++++++ .../websiteFunctions/DockerContainers.js | 188 ++++++++++-------- .../websiteFunctions/DockerSiteHome.html | 2 +- websiteFunctions/urls.py | 8 +- 4 files changed, 174 insertions(+), 89 deletions(-) diff --git a/websiteFunctions/dockerviews.py b/websiteFunctions/dockerviews.py index 2d4c6136c..6a1a44210 100644 --- a/websiteFunctions/dockerviews.py +++ b/websiteFunctions/dockerviews.py @@ -162,6 +162,71 @@ def restartContainer(request): container.restart() return HttpResponse(json.dumps({'status': 1})) + return HttpResponse('Not allowed') + except Exception as e: + return HttpResponse(json.dumps({ + 'status': 0, + 'error_message': str(e) + })) + +@csrf_exempt +@require_login +def n8n_container_operation(request): + try: + if request.method == 'POST': + userID = request.session['userID'] + currentACL = ACLManager.loadedACL(userID) + admin = Administrator.objects.get(pk=userID) + + data = json.loads(request.body) + container_id = data.get('container_id') + operation = data.get('operation') + + # Get the container + docker_manager = DockerManager() + container = docker_manager.get_container(container_id) + + if not container: + return HttpResponse(json.dumps({ + 'status': 0, + 'error_message': 'Container not found' + })) + + # Handle different operations + if operation == 'create_backup': + # For now, just return mock data to test UI functionality + backup_options = data.get('options', {}) + include_credentials = backup_options.get('includeCredentials', True) + include_executions = backup_options.get('includeExecutions', False) + + # In a real implementation, you would call the n8n API to create a backup + # For now, simulate a successful backup + + return HttpResponse(json.dumps({ + 'status': 1, + 'message': 'Backup simulation successful. In a production environment, this would download a backup file.', + # In real implementation, you would provide a download URL + # 'download_url': '/path/to/download/backup.json' + })) + + elif operation == 'restore_backup': + # For now, just return mock data to test UI functionality + backup_data = data.get('backup_data') + + # In a real implementation, you would call the n8n API to restore from backup + # For now, simulate a successful restore + + return HttpResponse(json.dumps({ + 'status': 1, + 'message': 'Restore simulation successful.' + })) + + else: + return HttpResponse(json.dumps({ + 'status': 0, + 'error_message': f'Unknown operation: {operation}' + })) + return HttpResponse('Not allowed') except Exception as e: return HttpResponse(json.dumps({ diff --git a/websiteFunctions/static/websiteFunctions/DockerContainers.js b/websiteFunctions/static/websiteFunctions/DockerContainers.js index e75fb19ad..6c51cc609 100644 --- a/websiteFunctions/static/websiteFunctions/DockerContainers.js +++ b/websiteFunctions/static/websiteFunctions/DockerContainers.js @@ -348,37 +348,31 @@ app.controller('ListDockersitecontainer', function ($scope, $http) { // Backup and Restore Functions - // Initialize backup options + // Function to initialize backup options for a container $scope.initBackupOptions = function(container) { + // Initialize backup options if not present if (!container.backupOptions) { container.backupOptions = { includeCredentials: true, includeExecutions: false }; } - - if (!container.scheduledBackup) { - container.scheduledBackup = { - frequency: 'disabled', - retention: 30 - }; - } }; - - // Create a backup + + // Function to create a backup $scope.createBackup = function(container) { + // Initialize options if not already done + $scope.initBackupOptions(container); + $scope.cyberpanelLoading = false; $('#cyberpanelLoading').show(); - // Initialize backup options if they don't exist - $scope.initBackupOptions(container); - - var url = "/websites/n8n/create_backup"; + var url = "/docker/n8n_container_operation"; var data = { 'container_id': container.id, - 'include_credentials': container.backupOptions.includeCredentials, - 'include_executions': container.backupOptions.includeExecutions + 'operation': 'create_backup', + 'options': container.backupOptions }; var config = { @@ -387,74 +381,74 @@ app.controller('ListDockersitecontainer', function ($scope, $http) { } }; - $http.post(url, data, config).then(function(response) { - $scope.cyberpanelLoading = true; - $('#cyberpanelLoading').hide(); - - if (response.data.status === 1) { - // Download the backup file - var backupData = response.data.backup; - var fileName = 'n8n-backup-' + new Date().toISOString().slice(0, 10) + '.json'; + $http.post(url, data, config).then( + function(response) { + $scope.cyberpanelLoading = true; + $('#cyberpanelLoading').hide(); - // Create a download link - var a = document.createElement('a'); - var blob = new Blob([JSON.stringify(backupData)], {type: 'application/json'}); - var url = window.URL.createObjectURL(blob); - a.href = url; - a.download = fileName; - a.click(); - window.URL.revokeObjectURL(url); + if (response.data.status === 1) { + new PNotify({ + title: 'Success!', + text: 'Backup created successfully. ' + (response.data.message || ''), + type: 'success' + }); + + // Add download link if provided + if (response.data.download_url) { + window.location.href = response.data.download_url; + } + } else { + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message || 'Failed to create backup. Please try again.', + type: 'error' + }); + } + }, + function(error) { + $scope.cyberpanelLoading = true; + $('#cyberpanelLoading').hide(); - new PNotify({ - title: 'Success!', - text: 'Backup created and downloaded successfully.', - type: 'success' - }); - } else { new PNotify({ title: 'Operation Failed!', - text: response.data.error_message, + text: 'Connection error while creating backup.', type: 'error' }); + + console.error("Error creating backup:", error); } - }, function(response) { - $scope.cyberpanelLoading = true; - $('#cyberpanelLoading').hide(); - - new PNotify({ - title: 'Operation Failed!', - text: 'Connection disrupted, refresh the page.', - type: 'error' - }); - }); + ); }; - // Restore from a backup + // Function to restore from a backup $scope.restoreFromBackup = function(container) { - // Check if a file has been selected var fileInput = document.getElementById('backupFile'); + if (!fileInput.files || fileInput.files.length === 0) { new PNotify({ - title: 'Error!', - text: 'Please select a backup file to restore.', - type: 'error' + title: 'Warning!', + text: 'Please select a backup file first.', + type: 'warning' }); return; } + var file = fileInput.files[0]; + var reader = new FileReader(); + $scope.cyberpanelLoading = false; $('#cyberpanelLoading').show(); - // Read the backup file - var reader = new FileReader(); reader.onload = function(e) { try { + // Try to parse the file as JSON to verify it's a valid backup var backupData = JSON.parse(e.target.result); - var url = "/websites/n8n/restore_backup"; + var url = "/docker/n8n_container_operation"; var data = { 'container_id': container.id, + 'operation': 'restore_backup', 'backup_data': backupData }; @@ -464,49 +458,73 @@ app.controller('ListDockersitecontainer', function ($scope, $http) { } }; - $http.post(url, data, config).then(function(response) { - $scope.cyberpanelLoading = true; - $('#cyberpanelLoading').hide(); - - if (response.data.status === 1) { - new PNotify({ - title: 'Success!', - text: 'Backup restored successfully.', - type: 'success' - }); + $http.post(url, data, config).then( + function(response) { + $scope.cyberpanelLoading = true; + $('#cyberpanelLoading').hide(); + + if (response.data.status === 1) { + new PNotify({ + title: 'Success!', + text: 'Backup restored successfully.', + type: 'success' + }); + + // Refresh workflows and credentials after restore + if (typeof $scope.refreshWorkflows === 'function') { + $scope.refreshWorkflows(container); + } + + if (typeof $scope.refreshCredentials === 'function') { + $scope.refreshCredentials(container); + } + } else { + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message || 'Failed to restore backup.', + type: 'error' + }); + } + }, + function(error) { + $scope.cyberpanelLoading = true; + $('#cyberpanelLoading').hide(); - // Refresh workflows after restore - $scope.refreshWorkflows(container); - } else { new PNotify({ title: 'Operation Failed!', - text: response.data.error_message, + text: 'Connection error while restoring backup.', type: 'error' }); + + console.error("Error restoring backup:", error); } - }, function(response) { - $scope.cyberpanelLoading = true; - $('#cyberpanelLoading').hide(); - - new PNotify({ - title: 'Operation Failed!', - text: 'Connection disrupted, refresh the page.', - type: 'error' - }); - }); - } catch (error) { + ); + } catch (e) { $scope.cyberpanelLoading = true; $('#cyberpanelLoading').hide(); new PNotify({ - title: 'Error!', - text: 'Invalid backup file format: ' + error.message, + title: 'Invalid Backup File', + text: 'The selected file is not a valid backup file.', type: 'error' }); + + console.error("Error parsing backup file:", e); } }; - reader.readAsText(fileInput.files[0]); + reader.onerror = function() { + $scope.cyberpanelLoading = true; + $('#cyberpanelLoading').hide(); + + new PNotify({ + title: 'Operation Failed!', + text: 'Error reading the backup file.', + type: 'error' + }); + }; + + reader.readAsText(file); }; // Save backup schedule diff --git a/websiteFunctions/templates/websiteFunctions/DockerSiteHome.html b/websiteFunctions/templates/websiteFunctions/DockerSiteHome.html index 70189915a..86fa0a57f 100644 --- a/websiteFunctions/templates/websiteFunctions/DockerSiteHome.html +++ b/websiteFunctions/templates/websiteFunctions/DockerSiteHome.html @@ -773,7 +773,7 @@ - + diff --git a/websiteFunctions/urls.py b/websiteFunctions/urls.py index 6255cd2df..58fb64bf2 100755 --- a/websiteFunctions/urls.py +++ b/websiteFunctions/urls.py @@ -1,5 +1,6 @@ from django.urls import path from . import views +from websiteFunctions.dockerviews import startContainer, stopContainer, restartContainer, n8n_container_operation urlpatterns = [ path('', views.loadWebsitesHome, name='loadWebsitesHome'), @@ -180,9 +181,10 @@ urlpatterns = [ path('fetchDockersite', views.fetchDockersite, name='fetchDockersite'), # Docker Container Actions - path('docker/startContainer', views.startContainer, name='startContainer'), - path('docker/stopContainer', views.stopContainer, name='stopContainer'), - path('docker/restartContainer', views.restartContainer, name='restartContainer'), + path('docker/startContainer', startContainer, name='startContainer'), + path('docker/stopContainer', stopContainer, name='stopContainer'), + path('docker/restartContainer', restartContainer, name='restartContainer'), + path('docker/n8n_container_operation', n8n_container_operation, name='n8n_container_operation'), # SSH Configs path('getSSHConfigs', views.getSSHConfigs, name='getSSHConfigs'),