ai_upgrade_assistant-0.2.0-alpha2/js/upgrade_assistant.js

js/upgrade_assistant.js
(function ($, Drupal, drupalSettings) {
  'use strict';

  let lastTerminalOutput = [];

  Drupal.behaviors.aiUpgradeAssistant = {
    attach: function (context, settings) {
      // Initialize terminal output
      const terminal = $('#terminal-output', context);
      if (terminal.length) {
        this.initializeTerminal(terminal);
      }

      // Initialize check status button
      const checkStatusUrl = drupalSettings.aiUpgradeAssistant.checkStatusUrl;
      const refreshInterval = drupalSettings.aiUpgradeAssistant.refreshInterval || 2000;
      const progressBar = $('.progress-bar', context);
      const $results = $('#upgrade-results-container');
      const $button = $('#check-status-button', context).once('upgrade-assistant').on('click', function(e) {
        e.preventDefault();

        // Disable button and show loading
        $button.prop('disabled', true).val(Drupal.t('Checking...'));
        
        // Make AJAX call
        $.ajax({
          url: checkStatusUrl,
          method: 'GET',
          success: function(response) {
            if (response.status === 'success') {
              var html = '<div class="upgrade-assistant-status">';
              
              // Add status items
              if (response.data.status_items.length > 0) {
                html += '<h3>' + Drupal.t('System Status') + '</h3><ul>';
                response.data.status_items.forEach(function(item) {
                  html += '<li class="status-' + item.type + '">' + item.message + '</li>';
                });
                html += '</ul>';
              } else {
                html += '<p>' + Drupal.t('Your site is up to date!') + '</p>';
              }
              
              // Add actions
              if (response.data.actions.length > 0) {
                html += '<h3>' + Drupal.t('Recommended Actions') + '</h3>';
                response.data.actions.forEach(function(action) {
                  html += '<div class="upgrade-action">' +
                    '<h4>' + action.title + '</h4>' +
                    '<pre>' + action.command + '</pre>' +
                    '<button class="button" onclick="return confirm(\'' + 
                    Drupal.t('Are you sure you want to run this command?') + 
                    '\')">' + Drupal.t('Run Command') + '</button>' +
                    '</div>';
                });
              }
              
              html += '</div>';
              $results.html(html);
            } else {
              $results.html('<div class="messages messages--error">' + 
                Drupal.t('Error checking status') + '</div>');
            }
          },
          error: function(xhr) {
            $results.html('<div class="messages messages--error">' + 
              Drupal.t('Error checking status: @error', {
                '@error': xhr.responseJSON?.message || Drupal.t('Unknown error')
              }) + '</div>');
          },
          complete: function() {
            // Re-enable button
            $button.prop('disabled', false).val(Drupal.t('Check Site Status'));
          }
        });
      });

      function updateTerminalOutput(messages) {
        if (!Array.isArray(messages) || messages.length === 0) {
          return;
        }

        // Only add new messages that we haven't seen before
        const newMessages = messages.filter(msg => {
          return !lastTerminalOutput.some(last => 
            last.timestamp === msg.timestamp && last.message === msg.message
          );
        });

        if (newMessages.length === 0) {
          return;
        }

        // Update our last seen messages
        lastTerminalOutput = messages;

        // Add new messages to terminal
        newMessages.forEach(msg => {
          const timestamp = new Date(msg.timestamp * 1000).toLocaleTimeString();
          const cssClass = msg.type === 'error' ? 'text-danger' : 
                         msg.type === 'success' ? 'text-success' : 'text-info';
          
          terminal.append(
            $('<div>', {
              class: cssClass,
              text: `[${timestamp}] ${msg.message}`
            })
          );
        });

        // Scroll to bottom
        terminal.scrollTop(terminal[0].scrollHeight);
      }

      function checkStatus() {
        $.getJSON(checkStatusUrl)
          .done(function (response) {
            // Update progress bar
            if (response.progress !== undefined) {
              progressBar.css('width', response.progress + '%')
                        .attr('aria-valuenow', response.progress)
                        .text(response.progress + '%');
            }

            // Update terminal output
            if (response.terminal_output) {
              updateTerminalOutput(response.terminal_output);
            }

            // Continue polling if batch is active
            if (response.is_active) {
              setTimeout(checkStatus, refreshInterval);
            }
          })
          .fail(function (jqXHR, textStatus, errorThrown) {
            console.error('Status check failed:', textStatus, errorThrown);
            // Retry on failure
            setTimeout(checkStatus, refreshInterval);
          });
      }

      // Start checking status
      checkStatus();
    },

    initializeTerminal: function(terminal) {
      if (!terminal.length) return;

      // Start polling for terminal updates
      this.pollTerminal(terminal);
    },

    pollTerminal: function(terminal) {
      const self = this;
      const url = drupalSettings.path.baseUrl + 'admin/reports/upgrade-assistant/terminal';

      function poll() {
        $.ajax({
          url: url,
          method: 'GET',
          success: function(response) {
            if (response.output && response.output.length) {
              // Clear terminal if it's getting too long
              if (terminal.children().length > 200) {
                terminal.empty();
              }

              // Add new messages
              response.output.forEach(function(item) {
                const timestamp = new Date(item.timestamp * 1000).toLocaleTimeString();
                const line = $('<div class="terminal-line"></div>')
                  .text(`[${timestamp}] ${item.message}`);
                terminal.append(line);
              });

              // Auto-scroll to bottom
              terminal.scrollTop(terminal[0].scrollHeight);
            }
          },
          complete: function() {
            // Continue polling if the terminal is still in the DOM
            if (terminal.length && terminal.closest('body').length) {
              setTimeout(poll, 1000);
            }
          }
        });
      }

      // Start polling
      poll();
    }
  };

})(jQuery, Drupal, drupalSettings);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc