ab_admin 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/stylesheets/ab_admin/fileupload.css.scss +3 -1
- data/app/views/admin/base/_table.html.slim +1 -1
- data/app/views/admin/fileupload/_container.html.slim +1 -0
- data/config/locales/ru.yml +1 -1
- data/features/step_definitions/dsl/batch_actions_steps.rb +1 -1
- data/lib/ab_admin.rb +2 -1
- data/lib/ab_admin/concerns/admin_addition.rb +27 -0
- data/lib/ab_admin/concerns/validations.rb +24 -0
- data/lib/ab_admin/core_ext/array.rb +17 -31
- data/lib/ab_admin/core_ext/string.rb +7 -7
- data/lib/ab_admin/engine.rb +1 -0
- data/lib/ab_admin/models/asset.rb +1 -1
- data/lib/ab_admin/models/user.rb +1 -1
- data/lib/ab_admin/version.rb +1 -1
- data/lib/ab_admin/views/form_builder.rb +4 -0
- data/lib/ab_admin/views/inputs/token_input.rb +15 -0
- data/lib/generators/ab_admin/install/templates/models/user_state.rb +4 -17
- data/spec/models/user_spec.rb +4 -4
- metadata +5 -4
- data/lib/ab_admin/mailers/development_mail_interceptor.rb +0 -11
@@ -2,7 +2,7 @@ table.table.table-striped.index_table#list
|
|
2
2
|
thead
|
3
3
|
tr.pjax_links
|
4
4
|
= batch_action_toggle
|
5
|
-
th
|
5
|
+
th= sort_link(@search, :id)
|
6
6
|
- resource_class.content_columns.map(&:name).without('updated_at').each do |col|
|
7
7
|
th= sort_link(@search, col)
|
8
8
|
th=t 'admin.table.actions'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
= content_tag :div, :id => element_id, :class => css_class, :data => container_data do
|
2
|
+
= error
|
2
3
|
.fileupload-drop-area
|
3
4
|
span= t('admin.fileupload.drop_here')
|
4
5
|
.fileupload-list.clearfix= render :partial => "admin/fileupload/#{asset_render_template}", :collection => assets
|
data/config/locales/ru.yml
CHANGED
data/lib/ab_admin.rb
CHANGED
@@ -49,6 +49,7 @@ module AbAdmin
|
|
49
49
|
autoload :Utilities, 'ab_admin/concerns/utilities'
|
50
50
|
autoload :Headerable, 'ab_admin/concerns/headerable'
|
51
51
|
autoload :NestedSet, 'ab_admin/concerns/nested_set'
|
52
|
+
autoload :Validations, 'ab_admin/concerns/validations'
|
52
53
|
end
|
53
54
|
|
54
55
|
module Controllers
|
@@ -59,7 +60,6 @@ module AbAdmin
|
|
59
60
|
end
|
60
61
|
|
61
62
|
module Mailers
|
62
|
-
autoload :DevelopmentMailInterceptor, 'ab_admin/mailers/development_mail_interceptor'
|
63
63
|
autoload :Helpers, 'ab_admin/mailers/helpers'
|
64
64
|
autoload :MailAttachHelper, 'ab_admin/mailers/mail_attach_helper'
|
65
65
|
end
|
@@ -91,6 +91,7 @@ module AbAdmin
|
|
91
91
|
autoload :TreeSelectInput, 'ab_admin/views/inputs/tree_select_input'
|
92
92
|
autoload :AssociationInput, 'ab_admin/views/inputs/association_input'
|
93
93
|
autoload :DateTimeInput, 'ab_admin/views/inputs/date_time_input'
|
94
|
+
autoload :TokenInput, 'ab_admin/views/inputs/token_input'
|
94
95
|
end
|
95
96
|
end
|
96
97
|
|
@@ -13,6 +13,33 @@ module AbAdmin
|
|
13
13
|
self.batch_actions = [:destroy]
|
14
14
|
end
|
15
15
|
|
16
|
+
module ClassMethods
|
17
|
+
def for_input_token(r, attr='name_ru')
|
18
|
+
{:id => r.id, :text => r[attr]}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def for_input_token
|
23
|
+
{:id => self.id, :text => self.name}
|
24
|
+
end
|
25
|
+
|
26
|
+
def token_data(method, options={})
|
27
|
+
assoc = self.class.reflect_on_association(method)
|
28
|
+
records = self.send(method)
|
29
|
+
data = Array(records).map(&:for_input_token)
|
30
|
+
data = {
|
31
|
+
:pre => data.to_json,
|
32
|
+
:class => assoc.klass.name,
|
33
|
+
:multi => assoc.collection?,
|
34
|
+
:c => options.delete(:c)
|
35
|
+
}
|
36
|
+
if options[:geo_order]
|
37
|
+
singular = self.class.model_name.singular
|
38
|
+
data[:c] ||= {:with => {:lat => "#{singular}_lat", :lon => "#{singular}_lon"}}.to_json
|
39
|
+
end
|
40
|
+
options.reverse_deep_merge!(:class => 'fancy_select', :data => data)
|
41
|
+
end
|
42
|
+
|
16
43
|
def next_prev_by_url(scope, url, prev=false)
|
17
44
|
predicates = {'>' => '<', '<' => '>', 'desc' => 'asc', 'asc' => 'desc'}
|
18
45
|
query = Rack::Utils.parse_nested_query(URI.parse(url).query).symbolize_keys
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module AbAdmin
|
2
|
+
module Concerns
|
3
|
+
module Validations
|
4
|
+
class UniqTranslationValidator < ActiveModel::EachValidator
|
5
|
+
def validate_each(record, attribute, value)
|
6
|
+
::I18n.available_locales.each do |l|
|
7
|
+
next if record.read_attribute(attribute, :locale => l).blank?
|
8
|
+
records_scope = record.class.const_get(:Translation).where("#{record.class.model_name.foreign_key} != #{record.id || 0}")
|
9
|
+
same = records_scope.where(:name => record.read_attribute(attribute, :locale => l), :locale => l.to_s).exists?
|
10
|
+
record.errors.add("#{attribute}_#{l}", :taken) if same
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class AssetValidator < ActiveModel::EachValidator
|
16
|
+
def validate_each(record, attribute, value)
|
17
|
+
if Array(record.fileupload_asset(attribute)).all?{|a| a.new_record? }
|
18
|
+
record.errors.add(attribute, :blank)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -22,33 +22,19 @@ class Array
|
|
22
22
|
inject(:+) / size
|
23
23
|
end
|
24
24
|
|
25
|
-
def zip_all
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def pearson(b)
|
38
|
-
return 0 if self.size != b.size || !Object.const_defined?("Statsample")
|
39
|
-
Statsample::Bivariate.pearson(self.to_scale, b.to_scale)
|
40
|
-
end
|
41
|
-
|
42
|
-
def pluck!(method, *args)
|
43
|
-
each_index { |x| self[x] = self[x].send method, *args }
|
44
|
-
end
|
45
|
-
|
46
|
-
alias invoke! pluck!
|
25
|
+
#def zip_all
|
26
|
+
# self[0].zip *self[1..-1]
|
27
|
+
#end
|
28
|
+
#
|
29
|
+
#def pluck!(method, *args)
|
30
|
+
# each_index { |x| self[x] = self[x].send method, *args }
|
31
|
+
#end
|
32
|
+
#
|
33
|
+
#alias invoke! pluck!
|
47
34
|
|
48
35
|
def without(*values)
|
49
36
|
copy = self.dup
|
50
|
-
|
51
|
-
copy
|
37
|
+
copy.without!(*values)
|
52
38
|
end
|
53
39
|
|
54
40
|
def without!(*values)
|
@@ -80,11 +66,11 @@ class Array
|
|
80
66
|
|
81
67
|
end
|
82
68
|
|
83
|
-
module Enumerable
|
84
|
-
def pluck(method, *args)
|
85
|
-
map { |x| x.send method, *args }
|
86
|
-
end
|
87
|
-
|
88
|
-
alias invoke pluck
|
89
|
-
end
|
69
|
+
#module Enumerable
|
70
|
+
# def pluck(method, *args)
|
71
|
+
# map { |x| x.send method, *args }
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# alias invoke pluck
|
75
|
+
#end
|
90
76
|
|
@@ -2,6 +2,10 @@
|
|
2
2
|
class String
|
3
3
|
#LUCENE_ESCAPE_REGEX = /(\+|-|&&|\|\||!|\(|\)|{|}|\[|\]|`|"|~|\?|:|\\)/
|
4
4
|
LUCENE_ESCAPE_REGEX = /(\+|-|&&|\|\||!|\(|\)|{|}|\[|\]|`|"|~|\?|:|\\|\s)/
|
5
|
+
KEYBOARDS = {
|
6
|
+
:en => %{qwertyuiop[]asdfghjkl;'zxcvbnm,./},
|
7
|
+
:ru => %{йцукенгшщзхъфывапролджэячсмитьбю/}
|
8
|
+
}
|
5
9
|
|
6
10
|
def lucene_escape
|
7
11
|
self.gsub(LUCENE_ESCAPE_REGEX, "\\\\\\1")
|
@@ -38,21 +42,17 @@ class String
|
|
38
42
|
def tr_lang(from=nil, to=nil)
|
39
43
|
return '' if self.blank?
|
40
44
|
|
41
|
-
keyboard = {}
|
42
|
-
keyboard[:en] = %{qwertyuiop[]asdfghjkl;'zxcvbnm,./}
|
43
|
-
keyboard[:ru] = %{йцукенгшщзхъфывапролджэячсмитьбю/}
|
44
|
-
|
45
45
|
unless from || to
|
46
|
-
if
|
46
|
+
if KEYBOARDS[:en].index(self[0])
|
47
47
|
from, to = :en, :ru
|
48
|
-
elsif
|
48
|
+
elsif KEYBOARDS[:ru].index(self[0])
|
49
49
|
from, to = :ru, :en
|
50
50
|
else
|
51
51
|
from, to = :en, :ru
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
self.tr(
|
55
|
+
self.tr(KEYBOARDS[from], KEYBOARDS[to])
|
56
56
|
end
|
57
57
|
|
58
58
|
def count_words
|
data/lib/ab_admin/engine.rb
CHANGED
@@ -15,6 +15,7 @@ module AbAdmin
|
|
15
15
|
ActiveRecord::Base.send :include, AbAdmin::Concerns::Utilities
|
16
16
|
ActiveRecord::Base.send :include, AbAdmin::Concerns::Silencer
|
17
17
|
ActiveRecord::Base.send :extend, AbAdmin::Concerns::Silencer
|
18
|
+
ActiveRecord::Base.send :include, AbAdmin::Concerns::Validations
|
18
19
|
end
|
19
20
|
|
20
21
|
ActiveSupport.on_load :action_mailer do
|
@@ -51,7 +51,7 @@ module AbAdmin
|
|
51
51
|
:only => [:id, :guid, :assetable_id, :assetable_type, :user_id,
|
52
52
|
:data_file_size, :data_content_type, :is_main, :original_name],
|
53
53
|
:root => 'asset',
|
54
|
-
:methods => [:filename, :url, :
|
54
|
+
:methods => [:filename, :url, :thumb_url, :width, :height]
|
55
55
|
}.merge(options || {})
|
56
56
|
|
57
57
|
super
|
data/lib/ab_admin/models/user.rb
CHANGED
@@ -6,7 +6,7 @@ module AbAdmin
|
|
6
6
|
included do
|
7
7
|
has_one :avatar, :as => :assetable, :dependent => :destroy, :autosave => true
|
8
8
|
|
9
|
-
scope :
|
9
|
+
scope :managers, where(:user_role_id => [::UserRoleType.admin.id, ::UserRoleType.moderator.id])
|
10
10
|
scope :active, where(:trust_state => ::UserState.active.id)
|
11
11
|
scope :admin, includes(:avatar)
|
12
12
|
|
data/lib/ab_admin/version.rb
CHANGED
@@ -14,6 +14,7 @@ module AbAdmin
|
|
14
14
|
map_type :tree_select, :to => ::AbAdmin::Views::Inputs::TreeSelectInput
|
15
15
|
map_type :association, :to => ::AbAdmin::Views::Inputs::AssociationInput
|
16
16
|
map_type :date, :time, :datetime, :to => ::AbAdmin::Views::Inputs::DateTimeInput
|
17
|
+
map_type :token, :to => ::AbAdmin::Views::Inputs::TokenInput
|
17
18
|
|
18
19
|
def input(attribute_name, options = {}, &block)
|
19
20
|
if options[:fancy]
|
@@ -118,6 +119,7 @@ module AbAdmin
|
|
118
119
|
|
119
120
|
locals = {
|
120
121
|
element_id: element_id,
|
122
|
+
error: error(attribute_name),
|
121
123
|
file_title: (options[:file_title] || script_options['allowedExtensions'].join(', ')),
|
122
124
|
file_max_size: max_size,
|
123
125
|
assets: [value].flatten.delete_if { |v| v.nil? || v.new_record? },
|
@@ -133,6 +135,8 @@ module AbAdmin
|
|
133
135
|
|
134
136
|
locals[:css_class] = ['fileupload', "#{locals[:asset_render_template]}_asset_type"]
|
135
137
|
locals[:css_class] << (script_options['multiple'] ? 'many_assets' : 'one_asset')
|
138
|
+
locals[:css_class] << 'error' if locals[:error]
|
139
|
+
|
136
140
|
|
137
141
|
js_opts = [locals[:element_id], template.sort_admin_assets_path(:klass => asset_klass), locals[:multiple]].map(&:inspect).join(', ')
|
138
142
|
locals[:js] = <<-JAVASCRIPT
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module AbAdmin
|
2
|
+
module Views
|
3
|
+
module Inputs
|
4
|
+
class TokenInput < ::SimpleForm::Inputs::StringInput
|
5
|
+
|
6
|
+
def input
|
7
|
+
attr = options.delete(:assoc) || attribute_name.to_s.sub(/^token_|_id$/, '')
|
8
|
+
input_html_options.reverse_deep_merge!(object.token_data(attr.to_sym, options.extract!(:geo_order, :c)))
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,19 +1,6 @@
|
|
1
|
-
class UserState
|
2
|
-
|
3
|
-
|
4
|
-
@code = code.to_sym
|
5
|
-
end
|
1
|
+
class UserState < AbAdmin::Models::TypeModel
|
2
|
+
self.codes = [:pending, :active, :suspended, :deleted]
|
3
|
+
self.i18n_scope = [:admin, :user, :state]
|
6
4
|
|
7
|
-
|
8
|
-
builder.member :pending, :object => new('pending')
|
9
|
-
builder.member :active, :object => new('active')
|
10
|
-
builder.member :suspended, :object => new('suspended')
|
11
|
-
builder.member :deleted, :object => new('deleted')
|
12
|
-
end
|
13
|
-
|
14
|
-
attr_reader :code
|
15
|
-
|
16
|
-
def title
|
17
|
-
I18n.t(@code, :scope => [:admin, :user, :state])
|
18
|
-
end
|
5
|
+
define_enum_by_codes
|
19
6
|
end
|
data/spec/models/user_spec.rb
CHANGED
@@ -38,14 +38,14 @@ describe User do
|
|
38
38
|
@inactive = create(:user)
|
39
39
|
end
|
40
40
|
|
41
|
-
it 'search for
|
42
|
-
User.
|
43
|
-
User.
|
41
|
+
it 'search for managers' do
|
42
|
+
User.managers.should_not include(@user)
|
43
|
+
User.managers.should include(@moderator)
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'search for active users' do
|
47
47
|
User.active.should include(@user)
|
48
|
-
User.
|
48
|
+
User.managers.should_not include(@inactive)
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ab_admin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.2.
|
5
|
+
version: 0.2.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Alex Leschenko
|
@@ -797,6 +797,7 @@ files:
|
|
797
797
|
- lib/ab_admin/concerns/nested_set.rb
|
798
798
|
- lib/ab_admin/concerns/silencer.rb
|
799
799
|
- lib/ab_admin/concerns/utilities.rb
|
800
|
+
- lib/ab_admin/concerns/validations.rb
|
800
801
|
- lib/ab_admin/config/base.rb
|
801
802
|
- lib/ab_admin/config/optional_display.rb
|
802
803
|
- lib/ab_admin/controllers/callbacks.rb
|
@@ -818,7 +819,6 @@ files:
|
|
818
819
|
- lib/ab_admin/i18n_tools/google_translate.rb
|
819
820
|
- lib/ab_admin/i18n_tools/model_translator.rb
|
820
821
|
- lib/ab_admin/i18n_tools/translate_app.rb
|
821
|
-
- lib/ab_admin/mailers/development_mail_interceptor.rb
|
822
822
|
- lib/ab_admin/mailers/helpers.rb
|
823
823
|
- lib/ab_admin/mailers/mail_attach_helper.rb
|
824
824
|
- lib/ab_admin/menu_builder.rb
|
@@ -846,6 +846,7 @@ files:
|
|
846
846
|
- lib/ab_admin/views/inputs/color_input.rb
|
847
847
|
- lib/ab_admin/views/inputs/date_time_input.rb
|
848
848
|
- lib/ab_admin/views/inputs/editor_input.rb
|
849
|
+
- lib/ab_admin/views/inputs/token_input.rb
|
849
850
|
- lib/ab_admin/views/inputs/tree_select_input.rb
|
850
851
|
- lib/ab_admin/views/manager_helpers.rb
|
851
852
|
- lib/ab_admin/views/search_form_builder.rb
|
@@ -1848,7 +1849,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
1848
1849
|
version: '0'
|
1849
1850
|
segments:
|
1850
1851
|
- 0
|
1851
|
-
hash: -
|
1852
|
+
hash: -2578895605994787711
|
1852
1853
|
none: false
|
1853
1854
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
1854
1855
|
requirements:
|
@@ -1857,7 +1858,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1857
1858
|
version: '0'
|
1858
1859
|
segments:
|
1859
1860
|
- 0
|
1860
|
-
hash: -
|
1861
|
+
hash: -2578895605994787711
|
1861
1862
|
none: false
|
1862
1863
|
requirements: []
|
1863
1864
|
rubyforge_project:
|