Merge branch 'warn-about-referenced-users' into 'master'
Show warning when a comment will add 10 or more people to the discussion. Addresses internal issue https://dev.gitlab.org/gitlab/gitlabhq/issues/2054 New issue: ![Screen_Shot_2015-06-02_at_14.48.46](https://gitlab.com/gitlab-org/gitlab-ce/uploads/6771ff8748b9b548a9f0f32a5a8b9bb1/Screen_Shot_2015-06-02_at_14.48.46.png) New comment: ![Screen_Shot_2015-06-02_at_14.48.51](https://gitlab.com/gitlab-org/gitlab-ce/uploads/25ec5f06490e1e6b36e453e055a7b403/Screen_Shot_2015-06-02_at_14.48.51.png) See merge request !754
This commit is contained in:
commit
5a026152b7
21 changed files with 133 additions and 60 deletions
|
@ -4,6 +4,7 @@ v 7.12.0 (unreleased)
|
|||
- Fix timeout when rendering file with thousands of lines.
|
||||
- Don't notify users mentioned in code blocks or blockquotes.
|
||||
- Omit link to generate labels if user does not have access to create them (Stan Hu)
|
||||
- Show warning when a comment will add 10 or more people to the discussion.
|
||||
- Disable changing of the source branch in merge request update API (Stan Hu)
|
||||
- Shorten merge request WIP text.
|
||||
- Add option to disallow users from registering any application to use GitLab as an OAuth provider
|
||||
|
|
|
@ -10,12 +10,17 @@ class @DropzoneInput
|
|||
iconSpinner = "<i class=\"fa fa-spinner fa-spin div-dropzone-icon\"></i>"
|
||||
btnAlert = "<button type=\"button\"" + alertAttr + ">×</button>"
|
||||
project_uploads_path = window.project_uploads_path or null
|
||||
markdown_preview_path = window.markdown_preview_path or null
|
||||
max_file_size = gon.max_file_size or 10
|
||||
|
||||
form_textarea = $(form).find("textarea.markdown-area")
|
||||
form_textarea.wrap "<div class=\"div-dropzone\"></div>"
|
||||
form_textarea.bind 'paste', (event) =>
|
||||
form_textarea.on 'paste', (event) =>
|
||||
handlePaste(event)
|
||||
form_textarea.on "input", ->
|
||||
hideReferencedUsers()
|
||||
form_textarea.on "blur", ->
|
||||
renderMarkdown()
|
||||
|
||||
form_dropzone = $(form).find('.div-dropzone')
|
||||
form_dropzone.parent().addClass "div-dropzone-wrapper"
|
||||
|
@ -45,16 +50,7 @@ class @DropzoneInput
|
|||
form.find(".md-write-holder").hide()
|
||||
form.find(".md-preview-holder").show()
|
||||
|
||||
preview = form.find(".js-md-preview")
|
||||
mdText = form.find(".markdown-area").val()
|
||||
if mdText.trim().length is 0
|
||||
preview.text "Nothing to preview."
|
||||
else
|
||||
preview.text "Loading..."
|
||||
$.post($(this).data("url"),
|
||||
md_text: mdText
|
||||
).success (previewData) ->
|
||||
preview.html previewData
|
||||
renderMarkdown()
|
||||
|
||||
# Write button
|
||||
$(document).off "click", ".js-md-write-button"
|
||||
|
@ -133,6 +129,40 @@ class @DropzoneInput
|
|||
|
||||
child = $(dropzone[0]).children("textarea")
|
||||
|
||||
hideReferencedUsers = ->
|
||||
referencedUsers = form.find(".referenced-users")
|
||||
referencedUsers.hide()
|
||||
|
||||
renderReferencedUsers = (users) ->
|
||||
referencedUsers = form.find(".referenced-users")
|
||||
|
||||
if referencedUsers.length
|
||||
if users.length >= 10
|
||||
referencedUsers.show()
|
||||
referencedUsers.find(".js-referenced-users-count").text users.length
|
||||
else
|
||||
referencedUsers.hide()
|
||||
|
||||
renderMarkdown = ->
|
||||
preview = form.find(".js-md-preview")
|
||||
mdText = form.find(".markdown-area").val()
|
||||
if mdText.trim().length is 0
|
||||
preview.text "Nothing to preview."
|
||||
hideReferencedUsers()
|
||||
else
|
||||
preview.text "Loading..."
|
||||
$.ajax(
|
||||
type: "POST",
|
||||
url: markdown_preview_path,
|
||||
data: {
|
||||
text: mdText
|
||||
},
|
||||
dataType: "json"
|
||||
).success (data) ->
|
||||
preview.html data.body
|
||||
|
||||
renderReferencedUsers data.references.users
|
||||
|
||||
formatLink = (link) ->
|
||||
text = "[#{link.alt}](#{link.url})"
|
||||
text = "!#{text}" if link.is_image
|
||||
|
|
|
@ -10,7 +10,7 @@ GitLab.GfmAutoComplete =
|
|||
|
||||
# Team Members
|
||||
Members:
|
||||
template: '<li>${username} <small>${name}</small></li>'
|
||||
template: '<li>${username} <small>${title}</small></li>'
|
||||
|
||||
# Issues and MergeRequests
|
||||
Issues:
|
||||
|
@ -34,7 +34,13 @@ GitLab.GfmAutoComplete =
|
|||
searchKey: 'search'
|
||||
callbacks:
|
||||
beforeSave: (members) ->
|
||||
$.map members, (m) -> name: m.name, username: m.username, search: "#{m.username} #{m.name}"
|
||||
$.map members, (m) ->
|
||||
title = m.name
|
||||
title += " (#{m.count})" if m.count
|
||||
|
||||
username: m.username
|
||||
title: sanitize(title)
|
||||
search: sanitize("#{m.username} #{m.name}")
|
||||
|
||||
input.atwho
|
||||
at: '#'
|
||||
|
@ -44,7 +50,10 @@ GitLab.GfmAutoComplete =
|
|||
insertTpl: '${atwho-at}${id}'
|
||||
callbacks:
|
||||
beforeSave: (issues) ->
|
||||
$.map issues, (i) -> id: i.iid, title: sanitize(i.title), search: "#{i.iid} #{i.title}"
|
||||
$.map issues, (i) ->
|
||||
id: i.iid
|
||||
title: sanitize(i.title)
|
||||
search: "#{i.iid} #{i.title}"
|
||||
|
||||
input.atwho
|
||||
at: '!'
|
||||
|
@ -54,7 +63,10 @@ GitLab.GfmAutoComplete =
|
|||
insertTpl: '${atwho-at}${id}'
|
||||
callbacks:
|
||||
beforeSave: (merges) ->
|
||||
$.map merges, (m) -> id: m.iid, title: sanitize(m.title), search: "#{m.iid} #{m.title}"
|
||||
$.map merges, (m) ->
|
||||
id: m.iid
|
||||
title: sanitize(m.title)
|
||||
search: "#{m.iid} #{m.title}"
|
||||
|
||||
input.one 'focus', =>
|
||||
$.getJSON(@dataSource).done (data) ->
|
||||
|
|
|
@ -52,6 +52,22 @@
|
|||
transition: opacity 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.md-area {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.md-header ul {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.referenced-users {
|
||||
padding: 10px 0;
|
||||
color: #999;
|
||||
margin-left: 10px;
|
||||
margin-top: 1px;
|
||||
margin-right: 130px;
|
||||
}
|
||||
|
||||
.md-preview-holder {
|
||||
background: #FFF;
|
||||
border: 1px solid #ddd;
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.referenced-users {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.issues-filters,
|
||||
.dash-projects-filters,
|
||||
.check-all-holder {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
.zennable {
|
||||
position: relative;
|
||||
|
||||
.zen-toggle-comment {
|
||||
display: none;
|
||||
}
|
||||
|
@ -8,8 +6,9 @@
|
|||
.zen-enter-link {
|
||||
color: #888;
|
||||
position: absolute;
|
||||
top: -26px;
|
||||
top: 0px;
|
||||
right: 4px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.zen-leave-link {
|
||||
|
|
|
@ -39,11 +39,8 @@
|
|||
|
||||
.new_note, .edit_note {
|
||||
.buttons {
|
||||
float: left;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.clearfix {
|
||||
margin-bottom: 0;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.note-preview-holder {
|
||||
|
@ -82,7 +79,6 @@
|
|||
|
||||
.note-form-actions {
|
||||
background: #F9F9F9;
|
||||
height: 45px;
|
||||
|
||||
.note-form-option {
|
||||
margin-top: 8px;
|
||||
|
|
|
@ -151,7 +151,17 @@ class ProjectsController < ApplicationController
|
|||
end
|
||||
|
||||
def markdown_preview
|
||||
render text: view_context.markdown(params[:md_text])
|
||||
text = params[:text]
|
||||
|
||||
ext = Gitlab::ReferenceExtractor.new(@project, current_user)
|
||||
ext.analyze(text)
|
||||
|
||||
render json: {
|
||||
body: view_context.markdown(text),
|
||||
references: {
|
||||
users: ext.users.map(&:username)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -38,13 +38,13 @@ module Projects
|
|||
def groups
|
||||
current_user.authorized_groups.sort_by(&:path).map do |group|
|
||||
count = group.users.count
|
||||
{ username: group.path, name: "#{group.name} (#{count})" }
|
||||
{ username: group.path, name: group.name, count: count }
|
||||
end
|
||||
end
|
||||
|
||||
def all_members
|
||||
count = project.team.members.flatten.count
|
||||
[{ username: "all", name: "All Project and Group Members (#{count})" }]
|
||||
[{ username: "all", name: "All Project and Group Members", count: count }]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,8 +15,10 @@
|
|||
%meta{name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1'}
|
||||
%meta{name: 'theme-color', content: '#474D57'}
|
||||
|
||||
= yield(:meta_tags)
|
||||
= yield :meta_tags
|
||||
|
||||
= render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id')
|
||||
= render 'layouts/piwik' if extra_config.has_key?('piwik_url') && extra_config.has_key?('piwik_site_id')
|
||||
= render 'layouts/bootlint' if Rails.env.development?
|
||||
|
||||
= yield :scripts_head
|
||||
|
|
|
@ -22,5 +22,3 @@
|
|||
= render "layouts/flash"
|
||||
.clearfix
|
||||
= yield
|
||||
|
||||
= yield :embedded_scripts
|
||||
|
|
|
@ -8,3 +8,5 @@
|
|||
= render "layouts/header/public", title: header_title
|
||||
|
||||
= render 'layouts/page', sidebar: sidebar
|
||||
|
||||
= yield :scripts_body
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
- header_title project_title(@project)
|
||||
- sidebar "project" unless sidebar
|
||||
|
||||
- content_for :embedded_scripts do
|
||||
- content_for :scripts_head do
|
||||
-if current_user
|
||||
:javascript
|
||||
window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}";
|
||||
window.markdown_preview_path = "#{markdown_preview_namespace_project_path(@project.namespace, @project)}";
|
||||
|
||||
- content_for :scripts_body do
|
||||
= render "layouts/init_auto_complete" if current_user
|
||||
|
||||
= render template: "layouts/application"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
= f.label :description, 'Description', class: 'control-label'
|
||||
.col-sm-10
|
||||
|
||||
= render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do
|
||||
= render layout: 'projects/md_preview', locals: { preview_class: "wiki", referenced_users: true } do
|
||||
= render 'projects/zen', f: f, attr: :description,
|
||||
classes: 'description form-control'
|
||||
.col-sm-12.hint
|
||||
|
|
|
@ -1,13 +1,24 @@
|
|||
%ul.nav.nav-tabs
|
||||
%li.active
|
||||
= link_to '#md-write-holder', class: 'js-md-write-button' do
|
||||
Write
|
||||
%li
|
||||
= link_to '#md-preview-holder', class: 'js-md-preview-button',
|
||||
data: { url: markdown_preview_namespace_project_path(@project.namespace, @project) } do
|
||||
Preview
|
||||
%div
|
||||
.md-write-holder
|
||||
= yield
|
||||
.md.md-preview-holder.hide
|
||||
.js-md-preview{class: (preview_class if defined?(preview_class))}
|
||||
.md-area
|
||||
.md-header.clearfix
|
||||
%ul.nav.nav-tabs
|
||||
%li.active
|
||||
= link_to '#md-write-holder', class: 'js-md-write-button' do
|
||||
Write
|
||||
%li
|
||||
= link_to '#md-preview-holder', class: 'js-md-preview-button' do
|
||||
Preview
|
||||
|
||||
- if defined?(referenced_users) && referenced_users
|
||||
%span.referenced-users.pull-left.hide
|
||||
= icon('exclamation-triangle')
|
||||
You are about to add
|
||||
%strong
|
||||
%span.js-referenced-users-count 0
|
||||
people
|
||||
to the discussion. Proceed with caution.
|
||||
|
||||
%div
|
||||
.md-write-holder
|
||||
= yield
|
||||
.md.md-preview-holder.hide
|
||||
.js-md-preview{class: (preview_class if defined?(preview_class))}
|
||||
|
|
|
@ -10,5 +10,3 @@
|
|||
$('#issue_assignee_id').val("#{current_user.id}").trigger("change");
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}";
|
||||
|
|
|
@ -8,5 +8,3 @@
|
|||
$('#merge_request_assignee_id').val("#{current_user.id}").trigger("change");
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}";
|
||||
|
|
|
@ -51,8 +51,6 @@
|
|||
e.preventDefault();
|
||||
});
|
||||
|
||||
window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}";
|
||||
|
||||
:javascript
|
||||
var merge_request
|
||||
merge_request = new MergeRequest({
|
||||
|
|
|
@ -50,5 +50,3 @@
|
|||
dateFormat: "yy-mm-dd",
|
||||
onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) }
|
||||
}).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#milestone_due_date').val()));
|
||||
|
||||
window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}";
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
= f.hidden_field :noteable_id
|
||||
= f.hidden_field :noteable_type
|
||||
|
||||
= render layout: 'projects/md_preview', locals: { preview_class: "note-text" } do
|
||||
= render layout: 'projects/md_preview', locals: { preview_class: "note-text", referenced_users: true } do
|
||||
= render 'projects/zen', f: f, attr: :note,
|
||||
classes: 'note_text js-note-text'
|
||||
|
||||
|
@ -15,10 +15,7 @@
|
|||
.error-alert
|
||||
|
||||
.note-form-actions
|
||||
.buttons
|
||||
.buttons.clearfix
|
||||
= f.submit 'Add Comment', class: "btn comment-btn btn-grouped js-comment-button"
|
||||
= yield(:note_actions)
|
||||
%a.btn.grouped.js-close-discussion-note-form Cancel
|
||||
|
||||
:javascript
|
||||
window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}";
|
||||
|
|
|
@ -41,6 +41,3 @@
|
|||
- else
|
||||
= f.submit 'Create page', class: "btn-create btn"
|
||||
= link_to "Cancel", namespace_project_wiki_path(@project.namespace, @project, :home), class: "btn btn-cancel"
|
||||
|
||||
:javascript
|
||||
window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}";
|
||||
|
|
Loading…
Reference in a new issue