redmineup 1.1.3 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitlab-ci.yml +7 -17
  4. data/README.md +74 -153
  5. data/app/assets/javascripts/consumer.js +37 -60
  6. data/app/assets/javascripts/consumer_worker.js +199 -0
  7. data/app/assets/javascripts/jquery.colorPicker.min.js +26 -0
  8. data/app/assets/javascripts/select2_helpers.js +10 -0
  9. data/app/assets/stylesheets/redmineup.css +509 -0
  10. data/app/views/redmineup/_additional_assets.html.erb +1 -0
  11. data/config/locales/en.yml +1 -0
  12. data/config/locales/ru.yml +1 -0
  13. data/config/routes.rb +4 -0
  14. data/doc/CHANGELOG +72 -25
  15. data/doc/active-record-mixins.md +156 -0
  16. data/doc/assets-money-and-utilities.md +71 -0
  17. data/doc/tagging-and-select2.md +108 -0
  18. data/lib/action_cable/connection/rup_connection.rb +17 -0
  19. data/lib/action_cable/server/rup_server.rb +4 -0
  20. data/lib/redmineup/acts_as_taggable/tag.rb +13 -3
  21. data/lib/redmineup/acts_as_taggable/up_acts_as_taggable.rb +9 -6
  22. data/lib/redmineup/acts_as_viewed/up_acts_as_viewed.rb +1 -1
  23. data/lib/redmineup/engine.rb +12 -2
  24. data/lib/redmineup/helpers/datetime_helper.rb +23 -0
  25. data/lib/redmineup/helpers/external_assets_helper.rb +14 -6
  26. data/lib/redmineup/helpers/form_tag_helper.rb +43 -0
  27. data/lib/redmineup/helpers/tags_helper.rb +41 -0
  28. data/lib/redmineup/hooks/views_layouts_hook.rb +1 -5
  29. data/lib/redmineup/money_helper.rb +10 -2
  30. data/lib/redmineup/patches/action_cable_base_patch.rb +9 -2
  31. data/lib/redmineup/patches/action_cable_patch.rb +2 -4
  32. data/lib/redmineup/patches/auto_completes_controller_patch.rb +19 -0
  33. data/lib/redmineup/patches/compatibility/sprite_patch.rb +1 -1
  34. data/lib/redmineup/patches/compatibility/user_patch.rb +3 -3
  35. data/lib/redmineup/version.rb +1 -1
  36. data/lib/redmineup.rb +16 -35
  37. data/test/acts_as_taggable/tag_test.rb +12 -9
  38. data/test/schema.rb +1 -1
  39. data/test/tags_helper_view_test.rb +41 -0
  40. data/test/test_helper.rb +2 -1
  41. metadata +14 -2
data/doc/CHANGELOG CHANGED
@@ -4,64 +4,111 @@ Redmine UP gem - general functions for plugins (tags, vote, viewing, currency)
4
4
  Copyright (C) 2011-2026 Kirill Bezrukov (RedmineUP)
5
5
  https://www.redmineup.com/
6
6
 
7
+ == 2026-06-26 v1.1.11
8
+
9
+ * Added shared workers for websocket connection
10
+
11
+ == 2026-06-04 v1.1.10
12
+
13
+ * Added colorpicker JS component to shared gem assets, loaded globally via `redmineup_assets`
14
+ * Fixed viewings table ip column limit to 45 characters for IPv6 address support
15
+
16
+ == 2026-05-30 v1.1.9
17
+
18
+ * Added `prices_formatted_collection` to `MoneyHelper` — returns plain text price strings from currency hash, used by query totals
19
+
20
+ == 2026-05-01 v1.1.8
21
+
22
+ * Added `on_select` callback and `select_icon` options for `select2tag` helper
23
+ * Updated `requires_redmineup` version guard to reduce boilerplate in plugin init
24
+ * Fixed `link_to` display compatibility issue in Redmine 5
25
+
26
+ == 2026-04-18 v1.1.7
27
+
28
+ * hot fix for atom/rss compatibility for redmine < 5
29
+
30
+ == 2026-04-17 v1.1.6
31
+
32
+ * Added helpers for timezone conversions
33
+
34
+ == 2026-04-17 v1.1.5
35
+
36
+ * Added tag cloud links helper with URL convention by key
37
+ * Added shared tag list fields for views and FormBuilder
38
+ * Added shared tag autocomplete route for taggable models
39
+ * Updated layout hook to load shared gem assets globally
40
+ * Updated tag helpers registration in ActionView context
41
+ * Fixed tag color fallback for backward compatibility
42
+ * Fixed helper behavior for Ruby 2.3 compatibility
43
+
44
+ == 2026-04-10 v1.1.4
45
+
46
+ * Fixed tag queries for MSSQL adapter
47
+
7
48
  == 2026-03-10 v1.1.3
