From d8935309dfbe3b2e0adb9a9017634dac97e10fcb Mon Sep 17 00:00:00 2001 From: Ludovic <54670129+lbr38@users.noreply.github.com> Date: Sun, 5 Jan 2025 11:11:17 +0100 Subject: [PATCH] patch --- www/controllers/Task/Step.php | 2 +- www/controllers/ajax/task.php | 11 + .../resources/js/events/task/actions.js | 42 +++- www/public/resources/js/functions/task.js | 220 ++++++++++++------ www/public/resources/js/general.js | 22 -- .../includes/containers/tasks/log.inc.php | 6 +- 6 files changed, 198 insertions(+), 105 deletions(-) diff --git a/www/controllers/Task/Step.php b/www/controllers/Task/Step.php index bd027f5e..3c624b52 100644 --- a/www/controllers/Task/Step.php +++ b/www/controllers/Task/Step.php @@ -44,7 +44,7 @@ public function getSteps() : string include(ROOT . '/views/includes/containers/tasks/log/step.inc.php'); $content = ob_get_clean(); - // Add step name, status and HTML content to the steps array + // Add HTML content to the steps array $this->content['steps'][$stepIdentifier]['html'] = $content; } } diff --git a/www/controllers/ajax/task.php b/www/controllers/ajax/task.php index f15148e5..cc1f700d 100644 --- a/www/controllers/ajax/task.php +++ b/www/controllers/ajax/task.php @@ -129,4 +129,15 @@ response(HTTP_OK, $content); } +if ($_POST['action'] == 'get-task-status' and !empty($_POST['taskId'])) { + try { + $task = $myTask->getById($_POST['taskId']); + $status = $task['Status']; + } catch (\Exception $e) { + response(HTTP_BAD_REQUEST, $e->getMessage()); + } + + response(HTTP_OK, $status); +} + response(HTTP_BAD_REQUEST, 'Invalid action'); diff --git a/www/public/resources/js/events/task/actions.js b/www/public/resources/js/events/task/actions.js index 391ed33f..a0c8e706 100644 --- a/www/public/resources/js/events/task/actions.js +++ b/www/public/resources/js/events/task/actions.js @@ -4,7 +4,7 @@ $(document).ready(function () { localStorage.removeItem('scrollLock'); // Start log scroll event listener - scrollEvent(); + scrollEventListener(); // Start log autorefresh, with or without autoscroll autorefresh(); @@ -36,7 +36,7 @@ $(document).on('click','.show-task-btn',function () { // Reload task container to print the new task log reloadContainer('tasks/log').then(function () { // Restart log scroll event listener - scrollEvent(); + scrollEventListener(); }); }); @@ -48,19 +48,12 @@ $(document).on('click','#autoscroll-btn',function () { // Enable autoscroll if (autoscroll == 'false') { - setCookie('autoscroll', 'true'); - $(this).find('img').attr('src', '/assets/icons/pause.svg'); - $(this).attr('title', 'Disable auto refresh and scroll'); + enableAutoScroll(); } // Disable autoscroll if (autoscroll == '' || autoscroll == 'true') { - setCookie('autoscroll', 'false'); - $(this).find('img').attr('src', '/assets/icons/play.svg'); - $(this).attr('title', 'Enable auto refresh and scroll'); - - // Restart scroll event listener because autoscroll may have broken it - scrollEvent(); + disableAutoScroll(); } }); @@ -174,6 +167,9 @@ $(document).on('click','.step-bottom-btn',function () { // Remove scroll lock localStorage.removeItem('scrollLock'); + + // Enable autoscroll + enableAutoScroll() }); }); @@ -314,6 +310,30 @@ $(document).on('click','.cancel-scheduled-task-btn',function (e) { ); }); +/** + * Event: stop task + */ +$(document).on('click','.stop-task-btn',function () { + var taskId = $(this).attr('task-id'); + + printAlert('Stopping task...', 'info'); + + ajaxRequest( + // Controller: + 'task', + // Action: + 'stopTask', + // Data: + { + taskId: taskId + }, + // Print success alert: + true, + // Print error alert: + true + ); +}); + /** * Event: relaunch task */ diff --git a/www/public/resources/js/functions/task.js b/www/public/resources/js/functions/task.js index 82dd3305..fa4686f6 100644 --- a/www/public/resources/js/functions/task.js +++ b/www/public/resources/js/functions/task.js @@ -8,12 +8,13 @@ function autorefresh() return; } - // Autorefresh with new steps and content every 1000ms + // Autorefresh with new steps and content every 2sec setInterval(function () { + console.log('Start setinterval'); // Retrieve task Id var taskId = $('#log-refresh-container').attr('task-id'); - // Ignore refresh if task is not running (wait for 1000ms and try again) + // Ignore refresh if task is not running (wait for 2sec and try again) if ($('#log-refresh-container').attr('task-status') != 'running') { return; } @@ -34,11 +35,79 @@ function autorefresh() 'console' ).then(function () { // Refresh each step in the DOM - refreshStepsInDOM(JSON.parse(jsonValue.message)); + refreshStepsInDOM(JSON.parse(jsonValue.message)).then(function () { + // Restart scroll event listener after each step refresh + scrollEventListener(); + }); + + /** + * Get current task status, then refresh the task status in the DOM + */ + ajaxRequest( + // Controller: + 'task', + // Action: + 'get-task-status', + // Data: + { + taskId: taskId + }, + // Print success alert: + false, + // Print error alert: + 'console' + ).then(function () { + var status = jsonValue.message; + + // Refresh task status in the DOM, if the task is not running anymore, this will prevent the task from refreshing again + $('#log-refresh-container').attr('task-status', status); + + // Remove the autoscroll button if the task is done, error or stopped + if (status == 'done' || status == 'error' || status == 'stopped') { + $('#autoscroll-btn').remove(); + } + }); }); }, 2000); } +/** + * Enable autoscroll + */ +function enableAutoScroll() +{ + // Autoscroll can be enabled only if the task is running + if ($('#log-refresh-container').attr('task-status') == 'running') { + // Set autoscroll cookie to true to enable autoscroll + setCookie('autoscroll', 'true'); + + $('#autoscroll-btn').find('img').attr('src', '/assets/icons/pause.svg'); + $('#autoscroll-btn').attr('title', 'Disable auto refresh and scroll'); + + console.log('Autoscroll enabled'); + } + + // Restart scroll event listener + scrollEventListener(); +} + +/** + * Disable autoscroll + */ +function disableAutoScroll() +{ + // Set autoscroll cookie to false to disable autoscroll + setCookie('autoscroll', 'false'); + + $('#autoscroll-btn').find('img').attr('src', '/assets/icons/play.svg'); + $('#autoscroll-btn').attr('title', 'Enable auto refresh and scroll'); + + // Restart scroll event listener + scrollEventListener(); + + console.log('Autoscroll disabled'); +} + /** * Refresh each step, based on the status received from the server (in JSON format) * @param {*} steps @@ -46,78 +115,88 @@ function autorefresh() */ function refreshStepsInDOM(steps) { - var autoscroll = false; + return new Promise((resolve, reject) => { + try { + var autoscroll = false; - // Retrieve task Id - var taskId = $('#log-refresh-container').attr('task-id'); + // Retrieve task Id + var taskId = $('#log-refresh-container').attr('task-id'); - // Parse steps JSON - steps = JSON.parse(JSON.stringify(steps)); + // Parse steps JSON + steps = JSON.parse(JSON.stringify(steps)); - // For each step - $.each(steps.steps, function (stepIdentifier, step) { - // If the step exists in the DOM - if ($('.task-step[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').length > 0) { - // Get current step title status in the DOM - var status = $('.task-step[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').attr('status'); + // For each step + $.each(steps.steps, function (stepIdentifier, step) { + // If the step exists in the DOM + if ($('.task-step[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').length > 0) { + // Get current step title status in the DOM + var status = $('.task-step[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').attr('status'); - // If the status is different, replace its content with the new one - if (status != step.status) { - $('.task-step[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').replaceWith(step.html); - } - - // If the step does not exist in the DOM, append it to the container - } else { - $('.steps-container[task-id="' + taskId + '"]').append(step.html); - } - - // If autoscroll if enabled, scroll to the bottom of the step content - if (getCookie('autoscroll') == '' || getCookie('autoscroll') == 'true') { - autoscroll = true; - } + // If the status is different, replace its content with the new one + if (status != step.status) { + $('.task-step[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').replaceWith(step.html); + } - // Get step content (all its substeps) - ajaxRequest( - // Controller: - 'task', - // Action: - 'get-step-content', - // Data: - { - taskId: taskId, - stepIdentifier: stepIdentifier, - autoscroll: autoscroll - }, - // Print success alert: - false, - // Print error alert: - 'console' - ).then(function () { - // If there is no step content, append step content to the container, just after the step title, then make it visible - if ($('.steps-container[task-id="' + taskId + '"]').find('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').length == 0) { - $('.steps-container[task-id="' + taskId + '"]').find('.task-step[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').after(jsonValue.message); - $('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').css('display', 'grid'); - } - - // If autoscroll if enabled, scroll to the bottom of the step content - if (autoscroll) { - // Get current step content visibility - visibility = $('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').is(':visible'); - - // Replace step content with the new one - $('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').replaceWith(jsonValue.message); - - // If step content was visible, make it visible again - if (visibility) { - $('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').css('display', 'grid'); + // If the step does not exist in the DOM, append it to the container + } else { + $('.steps-container[task-id="' + taskId + '"]').append(step.html); } - // If step content exists, scroll to the bottom of the step content - if ($('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').length > 0) { - $('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').scrollTop($('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]')[0].scrollHeight); + // If autoscroll if enabled, scroll to the bottom of the step content + if (getCookie('autoscroll') == '' || getCookie('autoscroll') == 'true') { + autoscroll = true; } - } - }); + + // Get step content (all its substeps) + ajaxRequest( + // Controller: + 'task', + // Action: + 'get-step-content', + // Data: + { + taskId: taskId, + stepIdentifier: stepIdentifier, + autoscroll: autoscroll + }, + // Print success alert: + false, + // Print error alert: + 'console' + ).then(function () { + // If there is no step content, append step content to the container, just after the step title, then make it visible + if ($('.steps-container[task-id="' + taskId + '"]').find('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').length == 0) { + $('.steps-container[task-id="' + taskId + '"]').find('.task-step[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').after(jsonValue.message); + $('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').css('display', 'grid'); + } + + // If autoscroll if enabled, scroll to the bottom of the step content + if (autoscroll) { + // Get current step content visibility + visibility = $('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').is(':visible'); + + // Replace step content with the new one + $('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').replaceWith(jsonValue.message); + + // If step content was visible, make it visible again + if (visibility) { + $('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').css('display', 'grid'); + } + + // If step content exists, scroll to the bottom of the step content + if ($('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').length > 0) { + $('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]').scrollTop($('.task-step-content[task-id="' + taskId + '"][step="' + stepIdentifier + '"]')[0].scrollHeight); + } + } + + // Resolve promise + resolve('Steps refreshed'); + }); + }); + } catch (error) { + // Reject promise + reject('Failed to refresh steps'); + } }); } @@ -125,7 +204,7 @@ function refreshStepsInDOM(steps) * Start log scroll event listener * This is used to listen for user scroll up or down in the logs */ -function scrollEvent() +function scrollEventListener() { $('.task-step-content').scroll(function () { var taskId = $(this).attr('task-id'); @@ -170,6 +249,11 @@ function scrollEvent() */ localStorage.setItem('lastScrollPosition', currentScrollPosition); + if (scroll == 'up') { + console.log('scroll up detected, disabling autoscroll'); + disableAutoScroll(); + } + /** * Load more logs on scroll up */ diff --git a/www/public/resources/js/general.js b/www/public/resources/js/general.js index 6090af14..3a16d9c8 100644 --- a/www/public/resources/js/general.js +++ b/www/public/resources/js/general.js @@ -71,28 +71,6 @@ $(document).keyup(function (e) { } }); -/** - * Event: stop task - */ -$(document).on('click','.stop-task-btn',function () { - var taskId = $(this).attr('task-id'); - - ajaxRequest( - // Controller: - 'task', - // Action: - 'stopTask', - // Data: - { - taskId: taskId - }, - // Print success alert: - true, - // Print error alert: - true - ); -}); - /** * Event: print a copy icon on element with .copy class */ diff --git a/www/views/includes/containers/tasks/log.inc.php b/www/views/includes/containers/tasks/log.inc.php index dbe012e4..574f1f8c 100644 --- a/www/views/includes/containers/tasks/log.inc.php +++ b/www/views/includes/containers/tasks/log.inc.php @@ -19,9 +19,9 @@ // Print the auto scroll button only if the task is running if ($taskInfo['Status'] == 'running') : - if (empty($_COOKIE['autoscroll'])) { - $autoscroll = 'true'; - } else { + $autoscroll = 'true'; + + if (!empty($_COOKIE['autoscroll'])) { $autoscroll = $_COOKIE['autoscroll']; }