Add notification center button and fix stat-card/activity board loading

This commit is contained in:
master3395
2026-01-19 17:37:47 +01:00
parent 0b2187e3f9
commit 97068705a2
3316 changed files with 723670 additions and 4579 deletions

View File

@@ -0,0 +1,415 @@
var app = angular.module('CyberCP');
app.controller('ListDockersitecontainer', function ($scope, $http) {
$scope.cyberPanelLoading = true;
$scope.cyberpanelLoading = true;
$scope.conatinerview = true;
$scope.ContainerList = [];
$('#cyberpanelLoading').hide();
// Format bytes to human readable
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
$scope.getcontainer = function () {
$('#cyberpanelLoading').show();
url = "/docker/getDockersiteList";
var data = {'name': $('#sitename').html()};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialData, cantLoadInitialData);
function ListInitialData(response) {
$('#cyberpanelLoading').hide();
if (response.data.status === 1) {
$scope.cyberPanelLoading = true;
var finalData = JSON.parse(response.data.data[1]);
$scope.ContainerList = finalData;
$("#listFail").hide();
} else {
$("#listFail").fadeIn();
$scope.errorMessage = response.data.error_message;
}
}
function cantLoadInitialData(response) {
$scope.cyberPanelLoading = true;
$('#cyberpanelLoading').hide();
new PNotify({
title: 'Operation Failed!',
text: 'Connection disrupted, refresh the page.',
type: 'error'
});
}
};
$scope.Lunchcontainer = function (containerid) {
$scope.cyberpanelLoading = false;
$('#cyberpanelLoading').show();
var url = "/docker/getContainerAppinfo";
var data = {
'name': $('#sitename').html(),
'id': containerid
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialData, cantLoadInitialData);
function ListInitialData(response) {
$scope.cyberpanelLoading = true;
$('#cyberpanelLoading').hide();
if (response.data.status === 1) {
var containerInfo = response.data.data[1];
console.log("Full container info:", containerInfo);
// Find the container in the list and update its information
for (var i = 0; i < $scope.ContainerList.length; i++) {
if ($scope.ContainerList[i].id === containerid) {
// Basic Information
$scope.ContainerList[i].status = containerInfo.status;
$scope.ContainerList[i].created = new Date(containerInfo.created);
$scope.ContainerList[i].uptime = containerInfo.uptime;
$scope.ContainerList[i].image = containerInfo.image;
// Environment Variables - ensure it's properly set
if (containerInfo.environment) {
console.log("Setting environment:", containerInfo.environment);
$scope.ContainerList[i].environment = containerInfo.environment;
console.log("Container after env update:", $scope.ContainerList[i]);
} else {
console.log("No environment in container info");
}
// Resource Usage
var memoryBytes = containerInfo.memory_usage;
$scope.ContainerList[i].memoryUsage = formatBytes(memoryBytes);
$scope.ContainerList[i].memoryUsagePercent = (memoryBytes / (1024 * 1024 * 1024)) * 100;
$scope.ContainerList[i].cpuUsagePercent = (containerInfo.cpu_usage / 10000000000) * 100;
// Network & Ports
$scope.ContainerList[i].ports = containerInfo.ports;
// Volumes
$scope.ContainerList[i].volumes = containerInfo.volumes;
break;
}
}
// Get container logs
$scope.getcontainerlog(containerid);
} else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialData(response) {
$scope.cyberpanelLoading = true;
$('#cyberpanelLoading').hide();
new PNotify({
title: 'Operation Failed!',
text: 'Connection disrupted, refresh the page.',
type: 'error'
});
}
};
$scope.getcontainerlog = function (containerid) {
$scope.cyberpanelLoading = false;
var url = "/docker/getContainerApplog";
var data = {
'name': $('#sitename').html(),
'id': containerid
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialData, cantLoadInitialData);
function ListInitialData(response) {
$scope.cyberpanelLoading = true;
$scope.conatinerview = false;
$('#cyberpanelLoading').hide();
if (response.data.status === 1) {
// Find the container in the list and update its logs
for (var i = 0; i < $scope.ContainerList.length; i++) {
if ($scope.ContainerList[i].id === containerid) {
$scope.ContainerList[i].logs = response.data.data[1];
break;
}
}
} else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialData(response) {
$scope.cyberpanelLoading = true;
$('#cyberpanelLoading').hide();
$scope.conatinerview = false;
new PNotify({
title: 'Operation Failed!',
text: 'Connection disrupted, refresh the page.',
type: 'error'
});
}
};
// Auto-refresh container info every 30 seconds
var refreshInterval;
$scope.$watch('conatinerview', function(newValue, oldValue) {
if (newValue === false) { // When container view is shown
refreshInterval = setInterval(function() {
if ($scope.cid) {
$scope.Lunchcontainer($scope.cid);
}
}, 30000); // 30 seconds
} else { // When container view is hidden
if (refreshInterval) {
clearInterval(refreshInterval);
}
}
});
// Clean up on controller destruction
$scope.$on('$destroy', function() {
if (refreshInterval) {
clearInterval(refreshInterval);
}
});
// Initialize
$scope.getcontainer();
// Keep your existing functions
$scope.recreateappcontainer = function() { /* ... */ };
$scope.refreshStatus = function() { /* ... */ };
$scope.restarthStatus = function() { /* ... */ };
$scope.StopContainerAPP = function() { /* ... */ };
$scope.cAction = function(action) {
$scope.cyberpanelLoading = false;
$('#cyberpanelLoading').show();
var url = "/docker/";
switch(action) {
case 'start':
url += "startContainer";
break;
case 'stop':
url += "stopContainer";
break;
case 'restart':
url += "restartContainer";
break;
default:
console.error("Unknown action:", action);
return;
}
var data = {
'name': $('#sitename').html(),
'container_id': $scope.selectedContainer.id
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(
function(response) {
$scope.cyberpanelLoading = true;
$('#cyberpanelLoading').hide();
if (response.data.status === 1) {
new PNotify({
title: 'Success!',
text: 'Container ' + action + ' successful.',
type: 'success'
});
// Update container status after action
$scope.selectedContainer.status = action === 'stop' ? 'stopped' : 'running';
// Refresh container info
$scope.Lunchcontainer($scope.selectedContainer.id);
} else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message || 'An unknown error occurred.',
type: 'error'
});
}
},
function(error) {
$scope.cyberpanelLoading = true;
$('#cyberpanelLoading').hide();
new PNotify({
title: 'Operation Failed!',
text: 'Connection disrupted or server error occurred.',
type: 'error'
});
console.error("Error during container action:", error);
}
);
};
// Update the container selection when actions are triggered
$scope.setSelectedContainer = function(container) {
$scope.selectedContainer = container;
};
// Update the button click handlers to set selected container
$scope.handleAction = function(action, container) {
$scope.setSelectedContainer(container);
$scope.cAction(action);
};
// Add specific action functions that are referenced in the template
$scope.startContainer = function(containerId, containerName) {
$scope.selectedContainer = { id: containerId, name: containerName };
$scope.cAction('start');
};
$scope.stopContainer = function(containerId, containerName) {
$scope.selectedContainer = { id: containerId, name: containerName };
$scope.cAction('stop');
};
$scope.restartContainer = function(containerId, containerName) {
$scope.selectedContainer = { id: containerId, name: containerName };
$scope.cAction('restart');
};
$scope.openSettings = function(container) {
$scope.selectedContainer = container;
$('#settings').modal('show');
};
$scope.saveSettings = function() {
$scope.cyberpanelLoading = false;
$('#cyberpanelLoading').show();
var url = "/docker/updateContainerSettings";
var data = {
'name': $('#sitename').html(),
'id': $scope.selectedContainer.id,
'memoryLimit': $scope.selectedContainer.memoryLimit,
'startOnReboot': $scope.selectedContainer.startOnReboot
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialData, cantLoadInitialData);
function ListInitialData(response) {
$scope.cyberpanelLoading = true;
$('#cyberpanelLoading').hide();
if (response.data.status === 1) {
new PNotify({
title: 'Success!',
text: 'Container settings updated successfully.',
type: 'success'
});
$('#settings').modal('hide');
// Refresh container info after update
$scope.Lunchcontainer($scope.selectedContainer.id);
} else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialData(response) {
$scope.cyberpanelLoading = true;
$('#cyberpanelLoading').hide();
new PNotify({
title: 'Operation Failed!',
text: 'Connection disrupted, refresh the page.',
type: 'error'
});
}
};
// Add location service to the controller for the n8n URL
$scope.location = window.location;
// Function to extract n8n version from environment variables
$scope.getN8nVersion = function(container) {
console.log('getN8nVersion called with container:', container);
if (!container || !container.environment) {
console.log('No container or environment data');
return 'unknown';
}
console.log('Container environment:', container.environment);
var version = null;
// Try to find NODE_VERSION first
version = container.environment.find(function(env) {
return env && env.startsWith('NODE_VERSION=');
});
if (version) {
console.log('Found NODE_VERSION:', version);
return version.split('=')[1];
}
// Try to find N8N_VERSION
version = container.environment.find(function(env) {
return env && env.startsWith('N8N_VERSION=');
});
if (version) {
console.log('Found N8N_VERSION:', version);
return version.split('=')[1];
}
console.log('No version found in environment');
return 'unknown';
};
});

