Refactor discussion edit widget to have only one at a time.

This commit is contained in:
Fatih Acet 2016-10-14 00:11:43 +03:00
parent 7c2a4699b8
commit 1100320b0c
6 changed files with 97 additions and 40 deletions

View file

@ -129,4 +129,16 @@
})(window);
gl.utils.isElementVisibleInViewport = function(el) {
var rect = el.getBoundingClientRect();
var height = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom - 110 < 0 || rect.top - height >= 0); // -110 for sticky GitLab navigation header
}
gl.utils.animateToElement = function($el) {
return $('body, html').animate({
scrollTop: $el.offset().top - 110
}, 200);
}
}).call(this);

View file

@ -63,7 +63,7 @@
// change note in UI after update
$(document).on("ajax:success", "form.edit-note", this.updateNote);
// Edit note link
$(document).on("click", ".js-note-edit", this.showEditForm);
$(document).on("click", ".js-note-edit", this.showEditForm.bind(this));
$(document).on("click", ".note-edit-cancel", this.cancelEdit);
// Reopen and close actions for Issue/MR combined with note form submit
$(document).on("click", ".js-comment-button", this.updateCloseButton);
@ -466,6 +466,9 @@
var $html, $note_li;
// Convert returned HTML to a jQuery object so we can modify it further
$html = $(note.html);
$('.note-edit-form').insertBefore('.notes-form');
gl.utils.localTimeAgo($('.js-timeago', $html));
$html.renderGFM();
$html.find('.js-task-list-container').taskList('enable');
@ -480,48 +483,73 @@
};
Notes.prototype.checkContentToAllowEditing = function($el) {
var initialContent = $el.find('.original-note-content').text().trim();
var currentContent = $el.find('.note-textarea').val();
var isAllowed = true;
if (currentContent === initialContent) {
this.removeNoteEditForm($el);
$el.find('.js-md-write-button').trigger('click');
}
else {
var $buttons = $el.find('.note-form-actions');
var isButtonsVisible = gl.utils.isElementVisibleInViewport($buttons[0]);
var isWidgetVisible = gl.utils.isElementVisibleInViewport($el[0]);
if (!isButtonsVisible || !isWidgetVisible) {
gl.utils.animateToElement($el);
}
$el.find('.js-edit-warning').show();
$el.find('.js-md-write-button').trigger('click');
isAllowed = false;
}
return isAllowed;
}
/*
Called in response to clicking the edit note link
Replaces the note text with the note edit form
Adds a data attribute to the form with the original content of the note for cancellations
*/
*/
Notes.prototype.showEditForm = function(e, scrollTo, myLastNote) {
var $noteText, done, form, note;
e.preventDefault();
note = $(this).closest(".note");
note.addClass("is-editting");
form = note.find(".note-edit-form");
form.addClass('current-note-edit-form');
// Show the attachment delete link
note.find(".js-note-attachment-delete").show();
done = function($noteText) {
var noteTextVal;
// Neat little trick to put the cursor at the end
noteTextVal = $noteText.val();
// Store the original note text in a data attribute to retrieve if a user cancels edit.
form.find('form.edit-note').data('original-note', noteTextVal);
return $noteText.val('').val(noteTextVal);
};
new GLForm(form);
if ((scrollTo != null) && (myLastNote != null)) {
// scroll to the bottom
// so the open of the last element doesn't make a jump
$('html, body').scrollTop($(document).height());
return $('html, body').animate({
scrollTop: myLastNote.offset().top - 150
}, 500, function() {
var $noteText;
$noteText = form.find(".js-note-text");
$noteText.focus();
return done($noteText);
});
} else {
$noteText = form.find('.js-note-text');
$noteText.focus();
return done($noteText);
var $currentlyEditing = $('.note.is-editting');
if ($currentlyEditing.length) {
var isEditAllowed = this.checkContentToAllowEditing($currentlyEditing);
if (!isEditAllowed) {
return;
}
}
var note = $(e.target).closest('.note');
var $editForm = $('.note-edit-form');
var $originalContentEl = note.find('.original-note-content');
var originalContent = $originalContentEl.text().trim();
var postUrl = $originalContentEl.data('post-url');
var form = note.find('.note-edit-form');
var $noteText = form.find('.js-note-text');
var noteTextVal = $noteText.val(); // Neat little trick to put the cursor at the end
note.addClass('is-editting');
$editForm.insertAfter(note.find('.note-text'));
$editForm.find('.js-note-text').val(originalContent);
$editForm.find('form').attr('action', postUrl);
form.addClass('current-note-edit-form');
note.find('.js-note-attachment-delete').show(); // Show the attachment delete link
new GLForm(form);
$noteText.focus();
// Store the original note text in a data attribute to retrieve if a user cancels edit.
form.find('form.edit-note').data('original-note', noteTextVal);
$noteText.val('').val(noteTextVal);
};
@ -532,15 +560,17 @@
*/
Notes.prototype.cancelEdit = function(e) {
var note;
e.preventDefault();
note = $(e.target).closest('.note');
var note = $(e.target).closest('.note');
note.find('.js-edit-warning').hide();
note.find('.js-md-write-button').trigger('click');
$('.note-edit-form').insertBefore('.notes-form');
return this.removeNoteEditForm(note);
};
Notes.prototype.removeNoteEditForm = function(note) {
var form;
form = note.find(".current-note-edit-form");
var form = note.find(".current-note-edit-form");
note.removeClass("is-editting");
form.removeClass("current-note-edit-form");
// Replace markdown textarea text with original note text.

View file

@ -601,3 +601,12 @@ ul.notes {
position: relative;
}
}
.note-edit-warning.settings-message {
display: none;
position: relative;
top: 1px;
left: 7px;
padding: 5px 10px;
}

View file

@ -7,5 +7,7 @@
.note-form-actions.clearfix
= f.submit 'Save Comment', class: 'btn btn-nr btn-save js-comment-button'
%span.settings-message.note-edit-warning.js-edit-warning
Finish editing this message first!
%button.btn.btn-nr.btn-cancel.note-edit-cancel{ type: 'button' }
Cancel

View file

@ -67,7 +67,8 @@
= note.redacted_note_html
= edited_time_ago_with_tooltip(note, placement: 'bottom', html_class: 'note_edited_ago', include_author: true)
- if note_editable
= render 'projects/notes/edit_form', note: note
.original-note-content.hidden{data: {post_url: namespace_project_note_path(@project.namespace, @project, note), target_id: note.noteable.id, target_type: note.noteable.class.name.underscore}}
#{note.note}
.note-awards
= render 'award_emoji/awards_block', awardable: note, inline: false
- if note.system

View file

@ -6,3 +6,6 @@
= render 'discussions/discussion', discussion: discussion
- else
= render partial: "projects/notes/note", collection: @notes, as: :note
= render 'projects/notes/edit_form', note: @notes[0]
= hidden_field_tag :authenticity_token, form_authenticity_token