8
49
 
9
- * Fixed ActionCable compatibility
10
50
  * Added send method for ActionCable
51
+ * Fixed ActionCable compatibility with cable.yaml apply
11
52
 
12
53
  == 2025-11-07 v1.1.2
13
54
 
14
- * Fixed assets loading error
55
+ * Fixed shared assets loading error
15
56
 
16
- == 2025-10-24 v1.1.1
57
+ == 2025-10-01 v1.1.1
17
58
 
18
- * Fixed activation for sprite_icon patch
59
+ * Updated sprite_icon patch activation logic
19
60
 
20
61
  == 2025-07-24 v1.1.0
21
62
 
22
- * Added ActionCable methods
23
- * Fixed Tags migration method
24
- * Fixed svg icons for context menu
63
+ * Added ActionCable methods for plugin integrations
64
+ * Added SVG icon support for context menu actions
65
+ * Fixed tag migration method for old Rails versions
25
66
 
26
67
  == 2025-07-09 v1.0.13
27
68
 
28
- * Added color to Tag
69
+ * Added tag color support in tag model behavior
70
+
71
+ == 2025-07-08 v1.0.12
29
72
 
30
- == 2025-02-04 v1.0.11
73
+ * Added tag color selection functionality
31
74
 
32
- * Fixed bug with Redmine language settings
75
+ == 2025-03-30 v1.0.11
76
+
77
+ * Fixed ApplicationRecord loading compatibility
78
+
79
+ == 2025-02-04 v1.0.10
80
+
81
+ * Fixed SVG icon compatibility for older Redmine code
33
82
 
34
83
  == 2025-02-04 v1.0.9
35
84
 
36
85
  * Added regex_replace Liquid filter
37
- * Added svg icons for Redmine 6
86
+ * Added SVG icons for Redmine 6
87
+ * Fixed Liquid internal error in filter execution
88
+ * Fixed parse_inline_attachments Liquid filter behavior
38
89
 
39
90
  == 2025-01-31 v1.0.8
40
91
 
41
- * Fixed compatibility patch for Redmine < 5
92
+ * Fixed compatibility patch for Redmine versions below 5
42
93
 
43
94
  == 2025-01-29 v1.0.7
44
95
 
45
- * Fixed parse_inline_attachments Liquid filter
46
- * Added compatibility patch for Redmine 6 sprite_icon
96
+ * Added sprite_icon compatibility patch for Redmine 6
97
+ * Fixed parse_inline_attachments Liquid filter behavior
47
98
 
48
99
  == 2024-05-07 v1.0.6
49
100
 
50
- * Updated Chart.js to v3.9.1
51
- * Fixed assets paths for Redmine 5.3+
52
101
  * Added attachments to IssueDrop and JournalDrop
53
- * Added filter parse_inline_attachments for replace image urls
102
+ * Added parse_inline_attachments filter for image URL fix
103
+ * Updated Chart.js library to version 3.9.1
104
+ * Fixed asset paths for Redmine 5.3 and newer
54
105
 
55
106
  == 2024-01-31 v1.0.5
56
107
 
57
- * Added plugin_installed? method
58
- * Compatibility patches for ApplicationRecord
108
+ * Added plugin_installed? helper for plugin checks
109
+ * Fixed ApplicationRecord compatibility patch behavior
59
110
 
60
111
  == 2023-10-12 v1.0.1
61
112
 
