redmine_extensions 0.1.14 → 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/redmine_extensions/redmine_extensions.js.orig +648 -0
  3. data/app/views/easy_entity_assignments/_query_index.html.erb.orig +16 -0
  4. data/config/locales/cs.yml +4 -1
  5. data/config/locales/en.yml +1 -0
  6. data/lib/generators/redmine_extensions/entity/templates/context_menu.html.erb.erb +14 -1
  7. data/lib/generators/redmine_extensions/entity/templates/controller.rb.erb +40 -6
  8. data/lib/generators/redmine_extensions/entity/templates/edit.js.erb.erb +5 -5
  9. data/lib/generators/redmine_extensions/entity/templates/index.js.erb.erb +3 -3
  10. data/lib/generators/redmine_extensions/entity/templates/new.js.erb.erb +5 -5
  11. data/lib/generators/redmine_extensions/entity/templates/show.js.erb.erb +3 -3
  12. data/lib/redmine_extensions/easy_query_helpers/outputs.rb +18 -2
  13. data/lib/redmine_extensions/query_output.rb +30 -11
  14. data/lib/redmine_extensions/redmine_patches/controllers/issues_controller_patch.rb +9 -0
  15. data/lib/redmine_extensions/version.rb +1 -1
  16. data/lib/redmine_extensions/version.rb.orig +7 -0
  17. data/spec/redmine/app/controllers/custom_field_enumerations_controller.rb +75 -0
  18. data/spec/redmine/app/controllers/imports_controller.rb +121 -0
  19. data/spec/redmine/app/helpers/imports_helper.rb +47 -0
  20. data/spec/redmine/app/models/custom_field_enumeration.rb +90 -0
  21. data/spec/redmine/app/models/import.rb +249 -0
  22. data/spec/redmine/app/models/import_item.rb +22 -0
  23. data/spec/redmine/app/models/issue_import.rb +186 -0
  24. data/spec/redmine/app/views/attachments/image.html.erb +3 -0
  25. data/spec/redmine/app/views/attachments/other.html.erb +3 -0
  26. data/spec/redmine/app/views/common/_image.html.erb +1 -0
  27. data/spec/redmine/app/views/common/_other.html.erb +1 -0
  28. data/spec/redmine/app/views/custom_field_enumerations/create.js.erb +2 -0
  29. data/spec/redmine/app/views/custom_field_enumerations/destroy.html.erb +14 -0
  30. data/spec/redmine/app/views/custom_field_enumerations/index.html.erb +47 -0
  31. data/spec/redmine/app/views/custom_fields/formats/_enumeration.erb +12 -0
  32. data/spec/redmine/app/views/imports/_fields_mapping.html.erb +90 -0
  33. data/spec/redmine/app/views/imports/mapping.html.erb +52 -0
  34. data/spec/redmine/app/views/imports/mapping.js.erb +1 -0
  35. data/spec/redmine/app/views/imports/new.html.erb +15 -0
  36. data/spec/redmine/app/views/imports/run.html.erb +20 -0
  37. data/spec/redmine/app/views/imports/run.js.erb +11 -0
  38. data/spec/redmine/app/views/imports/settings.html.erb +30 -0
  39. data/spec/redmine/app/views/imports/show.html.erb +38 -0
  40. data/spec/redmine/app/views/layouts/_file.html.erb +15 -0
  41. data/spec/redmine/app/views/mailer/security_notification.html.erb +13 -0
  42. data/spec/redmine/app/views/mailer/security_notification.text.erb +8 -0
  43. data/spec/redmine/app/views/mailer/settings_updated.html.erb +14 -0
  44. data/spec/redmine/app/views/mailer/settings_updated.text.erb +12 -0
  45. data/spec/redmine/app/views/queries/_query_form.html.erb +62 -0
  46. data/spec/redmine/app/views/repositories/_changeset.html.erb +40 -0
  47. data/spec/redmine/app/views/search/index.api.rsb +12 -0
  48. data/spec/redmine/app/views/settings/_api.html.erb +10 -0
  49. data/spec/redmine/app/views/settings/_attachments.html.erb +21 -0
  50. data/spec/redmine/app/views/wiki/_new_modal.html.erb +21 -0
  51. data/spec/redmine/app/views/wiki/new.html.erb +17 -0
  52. data/spec/redmine/app/views/wiki/new.js.erb +2 -0
  53. data/spec/redmine/appveyor.yml +36 -0
  54. data/spec/redmine/db/migrate/20150725112753_insert_allowed_statuses_for_new_issues.rb +23 -0
  55. data/spec/redmine/db/migrate/20150730122707_create_imports.rb +13 -0
  56. data/spec/redmine/db/migrate/20150730122735_create_import_items.rb +10 -0
  57. data/spec/redmine/db/migrate/20150921204850_change_time_entries_comments_limit_to_1024.rb +9 -0
  58. data/spec/redmine/db/migrate/20150921210243_change_wiki_contents_comments_limit_to_1024.rb +11 -0
  59. data/spec/redmine/db/migrate/20151020182334_change_attachments_filesize_limit_to_8.rb +9 -0
  60. data/spec/redmine/db/migrate/20151020182731_fix_comma_in_user_format_setting_value.rb +13 -0
  61. data/spec/redmine/db/migrate/20151021184614_change_issue_categories_name_limit_to_60.rb +9 -0
  62. data/spec/redmine/db/migrate/20151021185456_change_auth_sources_filter_to_text.rb +9 -0
  63. data/spec/redmine/db/migrate/20151021190616_change_user_preferences_hide_mail_default_to_true.rb +9 -0
  64. data/spec/redmine/db/migrate/20151024082034_add_tokens_updated_on.rb +10 -0
  65. data/spec/redmine/db/migrate/20151025072118_create_custom_field_enumerations.rb +10 -0
  66. data/spec/redmine/db/migrate/20151031095005_add_projects_default_version_id.rb +12 -0
  67. data/spec/redmine/db/migrate/20160404080304_force_password_reset_during_setup.rb +9 -0
  68. data/spec/redmine/db/migrate/20160416072926_remove_position_defaults.rb +13 -0
  69. data/spec/redmine/db/migrate/20160529063352_add_roles_settings.rb +5 -0
  70. data/spec/redmine/lib/redmine/acts/positioned.rb +118 -0
  71. data/spec/redmine/lib/redmine/helpers/url.rb +35 -0
  72. data/spec/redmine/lib/redmine/hook/listener.rb +32 -0
  73. data/spec/redmine/lib/redmine/hook/view_listener.rb +78 -0
  74. data/spec/redmine/log/test.log +2 -0
  75. data/spec/redmine/plugins/dummy_plugin/Gemfile +1 -0
  76. data/spec/redmine/plugins/dummy_plugin/app/controllers/dummy_autocompletes_controller.rb +4 -0
  77. data/spec/redmine/plugins/dummy_plugin/app/views/dummy_autocompletes/index.html.erb +3 -0
  78. data/spec/redmine/plugins/dummy_plugin/config/locales/en.yml +2 -0
  79. data/spec/redmine/plugins/dummy_plugin/config/routes.rb +1 -0
  80. data/spec/redmine/plugins/dummy_plugin/init.rb +34 -0
  81. data/spec/redmine/plugins/dummy_plugin/lib/dummy_plugin/easy_patch/redmine/controllers/issues_controller_patch.example +30 -0
  82. data/spec/redmine/plugins/dummy_plugin/lib/dummy_plugin/easy_patch/redmine/helpers/issues_helper_patch.example +30 -0
  83. data/spec/redmine/plugins/dummy_plugin/lib/dummy_plugin/easy_patch/redmine/models/issue_patch.example +30 -0
  84. data/spec/redmine/plugins/dummy_plugin/lib/dummy_plugin/hooks.rb +5 -0
  85. data/spec/redmine/plugins/dummy_plugin/lib/dummy_plugin/internals.rb +4 -0
  86. data/spec/redmine/public/images/jstoolbar/bt_precode.png +0 -0
  87. data/spec/redmine/public/images/reorder.png +0 -0
  88. data/spec/redmine/public/javascripts/jquery-1.11.1-ui-1.11.0-ujs-3.1.4.js +21 -0
  89. data/spec/redmine/public/javascripts/redmine_extensions/application.js +13 -0
  90. data/spec/redmine/public/javascripts/redmine_extensions/easy_togglers.js +58 -0
  91. data/spec/redmine/public/javascripts/redmine_extensions/jquery.entityarray.js +130 -0
  92. data/spec/redmine/public/javascripts/redmine_extensions/redmine_extensions.js +642 -0
  93. data/spec/redmine/public/javascripts/responsive.js +83 -0
  94. data/spec/redmine/public/stylesheets/responsive.css +799 -0
  95. data/spec/redmine/test/fixtures/files/import_dates.csv +4 -0
  96. data/spec/redmine/test/fixtures/files/import_iso8859-1.csv +3 -0
  97. data/spec/redmine/test/fixtures/files/import_issues.csv +4 -0
  98. data/spec/redmine/test/fixtures/ldap/slapd.centos6.conf +24 -0
  99. data/spec/redmine/test/fixtures/ldap/slapd.ubuntu.12.04.conf +23 -0
  100. data/spec/redmine/test/fixtures/mail_handler/issue_update_with_cc.eml +19 -0
  101. data/spec/redmine/test/fixtures/mail_handler/ticket_on_project_given_by_to_header.eml +60 -0
  102. data/spec/redmine/test/fixtures/mail_handler/ticket_with_text_attachment_iso-8859-2.eml +31 -0
  103. data/spec/redmine/test/functional/custom_field_enumerations_controller_test.rb +115 -0
  104. data/spec/redmine/test/functional/imports_controller_test.rb +205 -0
  105. data/spec/redmine/test/functional/sessions_controller_test.rb +138 -0
  106. data/spec/redmine/test/integration/api_test/search_test.rb +92 -0
  107. data/spec/redmine/test/integration/routing/imports_test.rb +36 -0
  108. data/spec/redmine/test/integration/sessions_test.rb +97 -0
  109. data/spec/redmine/test/ui/custom_fields_test_ui.rb +38 -0
  110. data/spec/redmine/test/unit/attachment_transaction_test.rb +76 -0
  111. data/spec/redmine/test/unit/helpers/journals_helper_test.rb +48 -0
  112. data/spec/redmine/test/unit/helpers/wiki_helper_test.rb +45 -0
  113. data/spec/redmine/test/unit/issue_import_test.rb +178 -0
  114. data/spec/redmine/test/unit/lib/redmine/acts/positioned_with_scope_test.rb +53 -0
  115. data/spec/redmine/test/unit/lib/redmine/acts/positioned_without_scope_test.rb +55 -0
  116. data/spec/redmine/test/unit/lib/redmine/field_format/enumeration_format_test.rb +91 -0
  117. data/spec/support/easy_queries_helpers.rb +0 -0
  118. metadata +216 -10
@@ -0,0 +1,40 @@
1
+ <h2><%= l(:label_revision) %> <%= format_revision(@changeset) %></h2>
2
+
3
+ <div class="details">
4
+ <h4>
5
+ <%= avatar(@changeset.user, :size => "24") %>
6
+ <%= authoring(@changeset.committed_on, @changeset.author) %>
7
+ </h4>
8
+ <% if @changeset.scmid.present? || @changeset.parents.present? || @changeset.children.present? %>
9
+ <ul class="revision-info">
10
+ <% if @changeset.scmid.present? %>
11
+ <li>
12
+ <strong>ID </strong><%= @changeset.scmid %>
13
+ </li>
14
+ <% end %>
15
+ <% if @changeset.parents.present? %>
16
+ <li>
17
+ <strong><%= l(:label_parent_revision) %></strong>
18
+ <%= @changeset.parents.collect{
19
+ |p| link_to_revision(p, @repository, :text => format_revision(p))
20
+ }.join(", ").html_safe %>
21
+ </li>
22
+ <% end %>
23
+ <% if @changeset.children.present? %>
24
+ <li>
25
+ <strong><%= l(:label_child_revision) %></strong>
26
+ <%= @changeset.children.collect{
27
+ |p| link_to_revision(p, @repository, :text => format_revision(p))
28
+ }.join(", ").html_safe %>
29
+ </li>
30
+ <% end %>
31
+ </ul>
32
+ <% end %>
33
+
34
+ </div>
35
+
36
+ <%= textilizable @changeset.comments %>
37
+
38
+ <% if @changeset.issues.visible.any? || User.current.allowed_to?(:manage_related_issues, @repository.project) %>
39
+ <%= render :partial => 'related_issues' %>
40
+ <% end %>
@@ -0,0 +1,12 @@
1
+ api.array :results, api_meta(:total_count => @result_count, :offset => @offset, :limit => @limit) do
2
+ @results.each do |result|
3
+ api.result do
4
+ api.id result.id
5
+ api.title result.event_title
6
+ api.type result.event_type
7
+ api.url url_for(result.event_url(:only_path => false))
8
+ api.description result.event_description
9
+ api.datetime result.event_datetime
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ <%= form_tag({:action => 'edit', :tab => 'api'}) do %>
2
+
3
+ <div class="box tabular settings">
4
+ <p><%= setting_check_box :rest_api_enabled %></p>
5
+
6
+ <p><%= setting_check_box :jsonp_enabled %></p>
7
+ </div>
8
+
9
+ <%= submit_tag l(:button_save) %>
10
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <%= form_tag({:action => 'edit', :tab => 'attachments'}) do %>
2
+
3
+ <div class="box tabular settings">
4
+ <p><%= setting_text_field :attachment_max_size, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %></p>
5
+
6
+ <p><%= setting_text_area :attachment_extensions_allowed %>
7
+ <em class="info"><%= l(:text_comma_separated) %> <%= l(:label_example) %>: txt, png</em></p>
8
+
9
+ <p><%= setting_text_area :attachment_extensions_denied %>
10
+ <em class="info"><%= l(:text_comma_separated) %> <%= l(:label_example) %>: js, swf</em></p>
11
+
12
+ <p><%= setting_text_field :file_max_size_displayed, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %></p>
13
+
14
+ <p><%= setting_text_field :diff_max_lines_displayed, :size => 6 %></p>
15
+
16
+ <p><%= setting_text_field :repositories_encodings, :size => 60 %>
17
+ <em class="info"><%= l(:text_comma_separated) %></em></p>
18
+ </div>
19
+
20
+ <%= submit_tag l(:button_save) %>
21
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <h3 class="title"><%=l(:label_wiki_page_new)%></h3>
2
+
3
+ <%= labelled_form_for :page, @page,
4
+ :url => new_project_wiki_page_path(@project),
5
+ :method => 'post',
6
+ :remote => true do |f| %>
7
+
8
+ <%= render_error_messages @page.errors.full_messages_for(:title) %>
9
+
10
+ <div class="box tabular">
11
+ <p>
12
+ <%= f.text_field :title, :name => 'title', :size => 60, :required => true %>
13
+ <em class="info"><%= l(:text_unallowed_characters) %>: , . / ? ; : |</em>
14
+ </p>
15
+ </div>
16
+
17
+ <p class="buttons">
18
+ <%= submit_tag l(:label_next), :name => nil %>
19
+ <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
20
+ </p>
21
+ <% end %>
@@ -0,0 +1,17 @@
1
+ <%= title l(:label_wiki_page_new) %>
2
+
3
+ <%= labelled_form_for :page, @page,
4
+ :url => new_project_wiki_page_path(@project) do |f| %>
5
+
6
+ <%= render_error_messages @page.errors.full_messages_for(:title) %>
7
+
8
+ <div class="box tabular">
9
+ <p>
10
+ <%= f.text_field :title, :name => 'title', :size => 60, :required => true %>
11
+ <em class="info"><%= l(:text_unallowed_characters) %>: , . / ? ; : |</em>
12
+ </p>
13
+ </div>
14
+
15
+ <%= submit_tag(l(:label_next)) %>
16
+
17
+ <% end %>
@@ -0,0 +1,2 @@
1
+ $('#ajax-modal').html('<%= escape_javascript(render :partial => 'wiki/new_modal') %>');
2
+ showModal('ajax-modal', '600px');
@@ -0,0 +1,36 @@
1
+ # Redmine runs tests on own continuous integration server.
2
+ # http://www.redmine.org/projects/redmine/wiki/Continuous_integration
3
+ # You can also run tests on your environment.
4
+
5
+ install:
6
+ - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
7
+ - ruby --version
8
+ - gem --version
9
+ - git --version
10
+ - hg --version
11
+
12
+ build: off
13
+
14
+ test_script:
15
+ - bundle install --without rmagick
16
+ - set SCMS=mercurial
17
+ - set RUN_ON_NOT_OFFICIAL=
18
+ - set RUBY_VER=1.9
19
+ - set BRANCH=trunk
20
+ - bundle exec rake config/database.yml
21
+ - bundle install
22
+ - bundle exec rake ci:setup
23
+ - bundle exec rake test
24
+
25
+ environment:
26
+ global:
27
+ RAILS_ENV: test
28
+ DATABASE_ADAPTER: sqlite3
29
+ matrix:
30
+ - ruby_version: "193"
31
+ - ruby_version: "200"
32
+ - ruby_version: "200-x64"
33
+ - ruby_version: "21"
34
+ - ruby_version: "21-x64"
35
+ - ruby_version: "22"
36
+ - ruby_version: "22-x64"
@@ -0,0 +1,23 @@
1
+ class InsertAllowedStatusesForNewIssues < ActiveRecord::Migration
2
+ def self.up
3
+ # Adds the default status for all trackers and roles
4
+ sql = "INSERT INTO #{WorkflowTransition.table_name} (tracker_id, old_status_id, new_status_id, role_id, type)" +
5
+ " SELECT t.id, 0, t.default_status_id, r.id, 'WorkflowTransition'" +
6
+ " FROM #{Tracker.table_name} t, #{Role.table_name} r"
7
+ WorkflowTransition.connection.execute(sql)
8
+
9
+ # Adds other statuses that are reachable with one transition
10
+ # to preserve previous behaviour as default
11
+ sql = "INSERT INTO #{WorkflowTransition.table_name} (tracker_id, old_status_id, new_status_id, role_id, type)" +
12
+ " SELECT t.id, 0, w.new_status_id, w.role_id, 'WorkflowTransition'" +
13
+ " FROM #{Tracker.table_name} t" +
14
+ " JOIN #{IssueStatus.table_name} s on s.id = t.default_status_id" +
15
+ " JOIN #{WorkflowTransition.table_name} w on w.tracker_id = t.id and w.old_status_id = s.id and w.type = 'WorkflowTransition'" +
16
+ " WHERE w.new_status_id <> t.default_status_id"
17
+ WorkflowTransition.connection.execute(sql)
18
+ end
19
+
20
+ def self.down
21
+ WorkflowTransition.where(:old_status_id => 0).delete_all
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ class CreateImports < ActiveRecord::Migration
2
+ def change
3
+ create_table :imports do |t|
4
+ t.string :type
5
+ t.integer :user_id, :null => false
6
+ t.string :filename
7
+ t.text :settings
8
+ t.integer :total_items
9
+ t.boolean :finished, :null => false, :default => false
10
+ t.timestamps :null => false
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ class CreateImportItems < ActiveRecord::Migration
2
+ def change
3
+ create_table :import_items do |t|
4
+ t.integer :import_id, :null => false
5
+ t.integer :position, :null => false
6
+ t.integer :obj_id
7
+ t.text :message
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ class ChangeTimeEntriesCommentsLimitTo1024 < ActiveRecord::Migration
2
+ def self.up
3
+ change_column :time_entries, :comments, :string, :limit => 1024
4
+ end
5
+
6
+ def self.down
7
+ change_column :time_entries, :comments, :string, :limit => 255
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class ChangeWikiContentsCommentsLimitTo1024 < ActiveRecord::Migration
2
+ def self.up
3
+ change_column :wiki_content_versions, :comments, :string, :limit => 1024, :default => ''
4
+ change_column :wiki_contents, :comments, :string, :limit => 1024, :default => ''
5
+ end
6
+
7
+ def self.down
8
+ change_column :wiki_content_versions, :comments, :string, :limit => 255, :default => ''
9
+ change_column :wiki_contents, :comments, :string, :limit => 255, :default => ''
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class ChangeAttachmentsFilesizeLimitTo8 < ActiveRecord::Migration
2
+ def self.up
3
+ change_column :attachments, :filesize, :integer, :limit => 8, :default => 0, :null => false
4
+ end
5
+
6
+ def self.down
7
+ change_column :attachments, :filesize, :integer, :limit => 4, :default => 0, :null => false
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ class FixCommaInUserFormatSettingValue < ActiveRecord::Migration
2
+ def self.up
3
+ Setting.
4
+ where(:name => 'user_format', :value => 'lastname_coma_firstname').
5
+ update_all(:value => 'lastname_comma_firstname')
6
+ end
7
+
8
+ def self.down
9
+ Setting.
10
+ where(:name => 'user_format', :value => 'lastname_comma_firstname').
11
+ update_all(:value => 'lastname_coma_firstname')
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ class ChangeIssueCategoriesNameLimitTo60 < ActiveRecord::Migration
2
+ def self.up
3
+ change_column :issue_categories, :name, :string, :limit => 60, :default => "", :null => false
4
+ end
5
+
6
+ def self.down
7
+ change_column :issue_categories, :name, :string, :limit => 30, :default => "", :null => false
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class ChangeAuthSourcesFilterToText < ActiveRecord::Migration
2
+ def self.up
3
+ change_column :auth_sources, :filter, :text
4
+ end
5
+
6
+ def self.down
7
+ change_column :auth_sources, :filter, :string
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class ChangeUserPreferencesHideMailDefaultToTrue < ActiveRecord::Migration
2
+ def self.up
3
+ change_column :user_preferences, :hide_mail, :boolean, :default => true
4
+ end
5
+
6
+ def self.down
7
+ change_column :user_preferences, :hide_mail, :boolean, :default => false
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ class AddTokensUpdatedOn < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :tokens, :updated_on, :timestamp
4
+ Token.update_all("updated_on = created_on")
5
+ end
6
+
7
+ def self.down
8
+ remove_column :tokens, :updated_on
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ class CreateCustomFieldEnumerations < ActiveRecord::Migration
2
+ def change
3
+ create_table :custom_field_enumerations do |t|
4
+ t.integer :custom_field_id, :null => false
5
+ t.string :name, :null => false
6
+ t.boolean :active, :default => true, :null => false
7
+ t.integer :position, :default => 1, :null => false
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ class AddProjectsDefaultVersionId < ActiveRecord::Migration
2
+ def self.up
3
+ # Don't try to add the column if redmine_default_version plugin was used
4
+ unless column_exists?(:projects, :default_version_id, :integer)
5
+ add_column :projects, :default_version_id, :integer, :default => nil
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ remove_column :projects, :default_version_id
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ class ForcePasswordResetDuringSetup < ActiveRecord::Migration
2
+ def up
3
+ User.where(login: "admin", last_login_on: nil).update_all(must_change_passwd: true)
4
+ end
5
+
6
+ def down
7
+ User.where(login: "admin", last_login_on: nil, must_change_passwd: true).update_all(must_change_passwd: false)
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ class RemovePositionDefaults < ActiveRecord::Migration
2
+ def up
3
+ [Board, CustomField, Enumeration, IssueStatus, Role, Tracker].each do |klass|
4
+ change_column klass.table_name, :position, :integer, :default => nil
5
+ end
6
+ end
7
+
8
+ def down
9
+ [Board, CustomField, Enumeration, IssueStatus, Role, Tracker].each do |klass|
10
+ change_column klass.table_name, :position, :integer, :default => 1
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ class AddRolesSettings < ActiveRecord::Migration
2
+ def change
3
+ add_column :roles, :settings, :text
4
+ end
5
+ end
@@ -0,0 +1,118 @@
1
+ # Redmine - project management software
2
+ # Copyright (C) 2006-2016 Jean-Philippe Lang
3
+ #
4
+ # This program is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU General Public License
6
+ # as published by the Free Software Foundation; either version 2
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
+
18
+ module Redmine
19
+ module Acts
20
+ module Positioned
21
+ def self.included(base)
22
+ base.extend ClassMethods
23
+ end
24
+
25
+ # This extension provides the capabilities for reordering objects in a list.
26
+ # The class needs to have a +position+ column defined as an integer on the
27
+ # mapped database table.
28
+ module ClassMethods
29
+ # Configuration options are:
30
+ #
31
+ # * +scope+ - restricts what is to be considered a list. Must be a symbol
32
+ # or an array of symbols
33
+ def acts_as_positioned(options = {})
34
+ class_attribute :positioned_options
35
+ self.positioned_options = {:scope => Array(options[:scope])}
36
+
37
+ send :include, Redmine::Acts::Positioned::InstanceMethods
38
+
39
+ before_save :set_default_position
40
+ after_save :update_position
41
+ after_destroy :remove_position
42
+ end
43
+ end
44
+
45
+ module InstanceMethods
46
+ def self.included(base)
47
+ base.extend ClassMethods
48
+ end
49
+
50
+ private
51
+
52
+ def position_scope
53
+ build_position_scope {|c| send(c)}
54
+ end
55
+
56
+ def position_scope_was
57
+ build_position_scope {|c| send("#{c}_was")}
58
+ end
59
+
60
+ def build_position_scope
61
+ condition_hash = self.class.positioned_options[:scope].inject({}) do |h, column|
62
+ h[column] = yield(column)
63
+ h
64
+ end
65
+ self.class.where(condition_hash)
66
+ end
67
+
68
+ def set_default_position
69
+ if position.nil?
70
+ self.position = position_scope.maximum(:position).to_i + (new_record? ? 1 : 0)
71
+ end
72
+ end
73
+
74
+ def update_position
75
+ if !new_record? && position_scope_changed?
76
+ remove_position
77
+ insert_position
78
+ elsif position_changed?
79
+ if position_was.nil?
80
+ insert_position
81
+ else
82
+ shift_positions
83
+ end
84
+ end
85
+ end
86
+
87
+ def insert_position
88
+ position_scope.where("position >= ? AND id <> ?", position, id).update_all("position = position + 1")
89
+ end
90
+
91
+ def remove_position
92
+ position_scope_was.where("position >= ? AND id <> ?", position_was, id).update_all("position = position - 1")
93
+ end
94
+
95
+ def position_scope_changed?
96
+ (changed & self.class.positioned_options[:scope].map(&:to_s)).any?
97
+ end
98
+
99
+ def shift_positions
100
+ offset = position_was <=> position
101
+ min, max = [position, position_was].sort
102
+ r = position_scope.where("id <> ? AND position BETWEEN ? AND ?", id, min, max).update_all("position = position + #{offset}")
103
+ if r != max - min
104
+ reset_positions_in_list
105
+ end
106
+ end
107
+
108
+ def reset_positions_in_list
109
+ position_scope.reorder(:position, :id).pluck(:id).each_with_index do |record_id, p|
110
+ self.class.where(:id => record_id).update_all(:position => p+1)
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ ActiveRecord::Base.send :include, Redmine::Acts::Positioned