View File

@@ -0,0 +1,15 @@
// Wait for Angular to be ready
angular.element(document).ready(function() {
// Ensure the CyberCP module exists
if (typeof angular.module('CyberCP') === 'undefined') {
console.error('CyberCP module not found!');
return;
}
// Bootstrap Angular manually if needed
var element = document.querySelector('[ng-controller="ListDockersitecontainer"]');
if (element && !angular.element(element).data('$scope')) {
console.log('Manually bootstrapping Angular for Docker container page');
angular.bootstrap(element, ['CyberCP']);
}
});

View File

@@ -0,0 +1,162 @@
// Resource Monitoring
let cpuChart, memoryChart, diskChart;
let cpuData = [], memoryData = [], diskData = [];
const maxDataPoints = 30;
function initializeCharts() {
// CPU Chart
const cpuCtx = document.getElementById('cpuChart').getContext('2d');
cpuChart = new Chart(cpuCtx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'CPU Usage (%)',
data: [],
borderColor: '#2563eb',
backgroundColor: 'rgba(37, 99, 235, 0.1)',
borderWidth: 2,
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: 100,
ticks: {
callback: function(value) {
return value + '%';
}
}
}
}
}
});
// Memory Chart
const memoryCtx = document.getElementById('memoryChart').getContext('2d');
memoryChart = new Chart(memoryCtx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'Memory Usage (%)',
data: [],
borderColor: '#00b894',
backgroundColor: 'rgba(0, 184, 148, 0.1)',
borderWidth: 2,
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: 100,
ticks: {
callback: function(value) {
return value + '%';
}
}
}
}
}
});
// Disk Chart
const diskCtx = document.getElementById('diskChart').getContext('2d');
diskChart = new Chart(diskCtx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'Disk Usage (%)',
data: [],
borderColor: '#ff9800',
backgroundColor: 'rgba(255, 152, 0, 0.1)',
borderWidth: 2,
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: 100,
ticks: {
callback: function(value) {
return value + '%';
}
}
}
}
}
});
}
function updateCharts(data) {
const now = new Date();
const timeLabel = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds();
// Update CPU Chart
cpuData.push(data.cpu_usage);
if (cpuData.length > maxDataPoints) cpuData.shift();
cpuChart.data.labels.push(timeLabel);
if (cpuChart.data.labels.length > maxDataPoints) cpuChart.data.labels.shift();
cpuChart.data.datasets[0].data = cpuData;
cpuChart.update();
// Update Memory Chart
memoryData.push(data.memory_usage);
if (memoryData.length > maxDataPoints) memoryData.shift();
memoryChart.data.labels.push(timeLabel);
if (memoryChart.data.labels.length > maxDataPoints) memoryChart.data.labels.shift();
memoryChart.data.datasets[0].data = memoryData;
memoryChart.update();
// Update Disk Chart
diskData.push(data.disk_percent);
if (diskData.length > maxDataPoints) diskData.shift();
diskChart.data.labels.push(timeLabel);
if (diskChart.data.labels.length > maxDataPoints) diskChart.data.labels.shift();
diskChart.data.datasets[0].data = diskData;
diskChart.update();
}
function fetchResourceUsage() {
$.ajax({
url: '/website/get_website_resources/',
type: 'POST',
data: JSON.stringify({
'domain': $('#domainNamePage').text()
}),
contentType: 'application/json',
success: function(data) {
if (data.status === 1) {
updateCharts(data);
}
},
error: function() {
console.error('Error fetching resource usage data');
}
});
}
// Initialize charts when the page loads
$(document).ready(function() {
initializeCharts();
// Fetch resource usage every 5 seconds
setInterval(fetchResourceUsage, 5000);
// Initial fetch
fetchResourceUsage();
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
// WordPress Backup and Staging Functions Extension
// Simple fixes for backup and staging functionality
$(document).ready(function() {
// Override getCreationStatus to show progress
if (typeof window.getCreationStatus === 'undefined') {
window.getCreationStatus = function() {
var url = "/websites/installWordpressStatus";
var data = {
statusFile: window.statusFile
};
$.ajax({
type: 'POST',
url: url,
data: JSON.stringify(data),
contentType: 'application/json',
headers: {
'X-CSRFToken': getCookie('csrftoken')
},
success: function(response) {
if (response.abort === 1) {
// Operation complete
$('#wordpresshomeloading').hide();
$('#createBackupBtn').prop('disabled', false).html('<i class="fas fa-download"></i> Create Backup');
$('button[ng-click="CreateStagingNow()"]')
.prop('disabled', false).html('<i class="fas fa-clone"></i> Create Staging Site');
// Hide progress bar, show success/error
if (response.installStatus === 1) {
if (window.statusFile && window.statusFile.includes('backup')) {
$('#backupStatus').html('<span style="color: #10b981;">✓ Backup created successfully!</span>');
// Show new progress section as success
$('#backupProgressSection').show();
$('#backupStatusMessage').show();
$('#backupCurrentStatus').text('Backup successfully created.');
$('#backupProgressBar').css('width', '100%').attr('aria-valuenow', 100);
$('#backupProgressPercent').text('100%');
$('#backupErrorBox').hide();
$('#backupSuccessBox').show();
} else {
$('#stagingStatus').html('<span style="color: #10b981;">✓ Staging site created successfully!</span>');
var scope = angular.element($('[ng-controller="WPsiteHome"]')).scope();
if (scope && scope.fetchstaging) {
scope.$apply(function() {
scope.fetchstaging();
});
}
}
} else {
var errorMsg = response.error_message || 'Operation failed';
if (window.statusFile && window.statusFile.includes('backup')) {
$('#backupStatus').html('<span style="color: #ef4444;">✗ ' + errorMsg + '</span>');
// Show error in new progress section
$('#backupProgressSection').show();
$('#backupStatusMessage').hide();
$('#backupProgressBar').css('width', '0%').attr('aria-valuenow', 0);
$('#backupProgressPercent').text('0%');
$('#backupErrorBox').show();
$('#backupErrorMessage').text(errorMsg);
$('#backupSuccessBox').hide();
} else {
$('#stagingStatus').html('<span style="color: #ef4444;">✗ ' + errorMsg + '</span>');
}
}
} else {
// Still in progress
var status = response.currentStatus || 'Processing...';
var progress = response.installationProgress || 0;
var statusHtml = '<i class="fas fa-spinner fa-pulse"></i> ' + status + ' (' + progress + '%)';
if (window.statusFile && window.statusFile.includes('backup')) {
$('#backupStatus').html(statusHtml);
// Show and update progress bar
$('#backupProgressSection').show();
$('#backupStatusMessage').show();
$('#backupCurrentStatus').text(status);
$('#backupProgressBar').css('width', progress + '%').attr('aria-valuenow', progress);
$('#backupProgressPercent').text(progress + '%');
$('#backupErrorBox').hide();
$('#backupSuccessBox').hide();
} else {
$('#stagingStatus').html(statusHtml);
}
setTimeout(window.getCreationStatus, 1000);
}
},
error: function() {
$('#wordpresshomeloading').hide();
$('#createBackupBtn').prop('disabled', false).html('<i class="fas fa-download"></i> Create Backup');
$('button[ng-click="CreateStagingNow()"]')
.prop('disabled', false).html('<i class="fas fa-clone"></i> Create Staging Site');
// Show error in progress section if backup
if (window.statusFile && window.statusFile.includes('backup')) {
$('#backupProgressSection').show();
$('#backupStatusMessage').hide();
$('#backupProgressBar').css('width', '0%').attr('aria-valuenow', 0);
$('#backupProgressPercent').text('0%');
$('#backupErrorBox').show();
$('#backupErrorMessage').text('Error loading backup status.');
$('#backupSuccessBox').hide();
}
}
});
};
}
});