typus 3.0.8 → 3.0.9
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.
- data/Gemfile +8 -1
- data/README.md +2 -2
- data/Rakefile +6 -14
- data/app/controllers/admin/base_controller.rb +1 -1
- data/app/controllers/admin/dashboard_controller.rb +0 -1
- data/app/controllers/admin/resources_controller.rb +8 -11
- data/app/controllers/admin/session_controller.rb +5 -4
- data/app/helpers/admin/base_helper.rb +9 -2
- data/app/helpers/admin/dashboard_helper.rb +0 -6
- data/app/helpers/admin/display_helper.rb +1 -0
- data/app/helpers/admin/file_preview_helper.rb +0 -2
- data/app/helpers/admin/filters_helper.rb +6 -3
- data/app/helpers/admin/form_helper.rb +2 -4
- data/app/helpers/admin/list_helper.rb +1 -3
- data/app/helpers/admin/relationships_helper.rb +2 -4
- data/app/helpers/admin/resources_helper.rb +0 -2
- data/app/helpers/admin/search_helper.rb +0 -2
- data/app/helpers/admin/sidebar_helper.rb +0 -2
- data/app/helpers/admin/table_helper.rb +3 -6
- data/app/views/admin/account/forgot_password.html.erb +2 -2
- data/app/views/admin/account/new.html.erb +3 -7
- data/app/views/admin/{helpers/dashboard → dashboard}/_applications.html.erb +0 -0
- data/app/views/admin/dashboard/_sidebar.html.erb +1 -1
- data/app/views/admin/dashboard/show.html.erb +7 -1
- data/app/views/admin/helpers/base/_apps.html.erb +1 -1
- data/app/views/admin/helpers/base/_login_info.html.erb +2 -2
- data/app/views/admin/helpers/filters/_filters.html.erb +3 -1
- data/app/views/admin/resources/_form.html.erb +5 -2
- data/app/views/admin/resources/edit.html.erb +1 -1
- data/app/views/admin/resources/index.html.erb +1 -1
- data/app/views/admin/resources/show.html.erb +2 -2
- data/app/views/admin/session/new.html.erb +3 -7
- data/app/views/admin/templates/_belongs_to.html.erb +8 -1
- data/app/views/admin/templates/_belongs_to_with_autocomplete.html.erb +1 -1
- data/app/views/admin/templates/_relate_form.html.erb +1 -1
- data/app/views/admin/templates/_relate_form_with_autocomplete.html.erb +3 -1
- data/app/views/admin/templates/_string.html.erb +1 -1
- data/app/views/admin/templates/_text.html.erb +1 -1
- data/app/views/layouts/admin/base.html.erb +2 -0
- data/app/views/layouts/admin/headless.html.erb +2 -0
- data/app/views/layouts/admin/session.html.erb +6 -0
- data/config/routes.rb +4 -1
- data/lib/support/active_record.rb +0 -10
- data/lib/support/fake_user.rb +4 -6
- data/lib/support/object.rb +4 -0
- data/lib/support/string.rb +0 -8
- data/lib/typus.rb +2 -3
- data/lib/typus/authentication/base.rb +0 -1
- data/lib/typus/authentication/session.rb +22 -29
- data/lib/typus/orm/active_record.rb +5 -5
- data/lib/typus/orm/active_record/admin_user_v1.rb +93 -0
- data/lib/typus/orm/active_record/admin_user_v2.rb +49 -0
- data/lib/typus/orm/active_record/class_methods.rb +23 -143
- data/lib/typus/orm/active_record/user/instance_methods.rb +64 -0
- data/lib/typus/orm/base.rb +170 -0
- data/lib/typus/orm/mongo/class_methods.rb +11 -0
- data/lib/typus/resources.rb +2 -1
- data/lib/typus/version.rb +1 -1
- data/test/app/controllers/admin/account_controller_test.rb +4 -2
- data/test/app/controllers/admin/assets_controller_test.rb +12 -12
- data/test/app/controllers/admin/categories_controller_test.rb +5 -12
- data/test/app/controllers/admin/comments_controller_test.rb +1 -1
- data/test/app/controllers/admin/image_holders_controller_test.rb +1 -1
- data/test/app/controllers/admin/invoices_controller_test.rb +1 -1
- data/test/app/controllers/admin/posts_controller_test.rb +32 -32
- data/test/app/controllers/admin/projects_controller_test.rb +1 -1
- data/test/app/controllers/admin/typus_users_controller_test.rb +13 -17
- data/test/app/controllers/admin/users_controller_test.rb +9 -9
- data/test/app/helpers/admin/list_helper_test.rb +17 -0
- data/test/app/models/admin_user_test.rb +5 -0
- data/test/app/models/typus_user_roles_test.rb +1 -0
- data/test/app/models/typus_user_test.rb +45 -11
- data/test/factories.rb +1 -1
- data/test/fixtures/rails_app/app/controllers/admin/hits_controller.rb +40 -0
- data/test/fixtures/rails_app/app/controllers/admin_user.rb +3 -0
- data/test/fixtures/rails_app/app/models/asset.rb +0 -6
- data/test/fixtures/rails_app/app/models/hit.rb +27 -0
- data/test/fixtures/rails_app/app/views/admin/hits/_edit.html.erb +7 -0
- data/test/fixtures/rails_app/app/views/admin/hits/_index.html.erb +3 -0
- data/test/fixtures/rails_app/app/views/admin/hits/index.html.erb +28 -0
- data/test/fixtures/rails_app/config/boot.rb +3 -10
- data/test/fixtures/rails_app/config/deploy.rb +1 -1
- data/test/fixtures/rails_app/config/mongoid.yml +20 -0
- data/test/fixtures/rails_app/config/typus/crud_extended.yml +2 -0
- data/test/fixtures/rails_app/config/typus/mongo_db.yml +4 -0
- data/test/fixtures/rails_app/config/typus/mongo_db_roles.yml +2 -0
- data/test/fixtures/rails_app/db/schema.rb +11 -0
- data/test/lib/support/fake_user_test.rb +4 -0
- data/test/lib/support/string_test.rb +0 -18
- data/test/lib/typus/orm/active_record/class_methods_test.rb +14 -2
- data/test/lib/typus/orm/active_record/search_test.rb +1 -1
- data/test/lib/typus_test.rb +2 -1
- data/typus.gemspec +1 -1
- metadata +32 -45
- data/lib/typus/orm/active_record/instance_methods.rb +0 -13
- data/lib/typus/orm/active_record/user.rb +0 -157
- data/test/fixtures/rails_app/public/javascripts/application.js +0 -2
- data/test/fixtures/rails_app/public/javascripts/controls.js +0 -965
- data/test/fixtures/rails_app/public/javascripts/dragdrop.js +0 -974
- data/test/fixtures/rails_app/public/javascripts/effects.js +0 -1123
- data/test/fixtures/rails_app/public/javascripts/prototype.js +0 -6001
- data/test/fixtures/rails_app/public/javascripts/rails.js +0 -175
|
@@ -2,12 +2,12 @@ if defined?(ActiveRecord)
|
|
|
2
2
|
require 'typus/orm/active_record/class_methods'
|
|
3
3
|
ActiveRecord::Base.extend Typus::Orm::ActiveRecord::ClassMethods
|
|
4
4
|
|
|
5
|
-
require 'typus/orm/active_record/instance_methods'
|
|
6
|
-
ActiveRecord::Base.send :include, Typus::Orm::ActiveRecord::InstanceMethods
|
|
7
|
-
|
|
8
5
|
require 'typus/orm/active_record/search'
|
|
9
6
|
ActiveRecord::Base.extend Typus::Orm::ActiveRecord::Search
|
|
10
7
|
|
|
11
|
-
require 'typus/orm/active_record/
|
|
12
|
-
ActiveRecord::Base.
|
|
8
|
+
require 'typus/orm/active_record/admin_user_v1'
|
|
9
|
+
ActiveRecord::Base.extend Typus::Orm::ActiveRecord::AdminUserV1::ClassMethods
|
|
10
|
+
|
|
11
|
+
require 'typus/orm/active_record/admin_user_v2'
|
|
12
|
+
ActiveRecord::Base.extend Typus::Orm::ActiveRecord::AdminUserV2::ClassMethods
|
|
13
13
|
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require 'typus/orm/active_record/user/instance_methods'
|
|
2
|
+
|
|
3
|
+
module Typus
|
|
4
|
+
module Orm
|
|
5
|
+
module ActiveRecord
|
|
6
|
+
module AdminUserV1
|
|
7
|
+
|
|
8
|
+
module ClassMethods
|
|
9
|
+
|
|
10
|
+
def enable_as_typus_user
|
|
11
|
+
|
|
12
|
+
attr_accessor :password
|
|
13
|
+
attr_protected :status
|
|
14
|
+
|
|
15
|
+
validates :email,
|
|
16
|
+
:presence => true,
|
|
17
|
+
:uniqueness => true,
|
|
18
|
+
:format => { :with => Typus::Regex::Email }
|
|
19
|
+
|
|
20
|
+
validates :password,
|
|
21
|
+
:confirmation => { :if => :password_required? },
|
|
22
|
+
:presence => { :if => :password_required? }
|
|
23
|
+
|
|
24
|
+
validates_length_of :password, :within => 6..40, :if => :password_required?
|
|
25
|
+
|
|
26
|
+
validates :role, :presence => true
|
|
27
|
+
|
|
28
|
+
before_save :initialize_salt, :encrypt_password, :initialize_token
|
|
29
|
+
|
|
30
|
+
serialize :preferences
|
|
31
|
+
|
|
32
|
+
def authenticate(email, password)
|
|
33
|
+
user = find_by_email_and_status(email, true)
|
|
34
|
+
user && user.authenticated?(password) ? user : nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def generate(*args)
|
|
38
|
+
options = args.extract_options!
|
|
39
|
+
options[:password] ||= ActiveSupport::SecureRandom.hex(4)
|
|
40
|
+
options[:role] ||= Typus.master_role
|
|
41
|
+
new :email => options[:email], :password => options[:password], :role => options[:role]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
include InstanceMethods
|
|
45
|
+
include Typus::Orm::ActiveRecord::User::InstanceMethods
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
module InstanceMethods
|
|
52
|
+
|
|
53
|
+
def authenticated?(password)
|
|
54
|
+
crypted_password == encrypt(password)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
protected
|
|
58
|
+
|
|
59
|
+
def generate_hash(string)
|
|
60
|
+
Digest::SHA1.hexdigest(string)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def encrypt_password
|
|
64
|
+
return if password.blank?
|
|
65
|
+
self.crypted_password = encrypt(password)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def encrypt(string)
|
|
69
|
+
generate_hash("--#{salt}--#{string}--")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def initialize_salt
|
|
73
|
+
self.salt = generate_hash("--#{Time.zone.now.to_s(:number)}--#{email}--") if new_record?
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def initialize_token
|
|
77
|
+
generate_token if new_record?
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def generate_token
|
|
81
|
+
self.token = encrypt("--#{Time.zone.now.to_s(:number)}--#{password}--").first(12)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def password_required?
|
|
85
|
+
crypted_password.blank? || !password.blank?
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'typus/orm/active_record/user/instance_methods'
|
|
2
|
+
require 'bcrypt'
|
|
3
|
+
|
|
4
|
+
module Typus
|
|
5
|
+
module Orm
|
|
6
|
+
module ActiveRecord
|
|
7
|
+
module AdminUserV2
|
|
8
|
+
|
|
9
|
+
module ClassMethods
|
|
10
|
+
|
|
11
|
+
def has_admin
|
|
12
|
+
|
|
13
|
+
attr_reader :password
|
|
14
|
+
attr_accessor :password_confirmation
|
|
15
|
+
|
|
16
|
+
validates :email, :presence => true, :uniqueness => true, :format => { :with => Typus::Regex::Email }
|
|
17
|
+
validates :password, :confirmation => true, :length => { :within => 6..40 }
|
|
18
|
+
validates :password_digest, :presence => true
|
|
19
|
+
|
|
20
|
+
include InstanceMethodsOnActivation
|
|
21
|
+
include Typus::Orm::ActiveRecord::User::InstanceMethods
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
module InstanceMethodsOnActivation
|
|
28
|
+
|
|
29
|
+
# Returns self if the password is correct, otherwise false.
|
|
30
|
+
def authenticate(unencrypted_password)
|
|
31
|
+
if BCrypt::Password.new(password_digest) == unencrypted_password
|
|
32
|
+
self
|
|
33
|
+
else
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Encrypts the password into the password_digest attribute.
|
|
39
|
+
def password=(unencrypted_password)
|
|
40
|
+
@password = unencrypted_password
|
|
41
|
+
self.password_digest = BCrypt::Password.create(unencrypted_password)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -3,6 +3,8 @@ module Typus
|
|
|
3
3
|
module ActiveRecord
|
|
4
4
|
module ClassMethods
|
|
5
5
|
|
|
6
|
+
include Typus::Orm::Base
|
|
7
|
+
|
|
6
8
|
# Model fields as an <tt>ActiveSupport::OrderedHash</tt>.
|
|
7
9
|
def model_fields
|
|
8
10
|
ActiveSupport::OrderedHash.new.tap do |hash|
|
|
@@ -17,16 +19,31 @@ module Typus
|
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
|
|
20
|
-
# Model description for admin panel.
|
|
21
|
-
def typus_description
|
|
22
|
-
read_model_config['description']
|
|
23
|
-
end
|
|
24
|
-
|
|
25
22
|
# Form and list fields
|
|
26
23
|
def typus_fields_for(filter)
|
|
27
24
|
ActiveSupport::OrderedHash.new.tap do |fields_with_type|
|
|
28
25
|
data = read_model_config['fields']
|
|
29
|
-
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Let's say for example we want to get the fields for actions
|
|
29
|
+
# related with editing stuff.
|
|
30
|
+
#
|
|
31
|
+
|
|
32
|
+
fields = case filter.to_sym
|
|
33
|
+
when :list, :form
|
|
34
|
+
# TODO: This statement is for backwards compatibility
|
|
35
|
+
# with the current tests, so can be removed in
|
|
36
|
+
# the near future.
|
|
37
|
+
data[filter.to_s] || data['default'] || ""
|
|
38
|
+
when :index
|
|
39
|
+
data['index'] || data['list'] || data['default'] || ""
|
|
40
|
+
when :new, :create
|
|
41
|
+
data['new'] || data['form'] || data['default'] || ""
|
|
42
|
+
when :edit, :update, :toggle
|
|
43
|
+
data['edit'] || data['form'] || data['default'] || ""
|
|
44
|
+
else
|
|
45
|
+
data[filter.to_s] || data['default'] || ""
|
|
46
|
+
end
|
|
30
47
|
|
|
31
48
|
virtual_fields = instance_methods.map { |i| i.to_s } - model_fields.keys.map { |i| i.to_s }
|
|
32
49
|
|
|
@@ -84,143 +101,6 @@ module Typus
|
|
|
84
101
|
end
|
|
85
102
|
end
|
|
86
103
|
|
|
87
|
-
# Extended actions for this model on Typus.
|
|
88
|
-
def typus_actions_on(filter)
|
|
89
|
-
actions = read_model_config['actions']
|
|
90
|
-
actions && actions[filter.to_s] ? actions[filter.to_s].extract_settings : []
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Used for +search+, +relationships+
|
|
94
|
-
def typus_defaults_for(filter)
|
|
95
|
-
read_model_config[filter.to_s].try(:extract_settings) || []
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def typus_search_fields
|
|
99
|
-
Hash.new.tap do |search|
|
|
100
|
-
typus_defaults_for(:search).each do |field|
|
|
101
|
-
if field.starts_with?("=")
|
|
102
|
-
field.slice!(0)
|
|
103
|
-
search[field] = "="
|
|
104
|
-
elsif field.starts_with?("^")
|
|
105
|
-
field.slice!(0)
|
|
106
|
-
search[field] = "^"
|
|
107
|
-
else
|
|
108
|
-
search[field] = "@"
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def typus_application
|
|
115
|
-
read_model_config['application'] || 'Unknown'
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def typus_field_options_for(filter)
|
|
119
|
-
options = read_model_config['fields']['options']
|
|
120
|
-
options && options[filter.to_s] ? options[filter.to_s].extract_settings.map { |i| i.to_sym } : []
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
#--
|
|
124
|
-
# With Typus::Resources we some application defaults.
|
|
125
|
-
#
|
|
126
|
-
# Typus::Resources.setup do |config|
|
|
127
|
-
# config.per_page = 15
|
|
128
|
-
# end
|
|
129
|
-
#
|
|
130
|
-
# If for any reason we need a better default for an specific resource we
|
|
131
|
-
# we override it on `application.yaml`.
|
|
132
|
-
#
|
|
133
|
-
# Post:
|
|
134
|
-
# ...
|
|
135
|
-
# options:
|
|
136
|
-
# per_page: 15
|
|
137
|
-
#++
|
|
138
|
-
def typus_options_for(filter)
|
|
139
|
-
options = read_model_config['options']
|
|
140
|
-
|
|
141
|
-
unless options.nil? || options[filter.to_s].nil?
|
|
142
|
-
options[filter.to_s]
|
|
143
|
-
else
|
|
144
|
-
Typus::Resources.send(filter)
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
def typus_export_formats
|
|
149
|
-
read_model_config['export'].try(:extract_settings) || []
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def typus_order_by
|
|
153
|
-
typus_defaults_for(:order_by).map do |field|
|
|
154
|
-
field.include?('-') ? "#{table_name}.#{field.delete('-')} DESC" : "#{table_name}.#{field} ASC"
|
|
155
|
-
end.join(', ')
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
#--
|
|
159
|
-
# Define our own boolean mappings.
|
|
160
|
-
#
|
|
161
|
-
# Post:
|
|
162
|
-
# fields:
|
|
163
|
-
# default: title, status
|
|
164
|
-
# options:
|
|
165
|
-
# booleans:
|
|
166
|
-
# status: "Published", "Not published"
|
|
167
|
-
#
|
|
168
|
-
#++
|
|
169
|
-
def typus_boolean(attribute = :default)
|
|
170
|
-
options = read_model_config['fields']['options']
|
|
171
|
-
|
|
172
|
-
boolean = if options && options['booleans'] && boolean = options['booleans'][attribute.to_s]
|
|
173
|
-
boolean.is_a?(String) ? boolean.extract_settings : boolean
|
|
174
|
-
else
|
|
175
|
-
["True", "False"]
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
[[boolean.first, "true"], [boolean.last, "false"]]
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
#--
|
|
182
|
-
# Custom date formats.
|
|
183
|
-
#++
|
|
184
|
-
def typus_date_format(attribute = :default)
|
|
185
|
-
options = read_model_config['fields']['options']
|
|
186
|
-
if options && options['date_formats'] && options['date_formats'][attribute.to_s]
|
|
187
|
-
options['date_formats'][attribute.to_s].to_sym
|
|
188
|
-
else
|
|
189
|
-
:default
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
#--
|
|
194
|
-
# This is user to use custome templates for attribute:
|
|
195
|
-
#
|
|
196
|
-
# Post:
|
|
197
|
-
# fields:
|
|
198
|
-
# form: title, body, status
|
|
199
|
-
# options:
|
|
200
|
-
# templates:
|
|
201
|
-
# body: rich_text
|
|
202
|
-
#
|
|
203
|
-
# Templates are stored on <tt>app/views/admin/templates</tt>.
|
|
204
|
-
#++
|
|
205
|
-
def typus_template(attribute)
|
|
206
|
-
options = read_model_config['fields']['options']
|
|
207
|
-
if options && options['templates'] && options['templates'][attribute.to_s]
|
|
208
|
-
options['templates'][attribute.to_s]
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def adapter
|
|
213
|
-
@adapter ||= ::ActiveRecord::Base.configurations[Rails.env]['adapter']
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def typus_user_id?
|
|
217
|
-
columns.map { |u| u.name }.include?(Typus.user_fk)
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
def read_model_config
|
|
221
|
-
Typus::Configuration.config[name] or raise "No typus configuration specified for #{name}"
|
|
222
|
-
end
|
|
223
|
-
|
|
224
104
|
end
|
|
225
105
|
end
|
|
226
106
|
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Typus
|
|
2
|
+
module Orm
|
|
3
|
+
module ActiveRecord
|
|
4
|
+
module User
|
|
5
|
+
module InstanceMethods
|
|
6
|
+
|
|
7
|
+
def to_label
|
|
8
|
+
full_name = [first_name, last_name].delete_if { |s| s.blank? }
|
|
9
|
+
full_name.any? ? full_name.join(" ") : email
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def resources
|
|
13
|
+
Typus::Configuration.roles[role.to_s].compact
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def applications
|
|
17
|
+
Typus.applications.delete_if { |a| application(a).empty? }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def application(name)
|
|
21
|
+
Typus.application(name).delete_if { |r| !resources.keys.include?(r) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def can?(action, resource, options = {})
|
|
25
|
+
resource = resource.model_name if resource.is_a?(Class)
|
|
26
|
+
|
|
27
|
+
return false if !resources.include?(resource)
|
|
28
|
+
return true if resources[resource].include?("all")
|
|
29
|
+
|
|
30
|
+
action = options[:special] ? action : action.acl_action_mapper
|
|
31
|
+
|
|
32
|
+
resources[resource].extract_settings.include?(action)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def cannot?(*args)
|
|
36
|
+
!can?(*args)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def is_root?
|
|
40
|
+
role == Typus.master_role
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def is_not_root?
|
|
44
|
+
!is_root?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def locale
|
|
48
|
+
(preferences && preferences[:locale]) ? preferences[:locale] : ::I18n.default_locale
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def locale=(locale)
|
|
52
|
+
self.preferences ||= {}
|
|
53
|
+
self.preferences[:locale] = locale
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def owns?(resource)
|
|
57
|
+
id == resource.send(Typus.user_fk)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
module Typus
|
|
2
|
+
module Orm
|
|
3
|
+
module Base
|
|
4
|
+
|
|
5
|
+
# Model fields as an <tt>ActiveSupport::OrderedHash</tt>.
|
|
6
|
+
def model_fields; end
|
|
7
|
+
|
|
8
|
+
# Model relationships as an <tt>ActiveSupport::OrderedHash</tt>.
|
|
9
|
+
def model_relationships; end
|
|
10
|
+
|
|
11
|
+
# Model description for admin panel.
|
|
12
|
+
def typus_description
|
|
13
|
+
read_model_config['description']
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Form and list fields
|
|
17
|
+
def typus_fields_for(filter); end
|
|
18
|
+
|
|
19
|
+
def typus_filters; end
|
|
20
|
+
|
|
21
|
+
# Extended actions for this model on Typus.
|
|
22
|
+
def typus_actions_on(filter)
|
|
23
|
+
actions = read_model_config['actions']
|
|
24
|
+
actions && actions[filter.to_s] ? actions[filter.to_s].extract_settings : []
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Used for +search+, +relationships+
|
|
28
|
+
def typus_defaults_for(filter)
|
|
29
|
+
read_model_config[filter.to_s].try(:extract_settings) || []
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def typus_search_fields
|
|
33
|
+
Hash.new.tap do |search|
|
|
34
|
+
typus_defaults_for(:search).each do |field|
|
|
35
|
+
if field.starts_with?("=")
|
|
36
|
+
field.slice!(0)
|
|
37
|
+
search[field] = "="
|
|
38
|
+
elsif field.starts_with?("^")
|
|
39
|
+
field.slice!(0)
|
|
40
|
+
search[field] = "^"
|
|
41
|
+
else
|
|
42
|
+
search[field] = "@"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def typus_application
|
|
49
|
+
read_model_config['application'] || 'Unknown'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def typus_field_options_for(filter)
|
|
53
|
+
options = read_model_config['fields']['options']
|
|
54
|
+
options && options[filter.to_s] ? options[filter.to_s].extract_settings.map { |i| i.to_sym } : []
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#--
|
|
58
|
+
# With Typus::Resources we some application defaults.
|
|
59
|
+
#
|
|
60
|
+
# Typus::Resources.setup do |config|
|
|
61
|
+
# config.per_page = 15
|
|
62
|
+
# end
|
|
63
|
+
#
|
|
64
|
+
# If for any reason we need a better default for an specific resource we
|
|
65
|
+
# we override it on `application.yaml`.
|
|
66
|
+
#
|
|
67
|
+
# Post:
|
|
68
|
+
# ...
|
|
69
|
+
# options:
|
|
70
|
+
# per_page: 15
|
|
71
|
+
#++
|
|
72
|
+
def typus_options_for(filter)
|
|
73
|
+
options = read_model_config['options']
|
|
74
|
+
|
|
75
|
+
unless options.nil? || options[filter.to_s].nil?
|
|
76
|
+
options[filter.to_s]
|
|
77
|
+
else
|
|
78
|
+
Typus::Resources.send(filter)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def typus_export_formats
|
|
83
|
+
read_model_config['export'].try(:extract_settings) || []
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def typus_order_by
|
|
87
|
+
typus_defaults_for(:order_by).map do |field|
|
|
88
|
+
field.include?('-') ? "#{table_name}.#{field.delete('-')} DESC" : "#{table_name}.#{field} ASC"
|
|
89
|
+
end.join(', ')
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
#--
|
|
93
|
+
# Define our own boolean mappings.
|
|
94
|
+
#
|
|
95
|
+
# Post:
|
|
96
|
+
# fields:
|
|
97
|
+
# default: title, status
|
|
98
|
+
# options:
|
|
99
|
+
# booleans:
|
|
100
|
+
# status: "Published", "Not published"
|
|
101
|
+
#
|
|
102
|
+
#++
|
|
103
|
+
def typus_boolean(attribute = :default)
|
|
104
|
+
options = read_model_config['fields']['options']
|
|
105
|
+
|
|
106
|
+
boolean = if options && options['booleans'] && boolean = options['booleans'][attribute.to_s]
|
|
107
|
+
boolean.is_a?(String) ? boolean.extract_settings : boolean
|
|
108
|
+
else
|
|
109
|
+
["True", "False"]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
[[boolean.first, "true"], [boolean.last, "false"]]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
#--
|
|
116
|
+
# Custom date formats.
|
|
117
|
+
#++
|
|
118
|
+
def typus_date_format(attribute = :default)
|
|
119
|
+
options = read_model_config['fields']['options']
|
|
120
|
+
if options && options['date_formats'] && options['date_formats'][attribute.to_s]
|
|
121
|
+
options['date_formats'][attribute.to_s].to_sym
|
|
122
|
+
else
|
|
123
|
+
:default
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
#--
|
|
128
|
+
# This is user to use custome templates for attribute:
|
|
129
|
+
#
|
|
130
|
+
# Post:
|
|
131
|
+
# fields:
|
|
132
|
+
# form: title, body, status
|
|
133
|
+
# options:
|
|
134
|
+
# templates:
|
|
135
|
+
# body: rich_text
|
|
136
|
+
#
|
|
137
|
+
# Templates are stored on <tt>app/views/admin/templates</tt>.
|
|
138
|
+
#++
|
|
139
|
+
def typus_template(attribute)
|
|
140
|
+
options = read_model_config['fields']['options']
|
|
141
|
+
if options && options['templates'] && options['templates'][attribute.to_s]
|
|
142
|
+
options['templates'][attribute.to_s]
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def adapter
|
|
147
|
+
@adapter ||= ::ActiveRecord::Base.configurations[Rails.env]['adapter']
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def typus_user_id?
|
|
151
|
+
columns.map { |u| u.name }.include?(Typus.user_fk)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def read_model_config
|
|
155
|
+
Typus::Configuration.config[name] or raise "No typus configuration specified for #{name}"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
#--
|
|
159
|
+
# >> Post.to_resource
|
|
160
|
+
# => "posts"
|
|
161
|
+
# >> Admin::User.to_resource
|
|
162
|
+
# => "admin/users"
|
|
163
|
+
#++
|
|
164
|
+
def to_resource
|
|
165
|
+
name.underscore.pluralize
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|