62
- * RedmineUp module renamed to Redmineup
63
-
64
- == 2023-09-27 v1.0.0
65
-
66
- * Initial release
67
- * Mirgated from redmineup gem
113
+ * Added initial public release
114
+ * Updated module name from RedmineUp to Redmineup
@@ -0,0 +1,156 @@
1
+ # ActiveRecord mixins
2
+
3
+ This page documents the model mixins provided by `redmineup`.
4
+
5
+ ## `up_acts_as_taggable`
6
+
7
+ Adds polymorphic tagging support.
8
+
9
+ ### Migration
10
+
11
+ ```ruby
12
+ class CreateTags < ActiveRecord::Migration[6.1]
13
+ def change
14
+ ActiveRecord::Base.create_taggable_table
15
+ end
16
+ end
17
+ ```
18
+
19
+ Useful migration helpers:
20
+
21
+ - `ActiveRecord::Base.create_taggable_table`
22
+ - `ActiveRecord::Base.drop_taggable_table`
23
+ - `ActiveRecord::Base.add_tags_column(:tags, name: :color, type: :integer, default: nil)`
24
+ - `ActiveRecord::Base.remove_tags_columns(:tags, :color)`
25
+
26
+ ### Model
27
+
28
+ ```ruby
29
+ class Product < ApplicationRecord
30
+ up_acts_as_taggable
31
+ end
32
+ ```
33
+
34
+ ### Runtime API
35
+
36
+ - `record.tag_list` / `record.tag_list = 'a, b'`
37
+ - `record.save_tags` (called via callbacks)
38
+ - `Model.available_tags(project: @project, limit: 30)`
39
+ - `Model.tagged_with(['tag1', 'tag2'])`
40
+ - `Model.find_related_tags('tag1')`
41
+
42
+ ## `up_acts_as_draftable`
43
+
44
+ Adds draft save/restore workflow for unsaved or changed records.
45
+
46
+ ### Migration
47
+
48
+ ```ruby
49
+ class CreateDrafts < ActiveRecord::Migration[6.1]
50
+ def change
51
+ ActiveRecord::Base.create_drafts_table
52
+ end
53
+ end
54
+ ```
55
+
56
+ Helpers:
57
+
58
+ - `ActiveRecord::Base.create_drafts_table`
59
+ - `ActiveRecord::Base.drop_drafts_table`
60
+
61
+ ### Model
62
+
63
+ ```ruby
64
+ class WikiPage < ApplicationRecord
65
+ up_acts_as_draftable parent: :wiki
66
+ end
67
+ ```
68
+
69
+ ### Runtime API
70
+
71
+ - `record.save_draft`
72
+ - `record.update_draft(attrs)`
73
+ - `Model.drafts(User.current)`
74
+ - `Model.from_draft(draft_or_id)`
75
+
76
+ ## `up_acts_as_viewed`
77
+
78
+ Tracks unique views by user (or IP) and total views.
79
+
80
+ ### Migration
81
+
82
+ ```ruby
83
+ class CreateViewings < ActiveRecord::Migration[6.1]
84
+ def change
85
+ ActiveRecord::Base.create_viewings_table
86
+ end
87
+ end
88
+ ```
89
+
90
+ Optional helpers for models with embedded counters:
91
+
92
+ - `ActiveRecord::Base.generate_viewings_columns(table)`
93
+ - `Model.add_viewings_columns`
94
+ - `Model.remove_viewings_columns`
95
+ - `ActiveRecord::Base.drop_viewings_table`
96
+
97
+ ### Model
98
+
99
+ ```ruby
100
+ class Question < ApplicationRecord
101
+ up_acts_as_viewed
102
+ end
103
+ ```
104
+
105
+ ### Runtime API
106
+
107
+ - `record.view(request.remote_ip, User.current)`
108
+ - `record.viewed?`
109
+ - `record.view_count`
110
+ - `record.viewed_by?(request.remote_ip, User.current)`
111
+
112
+ ## `up_acts_as_votable` and `up_acts_as_voter`
113
+
114
+ Adds voting capabilities for content and users.
115
+
116
+ ### Migration
117
+
118
+ ```ruby
119
+ class CreateVotes < ActiveRecord::Migration[6.1]
120
+ def change
121
+ ActiveRecord::Base.create_votable_table
122
+ end
123
+ end
124
+ ```
125
+
126
+ Helpers:
127
+
128
+ - `ActiveRecord::Base.create_votable_table`
129
+ - `ActiveRecord::Base.drop_votable_table`
130
+
131
+ ### Models
132
+
133
+ ```ruby
134
+ class Question < ApplicationRecord
135
+ up_acts_as_votable
136
+ end
137
+
138
+ class User < ApplicationRecord
139
+ up_acts_as_voter
140
+ end
141
+ ```
142
+
143
+ ## `up_acts_as_priceable`
144
+
145
+ Generates currency-aware `*_to_s` methods for price fields.
146
+
147
+ ### Model
148
+
149
+ ```ruby
150
+ class Deal < ApplicationRecord
151
+ up_acts_as_priceable :amount, :tax_amount, :subtotal, :total
152
+ end
153
+ ```
154
+
155
+ This creates methods like `amount_to_s`, `tax_amount_to_s`, etc., backed by
156
+ `Redmineup::MoneyHelper#object_price`.
@@ -0,0 +1,71 @@
1
+ # Assets, money, and shared utilities
2
+
3
+ ## Asset helpers
4
+
5
+ Provided by `Redmineup::ExternalAssetsHelper`:
6
+
7
+ - `redmineup_assets`
8
+ - `select2_assets` (alias for `redmineup_assets`)
9
+ - `chartjs_assets`
10
+
11
+ `redmineup_assets` includes:
12
+
13
+ - `consumer.js`
14
+ - `select2.js`
15
+ - `select2_helpers.js`
16
+ - `redmineup.css`
17
+
18
+ The gem also hooks `view_layouts_base_html_head` and renders
19
+ `redmineup/_additional_assets`, so shared assets can be included globally.
20
+ Helpers are idempotent and safe to call from plugin views.
21
+
22
+ ## Money and currency
23
+
24
+ ### Settings API
25
+
26
+ `Redmineup::Settings::Money` provides access to plugin-level money settings:
27
+
28
+ - `default_currency`
29
+ - `major_currencies`
30
+ - `default_tax`
31
+ - `tax_type`, `tax_exclusive?`
32
+ - `thousands_delimiter`
33
+ - `decimal_separator`
34
+ - `disable_taxes?`
35
+
36
+ ### Formatting helpers
37
+
38
+ `Redmineup::MoneyHelper` provides:
39
+
40
+ - `price_to_currency(price, currency, options = {})`
41
+ - `object_price(record, :price)`
42
+ - `prices_collection_by_currency(hash, hide_zeros: true)`
43
+ - `collection_for_currencies_select`
44
+ - `all_currencies`
45
+
46
+ `up_acts_as_priceable` uses these helpers to generate `*_to_s` methods on
47
+ models.
48
+
49
+ ### Admin UI
50
+
51
+ `Redmineup::Currency.add_admin_money_menu` registers a Redmine admin menu item
52
+ that points to:
53
+
54
+ - `redmineup_settings_path(:money)`
55
+
56
+ ## Misc shared helpers and patches
57
+
58
+ - `Redmineup::CalendarsHelper#calendar_day_css_classes`
59
+ - Liquid patch for numeric conversion in `Liquid::StandardFilters`
60
+ - Liquid filters/drops under `lib/redmineup/liquid/**`
61
+ - Compatibility and ActionCable patches loaded at gem boot
62
+
63
+ ## Version requirements in plugins
64
+
65
+ Plugins typically guard compatibility in `init.rb`:
66
+
67
+ ```ruby
68
+ requires_redmineup version_or_higher: '1.1.5'
69
+ ```
70
+
71
+ Use this to fail fast when a plugin depends on newer helper or API behavior.
@@ -0,0 +1,108 @@
1
+ # Tagging and Select2 helpers
2
+
3
+ This page covers view helpers used by RedmineUP plugins for tag rendering,
4
+ tag editing, and select2-backed filters.
5
+
6
+ ## Tag rendering helpers
7
+
8
+ Provided by `Redmineup::TagsHelper`:
9
+
10
+ - `tag_link(url, tag_name, options = {})`
11
+ - `tag_links(tag_list, options = {}) { |tag| url }`
12
+ - `tag_cloud(tags, classes) { |tag, css_class| ... }`
13
+ - `tag_cloud_links(tags, key, options = {})`
14
+ - `tag_separator`
15
+
16
+ ### Recommended pattern
17
+
18
+ Define `*_tag_url` per plugin context:
19
+
20
+ ```ruby
21
+ def contact_tag_url(tag_name, options = {})
22
+ {
23
+ controller: 'contacts',
24
+ action: 'index',
25
+ set_filter: 1,
26
+ fields: [:tags],
27
+ values: { tags: [tag_name] },
28
+ operators: { tags: '=' }
29
+ }.merge(options)
30
+ end
31
+ ```
32
+
33
+ Then render the cloud via convention:
34
+
35
+ ```erb
36
+ <%= tag_cloud_links(Contact.available_tags(project: @project), :contact) %>
37
+ ```
38
+
39
+ `tag_cloud_links(tags, :contact)` expects `contact_tag_url(name)` to be defined
40
+ in the current view context.
41
+
42
+ ## Tag editors with Select2
43
+
44
+ Provided by `Redmineup::FormTagHelper`:
45
+
46
+ - `select2_tag(name, option_tags = nil, options = {})`
47
+ - `select2(...)` (alias)
48
+ - `tag_list_field_tag(name, value = [], options = {})`
49
+ - `transform_to_select2(type, options = {})`
50
+
51
+ `ActionView::Helpers::FormBuilder` is extended with:
52
+
53
+ - `f.tag_list_field(:tag_list, **options)`
54
+
55
+ ### Example: form object API
56
+
57
+ ```erb
58
+ <%= f.tag_list_field :tag_list, width: '95%' %>
59
+ ```
60
+
61
+ ### Example: standalone field API
62
+
63
+ ```erb
64
+ <%= tag_list_field_tag 'product[tag_list]', @product.tag_list, taggable_type: 'Product' %>
65
+ ```
66
+
67
+ ### Example: query/filter select2 transform
68
+
69
+ ```erb
70
+ <%= transform_to_select2 'product_tags',
71
+ url: auto_complete_taggable_tags_path(project_id: @project, taggable_type: 'Product') %>
72
+ ```
73
+
74
+ ## Tag autocomplete endpoint
75
+
76
+ `redmineup` adds a shared route:
77
+
78
+ - `GET /auto_completes/taggable_tags`
79
+
80
+ Named route:
81
+
82
+ - `auto_complete_taggable_tags_path`
83
+
84
+ Typical params used by plugins:
85
+
86
+ - `taggable_type`: model class name (`Contact`, `Person`, `Product`, `Issue`, `DriveEntry`)
87
+ - `project_id`: optional project scope
88
+ - `limit`: optional result size limit
89
+
90
+ Response format:
91
+
92
+ ```json
93
+ [
94
+ { "id": "important", "text": "important" },
95
+ { "id": "vip", "text": "vip" }
96
+ ]
97
+ ```
98
+
99
+ ## Real plugin usage
100
+
101
+ Patterns above are used by:
102
+
103
+ - `redmine_contacts` (`contact_tag_url`, `contact_tag_links`, `f.tag_list_field`)
104
+ - `redmine_people` (`people_tag_url`, `tag_cloud_links`, bulk edit tag forms)
105
+ - `redmine_products` (`product_tag_url`, `tag_list_field_tag`, select2 filters)
106
+ - `redmine_questions` (`question_tag_url`, `tag_cloud_links`)
107
+ - `redmine_drive` (`drive_entry_tag_url`, select2 tag filters)
108
+ - `redmineup_tags` (issue tag forms with `tag_list_field_tag`)
@@ -0,0 +1,17 @@
1
+ module ActionCable
2
+ module Connection
3
+ class RupConnection < ActionCable::Connection::Base
4
+ identified_by :current_user
5
+
6
+ def connect
7
+ self.current_user = find_verified_user
8
+ end
9
+
10
+ private
11
+
12
+ def find_verified_user
13
+ User.find_by(id: @request.session[:user_id]) || User.anonymous
14
+ end
15
+ end
16
+ end
17
+ end
@@ -8,6 +8,10 @@ module ActionCable
8
8
  @mutex = Monitor.new
9
9
  @remote_connections = @event_loop = @worker_pool = @pubsub = nil
10
10
  end
11
+
12
+ def setup_heartbeat_timer
13
+ Rails.logger.info('Heartbeat timer disabled for RupServer')
14
+ end
11
15
  end
12
16
  end
13
17
  end
@@ -1,3 +1,5 @@
1
+ require 'digest/md5'
2
+
1
3
  module Redmineup
2
4
  module ActsAsTaggable #:nodoc:
3
5
  class Tag < ActiveRecord::Base #:nodoc:
@@ -17,6 +19,10 @@ module Redmineup
17
19
  where("LOWER(name) LIKE LOWER(?)", name).first || create(:name => name)
18
20
  end
19
21
 
22
+ def self.color_from_name(str)
23
+ "##{Digest::MD5.hexdigest(str.to_s)[0..5]}"
24
+ end
25
+
20
26
  def ==(object)
21
27
  super || (object.is_a?(Tag) && name == object.name)
22
28
  end
@@ -30,11 +36,15 @@ module Redmineup
30
36
  end
31
37
 
32
38
  def color
33
- return ('#' + "%06x" % super) unless super.nil?
39
+ if self.class.column_names.include?('color')
40
+ db_color = read_attribute(:color)
41
+ return ('#' + "%06x" % db_color) unless db_color.nil?
42
+ end
43
+ self.class.color_from_name(name)
34
44
  end
35
45
 
36
46
  def color=(color)
37
- write_attribute(:color, color.from(1).hex) unless color.blank?
47
+ write_attribute(:color, color.sub(/\A#/, '').hex) unless color.blank?
38
48
  end
39
49
 
40
50
  class << self
@@ -74,7 +84,7 @@ module Redmineup
74
84
  having = 'COUNT(*) > 0'
75
85
  having = [having, at_least, at_most].compact.join(' AND ')
76
86
  group_by = "#{Tag.table_name}.id, #{Tag.table_name}.name"
77
- # group_by << " AND #{having}" unless having.blank?
87
+ group_by << ", #{Tag.table_name}.color" if column_names.include?('color')
78
88
 
79
89
  select_condition = if self.column_names.include?('color')
80
90
  "#{Tag.table_name}.id, #{Tag.table_name}.name, #{Tag.table_name}.color, COUNT(*) AS count"
@@ -52,6 +52,7 @@ module Redmineup
52
52
  if !self.connection.table_exists?(tag_name_table)
53
53
  self.connection.create_table(tag_name_table) do |t|
54
54
  t.column :name, :string
55
+ t.column :color, :integer
55
56
  end
56
57
  end
57
58
 
@@ -64,6 +65,7 @@ module Redmineup
64
65
  # You should make sure that the column created is
65
66
  # long enough to store the required class names.
66
67
  t.column :taggable_type, :string
68
+ t.column :color, :integer, default: nil
67
69
 
68
70
  t.column :created_at, :datetime
69
71
  end
@@ -82,16 +84,16 @@ module Redmineup
82
84
  #
83
85
  # E.g.: ActiveRecord::Base.add_tags_column(:tags, name: :color, type: :string, default: nil)
84
86
  def add_tags_column(table_name = :tags, **options)
85
- tag_column = options || { name: :color, type: :int, default: nil }
87
+ tag_column = options
86
88
  tag_column.assert_valid_keys(:name, :type, :default)
87
89
 
88
90
  raise ArgumentError, "Table `#{table_name}' not found" unless self.connection.table_exists?(table_name)
89
91
 
90
92
  self.table_name = table_name
91
- unless self.connection.column_exists?(table_name, tag_column[:name])
92
- self.connection.add_column table_name, tag_column[:name], tag_column[:type], default: tag_column[:default]
93
- self.reset_column_information
94
- end
93
+ return if connection.column_exists?(table_name, tag_column[:name])
94
+
95
+ connection.add_column table_name, tag_column[:name], tag_column[:type], default: tag_column[:default]
96
+ reset_column_information
95
97
  end
96
98
 
97
99
  # Remove the up_acts_as_taggable specific columns
@@ -140,13 +142,14 @@ module Redmineup
140
142
  scope = scope.where("#{table_name}.project_id IN (%s)", projects.map(&:id).join(','))
141
143
  end
142
144
 
143
- if options[:name_like]
145
+ if options[:name_like].present?
144
146
  scope = scope.where("LOWER(#{Tag.table_name}.name) LIKE LOWER(?)", "%#{options[:name_like]}%")
145
147
  end
146
148
 
147
149
  group_fields = ''
148
150
  group_fields << ", #{Tag.table_name}.created_at" if Tag.respond_to?(:created_at)
149
151
  group_fields << ", #{Tag.table_name}.updated_at" if Tag.respond_to?(:updated_at)
152
+ group_fields << ", #{Tag.table_name}.color" if Tag.column_names.include?('color')
150
153
 
151
154
  if base_class.respond_to?(:visible_condition)
152
155
  visible_condition = base_class.visible_condition(User.current)
@@ -235,7 +235,7 @@ module Redmineup
235
235
  t.column :viewer_id, :integer
236
236
  t.column :viewed_id, :integer
237
237
  t.column :viewed_type, :string
238
- t.column :ip, :string, :limit => '24'
238
+ t.column :ip, :string, :limit => '45'
239
239
  t.column :created_at, :datetime
240
240
  end
241
241
 
@@ -1,4 +1,14 @@
1
1
  module Redmineup
2
- class Engine < Rails::Engine
3
- end
2
+ class Engine < Rails::Engine
3
+ config.to_prepare do
4
+ next unless defined?(::Redmine::Plugin)
5
+
6
+ require 'auto_completes_controller'
7
+
8
+ require File.expand_path('../redmineup/patches/compatibility_patch', __dir__)
9
+ require File.expand_path('../redmineup/patches/auto_completes_controller_patch', __dir__)
10
+
11
+ require File.expand_path('../redmineup/hooks/views_layouts_hook', __dir__)
12
+ end
13
+ end
4
14
  end
@@ -0,0 +1,23 @@
1
+ module Redmineup
2
+ module DatetimeHelper
3
+ def convert_time_to_user_timezone(time)
4
+ if User.current.time_zone
5
+ time.in_time_zone(User.current.time_zone)
6
+ else
7
+ time.utc? ? time.localtime : time
8
+ end
9
+ end
10
+
11
+ def convert_time_to_utc(time = Time.now)
12
+ return Time.now.utc if time.blank?
13
+ return time.utc if time.respond_to?(:utc)
14
+
15
+ time_zone = User.current.time_zone
16
+ return Time.parse(time).utc unless time_zone
17
+
18
+ Time.use_zone(time_zone) do
19
+ Time.zone.parse(time).utc
20
+ end
21
+ end
22
+ end
23
+ end
@@ -2,19 +2,27 @@ module Redmineup
2
2
  module ExternalAssetsHelper
3
3
  include ActionView::Helpers::JavaScriptHelper
4
4
 
5
+ def redmineup_assets
6
+ return if @redmineup_assets_included
7
+
8
+ @redmineup_assets_included = true
9
+ javascript_include_tag('consumer', plugin: GEM_NAME) +
10
+ javascript_include_tag('select2', plugin: GEM_NAME) +
11
+ javascript_include_tag('select2_helpers', plugin: GEM_NAME) +
12
+ javascript_include_tag('jquery.colorPicker.min', plugin: GEM_NAME) +
13
+ stylesheet_link_tag('redmineup', plugin: GEM_NAME) +
14
+ javascript_tag("window.redmineupWorkerUrl = #{asset_path('consumer_worker.js', plugin: GEM_NAME).to_json};")
15
+ end
16
+
5
17
  def select2_assets
6
- return if @select2_tag_included
7
- @select2_tag_included = true
8
- javascript_include_tag('select2', plugin: GEM_NAME) +
9
- stylesheet_link_tag('select2', plugin: GEM_NAME) +
10
- javascript_include_tag('select2_helpers', plugin: GEM_NAME)
18
+ redmineup_assets
11
19
  end
12
20
 
13
21
  def chartjs_assets
14
22
  return if @chartjs_tag_included
23
+
15
24
  @chartjs_tag_included = true
16
25
  javascript_include_tag('chart.min', plugin: GEM_NAME)
17
26
  end
18
-
19
27
  end
20
28
  end