Commit 2fa77909 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce

parents d3e040c7 05ef7ba1
......@@ -21,6 +21,7 @@ v 7.13.0 (unreleased)
- Show a user's Two-factor Authentication status in the administration area.
- Explicit error when commit not found in the CI
- Improve performance for issue and merge request pages
- Users with guest access level can not set assignee, labels or milestones for issue and merge request
v 7.12.0 (unreleased)
- Fix Error 500 when one user attempts to access a personal, internal snippet (Stan Hu)
......
......@@ -31,19 +31,13 @@ class Dispatcher
when 'projects:compare:show'
new Diff()
when 'projects:issues:new','projects:issues:edit'
GitLab.GfmAutoComplete.setup()
shortcut_handler = new ShortcutsNavigation()
new ZenMode()
new DropzoneInput($('.issue-form'))
if page == 'projects:issues:new'
new IssuableForm($('.issue-form'))
when 'projects:merge_requests:new', 'projects:merge_requests:edit'
GitLab.GfmAutoComplete.setup()
new Diff()
shortcut_handler = new ShortcutsNavigation()
new ZenMode()
new DropzoneInput($('.merge-request-form'))
if page == 'projects:merge_requests:new'
new IssuableForm($('.merge-request-form'))
when 'projects:merge_requests:show'
new Diff()
......@@ -113,13 +107,6 @@ class Dispatcher
new NamespaceSelect()
when 'dashboard'
shortcut_handler = new ShortcutsDashboardNavigation()
switch path[1]
when 'issues', 'merge_requests'
new UsersSelect()
when 'groups'
switch path[1]
when 'issues', 'merge_requests'
new UsersSelect()
when 'profiles'
new Profile()
when 'projects'
......@@ -135,8 +122,6 @@ class Dispatcher
new ProjectNew()
when 'show'
new ProjectShow()
when 'issues', 'merge_requests'
new UsersSelect()
when 'wikis'
new Wikis()
shortcut_handler = new ShortcutsNavigation()
......
#= require jquery.waitforimages
class @IssuableContext
constructor: ->
new UsersSelect()
$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true})
$(".context .inline-update").on "change", "select", ->
$(this).submit()
$(".context .inline-update").on "change", ".js-assignee", ->
$(this).submit()
$('.issuable-details').waitForImages ->
$('.issuable-affix').affix offset:
top: ->
@top = ($('.issuable-affix').offset().top - 70)
bottom: ->
@bottom = $('.footer').outerHeight(true)
$('.issuable-affix').on 'affix.bs.affix', ->
$(@).width($(@).outerWidth())
.on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
$(@).width('')
class @IssuableForm
constructor: (@form) ->
GitLab.GfmAutoComplete.setup()
new UsersSelect()
new ZenMode()
@titleField = @form.find("input[name*='[title]']")
@descriptionField = @form.find("textarea[name*='[description]']")
......
......@@ -3,29 +3,12 @@
class @Issue
constructor: ->
$('.edit-issue.inline-update input[type="submit"]').hide()
$(".context .inline-update").on "change", "select", ->
$(this).submit()
$(".context .inline-update").on "change", "#issue_assignee_id", ->
$(this).submit()
# Prevent duplicate event bindings
@disableTaskList()
if $("a.btn-close").length
@initTaskList()
$('.issue-details').waitForImages ->
$('.issuable-affix').affix offset:
top: ->
@top = ($('.issuable-affix').offset().top - 70)
bottom: ->
@bottom = $('.footer').outerHeight(true)
$('.issuable-affix').on 'affix.bs.affix', ->
$(@).width($(@).outerWidth())
.on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
$(@).width('')
initTaskList: ->
$('.issue-details .js-task-list-container').taskList('enable')
$(document).on 'tasklist:changed', '.issue-details .js-task-list-container', @updateTaskList
......@@ -42,5 +25,5 @@ class @Issue
$.ajax
type: 'PATCH'
url: $('form.js-issue-update').attr('action')
url: $('form.js-issuable-update').attr('action')
data: patchData
......@@ -10,7 +10,6 @@ class @MergeRequest
# action - String, current controller action
#
constructor: (@opts) ->
@initContextWidget()
this.$el = $('.merge-request')
this.$('.show-all-commits').on 'click', =>
......@@ -26,28 +25,10 @@ class @MergeRequest
if $("a.btn-close").length
@initTaskList()
$('.merge-request-details').waitForImages ->
$('.issuable-affix').affix offset:
top: ->
@top = ($('.issuable-affix').offset().top - 70)
bottom: ->
@bottom = $('.footer').outerHeight(true)
$('.issuable-affix').on 'affix.bs.affix', ->
$(@).width($(@).outerWidth())
.on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
$(@).width('')
# Local jQuery finder
$: (selector) ->
this.$el.find(selector)
initContextWidget: ->
$('.edit-merge_request.inline-update input[type="submit"]').hide()
$(".context .inline-update").on "change", "select", ->
$(this).submit()
$(".context .inline-update").on "change", "#merge_request_assignee_id", ->
$(this).submit()
showAllCommits: ->
this.$('.first-commits').remove()
this.$('.all-commits').removeClass 'hide'
......@@ -68,5 +49,5 @@ class @MergeRequest
$.ajax
type: 'PATCH'
url: $('form.js-merge-request-update').attr('action')
url: $('form.js-issuable-update').attr('action')
data: patchData
......@@ -145,9 +145,3 @@ h2.issue-title {
.issue-form .select2-container {
width: 250px !important;
}
.issues-holder {
.issue-info {
margin-left: 20px;
}
}
......@@ -52,4 +52,12 @@ module GitlabRoutingHelper
def project_snippet_url(entity, *args)
namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args)
end
def toggle_subscription_path(entity, *args)
if entity.is_a?(Issue)
toggle_subscription_namespace_project_issue_path(entity.project.namespace, entity.project, entity)
else
toggle_subscription_namespace_project_merge_request_path(entity.project.namespace, entity.project, entity)
end
end
end
......@@ -185,7 +185,6 @@ class Ability
:modify_issue,
:modify_project_snippet,
:modify_merge_request,
:admin_issue,
:admin_milestone,
:admin_project_snippet,
:admin_project_member,
......
......@@ -26,4 +26,12 @@ class IssuableBaseService < BaseService
issuable, issuable.project, current_user, branch_type,
old_branch, new_branch)
end
def filter_params
unless can?(current_user, :admin_issue, project)
params.delete(:milestone_id)
params.delete(:label_ids)
params.delete(:assignee_id)
end
end
end
module Issues
class CreateService < Issues::BaseService
def execute
filter_params
label_params = params[:label_ids]
issue = project.issues.new(params.except(:label_ids))
issue.author = current_user
......
......@@ -17,6 +17,7 @@ module Issues
params[:assignee_id] = "" if params[:assignee_id] == IssuableFinder::NONE
params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE
filter_params
old_labels = issue.labels.to_a
if params.present? && issue.update_attributes(params.except(:state_event,
......
module MergeRequests
class CreateService < MergeRequests::BaseService
def execute
filter_params
label_params = params[:label_ids]
merge_request = MergeRequest.new(params.except(:label_ids))
merge_request.source_project = project
......
......@@ -27,6 +27,7 @@ module MergeRequests
params[:assignee_id] = "" if params[:assignee_id] == IssuableFinder::NONE
params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE
filter_params
old_labels = merge_request.labels.to_a
if params.present? && merge_request.update_attributes(
......
......@@ -17,5 +17,5 @@
= link_to issues_dashboard_url(format: :atom, private_token: current_user.private_token), class: 'btn' do
%i.fa.fa-rss
= render 'shared/issuable_filter', type: :issues
= render 'shared/issuable/filter', type: :issues
= render 'shared/issues'
......@@ -7,5 +7,5 @@
List all merge requests from all projects you have access to.
%hr
.append-bottom-20
= render 'shared/issuable_filter', type: :merge_requests
= render 'shared/issuable/filter', type: :merge_requests
= render 'shared/merge_requests'
......@@ -21,5 +21,5 @@
= link_to issues_group_url(@group, format: :atom, private_token: current_user.private_token), class: 'btn' do
%i.fa.fa-rss
= render 'shared/issuable_filter', type: :issues
= render 'shared/issuable/filter', type: :issues
= render 'shared/issues'
......@@ -10,5 +10,5 @@
To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page.
%hr
.append-bottom-20
= render 'shared/issuable_filter', type: :merge_requests
= render 'shared/issuable/filter', type: :merge_requests
= render 'shared/merge_requests'
......@@ -23,7 +23,7 @@
= cross_project_reference(@project, @issue)
%hr
.context
= render partial: 'issue_context', locals: { issue: @issue }
= render 'shared/issuable/context', issuable: @issue
- if @issue.labels.any?
.issuable-context-title
......
......@@ -3,7 +3,7 @@
%hr
= form_for [@project.namespace.becomes(Namespace), @project, @issue], html: { class: 'form-horizontal issue-form gfm-form' } do |f|
= render 'projects/issuable_form', f: f, issuable: @issue
= render 'shared/issuable/form', f: f, issuable: @issue
:javascript
$('.assign-to-me-link').on('click', function(e){
......
%li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue) }
- if controller.controller_name == 'issues'
- if controller.controller_name == 'issues' && can?(current_user, :admin_issue, @project)
.issue-check
= check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue", disabled: !can?(current_user, :modify_issue, issue)
= check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue"
.issue-title
%span.issue-title-text
......
= form_for [@project.namespace.becomes(Namespace), @project, @issue], remote: true, html: {class: 'edit-issue inline-update js-issue-update'} do |f|
%div.prepend-top-20
.issuable-context-title
%label
Assignee:
- if issue.assignee
%strong= link_to_member(@project, @issue.assignee, size: 24)
- else
none
- if can?(current_user, :modify_issue, @issue)
= users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @issue.assignee_id, null_user: true, first_user: true)
%div.prepend-top-20.clearfix
.issuable-context-title
%label
Milestone:
- if issue.milestone
%span.back-to-milestone
= link_to namespace_project_milestone_path(@project.namespace, @project, @issue.milestone) do
%strong
%i.fa.fa-clock-o
= @issue.milestone.title
- else
none
- if can?(current_user, :modify_issue, @issue)
= f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :issue_context
= f.submit class: 'btn'
- if current_user
- subscribed = @issue.subscribed?(current_user)
%div.prepend-top-20.clearfix
.issuable-context-title
%label
Subscription:
%button.btn.btn-block.subscribe-button{:type => 'button'}
%i.fa.fa-eye
%span= subscribed ? "Unsubscribe" : "Subscribe"
- subscribtion_status = subscribed ? "subscribed" : "unsubscribed"
.subscription-status{"data-status" => subscribtion_status}
.description-block.unsubscribed{class: ( "hidden" if subscribed )}
You're not receiving notifications from this thread.
.description-block.subscribed{class: ( "hidden" unless subscribed )}
You're receiving notifications because you're subscribed to this thread.
:coffeescript
new Subscription("#{toggle_subscription_namespace_project_issue_path(@issue.project.namespace, @project, @issue)}")
......@@ -11,14 +11,14 @@
= link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do
%i.fa.fa-rss
= render 'shared/issuable_search_form', path: namespace_project_issues_path(@project.namespace, @project)
= render 'shared/issuable/search_form', path: namespace_project_issues_path(@project.namespace, @project)
- if can? current_user, :write_issue, @project
= link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: @issuable_finder.assignee.try(:id), milestone_id: @issuable_finder.milestones.try(:first).try(:id) }), class: "btn btn-new pull-left", title: "New Issue", id: "new_issue_link" do
%i.fa.fa-plus
New Issue
= render 'shared/issuable_filter', type: :issues
= render 'shared/issuable/filter', type: :issues
.issues-holder
= render "issues"
- page_title "#{@issue.title} (##{@issue.iid})", "Issues"
.issue
.issue-details
.issue-details.issuable-details
%h4.page-title
.issue-box{ class: issue_box_class(@issue) }
- if @issue.closed?
......
- if params[:status_only]
- if @issue.valid?
:plain
$("##{dom_id(@issue)}").fadeOut();
- elsif params[:issue_context]
$('.context').html("#{escape_javascript(render partial: 'issue_context', locals: { issue: @issue })}");
$('.context').effect('highlight');
- if @issue.milestone
$('.milestone-nav-link').replaceWith("<span class='milestone-nav-link'>| <span class='light'>Milestone</span> #{escape_javascript(link_to @issue.milestone.title, namespace_project_milestone_path(@issue.project.namespace, @issue.project, @issue.milestone))}</span>")
- else
$('.milestone-nav-link').html('')
$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true})
$('.edit-issue.inline-update input[type="submit"]').hide();
new UsersSelect()
$('.context').html("#{escape_javascript(render 'shared/issuable/context', issuable: @issue)}");
$('.context').effect('highlight')
new Issue();
......@@ -20,7 +20,7 @@
= cross_project_reference(@project, @merge_request)
%hr
.context
= render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request }
= render 'shared/issuable/context', issuable: @merge_request
- if @merge_request.labels.any?
.issuable-context-title
......
= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: 'merge-request-form form-horizontal gfm-form' } do |f|
.merge-request-form-info
= render 'projects/issuable_form', f: f, issuable: @merge_request
= render 'shared/issuable/form', f: f, issuable: @merge_request
:javascript
disableButtonIfEmptyField("#merge_request_title", ".btn-save");
......
......@@ -11,7 +11,7 @@
%hr
= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: 'merge-request-form form-horizontal gfm-form' } do |f|
.merge-request-form-info
= render 'projects/issuable_form', f: f, issuable: @merge_request
= render 'shared/issuable/form', f: f, issuable: @merge_request
= f.hidden_field :source_project_id
= f.hidden_field :source_branch
= f.hidden_field :target_project_id
......
- page_title "#{@merge_request.title} (##{@merge_request.iid})", "Merge Requests"
.merge-request{'data-url' => merge_request_path(@merge_request)}
.merge-request-details
.merge-request-details.issuable-details
= render "projects/merge_requests/show/mr_title"
%hr
= render "projects/merge_requests/show/mr_box"
......
- page_title "Merge Requests"
.append-bottom-10
.pull-right
= render 'shared/issuable_search_form', path: namespace_project_merge_requests_path(@project.namespace, @project)
= render 'shared/issuable/search_form', path: namespace_project_merge_requests_path(@project.namespace, @project)
- if can? current_user, :write_merge_request, @project
.pull-left.hidden-xs
= link_to new_namespace_project_merge_request_path(@project.namespace, @project), class: "btn btn-new", title: "New Merge Request" do
%i.fa.fa-plus
New Merge Request
= render 'shared/issuable_filter', type: :merge_requests
= render 'shared/issuable/filter', type: :merge_requests
.merge-requests-holder
= render 'merge_requests'
- if params[:merge_request_context]
$('.context').html("#{escape_javascript(render partial: 'projects/merge_requests/show/context', locals: { issue: @issue })}");
$('.context').effect('highlight');
new UsersSelect()
$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true});
merge_request = new MergeRequest();
$('.context').html("#{escape_javascript(render 'shared/issuable/context', issuable: @merge_request)}");
$('.context').effect('highlight')
merge_request = new MergeRequest();
= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], remote: true, html: {class: 'edit-merge_request inline-update js-merge-request-update'} do |f|
= form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
%div.prepend-top-20
.issuable-context-title
%label
Assignee:
- if @merge_request.assignee
%strong= link_to_member(@project, @merge_request.assignee, size: 24)
- if issuable.assignee
%strong= link_to_member(@project, issuable.assignee, size: 24)
- else
none
.issuable-context-selectbox
- if can?(current_user, :modify_merge_request, @merge_request)
= users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @merge_request.assignee_id, project: @target_project, null_user: true)
- if can?(current_user, :admin_issue, @project)
= users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true)
%div.prepend-top-20.clearfix
.issuable-context-title
%label
Milestone:
- if @merge_request.milestone
- if issuable.milestone
%span.back-to-milestone
= link_to namespace_project_milestone_path(@project.namespace, @project, @merge_request.milestone) do
= link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do
%strong
= icon('clock-o')
= @merge_request.milestone.title
= issuable.milestone.title
- else
none
.issuable-context-selectbox
- if can?(current_user, :modify_merge_request, @merge_request)
= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: 'Select milestone' }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :merge_request_context
= f.submit class: 'btn'
- if can?(current_user, :admin_issue, @project)
= f.select(:milestone_id, milestone_options(issuable), { include_blank: 'Select milestone' }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :issuable_context
= f.submit class: 'btn hide'
- if current_user
- subscribed = @merge_request.subscribed?(current_user)
- subscribed = issuable.subscribed?(current_user)
%div.prepend-top-20.clearfix
.issuable-context-title
%label
......@@ -46,4 +46,5 @@
You're receiving notifications because you're subscribed to this thread.
:coffeescript
new Subscription("#{toggle_subscription_namespace_project_merge_request_path(@merge_request.project.namespace, @project, @merge_request)}")
new Subscription("#{toggle_subscription_path(issuable)}")
new IssuableContext()
......@@ -29,11 +29,10 @@
.issues-details-filters
= form_tag page_filter_path(without: [:assignee_id, :author_id, :milestone_title, :label_name]), method: :get, class: 'filter-form' do
- if controller.controller_name == 'issues'
- if controller.controller_name == 'issues' && can?(current_user, :admin_issue, @project)
.check-all-holder
= check_box_tag "check_all_issues", nil, false,
class: "check_all_issues left",
disabled: !can?(current_user, :modify_issue, @project)
class: "check_all_issues left"
.issues-other-filters
.filter-item.inline
= users_select_tag(:assignee_id, selected: params[:assignee_id],
......@@ -64,6 +63,8 @@
= button_tag "Update issues", class: "btn update_selected_issues btn-save"
:coffeescript
new UsersSelect()
$('form.filter-form').on 'submit', (event) ->
event.preventDefault()
Turbolinks.visit @.action + '&' + $(@).serialize()
......@@ -37,8 +37,9 @@
.clearfix
.error-alert
%hr
.form-group
%hr
- if can?(current_user, :admin_issue, @project)
.form-group
.issue-assignee
= f.label :assignee_id, class: 'control-label' do
%i.fa.fa-user
......@@ -49,7 +50,7 @@
selected: issuable.assignee_id, project: @target_project || @project)
&nbsp;
= link_to 'Assign to me', '#', class: 'btn assign-to-me-link'
.form-group
.form-group
.issue-milestone
= f.label :milestone_id, class: 'control-label' do
%i.fa.fa-clock-o
......@@ -64,7 +65,7 @@
&nbsp;
- if can? current_user, :admin_milestone, issuable.project
= link_to 'Create new milestone', new_namespace_project_milestone_path(issuable.project.namespace, issuable.project), target: :blank
.form-group
.form-group
= f.label :label_ids, class: 'control-label' do
%i.fa.fa-tag
Labels
......
......@@ -184,3 +184,15 @@ Feature: Project Issues
Then I should see that I am subscribed
When I click button "Unsubscribe"
Then I should see that I am unsubscribed
Scenario: I submit new unassigned issue as guest
Given I logout
Given public project "Community"
When I visit project "Community" page
And I click link "New Issue"
And I should not see assignee field
And I should not see milestone field
And I should not see labels field
And I submit new issue "500 error on profile"
Then I should see issue "500 error on profile"
......@@ -262,6 +262,24 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
end
step 'I should not see labels field' do
page.within '.issue-form' do
expect(page).not_to have_content("Labels")
end
end
step 'I should not see milestone field' do
page.within '.issue-form' do
expect(page).not_to have_content("Milestone")
end
end
step 'I should not see assignee field' do
page.within '.issue-form' do
expect(page).not_to have_content("Assign to")
end
end
def filter_issue(text)
fill_in 'issue_search', with: text
end
......
......@@ -157,7 +157,7 @@ module API
if issue.valid?
# Find or create labels and attach to issue. Labels are valid because
# we already checked its name, so there can't be an error here
unless params[:labels].nil?
if params[:labels] && can?(current_user, :admin_issue, user_project)
issue.remove_labels
# Create and add labels to the new created issue
issue.add_labels_by_names(params[:labels].split(','))
......
......@@ -218,7 +218,7 @@ describe 'Issues', feature: true do
it 'with dropdown menu' do
visit namespace_project_issue_path(project.namespace, project, issue)
find('.edit-issue.inline-update #issue_assignee_id').
find('.context #issue_assignee_id').
set project.team.members.first.id
click_button 'Update Issue'
......@@ -257,7 +257,7 @@ describe 'Issues', feature: true do
it 'with dropdown menu' do
visit namespace_project_issue_path(project.namespace, project, issue)
find('.edit-issue.inline-update').
find('.context').
select(milestone.title, from: 'issue_milestone_id')
click_button 'Update Issue'
......
require 'spec_helper'
feature 'Task Lists' do
feature 'Task Lists', feature: true do
include Warden::Test::Helpers
let(:project) { create(:project) }
......@@ -52,7 +52,7 @@ feature 'Task Lists' do
expect(page).to have_selector(container)
expect(page).to have_selector("#{container} .wiki .task-list .task-list-item .task-list-item-checkbox")
expect(page).to have_selector("#{container} .js-task-list-field")
expect(page).to have_selector('form.js-issue-update')
expect(page).to have_selector('form.js-issuable-update')
expect(page).to have_selector('a.btn-close')
end
......@@ -128,7 +128,7 @@ feature 'Task Lists' do
expect(page).to have_selector(container)
expect(page).to have_selector("#{container} .wiki .task-list .task-list-item .task-list-item-checkbox")
expect(page).to have_selector("#{container} .js-task-list-field")
expect(page).to have_selector('form.js-merge-request-update')
expect(page).to have_selector('form.js-issuable-update')
expect(page).to have_selector('a.btn-close')
end
......
......@@ -10,4 +10,4 @@
%textarea.js-task-list-field
\- [ ] Task List Item
%form.js-issue-update{action: '/foo'}
%form.js-issuable-update{action: '/foo'}
......@@ -10,4 +10,4 @@
%textarea.js-task-list-field
\- [ ] Task List Item
%form.js-merge-request-update{action: '/foo'}
%form.js-issuable-update{action: '/foo'}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment