Update the UI widget to indicate that AJAX is happening when 'Generate' is clicked.

Created on 6 February 2023, almost 2 years ago
Updated 21 May 2023, over 1 year ago

Problem/Motivation

Currently, it is unclear that action is happening when Generate is clicked on the balloon in CKEditor. We need to indicate activity to the user in the UI.

πŸ“Œ Task
Status

Closed: duplicate

Version

1.0

Component

OpenAI CKEditor

Created by

πŸ‡ΊπŸ‡ΈUnited States kevinquillen

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @kevinquillen
  • Assigned to matthieuscarset
  • Unassigning me from this issue.

    I don't know enough about CKEditor API yet.

    I was hoping it was a regularDrupal form and I would have made all improvements quickly.

    I wish I had availability to learn a whole new API to recreate the forms we have in our Drupal modules in the JS plugin, but I have to step back and focus on something else.

  • Issue was unassigned.
  • First commit to issue fork.
  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen

    A plugin can obtain other plugins in its constructor. Core ships with the CKEditor 5 "Notification" plugin, so:

        constructor(editor, config) {
            super(editor);
            this._notification = this.editor.plugins.get( Notification );
            // other code removed
        }
    

    Then, in the plugin methods you can use that plugin:

    if (!SomeCondition) {
      this._notification.showInfo('There was an error when connecting to OpenAI. Check the server logs for more details.', {
         namespace: 'openai:error',
      });
    } else {
    // .... and so on
    

    However, the Notification plugin in CKEditor only handles the storage of notifications. There is no UI component to show them, like a toast or flash message to the user. You have to bring your own library.

    I tried using Drupals native Message Javascript API. You can trigger an event with the Notification plugin:. For example:

          const notification = this._notification;
    
          notification.on( 'show:info:openai:error', ( e, data ) => {
            const messageId = this._messages.add(data.message, {type: 'error'});
    
            setTimeout(() => {
              this._messages.remove(messageId);
            }, 6000, messageId);
          });
    

    The result of that, when an error notification is detected, is:

    This is kind of obtrusive and awkward - and it also requires themes to have the "Messages" block active. What I think would be nicer is appending HTML at the end of the editor frame and writing a status update there. Alternatively, a lightweight toast library that can put the messages within the CKEditor frame, just like the old CKEditor 4 notification plugin used to do: https://ckeditor.com/cke4/addon/notification

  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen

    This is more where I would like it.

    When complete:

    I did this with a little bit of code to add a new template for textareas:

    function openai_ckeditor_theme() {
      $theme['textarea_openai'] = [
        'base hook' => 'textarea',
      ];
    
      return $theme;
    }
    
    /**
     * Implements hook_theme_suggestions_form_element_alter().
     */
    function openai_ckeditor_theme_suggestions_form_element_alter(array &$suggestions, array $variables, $hook) {
      if (isset($variables["element"]["#type"]) && $variables["element"]["#type"] === 'textarea') {
        // todo: How to tell if this form element is filter enabled with OpenAI plugin?
        $suggestions[] = 'textarea_openai';
      }
    }
    

    The twig template:

    {#
    /**
     * @file
     * Theme override for a 'textarea' #type form element.
     *
     * Available variables
     * - wrapper_attributes: A list of HTML attributes for the wrapper element.
     * - attributes: A list of HTML attributes for the <textarea> element.
     * - resizable: An indicator for whether the textarea is resizable.
     * - required: An indicator for whether the textarea is required.
     * - value: The textarea content.
     *
     * @see template_preprocess_textarea()
     */
    #}
    {%
      set classes = [
      'form-textarea',
      resizable ? 'resize-' ~ resizable,
      required ? 'required',
      'form-element',
      'form-element--type-textarea',
      'form-element--api-textarea',
    ]
    %}
    <div{{ wrapper_attributes.addClass('form-textarea-wrapper') }}>
      <textarea{{ attributes.addClass(classes) }}>{{ value }}</textarea>
      <div id="openai-status"></div>
    </div>
    

    Back in the plugin:

          notification.on( 'show:info:openai:init', ( e, data ) => {
            // todo: can't we make this work with regular Javascript?
            // let container = document.getElementById('openai-status');
            // const message = document.createTextNode(data.message);
            // container.appendChild(message);
    
            jQuery('div#openai-status').text(data.message);
          });
    
          notification.on( 'show:info:openai:error', ( e, data ) => {
            // todo: can't we make this work with regular Javascript?
            // let container = document.getElementById('openai-status');
            // const message = document.createTextNode(data.message);
            // container.appendChild(message);
    
            jQuery('div#openai-status').text(data.message);
          });
    
          notification.on( 'show:success:openai:complete', ( e, data ) => {
            // todo: can't we make this work with regular Javascript?
            // let container = document.getElementById('openai-status');
            // const message = document.createTextNode(data.message);
            // container.appendChild(message);
    
            jQuery('div#openai-status').text(data.message);
          });
    

    This puts the div just under the editor similar to the CKEditor demos - from there it can be styled with CSS to look more appealing.

  • Status changed to Needs work over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen
  • Status changed to Closed: duplicate over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen
  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen

    cp_dev opened an empty fork which made the branch unusable. Moving to πŸ“Œ Update the UI widget to indicate that network activity is happening in CKEditor. Fixed . Please do not open forks if you are not going to commit work.

Production build 0.71.5 2024