postComment()

in app/assets/javascripts/notes.js [1627:1819]


  postComment(e) {
    e.preventDefault();

    // Get Form metadata
    const $submitBtn = $(e.target);
    $submitBtn.prop('disabled', true);
    let $form = $submitBtn.parents('form');
    const $closeBtn = $form.find('.js-note-target-close');
    const isDiscussionNote =
      $submitBtn
        .parent()
        .find('li.droplab-item-selected')
        .attr('id') === 'discussion';
    const isMainForm = $form.hasClass('js-main-target-form');
    const isDiscussionForm = $form.hasClass('js-discussion-note-form');
    const isDiscussionResolve = $submitBtn.hasClass('js-comment-resolve-button');
    const { formData, formContent, formAction, formContentOriginal } = this.getFormData($form);
    let noteUniqueId;
    let systemNoteUniqueId;
    let hasQuickActions = false;
    let $notesContainer;
    let tempFormContent;

    // Get reference to notes container based on type of comment
    if (isDiscussionForm) {
      $notesContainer = $form.parent('.discussion-notes').find('.notes');
    } else if (isMainForm) {
      $notesContainer = $('ul.main-notes-list');
    }

    // If comment is to resolve discussion, disable submit buttons while
    // comment posting is finished.
    if (isDiscussionResolve) {
      $form.find('.js-comment-submit-button').disable();
    }

    tempFormContent = formContent;
    if (this.hasQuickActions(formContent)) {
      tempFormContent = this.stripQuickActions(formContent);
      hasQuickActions = true;
    }

    // Show placeholder note
    if (tempFormContent) {
      noteUniqueId = _.uniqueId('tempNote_');
      $notesContainer.append(
        this.createPlaceholderNote({
          formContent: tempFormContent,
          uniqueId: noteUniqueId,
          isDiscussionNote,
          currentUsername: gon.current_username,
          currentUserFullname: gon.current_user_fullname,
          currentUserAvatar: gon.current_user_avatar_url,
        }),
      );
    }

    // Show placeholder system note
    if (hasQuickActions) {
      systemNoteUniqueId = _.uniqueId('tempSystemNote_');
      $notesContainer.append(
        this.createPlaceholderSystemNote({
          formContent: this.getQuickActionDescription(
            formContent,
            AjaxCache.get(gl.GfmAutoComplete.dataSources.commands),
          ),
          uniqueId: systemNoteUniqueId,
        }),
      );
    }

    // Clear the form textarea
    if ($notesContainer.length) {
      if (isMainForm) {
        this.resetMainTargetForm(e);
      } else if (isDiscussionForm) {
        this.removeDiscussionNoteForm($form);
      }
    }

    $closeBtn.text($closeBtn.data('originalText'));

    // Make request to submit comment on server
    return axios
      .post(`${formAction}?html=true`, formData)
      .then(res => {
        const note = res.data;

        $submitBtn.prop('disabled', false);
        // Submission successful! remove placeholder
        $notesContainer.find(`#${noteUniqueId}`).remove();

        const $diffFile = $form.closest('.diff-file');
        if ($diffFile.length > 0) {
          const blurEvent = new CustomEvent('blur.imageDiff', {
            detail: e,
          });

          $diffFile[0].dispatchEvent(blurEvent);
        }

        // Reset cached commands list when command is applied
        if (hasQuickActions) {
          $form.find('textarea.js-note-text').trigger('clear-commands-cache.atwho');
        }

        // Clear previous form errors
        this.clearFlashWrapper();

        // Check if this was discussion comment
        if (isDiscussionForm) {
          // Remove flash-container
          $notesContainer.find('.flash-container').remove();

          // If comment intends to resolve discussion, do the same.
          if (isDiscussionResolve) {
            $form
              .attr('data-discussion-id', $submitBtn.data('discussionId'))
              .attr('data-resolve-all', 'true')
              .attr('data-project-path', $submitBtn.data('projectPath'));
          }

          // Show final note element on UI
          const isNewDiffComment = $notesContainer.length === 0;
          this.addDiscussionNote($form, note, isNewDiffComment);

          if (isNewDiffComment) {
            // Add image badge, avatar badge and toggle discussion badge for new image diffs
            const notePosition = $form.find('#note_position').val();
            if ($diffFile.length > 0 && notePosition.length > 0) {
              const { x, y, width, height } = JSON.parse(notePosition);
              const addBadgeEvent = new CustomEvent('addBadge.imageDiff', {
                detail: {
                  x,
                  y,
                  width,
                  height,
                  noteId: `note_${note.id}`,
                  discussionId: note.discussion_id,
                },
              });

              $diffFile[0].dispatchEvent(addBadgeEvent);
            }
          }

          // append flash-container to the Notes list
          if ($notesContainer.length) {
            $notesContainer.append('<div class="flash-container" style="display: none;"></div>');
          }
        } else if (isMainForm) {
          // Check if this was main thread comment
          // Show final note element on UI and perform form and action buttons cleanup
          this.addNote($form, note);
          this.reenableTargetFormSubmitButton(e);
        }

        if (note.commands_changes) {
          this.handleQuickActions(note);
        }

        $form.trigger('ajax:success', [note]);
      })
      .catch(() => {
        // Submission failed, remove placeholder note and show Flash error message
        $notesContainer.find(`#${noteUniqueId}`).remove();
        $submitBtn.prop('disabled', false);
        const blurEvent = new CustomEvent('blur.imageDiff', {
          detail: e,
        });

        const closestDiffFile = $form.closest('.diff-file');

        if (closestDiffFile.length) {
          closestDiffFile[0].dispatchEvent(blurEvent);
        }

        if (hasQuickActions) {
          $notesContainer.find(`#${systemNoteUniqueId}`).remove();
        }

        // Show form again on UI on failure
        if (isDiscussionForm && $notesContainer.length) {
          const replyButton = $notesContainer.parent().find('.js-discussion-reply-button');
          this.replyToDiscussionNote(replyButton[0]);
          $form = $notesContainer.parent().find('form');
        }

        $form.find('.js-note-text').val(formContentOriginal);
        this.reenableTargetFormSubmitButton(e);
        this.addNoteError($form);
      });
  }