Skip to content

Commit

Permalink
Merge pull request #34 from gtt-project/fix/sortable-text-blocks
Browse files Browse the repository at this point in the history
Sortable text_blocks (templates)
  • Loading branch information
sanak authored Mar 28, 2023
2 parents 60ab5bc + 65086e6 commit 07c904f
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 15 deletions.
26 changes: 21 additions & 5 deletions app/controllers/text_blocks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,20 @@ def update
r = RedmineTextBlocks::SaveTextBlock.(text_block_params,
text_block: @text_block)
if r.text_block_saved?
redirect_to index_path
respond_to do |format|
format.html {
flash[:notice] = l(:notice_successful_update)
redirect_to index_path
}
format.js { head 200 }
end
else
render 'edit'
respond_to do |format|
format.html {
render 'edit'
}
format.js { head 422 }
end
end
end

Expand All @@ -69,7 +80,7 @@ def index_path
end

def text_block_params
params[:text_block].permit :name, :text, :issue_status_ids => []
params[:text_block].permit :name, :text, :position, :issue_status_ids => []
end

def find_text_block
Expand All @@ -83,14 +94,19 @@ def find_project_by_project_id
end

def text_block_scope
TextBlock.order(name: :asc).where(project_id: @project&.id)
TextBlock.where(project_id: @project&.id).sorted
end

def get_issue_statuses
@issue_statuses = IssueStatus.all.sorted
end

def get_blocks_by_status(status_id)
IssueStatus.find(status_id).text_blocks.blank? ? text_block_scope : IssueStatus.find(status_id).text_blocks.where(project_id: [nil, @project&.id])
if IssueStatus.find(status_id).text_blocks.blank?
text_block_scope
else
IssueStatus.find(status_id).text_blocks.
where(project_id: [nil, @project&.id]).sorted
end
end
end
4 changes: 2 additions & 2 deletions app/helpers/text_blocks_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ def text_block_options(issue=nil)
end
status_textblocks = IssueStatus.find(issue.status_id).text_blocks if issue
if !status_textblocks.blank?
tags += status_textblocks.where(project_id: [nil, @project.id]).map{|tb|
tags += status_textblocks.where(project_id: [nil, @project.id]).sorted.map{|tb|
content_tag :option, value: tb.text do
tb.name
end
}
else
tags += TextBlock.where(project_id: [nil, @project.id]).to_a.map{|tb|
tags += TextBlock.where(project_id: [nil, @project.id]).sorted.to_a.map{|tb|
content_tag :option, value: tb.text do
tb.name
end
Expand Down
3 changes: 2 additions & 1 deletion app/models/text_block.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
class TextBlock < ActiveRecord::Base
belongs_to :project
has_and_belongs_to_many :issue_statuses
acts_as_positioned :scope => [:project_id]

validates :name, presence: true
validate :name_uniqueness

scope :sorted, ->{ order(Arel.sql('project_id IS NOT NULL, project_id ASC, position ASC')) }

private

Expand All @@ -19,5 +21,4 @@ def name_uniqueness
errors.add :name, I18n.t('model.text_block.name_uniqueness')
end
end

end
2 changes: 1 addition & 1 deletion app/views/projects/settings/_text_blocks.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
<%= link_to l(:label_text_block_new), new_project_text_block_path(@project), class: 'icon icon-add' %>
</p>

<%= render partial: 'text_blocks/list', locals: { text_blocks: TextBlock.where(project_id: @project.id) } %>
<%= render partial: 'text_blocks/list', locals: { text_blocks: TextBlock.where(project_id: @project.id).sorted } %>

3 changes: 3 additions & 0 deletions app/views/text_blocks/_list.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@
$("table.list.textblocks tbody td.text div").trigger('update.dot');
}
});
$(function() {
$("table.textblocks tbody").positionedItems();
});
<% end %>
<% end %>
5 changes: 4 additions & 1 deletion app/views/text_blocks/_text_block.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
<%= textilizable s %>
<% end %>
</div></td>
<td><%= delete_link(text_block.project ? project_text_block_path(text_block.project, text_block) : text_block_path(text_block)) %>
<td class="buttons">
<%= reorder_handle(text_block, url: text_block.project ? project_text_block_path(text_block.project, text_block) : text_block_path(text_block)) %>
<%= delete_link(text_block.project ? project_text_block_path(text_block.project, text_block) : text_block_path(text_block)) %>
</td>
</tr>
8 changes: 8 additions & 0 deletions db/migrate/20230325132825_add_position_to_text_blocks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class AddPositionToTextBlocks < ActiveRecord::Migration[5.2]
def change
add_column :text_blocks, :position, :integer
# # After executing "rake redmine:plugins:migrate", execute the following on "rails console", if keeping the existing positions is important:
# res = TextBlock.connection.select_all("SELECT id, name, project_id, row_number() over(PARTITION by project_id) AS position FROM #{TextBlock.table_name}")
# res.rows.each{|row| TextBlock.connection.execute("UPDATE #{TextBlock.table_name} SET position=#{row[3]} WHERE id=#{row[0]}")}
end
end
22 changes: 20 additions & 2 deletions test/integration/text_blocks_admin_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative '../test_helper'

class TextBlocksAdminTest < Redmine::IntegrationTest
fixtures :users, :email_addresses, :user_preferences
fixtures :users, :email_addresses, :user_preferences, :issue_statuses

def setup
super
Expand All @@ -23,14 +23,18 @@ def test_textblock_crud
assert_response :success

assert_difference 'TextBlock.count' do
post '/text_blocks', params: { text_block: { name: 'test', text: 'lorem ipsum'}}
post '/text_blocks', params: {
text_block: { name: 'test', text: 'lorem ipsum', issue_status_ids: [1, 2] }
}
end
assert_redirected_to '/text_blocks'

follow_redirect!

assert b = TextBlock.find_by_name('test')
assert_equal 'lorem ipsum', b.text
assert_equal [1, 2], b.issue_statuses.map(&:id).sort
assert_equal 1, b.position

get "/text_blocks/#{b.id}/edit"
assert_response :success
Expand All @@ -40,6 +44,20 @@ def test_textblock_crud
assert_equal 'lorem ipsum', b.text
assert_equal 'new', b.name

assert_difference 'TextBlock.count' do
post '/text_blocks', params: {
text_block: { name: 'test2', text: 'lorem ipsum2', issue_status_ids: [1, 2] }
}
end
assert_redirected_to '/text_blocks'

follow_redirect!

assert b = TextBlock.find_by_name('test2')
assert_equal 'lorem ipsum2', b.text
assert_equal [1, 2], b.issue_statuses.map(&:id).sort
assert_equal 2, b.position

assert_difference 'TextBlock.count', -1 do
delete "/text_blocks/#{b.id}"
end
Expand Down
22 changes: 20 additions & 2 deletions test/integration/text_blocks_project_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class TextBlocksProjectTest < Redmine::IntegrationTest
fixtures :users, :email_addresses, :user_preferences,
:roles, :projects, :members, :member_roles
:roles, :projects, :members, :member_roles, :issue_statuses

def setup
super
Expand Down Expand Up @@ -37,14 +37,18 @@ def test_textblock_crud
assert_response :success

assert_difference 'TextBlock.count' do
post '/projects/ecookbook/text_blocks', params: { text_block: { name: 'test', text: 'lorem ipsum'}}
post '/projects/ecookbook/text_blocks', params: {
text_block: { name: 'test', text: 'lorem ipsum', issue_status_ids: [1, 2] }
}
end
assert_redirected_to '/projects/ecookbook/settings/text_blocks'

follow_redirect!

assert b = TextBlock.find_by_name('test')
assert_equal 'lorem ipsum', b.text
assert_equal [1, 2], b.issue_statuses.map(&:id).sort
assert_equal 1, b.position

get "/projects/ecookbook/text_blocks/#{b.id}/edit"
assert_response :success
Expand All @@ -54,6 +58,20 @@ def test_textblock_crud
assert_equal 'lorem ipsum', b.text
assert_equal 'new', b.name

assert_difference 'TextBlock.count' do
post '/projects/ecookbook/text_blocks', params: {
text_block: { name: 'test2', text: 'lorem ipsum2', issue_status_ids: [1, 2] }
}
end
assert_redirected_to '/projects/ecookbook/settings/text_blocks'

follow_redirect!

assert b = TextBlock.find_by_name('test2')
assert_equal 'lorem ipsum2', b.text
assert_equal [1, 2], b.issue_statuses.map(&:id).sort
assert_equal 2, b.position

assert_difference 'TextBlock.count', -1 do
delete "/projects/ecookbook/text_blocks/#{b.id}"
end
Expand Down
37 changes: 36 additions & 1 deletion test/unit/text_block_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative '../test_helper'

class TextBlockTest < ActiveSupport::TestCase
fixtures :projects
fixtures :projects, :issue_statuses

setup do
@project = Project.find 'ecookbook'
Expand Down Expand Up @@ -55,6 +55,41 @@ class TextBlockTest < ActiveSupport::TestCase
end
end

test 'should save params in global text block' do
assert_difference 'TextBlock.count' do
r = RedmineTextBlocks::SaveTextBlock.(
{
name: 'test',
text: 'lorem ipsum',
issue_status_ids: [1, 2]
}
)
assert r.text_block_saved?
assert_equal 'test', r.text_block.name
assert_equal 'lorem ipsum', r.text_block.text
assert_equal [1, 2], r.text_block.issue_status_ids.sort
assert_equal 1, r.text_block.position
end
end

test 'should save params in local text block' do
assert_difference 'TextBlock.count' do
r = RedmineTextBlocks::SaveTextBlock.(
{
name: 'test',
text: 'lorem ipsum',
issue_status_ids: [1, 2]
},
project: @project
)
assert r.text_block_saved?
assert_equal 'test', r.text_block.name
assert_equal 'lorem ipsum', r.text_block.text
assert_equal [1, 2], r.text_block.issue_status_ids.sort
assert_equal 1, r.text_block.position
end
end

test 'deletion of project should delete textblocks' do
RedmineTextBlocks::SaveTextBlock.({name: 'test'}, project: @project)
assert_difference 'TextBlock.count', -1 do
Expand Down

0 comments on commit 07c904f

Please sign in to comment.