Actualizar plugin Questions a 1.0.2 light
This commit is contained in:
parent
b9e569d03f
commit
b37d1305f1
64 changed files with 394 additions and 229 deletions
34
plugins/redmine_questions/.drone.jsonnet
Normal file
34
plugins/redmine_questions/.drone.jsonnet
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
local Pipeline(rubyVer, db, license, redmine, dependents) = {
|
||||||
|
kind: "pipeline",
|
||||||
|
name: rubyVer + "-" + db + "-" + redmine + "-" + license + "-" + dependents,
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
name: "tests",
|
||||||
|
image: "redmineup/redmineup_ci",
|
||||||
|
commands: [
|
||||||
|
"service postgresql start && service mysql start && sleep 5",
|
||||||
|
"export PATH=~/.rbenv/shims:$PATH",
|
||||||
|
"export CODEPATH=`pwd`",
|
||||||
|
"/root/run_for.sh redmine_questions+" + license + " ruby-" + rubyVer + " " + db + " redmine-" + redmine + " " + dependents
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
[
|
||||||
|
Pipeline("2.4.1", "mysql", "pro", "trunk", ""),
|
||||||
|
Pipeline("2.4.1", "mysql", "light", "trunk", ""),
|
||||||
|
Pipeline("2.4.1", "pg", "pro", "trunk", ""),
|
||||||
|
Pipeline("2.4.1", "mysql", "pro", "4.1", ""),
|
||||||
|
Pipeline("2.4.1", "mysql", "light", "4.1", ""),
|
||||||
|
Pipeline("2.4.1", "pg", "pro", "4.1", ""),
|
||||||
|
Pipeline("2.4.1", "mysql", "pro", "4.0", ""),
|
||||||
|
Pipeline("2.4.1", "mysql", "light", "4.0", ""),
|
||||||
|
Pipeline("2.4.1", "pg", "pro", "4.0", ""),
|
||||||
|
Pipeline("2.4.1", "pg", "light", "4.0", ""),
|
||||||
|
Pipeline("2.2.6", "mysql", "pro", "3.4", ""),
|
||||||
|
Pipeline("2.2.6", "pg", "pro", "3.4", ""),
|
||||||
|
Pipeline("2.2.6", "mysql", "pro", "3.0", ""),
|
||||||
|
Pipeline("2.2.6", "mysql", "light", "3.0", ""),
|
||||||
|
Pipeline("1.9.3", "pg", "pro", "2.6", ""),
|
||||||
|
]
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -34,9 +34,11 @@ class QuestionsAnswersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
(render_403; return false) unless @answer.editable_by?(User.current)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
(render_403; return false) unless @answer.editable_by?(User.current) || User.current.allowed_to?(:accept_answers, @project)
|
||||||
@answer.safe_attributes = params[:answer]
|
@answer.safe_attributes = params[:answer]
|
||||||
@answer.save_attachments(params[:attachments])
|
@answer.save_attachments(params[:attachments])
|
||||||
if @answer.save
|
if @answer.save
|
||||||
|
@ -87,7 +89,7 @@ class QuestionsAnswersController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def redirect_to_question
|
def redirect_to_question
|
||||||
redirect_to question_path(@answer.question, :anchor => "question_item_#{@answer.id}")
|
redirect_to question_path(@answer.question, :anchor => "questions_answer_#{@answer.id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_answer
|
def find_answer
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -54,6 +54,7 @@ class QuestionsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
(render_403; return false) unless @question_item.editable_by?(User.current)
|
||||||
@question_item.safe_attributes = params[:question]
|
@question_item.safe_attributes = params[:question]
|
||||||
@question_item.save_attachments(params[:attachments])
|
@question_item.save_attachments(params[:attachments])
|
||||||
if @question_item.save
|
if @question_item.save
|
||||||
|
@ -133,6 +134,7 @@ class QuestionsController < ApplicationController
|
||||||
@text = (params[:question] ? params[:question][:content] : nil)
|
@text = (params[:question] ? params[:question][:content] : nil)
|
||||||
render :partial => 'common/preview'
|
render :partial => 'common/preview'
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def find_questions
|
def find_questions
|
||||||
|
@ -142,10 +144,10 @@ class QuestionsController < ApplicationController
|
||||||
scope = Question.visible
|
scope = Question.visible
|
||||||
scope = scope.where(:section_id => @section) if @section
|
scope = scope.where(:section_id => @section) if @section
|
||||||
|
|
||||||
columns = ["subject", "content"]
|
columns = ['subject', 'content']
|
||||||
tokens = seach.to_s.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect{|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}.uniq.select {|w| w.length > 1 }
|
tokens = seach.to_s.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect { |m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '') }.uniq.select { |w| w.length > 1 }
|
||||||
tokens = [] << tokens unless tokens.is_a?(Array)
|
tokens = [] << tokens unless tokens.is_a?(Array)
|
||||||
token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}
|
token_clauses = columns.collect { |column| "(LOWER(#{column}) LIKE ?)" }
|
||||||
sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(' AND ')
|
sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(' AND ')
|
||||||
find_options = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
|
find_options = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
|
||||||
|
|
||||||
|
@ -166,9 +168,9 @@ class QuestionsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
@limit = per_page_option
|
@limit = per_page_option
|
||||||
@offset = params[:page].to_i*@limit
|
@offset = params[:page].to_i * @limit
|
||||||
scope = scope.limit(@limit).offset(@offset)
|
scope = scope.limit(@limit).offset(@offset)
|
||||||
scope = scope.tagged_with(params[:tag]) unless params[:tag].blank?
|
scope = scope.tagged_with(params[:tag]) if params[:tag].present?
|
||||||
|
|
||||||
@topic_count = scope.count
|
@topic_count = scope.count
|
||||||
@topic_pages = Paginator.new @topic_count, @limit, params[:page]
|
@topic_pages = Paginator.new @topic_count, @limit, params[:page]
|
||||||
|
@ -178,7 +180,7 @@ class QuestionsController < ApplicationController
|
||||||
|
|
||||||
def find_section
|
def find_section
|
||||||
@section = QuestionsSection.find_by_id(params[:section_id] || (params[:question] && params[:question][:section_id]))
|
@section = QuestionsSection.find_by_id(params[:section_id] || (params[:question] && params[:question][:section_id]))
|
||||||
@section ||= @project.questions_sections.first
|
@section ||= @project.questions_sections.first if @project
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
render_404
|
render_404
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -58,6 +58,7 @@ class QuestionsSectionsController < ApplicationController
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@section.safe_attributes = params[:questions_section]
|
@section.safe_attributes = params[:questions_section]
|
||||||
|
@section.insert_at(@section.position) if @section.position_changed?
|
||||||
if @section.save
|
if @section.save
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -39,12 +39,13 @@ class QuestionsStatusesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@questions_status = QuestionsStatus.new(params[:questions_status])
|
@questions_status = QuestionsStatus.new
|
||||||
|
@questions_status.safe_attributes = params[:questions_status]
|
||||||
if request.post? && @questions_status.save
|
if request.post? && @questions_status.save
|
||||||
flash[:notice] = l(:notice_successful_create)
|
flash[:notice] = l(:notice_successful_create)
|
||||||
redirect_to :action => "plugin", :id => "redmine_questions", :controller => "settings", :tab => 'questions_statuses'
|
redirect_to action: 'plugin', id: 'redmine_questions', controller: 'settings', tab: 'questions_statuses'
|
||||||
else
|
else
|
||||||
render :action => 'new'
|
render action: 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,17 +55,18 @@ class QuestionsStatusesController < ApplicationController
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@questions_status = QuestionsStatus.find(params[:id])
|
@questions_status = QuestionsStatus.find(params[:id])
|
||||||
if @questions_status.update_attributes(params[:questions_status])
|
@questions_status.safe_attributes = params[:questions_status]
|
||||||
|
if @questions_status.save
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html {
|
format.html {
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
redirect_to :action => 'plugin', :id => 'redmine_questions', :controller => 'settings', :tab => 'questions_statuses'
|
redirect_to action: 'plugin', id: 'redmine_questions', controller: 'settings', tab: 'questions_statuses'
|
||||||
}
|
}
|
||||||
format.js { head 200 }
|
format.js { head 200 }
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { render :action => 'edit' }
|
format.html { render action: 'edit' }
|
||||||
format.js { head 422 }
|
format.js { head 422 }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -72,11 +74,9 @@ class QuestionsStatusesController < ApplicationController
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
QuestionsStatus.find(params[:id]).destroy
|
QuestionsStatus.find(params[:id]).destroy
|
||||||
redirect_to :action =>"plugin", :id => "redmine_questions", :controller => "settings", :tab => 'questions_statuses'
|
redirect_to action: 'plugin', id: 'redmine_questions', controller: 'settings', tab: 'questions_statuses'
|
||||||
rescue
|
rescue
|
||||||
flash[:error] = l(:error_products_unable_delete_questions_status)
|
flash[:error] = l(:error_products_unable_delete_questions_status)
|
||||||
redirect_to :action =>"plugin", :id => "redmine_questions", :controller => "settings", :tab => 'questions_statuses'
|
redirect_to action: 'plugin', id: 'redmine_questions', controller: 'settings', tab: 'questions_statuses'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -54,22 +54,22 @@ class Question < ActiveRecord::Base
|
||||||
:author_key => :author_id,
|
:author_key => :author_id,
|
||||||
:timestamp => "#{table_name}.created_on",
|
:timestamp => "#{table_name}.created_on",
|
||||||
:scope => joins({:section => :project}, :author)
|
:scope => joins({:section => :project}, :author)
|
||||||
acts_as_searchable :columns => ["#{table_name}.subject",
|
acts_as_searchable :columns => ["#{table_name}.subject",
|
||||||
"#{table_name}.content",
|
"#{table_name}.content",
|
||||||
"#{QuestionsAnswer.table_name}.content"],
|
"#{QuestionsAnswer.table_name}.content"],
|
||||||
:scope => joins({:section => :project}, :answers),
|
:scope => joins({:section => :project}, :answers),
|
||||||
:project_key => "#{QuestionsSection.table_name}.project_id"
|
:project_key => "#{QuestionsSection.table_name}.project_id"
|
||||||
else
|
else
|
||||||
acts_as_activity_provider :type => 'questions',
|
acts_as_activity_provider :type => 'questions',
|
||||||
:permission => :view_questions,
|
:permission => :view_questions,
|
||||||
:author_key => :author_id,
|
:author_key => :author_id,
|
||||||
:timestamp => "#{table_name}.created_on",
|
:timestamp => "#{table_name}.created_on",
|
||||||
:find_options => { :include => [{:section => :project}, :author] }
|
:find_options => { :include => [{:section => :project}, :author] }
|
||||||
acts_as_searchable :columns => ["#{table_name}.subject",
|
acts_as_searchable :columns => ["#{table_name}.subject",
|
||||||
"#{table_name}.content",
|
"#{table_name}.content",
|
||||||
"#{QuestionsAnswer.table_name}.content"],
|
"#{QuestionsAnswer.table_name}.content"],
|
||||||
:include => [{:section => :project}, :answers],
|
:include => [{:section => :project}, :answers],
|
||||||
:project_key => "#{QuestionsSection.table_name}.project_id"
|
:project_key => "#{QuestionsSection.table_name}.project_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
scope :solutions, lambda { joins(:section).where(:questions_sections => {:section_type => QuestionsSection::SECTION_TYPE_SOLUTIONS}) }
|
scope :solutions, lambda { joins(:section).where(:questions_sections => {:section_type => QuestionsSection::SECTION_TYPE_SOLUTIONS}) }
|
||||||
|
@ -114,7 +114,7 @@ class Question < ActiveRecord::Base
|
||||||
allowed_to_view_condition += projects_allowed_to_view_questions.empty? ? ' OR (0=1) ' : " OR (#{table_name}.project_id IN (#{projects_allowed_to_view_questions.join(',')}))"
|
allowed_to_view_condition += projects_allowed_to_view_questions.empty? ? ' OR (0=1) ' : " OR (#{table_name}.project_id IN (#{projects_allowed_to_view_questions.join(',')}))"
|
||||||
|
|
||||||
user.admin? ? '(1=1)' : allowed_to_view_condition
|
user.admin? ? '(1=1)' : allowed_to_view_condition
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.related(question, limit)
|
def self.related(question, limit)
|
||||||
tokens = question.subject.strip.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).
|
tokens = question.subject.strip.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).
|
||||||
|
@ -127,7 +127,7 @@ class Question < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def commentable?(user = User.current)
|
def commentable?(user = User.current)
|
||||||
return false if locked?
|
return false if locked?
|
||||||
user.allowed_to?(:comment_question, project)
|
user.allowed_to?(:comment_question, project)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -285,6 +285,6 @@ class Question < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_notification
|
def send_notification
|
||||||
Mailer.question_question_added(self).deliver if Setting.notified_events.include?('question_added')
|
Mailer.question_question_added(User.current, self).deliver if Setting.notified_events.include?('question_added')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -97,6 +97,7 @@ class QuestionsAnswer < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def editable_by?(user)
|
def editable_by?(user)
|
||||||
|
(author == user && user.allowed_to?(:edit_own_answers, project)) ||
|
||||||
user.allowed_to?(:edit_questions, project)
|
user.allowed_to?(:edit_questions, project)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ class QuestionsAnswer < ActiveRecord::Base
|
||||||
def votable_by?(user)
|
def votable_by?(user)
|
||||||
user.allowed_to?(:vote_questions, project)
|
user.allowed_to?(:vote_questions, project)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def check_accepted
|
def check_accepted
|
||||||
question.answers.update_all(:accepted => false) if question &&
|
question.answers.update_all(:accepted => false) if question &&
|
||||||
|
@ -121,6 +122,6 @@ class QuestionsAnswer < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_notification
|
def send_notification
|
||||||
Mailer.question_answer_added(self).deliver if Setting.notified_events.include?('question_answer_added')
|
Mailer.question_answer_added(User.current, self).deliver if Setting.notified_events.include?('question_answer_added')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -27,7 +27,12 @@ class QuestionsSection < ActiveRecord::Base
|
||||||
attr_protected :id if ActiveRecord::VERSION::MAJOR <= 4
|
attr_protected :id if ActiveRecord::VERSION::MAJOR <= 4
|
||||||
safe_attributes 'name', 'project', 'position', 'description', 'section_type'
|
safe_attributes 'name', 'project', 'position', 'description', 'section_type'
|
||||||
|
|
||||||
scope :with_questions_count, lambda { select("#{QuestionsSection.table_name}.*, count(#{QuestionsSection.table_name}.id) as questions_count").joins(:questions).order("project_id ASC").group("#{QuestionsSection.table_name}.id, #{QuestionsSection.table_name}.name, #{QuestionsSection.table_name}.project_id, #{QuestionsSection.table_name}.section_type") }
|
scope :with_questions_count, lambda {
|
||||||
|
select("#{QuestionsSection.table_name}.*, count(#{QuestionsSection.table_name}.id) as questions_count").
|
||||||
|
joins(:questions).
|
||||||
|
order("project_id ASC").
|
||||||
|
group(QuestionsSection.column_names.map { |column| "#{QuestionsSection.table_name}.#{column}" }.join(', '))
|
||||||
|
}
|
||||||
scope :for_project, lambda { |project| where(:project_id => project) unless project.blank? }
|
scope :for_project, lambda { |project| where(:project_id => project) unless project.blank? }
|
||||||
scope :visible, lambda {|*args|
|
scope :visible, lambda {|*args|
|
||||||
joins(:project).
|
joins(:project).
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -26,7 +26,7 @@ class QuestionsStatus < ActiveRecord::Base
|
||||||
attr_protected :id if ActiveRecord::VERSION::MAJOR <= 4
|
attr_protected :id if ActiveRecord::VERSION::MAJOR <= 4
|
||||||
safe_attributes 'name', 'is_closed', 'position', 'color'
|
safe_attributes 'name', 'is_closed', 'position', 'color'
|
||||||
|
|
||||||
validates :name, :presence => true, :uniqueness => true
|
validates :name, presence: true, uniqueness: true
|
||||||
|
|
||||||
scope :sorted, lambda { order(:position) }
|
scope :sorted, lambda { order(:position) }
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,41 @@
|
||||||
|
<% @project_sections = QuestionsSection.for_project(@project).sorted %>
|
||||||
<h3><%= l(:label_questions_sections_plural) %></h3>
|
<h3><%= l(:label_questions_sections_plural) %></h3>
|
||||||
|
|
||||||
<table class="list questions_sections">
|
<% if @project_sections.any? %>
|
||||||
<thead>
|
<table class="list questions_sections">
|
||||||
<tr>
|
<thead>
|
||||||
<th><%= l(:field_name) %></th>
|
<tr>
|
||||||
<th><%=l(:field_type)%></th>
|
<th><%= l(:field_name) %></th>
|
||||||
<th></th>
|
<th><%=l(:field_type)%></th>
|
||||||
</tr>
|
<th></th>
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% QuestionsSection.for_project(@project).sorted.each do |section| %>
|
|
||||||
<tr class="<%= cycle 'odd', 'even' %>">
|
|
||||||
<td class="name">
|
|
||||||
<%= h(section.name) %>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<%= section.l_type %>
|
|
||||||
</td>
|
|
||||||
<td class="buttons">
|
|
||||||
<% if User.current.allowed_to?(:manage_sections, @project) %>
|
|
||||||
<%= reorder_handle(section, :url => project_questions_section_path(@project, section), :param => 'questions_section') if respond_to?(:reorder_handle) %>
|
|
||||||
<%= link_to l(:button_edit), {:controller => 'questions_sections', :action => 'edit', :project_id => @project, :id => section}, :class => 'icon icon-edit' %>
|
|
||||||
<%= delete_link :controller => 'questions_sections', :action => 'destroy', :project_id => @project, :id => section %>
|
|
||||||
<% end %>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
<% @project_sections.each do |section| %>
|
||||||
|
<tr class="<%= cycle 'odd', 'even' %>">
|
||||||
|
<td class="name">
|
||||||
|
<%= h(section.name) %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= section.l_type %>
|
||||||
|
</td>
|
||||||
|
<td class="buttons">
|
||||||
|
<% if User.current.allowed_to?(:manage_sections, @project) %>
|
||||||
|
<%= reorder_handle(section, url: project_questions_section_path(@project, section), param: 'questions_section') if respond_to?(:reorder_handle) %>
|
||||||
|
<%= link_to l(:button_edit), edit_questions_section_path(section, project_id: @project), class: 'icon icon-edit' %>
|
||||||
|
<%= delete_link questions_section_path(section, project_id: @project) %>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% else %>
|
||||||
|
<p class="nodata"><%= l(:label_no_data) %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<% if User.current.allowed_to?(:manage_sections, @project) %>
|
<% if User.current.allowed_to?(:manage_sections, @project) %>
|
||||||
<%= link_to image_tag('add.png', :style => 'vertical-align: middle;')+l(:label_questions_section_new), :controller => 'questions_sections', :action => 'new', :project_id => @project %>
|
<%= link_to image_tag('add.png', style: 'vertical-align: middle;') + l(:label_questions_section_new), new_questions_section_path(project_id: @project) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= javascript_tag do %>
|
<%= javascript_tag do %>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<%= f.text_field :subject, :id => "question_subject", :size => 120%>
|
<%= f.text_field :subject, :id => "question_subject", :size => 120%>
|
||||||
</p>
|
</p>
|
||||||
<p><label><%= l(:label_questions_section) %></label><br />
|
<p><label><%= l(:label_questions_section) %></label><br />
|
||||||
<%= f.select :section_id, options_from_collection_for_select(QuestionsSection.where(:project_id => @project),:id, :name, f.object.section_id), :style => "width: 80%;", :required => true %>
|
<%= f.select :section_id, options_from_collection_for_select(QuestionsSection.where(:project_id => @project).sorted, :id, :name, f.object.section_id), :style => "width: 80%;", :required => true %>
|
||||||
<%= javascript_tag do %>
|
<%= javascript_tag do %>
|
||||||
$('#question_section_id').change(function() {
|
$('#question_section_id').change(function() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="question<%= " votable" if question_item.allow_voting? %> div-table" id="question_<%= question_item.id %>">
|
<div class="question<%= " votable" if question_item.allow_voting? %> div-table" id="question_<%= question_item.id %>">
|
||||||
<a href="#<%= question_item.id %>" class="wiki-anchor"></a>
|
<a href="#<%= question_item.id %>" class="wiki-anchor"></a>
|
||||||
<% if question_item.allow_voting? && User.current.allowed_to?(:vote_questions, @project) %>
|
<% if question_item.allow_voting? %>
|
||||||
<div class="vote">
|
<div class="vote">
|
||||||
<%= render :partial => 'questions_votes/question_item_vote', :locals => {:question_item => question_item} %>
|
<%= render :partial => 'questions_votes/question_item_vote', :locals => {:question_item => question_item} %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||||
</div>
|
</div>
|
||||||
<%= submit_tag l(:button_save) %>
|
<%= submit_tag l(:button_save) %>
|
||||||
<%= preview_link({:controller => 'questions', :action => 'preview', :question_id => @question_item}, 'question_form') %>
|
<%= preview_link({:controller => 'questions', :action => 'preview', :question_id => @question_item}, 'question_form') if Redmine::VERSION.to_s <= '3.4.5' %>
|
||||||
|
| <%= link_to l(:button_cancel), question_path(@question_item) %>
|
||||||
|
|
||||||
<% end %>
|
<% end %>
|
||||||
<div id="preview" class="wiki"></div>
|
<div id="preview" class="wiki"></div>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<div class="filters">
|
<div class="filters">
|
||||||
<%= form_tag({:controller => "questions", :action => "index"}, :method => :get, :id => "query_form") do %>
|
<%= form_tag({:controller => "questions", :action => "index"}, :method => :get, :id => "query_form") do %>
|
||||||
<%= text_field_tag(:topic_search, params[:topic_search], :autocomplete => "off", :class => "questions-search", :placeholder => l(:label_questions_search) ) %>
|
<%= text_field_tag(:topic_search, params[:topic_search], :autocomplete => "off", :class => "questions-search", :placeholder => l(:label_questions_search) ) %>
|
||||||
<%= javascript_tag "observeSearchfield('topic_search', 'topics_list', '#{ escape_javascript(autocomplete_for_subject_questions_path(:project_id => @project, :section_id => @section)) }')" %>
|
<%= javascript_tag "observeSearchfield('topic_search', 'topics_list', '#{ escape_javascript(autocomplete_for_subject_questions_path(:project_id => @project, :section_id => @section, :sort_order => @sort_order)) }')" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<h2><%= l(:label_message_new) %></h2>
|
<h2><%= l(:label_message_new) %></h2>
|
||||||
|
|
||||||
<%= form_for @question_item, { :url => questions_path, :html => {:multipart => true,
|
<%= form_for @question_item, { :url => project_questions_path(@project, {}), :html => {:multipart => true,
|
||||||
:id => 'question_form'}} do |f| %>
|
:id => 'question_form'}} do |f| %>
|
||||||
<div id="all_attributes">
|
<div id="all_attributes">
|
||||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
<%= render partial: 'form', locals: { f: f } %>
|
||||||
</div>
|
</div>
|
||||||
<%= submit_tag l(:button_create) %>
|
<%= submit_tag l(:button_create) %>
|
||||||
<% preview_link({:controller => 'questions', :action => 'preview', :id => @question_item}, 'question_form') %>
|
<% preview_link({ controller: 'questions', action: 'preview', id: @question_item }, 'question_form') if Redmine::VERSION.to_s <= '3.4.5' %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div id="preview" class="wiki"></div>
|
<div id="preview" class="wiki"></div>
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
<div class="contextual">
|
<div class="contextual">
|
||||||
<%= link_to(l(:button_edit), edit_questions_answer_path(question_item), :class => 'icon icon-edit') if question_item.editable_by?(User.current) %>
|
<% if question_item.editable_by?(User.current) %>
|
||||||
<%= link_to(l(:button_delete), questions_answer_path(question_item), :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') if question_item.destroyable_by?(User.current)
|
<%= link_to(l(:button_edit), edit_questions_answer_path(question_item), :class => 'icon icon-edit') %>
|
||||||
|
<% elsif User.current.allowed_to?(:accept_answers, @project) && !question_item.accepted? %>
|
||||||
|
<%= link_to(l(:label_questions_accept), questions_answer_path(question_item, answer: {accepted: true}), method: :put, :class => 'icon icon-accept') %>
|
||||||
|
<% elsif User.current.allowed_to?(:accept_answers, @project) && question_item.accepted? %>
|
||||||
|
<%= link_to(l(:label_questions_discard), questions_answer_path(question_item, answer: {accepted: false}), method: :put, :class => 'icon icon-discard') %>
|
||||||
|
<% end %>
|
||||||
|
<%= link_to(l(:button_delete), questions_answer_path(question_item), :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') if question_item.destroyable_by?(User.current)
|
||||||
%>
|
%>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="question answer<%= ' votable' if question_item.allow_voting? %> div-table" id="questions_answer_<%= question_item.id %>">
|
<div class="question answer<%= ' votable' if question_item.allow_voting? %> div-table" id="questions_answer_<%= question_item.id %>">
|
||||||
<a href="#<%= question_item.id %>" class="wiki-anchor"></a>
|
<a href="#<%= question_item.id %>" class="wiki-anchor"></a>
|
||||||
<% if question_item.allow_voting? && User.current.allowed_to?(:vote_questions, @project) %>
|
<% if question_item.allow_voting? %>
|
||||||
<div class="vote" >
|
<div class="vote" >
|
||||||
<%= render :partial => 'questions_votes/question_item_vote', :locals => {:question_item => question_item } %>
|
<%= render :partial => 'questions_votes/question_item_vote', :locals => {:question_item => question_item } %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
<%= back_url_hidden_field_tag %>
|
<%= back_url_hidden_field_tag %>
|
||||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||||
<%= submit_tag l(:button_save) %>
|
<%= submit_tag l(:button_save) %>
|
||||||
<%= preview_link(preview_questions_answers_path(@answer), 'answer-form') %>
|
<%= preview_link(preview_questions_answers_path(@answer), 'answer-form') if Redmine::VERSION.to_s <= '3.4.5' %>
|
||||||
|
| <%= link_to l(:button_cancel), question_path(@answer.question, :anchor => "question_item_#{@answer.id}") %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<div id="preview" class="wiki"></div>
|
<div id="preview" class="wiki"></div>
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,25 @@
|
||||||
<% previous_group = false %>
|
<% @sections.group_by(&:project).each do |project, sections| %>
|
||||||
<div class="section-list">
|
<% if @project.blank? %>
|
||||||
<% @sections.each do |section| %>
|
<div class="project-forums">
|
||||||
<% if @project.blank? && (group = section.project) != previous_group %>
|
<h3>
|
||||||
<% reset_cycle %>
|
<%= project.name %>
|
||||||
|
<%= link_to " \xc2\xbb", project_questions_sections_path(project_id: project.identifier) %>
|
||||||
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<% if group %>
|
|
||||||
<div class="project-forums">
|
|
||||||
<h3>
|
|
||||||
<%= group.name %>
|
|
||||||
<%= link_to " \xc2\xbb", project_questions_sections_path(:project_id => group.identifier) %>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<div class="section-list">
|
|
||||||
<% previous_group = group %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<a href="<%= url_for({:controller => "questions", :action => 'index', :section_id => section, :project_id => section.project}) %>" id="section_<%= section.id %>" class="section-tile">
|
<div class="section-list">
|
||||||
<h4>
|
<% sections.each do |section| %>
|
||||||
<%= section.name %>
|
<a id="section_<%= section.id %>" class="section-tile"
|
||||||
<span class="topic-count"><%= "(#{section.questions_count})" %></span>
|
href="<%= url_for({ controller: "questions", action: 'index', section_id: section, project_id: section.project }) %>">
|
||||||
</h4>
|
<h4>
|
||||||
<div class="description">
|
<%= section.name %>
|
||||||
<%= section.description %>
|
<span class="topic-count"><%= "(#{section.questions_count})" %></span>
|
||||||
</div>
|
</h4>
|
||||||
</a>
|
<div class="description">
|
||||||
|
<%= section.description %>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</ul>
|
|
||||||
|
|
|
@ -26,4 +26,3 @@
|
||||||
<% content_for :header_tags do %>
|
<% content_for :header_tags do %>
|
||||||
<%= javascript_include_tag :questions, :plugin => 'redmine_questions' %>
|
<%= javascript_include_tag :questions, :plugin => 'redmine_questions' %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
BIN
plugins/redmine_questions/assets/images/accept.png
Normal file
BIN
plugins/redmine_questions/assets/images/accept.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 781 B |
BIN
plugins/redmine_questions/assets/images/discard.png
Normal file
BIN
plugins/redmine_questions/assets/images/discard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
|
@ -400,3 +400,5 @@ div.question.votable .question-container .contextual {margin-top: 0px;}
|
||||||
.icon-tag { background-image: url(../images/tag_blue.png); }
|
.icon-tag { background-image: url(../images/tag_blue.png); }
|
||||||
.icon-question { background-image: url(../../../images/help.png); }
|
.icon-question { background-image: url(../../../images/help.png); }
|
||||||
.icon-solution { background-image: url(../images/book_open.png); }
|
.icon-solution { background-image: url(../images/book_open.png); }
|
||||||
|
.icon-accept { background-image: url(../images/accept.png); }
|
||||||
|
.icon-discard { background-image: url(../images/discard.png); }
|
|
@ -169,4 +169,6 @@ en:
|
||||||
permission_vote_questions: Vote questions
|
permission_vote_questions: Vote questions
|
||||||
permission_accept_answers: Accept answers
|
permission_accept_answers: Accept answers
|
||||||
permission_manage_sections: Manage sections
|
permission_manage_sections: Manage sections
|
||||||
permission_create_tags: Create new tags
|
permission_create_tags: Create new tags
|
||||||
|
label_questions_discard: Discard
|
||||||
|
permission_edit_own_answers: Edit own answers
|
|
@ -22,8 +22,6 @@ es:
|
||||||
|
|
||||||
field_questions_tags: Etiquetas
|
field_questions_tags: Etiquetas
|
||||||
|
|
||||||
label_questions_most_popular: Más populares
|
|
||||||
|
|
||||||
permission_view_questions: Ver Ayuda y Soporte
|
permission_view_questions: Ver Ayuda y Soporte
|
||||||
permission_edit_messages_tags: Editar etiquetas
|
permission_edit_messages_tags: Editar etiquetas
|
||||||
permission_edit_vote_messages: Votar mensajes
|
permission_edit_vote_messages: Votar mensajes
|
|
@ -94,4 +94,6 @@ ru:
|
||||||
permission_vote_questions: Голосовать за вопросы
|
permission_vote_questions: Голосовать за вопросы
|
||||||
permission_accept_answers: Принимать ответы
|
permission_accept_answers: Принимать ответы
|
||||||
permission_manage_sections: Управлять секциями
|
permission_manage_sections: Управлять секциями
|
||||||
permission_create_tags: Создавать новые тэги
|
permission_create_tags: Создавать новые тэги
|
||||||
|
label_questions_discard: Не принимать
|
||||||
|
permission_edit_own_answers: Редактировать свои ответы
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,9 +1,27 @@
|
||||||
== Redmine Q&A plugin changelog
|
== Redmine Q&A plugin changelog
|
||||||
|
|
||||||
Redmine Q&A plugin
|
Redmine Q&A plugin
|
||||||
Copyright (C) 2011-2018 RedmineUP
|
Copyright (C) 2011-2020 RedmineUP
|
||||||
https://www.redmineup.com/
|
https://www.redmineup.com/
|
||||||
|
|
||||||
|
== 2020-03-03 v1.0.2
|
||||||
|
|
||||||
|
* Redmine 4.1 support
|
||||||
|
* Fixed section position bug
|
||||||
|
* Fixed MSSQL group by bug
|
||||||
|
* Fixed "Help & Support" page layout
|
||||||
|
|
||||||
|
== 2019-08-23 v1.0.1
|
||||||
|
|
||||||
|
* Accept answer links
|
||||||
|
* Edit own answers permission
|
||||||
|
* Redmine 4 support
|
||||||
|
* Fixed sorting by unanswered question not working
|
||||||
|
* Fixed project variable dismissed
|
||||||
|
* Fixed status creating bug
|
||||||
|
* Fixed preview link, empty project bug
|
||||||
|
* Fixed boards migration bug
|
||||||
|
|
||||||
== 2018-08-31 v1.0.0
|
== 2018-08-31 v1.0.0
|
||||||
|
|
||||||
* Separate models for questions, answers and comments
|
* Separate models for questions, answers and comments
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -17,11 +17,11 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with redmine_questions. If not, see <http://www.gnu.org/licenses/>.
|
# along with redmine_questions. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
requires_redmine_crm version_or_higher: '0.0.38'
|
requires_redmine_crm version_or_higher: '0.0.41'
|
||||||
|
|
||||||
require 'redmine_questions'
|
require 'redmine_questions'
|
||||||
|
|
||||||
QA_VERSION_NUMBER = '1.0.0'
|
QA_VERSION_NUMBER = '1.0.2'
|
||||||
QA_VERSION_TYPE = "Light version"
|
QA_VERSION_TYPE = "Light version"
|
||||||
|
|
||||||
Redmine::Plugin.register :redmine_questions do
|
Redmine::Plugin.register :redmine_questions do
|
||||||
|
@ -47,6 +47,7 @@ Redmine::Plugin.register :redmine_questions do
|
||||||
permission :add_questions, { questions: [:create, :new, :preview, :update_form] }
|
permission :add_questions, { questions: [:create, :new, :preview, :update_form] }
|
||||||
permission :edit_questions, { questions: [:edit, :update, :preview, :update_form], questions_answers: [:edit, :update, :preview] }, require: :loggedin
|
permission :edit_questions, { questions: [:edit, :update, :preview, :update_form], questions_answers: [:edit, :update, :preview] }, require: :loggedin
|
||||||
permission :edit_own_questions, {questions: [:edit, :update, :preview, :update_form]}, require: :loggedin
|
permission :edit_own_questions, {questions: [:edit, :update, :preview, :update_form]}, require: :loggedin
|
||||||
|
permission :edit_own_answers, {questions_answers: [:edit, :update, :preview]}, require: :loggedin
|
||||||
permission :add_answers, { questions_answers: [:create, :show, :new, :edit, :update, :preview] }
|
permission :add_answers, { questions_answers: [:create, :show, :new, :edit, :update, :preview] }
|
||||||
permission :view_questions, { questions: [:index, :show, :autocomplete_for_subject], questions_sections: [:index] }, read: true
|
permission :view_questions, { questions: [:index, :show, :autocomplete_for_subject], questions_sections: [:index] }, read: true
|
||||||
permission :delete_questions, { questions: [:destroy] }, require: :loggedin
|
permission :delete_questions, { questions: [:destroy] }, require: :loggedin
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -70,6 +70,7 @@ module Redmine
|
||||||
end
|
end
|
||||||
|
|
||||||
def save_attachments(attachments, author = User.current)
|
def save_attachments(attachments, author = User.current)
|
||||||
|
attachments = attachments.to_unsafe_hash if attachments.respond_to?(:to_unsafe_hash)
|
||||||
attachments = attachments.values if attachments.is_a?(Hash)
|
attachments = attachments.values if attachments.is_a?(Hash)
|
||||||
if attachments.is_a?(Array)
|
if attachments.is_a?(Array)
|
||||||
attachments.each do |attachment|
|
attachments.each do |attachment|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -28,5 +28,3 @@ require_dependency 'redmine_questions/patches/auto_completes_controller_patch'
|
||||||
require_dependency 'redmine_questions/patches/comment_patch'
|
require_dependency 'redmine_questions/patches/comment_patch'
|
||||||
|
|
||||||
require_dependency 'acts_as_attachable_questions/init'
|
require_dependency 'acts_as_attachable_questions/init'
|
||||||
|
|
||||||
require 'redmine_questions/patches/compatibility/application_controller_patch' if Rails::VERSION::MAJOR < 4
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
|
||||||
# Q&A plugin for Redmine
|
|
||||||
#
|
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
|
||||||
# http://www.redmineup.com/
|
|
||||||
#
|
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# redmine_questions is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with redmine_questions. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
module RedmineQuestions
|
|
||||||
module Patches
|
|
||||||
module ApplicationControllerPatch
|
|
||||||
def self.included(base) # :nodoc:
|
|
||||||
base.class_eval do
|
|
||||||
unloadable # Send unloadable so it will not be unloaded in development
|
|
||||||
class << self
|
|
||||||
alias_method :before_action, :before_filter
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
unless ApplicationController.included_modules.include?(RedmineQuestions::Patches::ApplicationControllerPatch)
|
|
||||||
ApplicationController.send(:include, RedmineQuestions::Patches::ApplicationControllerPatch)
|
|
||||||
end
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -20,8 +20,15 @@
|
||||||
module RedmineQuestions
|
module RedmineQuestions
|
||||||
module Patches
|
module Patches
|
||||||
module MailerPatch
|
module MailerPatch
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
def deliver_question_comment_added(comment)
|
||||||
|
question_comment_added(User.current, comment).deliver_later
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
module InstanceMethods
|
||||||
def question_comment_added(comment)
|
def question_comment_added(_user = User.current, comment)
|
||||||
question = comment.commented.is_a?(Question) ? comment.commented : comment.commented.question
|
question = comment.commented.is_a?(Question) ? comment.commented : comment.commented.question
|
||||||
@question_url = url_for(:controller => 'questions', :action => 'show', :id => question.id)
|
@question_url = url_for(:controller => 'questions', :action => 'show', :id => question.id)
|
||||||
project_identifier = question.project.try(:identifier)
|
project_identifier = question.project.try(:identifier)
|
||||||
|
@ -36,7 +43,7 @@ module RedmineQuestions
|
||||||
:subject => "[#{project_prefix}] RE: #{question.subject}"
|
:subject => "[#{project_prefix}] RE: #{question.subject}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def question_question_added(question)
|
def question_question_added(_user = Current.user, question)
|
||||||
@question_url = url_for(:controller => 'questions', :action => 'show', :id => question.id)
|
@question_url = url_for(:controller => 'questions', :action => 'show', :id => question.id)
|
||||||
project_identifier = question.project.try(:identifier)
|
project_identifier = question.project.try(:identifier)
|
||||||
redmine_headers 'Project' => project_identifier, 'Question-Id' => question.id
|
redmine_headers 'Project' => project_identifier, 'Question-Id' => question.id
|
||||||
|
@ -51,9 +58,9 @@ module RedmineQuestions
|
||||||
:subject => "[#{project_prefix}] #{question.subject}"
|
:subject => "[#{project_prefix}] #{question.subject}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def question_answer_added(answer)
|
def question_answer_added(_user = Current.user, answer)
|
||||||
question = answer.question
|
question = answer.question
|
||||||
@question_url = url_for(:controller => 'questions', :action => 'show', :id => question.id)
|
@question_url = url_for(controller: 'questions', action: 'show', id: question.id)
|
||||||
project_identifier = question.project.try(:identifier)
|
project_identifier = question.project.try(:identifier)
|
||||||
redmine_headers 'Project' => project_identifier, 'Question-Id' => question.id
|
redmine_headers 'Project' => project_identifier, 'Question-Id' => question.id
|
||||||
message_id question
|
message_id question
|
||||||
|
@ -66,13 +73,14 @@ module RedmineQuestions
|
||||||
@answer = answer
|
@answer = answer
|
||||||
@question = question
|
@question = question
|
||||||
project_prefix = [project_identifier, question.section_name, "q&a#{question.id}"].compact.join(' - ')
|
project_prefix = [project_identifier, question.section_name, "q&a#{question.id}"].compact.join(' - ')
|
||||||
mail :to => recipients,
|
mail to: recipients,
|
||||||
:cc => cc,
|
cc: cc,
|
||||||
:subject => "[#{project_prefix}] - answ##{answer.id} - RE: #{question.subject}"
|
subject: "[#{project_prefix}] - answ##{answer.id} - RE: #{question.subject}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.included(receiver)
|
def self.included(receiver)
|
||||||
|
receiver.send :extend, ClassMethods
|
||||||
receiver.send :include, InstanceMethods
|
receiver.send :include, InstanceMethods
|
||||||
receiver.class_eval do
|
receiver.class_eval do
|
||||||
unloadable
|
unloadable
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -38,13 +38,13 @@ END_DESC
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
question_attrs = topic.attributes.slice('subject', 'content', 'author_id', 'locked').merge('project_id' => project.try(:id))
|
question_attrs = topic.attributes.slice('subject', 'content', 'author_id', 'locked')
|
||||||
migrated_question = section.questions.create(question_attrs)
|
migrated_question = section.questions.create(question_attrs)
|
||||||
migrated_question.attachments = topic.attachments.map { |attachment| attachment.copy }
|
migrated_question.attachments = topic.attachments.map { |attachment| attachment.copy }
|
||||||
|
|
||||||
topic.children.each do |reply|
|
topic.children.each do |reply|
|
||||||
if section.section_type == 'questions'
|
if section.section_type == 'questions'
|
||||||
answer_attrs = reply.slice('subject', 'content', 'author_id', 'locked').merge('project_id' => project.try(:id))
|
answer_attrs = reply.slice('subject', 'content', 'author_id', 'locked')
|
||||||
migrated_answer = migrated_question.answers.create(answer_attrs)
|
migrated_answer = migrated_question.answers.create(answer_attrs)
|
||||||
migrated_answer.attachments = reply.attachments.map { |attachment| attachment.copy }
|
migrated_answer.attachments = reply.attachments.map { |attachment| attachment.copy }
|
||||||
else
|
else
|
||||||
|
|
|
@ -9,4 +9,10 @@ answer_002:
|
||||||
content: This is answer for question_002
|
content: This is answer for question_002
|
||||||
question_id: 2
|
question_id: 2
|
||||||
author_id: 1
|
author_id: 1
|
||||||
accepted: false
|
accepted: false
|
||||||
|
answer_003:
|
||||||
|
id: 3
|
||||||
|
content: This is a second answer for question_001
|
||||||
|
question_id: 1
|
||||||
|
author_id: 3
|
||||||
|
accepted: false
|
10
plugins/redmine_questions/test/fixtures/questions_statuses.yml
vendored
Normal file
10
plugins/redmine_questions/test/fixtures/questions_statuses.yml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
section_001:
|
||||||
|
id: 1
|
||||||
|
name: Open
|
||||||
|
color: green
|
||||||
|
is_closed: false
|
||||||
|
section_002:
|
||||||
|
id: 2
|
||||||
|
name: Closed
|
||||||
|
color: red
|
||||||
|
is_closed: true
|
|
@ -3,7 +3,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -79,7 +79,7 @@ class QuestionsAnswersControllerTest < ActionController::TestCase
|
||||||
assert_redirected_to :controller => 'questions',
|
assert_redirected_to :controller => 'questions',
|
||||||
:action => 'show',
|
:action => 'show',
|
||||||
:id => question,
|
:id => question,
|
||||||
:anchor => "question_item_#{QuestionsAnswer.order(:id).last.id}"
|
:anchor => "questions_answer_#{QuestionsAnswer.order(:id).last.id}"
|
||||||
assert_equal old_answer_count + 1, question.answers.count
|
assert_equal old_answer_count + 1, question.answers.count
|
||||||
assert_equal 'Answer for the first question', question.answers.last.content
|
assert_equal 'Answer for the first question', question.answers.last.content
|
||||||
end
|
end
|
||||||
|
@ -92,11 +92,7 @@ class QuestionsAnswersControllerTest < ActionController::TestCase
|
||||||
:content => "Previewed answer",
|
:content => "Previewed answer",
|
||||||
}
|
}
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_select 'fieldset' do
|
assert_select 'p', :text => 'Previewed answer'
|
||||||
assert_select 'legend', :text => 'Preview'
|
|
||||||
assert_select 'p', :text => 'Previewed answer'
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_preview_edited_answer
|
def test_preview_edited_answer
|
||||||
|
@ -107,11 +103,7 @@ class QuestionsAnswersControllerTest < ActionController::TestCase
|
||||||
:content => "Previewed answer 1",
|
:content => "Previewed answer 1",
|
||||||
}
|
}
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_select 'fieldset' do
|
assert_select 'p', :text => 'Previewed answer 1'
|
||||||
assert_select 'legend', :text => 'Preview'
|
|
||||||
assert_select 'p', :text => 'Previewed answer 1'
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_destroy
|
def test_destroy
|
||||||
|
@ -121,7 +113,7 @@ class QuestionsAnswersControllerTest < ActionController::TestCase
|
||||||
assert_difference 'QuestionsAnswer.count', -1 do
|
assert_difference 'QuestionsAnswer.count', -1 do
|
||||||
compatible_request :post, :destroy, :id => answer.id
|
compatible_request :post, :destroy, :id => answer.id
|
||||||
end
|
end
|
||||||
assert_redirected_to question_path(answer.question, :anchor => "question_item_#{answer.id}")
|
assert_redirected_to question_path(answer.question, :anchor => "questions_answer_#{answer.id}")
|
||||||
assert_nil QuestionsAnswer.find_by_id(answer.id)
|
assert_nil QuestionsAnswer.find_by_id(answer.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -144,6 +136,6 @@ class QuestionsAnswersControllerTest < ActionController::TestCase
|
||||||
}
|
}
|
||||||
# assert_response :success
|
# assert_response :success
|
||||||
answer.reload
|
answer.reload
|
||||||
assert !answer.accepted, "Mark as officail answer did set for answer after update for user without permission"
|
assert !answer.accepted, "Mark as official answer did set for answer after update for user without permission"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -22,8 +22,8 @@
|
||||||
require File.expand_path('../../test_helper', __FILE__)
|
require File.expand_path('../../test_helper', __FILE__)
|
||||||
|
|
||||||
class QuestionsCommentsControllerTest < ActionController::TestCase
|
class QuestionsCommentsControllerTest < ActionController::TestCase
|
||||||
fixtures :users,
|
fixtures :users,
|
||||||
:projects,
|
:projects,
|
||||||
:roles,
|
:roles,
|
||||||
:members,
|
:members,
|
||||||
:member_roles,
|
:member_roles,
|
||||||
|
@ -38,7 +38,7 @@ class QuestionsCommentsControllerTest < ActionController::TestCase
|
||||||
:issue_categories,
|
:issue_categories,
|
||||||
:enabled_modules,
|
:enabled_modules,
|
||||||
:workflows,
|
:workflows,
|
||||||
:questions,
|
:questions,
|
||||||
:questions_answers,
|
:questions_answers,
|
||||||
:questions_sections
|
:questions_sections
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -22,8 +22,8 @@
|
||||||
require File.expand_path('../../test_helper', __FILE__)
|
require File.expand_path('../../test_helper', __FILE__)
|
||||||
|
|
||||||
class QuestionsControllerTest < ActionController::TestCase
|
class QuestionsControllerTest < ActionController::TestCase
|
||||||
fixtures :users,
|
fixtures :users,
|
||||||
:projects,
|
:projects,
|
||||||
:roles,
|
:roles,
|
||||||
:members,
|
:members,
|
||||||
:member_roles,
|
:member_roles,
|
||||||
|
@ -40,14 +40,13 @@ class QuestionsControllerTest < ActionController::TestCase
|
||||||
:attachments,
|
:attachments,
|
||||||
:workflows,
|
:workflows,
|
||||||
:time_entries,
|
:time_entries,
|
||||||
:questions,
|
:questions,
|
||||||
:questions_answers,
|
:questions_answers,
|
||||||
:questions_sections
|
:questions_sections
|
||||||
|
|
||||||
fixtures :email_addresses if ActiveRecord::VERSION::MAJOR >= 4
|
fixtures :email_addresses if ActiveRecord::VERSION::MAJOR >= 4
|
||||||
|
|
||||||
RedmineQuestions::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_questions).directory + '/test/fixtures/',
|
RedmineQuestions::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_questions).directory + '/test/fixtures/', [:tags, :taggings, :comments])
|
||||||
[:tags, :taggings, :comments])
|
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
RedmineQuestions::TestCase.prepare
|
RedmineQuestions::TestCase.prepare
|
||||||
|
@ -77,6 +76,34 @@ class QuestionsControllerTest < ActionController::TestCase
|
||||||
assert_select 'p.breadcrumb'
|
assert_select 'p.breadcrumb'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_get_new
|
||||||
|
@request.session[:user_id] = 1
|
||||||
|
compatible_request :get, :new, project_id: @project
|
||||||
|
|
||||||
|
assert_select 'input#question_subject'
|
||||||
|
assert_select 'select#question_section_id'
|
||||||
|
assert_select 'input[type=?]', 'submit'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_get_edit
|
||||||
|
@request.session[:user_id] = 1
|
||||||
|
compatible_request :get, :edit, id: 1
|
||||||
|
|
||||||
|
assert_select 'input#question_subject'
|
||||||
|
assert_select 'select#question_section_id'
|
||||||
|
assert_select 'input[type=?]', 'submit'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_post_create_failed
|
||||||
|
@request.session[:user_id] = 1
|
||||||
|
compatible_request :post, :create, :project_id => @project,
|
||||||
|
:question => {
|
||||||
|
|
||||||
|
:content => "Body of text"
|
||||||
|
}
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
def test_post_create
|
def test_post_create
|
||||||
@request.session[:user_id] = 1
|
@request.session[:user_id] = 1
|
||||||
ActionMailer::Base.deliveries.clear
|
ActionMailer::Base.deliveries.clear
|
||||||
|
@ -118,7 +145,7 @@ class QuestionsControllerTest < ActionController::TestCase
|
||||||
assert_select 'div#reply'
|
assert_select 'div#reply'
|
||||||
assert_select 'a.icon-del'
|
assert_select 'a.icon-del'
|
||||||
assert_select 'a.add-comment-link'
|
assert_select 'a.add-comment-link'
|
||||||
assert_select 'span.items', {:text => "(1-1/1)"}
|
assert_select 'span.items', {:text => "(1-2/2)"}
|
||||||
@dev_role.permissions << :add_answers
|
@dev_role.permissions << :add_answers
|
||||||
@dev_role.save
|
@dev_role.save
|
||||||
@request.session[:user_id] = 3
|
@request.session[:user_id] = 3
|
||||||
|
@ -164,20 +191,17 @@ class QuestionsControllerTest < ActionController::TestCase
|
||||||
end
|
end
|
||||||
assert_redirected_to questions_path(:section_id => question.section)
|
assert_redirected_to questions_path(:section_id => question.section)
|
||||||
assert_nil Question.find_by_id(question.id)
|
assert_nil Question.find_by_id(question.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_preview_new_question
|
def test_preview_new_question
|
||||||
@request.session[:user_id] = 1
|
@request.session[:user_id] = 1
|
||||||
question = questions(:question_001)
|
question = questions(:question_001)
|
||||||
compatible_xhr_request :post, :preview,
|
compatible_xhr_request :post, :preview,
|
||||||
:question => {
|
:question => {
|
||||||
:content => "Previewed question",
|
:content => "Previewed question",
|
||||||
}
|
}
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_select 'fieldset' do
|
assert_select 'p', :text => 'Previewed question'
|
||||||
assert_select 'legend', :text => 'Preview'
|
|
||||||
assert_select 'p', :text => 'Previewed question'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_update_question
|
def test_update_question
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
#
|
||||||
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
|
# Q&A plugin for Redmine
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
|
# http://www.redmineup.com/
|
||||||
|
#
|
||||||
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# redmine_questions is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with redmine_questions. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
require File.expand_path('../../test_helper', __FILE__)
|
||||||
|
|
||||||
|
class QuestionsStatusesControllerTest < ActionController::TestCase
|
||||||
|
fixtures :users,
|
||||||
|
:projects,
|
||||||
|
:roles,
|
||||||
|
:members,
|
||||||
|
:member_roles,
|
||||||
|
:trackers,
|
||||||
|
:enumerations,
|
||||||
|
:projects_trackers,
|
||||||
|
:issues,
|
||||||
|
:issue_statuses,
|
||||||
|
:versions,
|
||||||
|
:trackers,
|
||||||
|
:projects_trackers,
|
||||||
|
:issue_categories,
|
||||||
|
:enabled_modules,
|
||||||
|
:workflows,
|
||||||
|
:questions,
|
||||||
|
:questions_answers,
|
||||||
|
:questions_sections
|
||||||
|
|
||||||
|
fixtures :email_addresses if ActiveRecord::VERSION::MAJOR >= 4
|
||||||
|
|
||||||
|
RedmineQuestions::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_questions).directory + '/test/fixtures/', [:questions,
|
||||||
|
:questions_answers,
|
||||||
|
:questions_sections,
|
||||||
|
:questions_statuses])
|
||||||
|
|
||||||
|
def setup
|
||||||
|
RedmineQuestions::TestCase.prepare
|
||||||
|
@project = Project.find(1)
|
||||||
|
User.current = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_new
|
||||||
|
@request.session[:user_id] = 1
|
||||||
|
compatible_request :get, :new
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
assert_select 'input#questions_status_name'
|
||||||
|
assert_select 'input[type=?]', 'submit'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create
|
||||||
|
@request.session[:user_id] = 1
|
||||||
|
assert_difference 'QuestionsStatus.count' do
|
||||||
|
compatible_request :post, :create, questions_status: { name: 'Test status', color: 'green', is_closed: '0' }
|
||||||
|
end
|
||||||
|
assert_equal 'Test status', QuestionsStatus.last.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_delete
|
||||||
|
@request.session[:user_id] = 1
|
||||||
|
|
||||||
|
status = QuestionsStatus.find(1)
|
||||||
|
assert_difference 'QuestionsStatus.count', -1 do
|
||||||
|
compatible_request :delete, :destroy, id: status
|
||||||
|
end
|
||||||
|
assert_nil QuestionsStatus.where(id: status.id).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update
|
||||||
|
@request.session[:user_id] = 1
|
||||||
|
|
||||||
|
status = QuestionsStatus.find(1)
|
||||||
|
compatible_request :put, :update, id: status, questions_status: { name: 'New name', color: 'green', is_closed: '0' }
|
||||||
|
status.reload
|
||||||
|
assert_equal status.name, 'New name'
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,7 +3,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
@ -74,7 +74,7 @@ class RedmineQuestions::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.prepare
|
def self.prepare
|
||||||
Role.where(:id => [1, 3]).each do |r|
|
Role.where(:id => 1).each do |r|
|
||||||
# user_2
|
# user_2
|
||||||
r.permissions << :view_questions
|
r.permissions << :view_questions
|
||||||
r.permissions << :global_view_questions
|
r.permissions << :global_view_questions
|
||||||
|
@ -103,11 +103,6 @@ class RedmineQuestions::TestCase
|
||||||
r.save
|
r.save
|
||||||
end
|
end
|
||||||
|
|
||||||
Role.where(:id => 1).each do |r|
|
|
||||||
r.permissions << :accept_answers
|
|
||||||
r.save
|
|
||||||
end
|
|
||||||
|
|
||||||
Project.where(:id => [1, 2, 3, 4, 5]).each do |project|
|
Project.where(:id => [1, 2, 3, 4, 5]).each do |project|
|
||||||
EnabledModule.create(:project => project, :name => 'questions')
|
EnabledModule.create(:project => project, :name => 'questions')
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
# This file is a part of Redmine Q&A (redmine_questions) plugin,
|
||||||
# Q&A plugin for Redmine
|
# Q&A plugin for Redmine
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2018 RedmineUP
|
# Copyright (C) 2011-2020 RedmineUP
|
||||||
# http://www.redmineup.com/
|
# http://www.redmineup.com/
|
||||||
#
|
#
|
||||||
# redmine_questions is free software: you can redistribute it and/or modify
|
# redmine_questions is free software: you can redistribute it and/or modify
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue