rad_kit 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -2
- data/app/controllers/app.rb +5 -0
- data/app/controllers/base.rb +47 -0
- data/app/controllers/base_app.rb +18 -0
- data/app/controllers/comments.rb +49 -0
- data/app/controllers/items.rb +208 -0
- data/app/helpers/kit/authorization.rb +121 -0
- data/app/helpers/kit/captcha.rb +10 -0
- data/app/helpers/kit/controller_helper.rb +76 -0
- data/app/helpers/kit/item_helper.rb +110 -0
- data/app/helpers/kit/navigation_helper.rb +15 -0
- data/app/helpers/kit/pagination.rb +62 -0
- data/app/models/_item/attachments.rb +15 -0
- data/app/models/_item/container.rb +30 -0
- data/app/models/_item/slug.rb +28 -0
- data/app/models/attachment.rb +9 -0
- data/app/models/comment.rb +30 -0
- data/app/models/item.rb +136 -0
- data/app/models/secure_token.rb +45 -0
- data/app/models/tag.rb +71 -0
- data/app/static/kit/highlight.css +48 -0
- data/app/static/kit.css +3 -0
- data/app/static/kit.js +0 -0
- data/app/static/themes/default/objects.less +28 -0
- data/app/views/controllers/comments/_embedded.html.haml +13 -0
- data/app/views/controllers/comments/_form.html.haml +8 -0
- data/app/views/controllers/comments/actions.js.haml +22 -0
- data/app/views/controllers/comments/show.html.haml +11 -0
- data/app/views/controllers/items/_items.html.haml +2 -0
- data/app/views/controllers/items/actions.js.haml +23 -0
- data/app/views/controllers/items/all.html.haml +4 -0
- data/app/views/controllers/items/inherited_action.html.haml +1 -0
- data/app/views/kit/_bottom_panel.html.haml +9 -0
- data/app/views/kit/_debug.html.haml +13 -0
- data/app/views/kit/_messages.html.haml +4 -0
- data/app/views/kit/_navigation.html.haml +19 -0
- data/app/views/kit/_not_found.html.haml +1 -0
- data/app/views/kit/_top_panel.html.haml +19 -0
- data/app/views/kit/_web_analytics.html.erb +14 -0
- data/app/views/kit/aspects/_comments.html.haml +8 -0
- data/app/views/kit/captcha/_action.js.haml +2 -0
- data/app/views/kit/captcha/_form.html.haml +10 -0
- data/app/views/kit/layout.html.haml +22 -0
- data/app/views/kit/layout.js.haml +15 -0
- data/app/views/previews/_line.html.haml +8 -0
- data/app/views/previews/_thumb.html.haml +5 -0
- data/app/views/themes/default/file.html.haml +19 -0
- data/app/views/themes/default/folder.html.haml +15 -0
- data/app/views/themes/default/layout_definitions/default.yml +27 -0
- data/app/views/themes/default/list.html.haml +21 -0
- data/app/views/themes/default/list_item.html.haml +14 -0
- data/app/views/themes/default/page.html.haml +23 -0
- data/app/views/tools/_access.html.haml +12 -0
- data/app/views/tools/_buttons.html.haml +11 -0
- data/app/views/tools/_context_menu.html.haml +12 -0
- data/app/views/tools/_search.html.haml +5 -0
- data/app/views/tools/_tags.html.haml +10 -0
- data/config/locales/en.yml +136 -0
- data/config/locales/ru.yml +142 -0
- data/config/routes.rb +44 -0
- metadata +82 -23
data/Rakefile
CHANGED
@@ -2,9 +2,10 @@ require 'rake_ext'
|
|
2
2
|
|
3
3
|
project(
|
4
4
|
name: "kit",
|
5
|
-
official_name: 'rad_kit',
|
6
|
-
gem: true,
|
5
|
+
official_name: 'rad_kit',
|
7
6
|
summary: "Rapid Application Development Kit for Rad Framework",
|
7
|
+
dirs: ['app', 'config'],
|
8
|
+
gem: true,
|
8
9
|
|
9
10
|
author: "Alexey Petrushin",
|
10
11
|
homepage: "http://github.com/alexeypetrushin/rad_kit"
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Base
|
2
|
+
inherit Rad::Controller::Http
|
3
|
+
|
4
|
+
def smoke_test
|
5
|
+
render inline: 'ok'
|
6
|
+
end
|
7
|
+
|
8
|
+
protected
|
9
|
+
allow_get_for %()
|
10
|
+
|
11
|
+
inherit Rad::Controller::Localized
|
12
|
+
|
13
|
+
before :prepare_current_user
|
14
|
+
|
15
|
+
inherit Rad::Controller::Authorized
|
16
|
+
|
17
|
+
helper Helpers::Kit::NavigationHelper
|
18
|
+
|
19
|
+
#
|
20
|
+
# User Error
|
21
|
+
#
|
22
|
+
def catch_user_error
|
23
|
+
begin
|
24
|
+
yield
|
25
|
+
rescue UserError => e
|
26
|
+
msg = e.message || ""
|
27
|
+
flash.error = msg
|
28
|
+
flash.sticky_error = msg
|
29
|
+
|
30
|
+
if request.xhr? or params.format == 'js'
|
31
|
+
render inline: %(rad.error("#{msg.js_escape.html_escape}");), layout: false
|
32
|
+
else
|
33
|
+
dont_persist_params{redirect_to default_path}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
around :catch_user_error
|
38
|
+
|
39
|
+
|
40
|
+
#
|
41
|
+
# Interface Builder
|
42
|
+
#
|
43
|
+
def set_theme
|
44
|
+
theme.name = params.theme || rad.face.theme # || 'default'
|
45
|
+
end
|
46
|
+
before :set_theme
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class BaseApp < Controllers::Base
|
2
|
+
inherit Helpers::Kit::ControllerHelper
|
3
|
+
|
4
|
+
helper Helpers::Kit::Authorization, Helpers::Kit::Captcha, Helpers::Kit::Pagination
|
5
|
+
|
6
|
+
def prepare_general_params
|
7
|
+
if params._tags
|
8
|
+
@selected_tags = params._tags.split('-').select{|tag| Models::Tag.valid_name?(tag)}
|
9
|
+
else
|
10
|
+
@selected_tags = []
|
11
|
+
end
|
12
|
+
@selected_tags.freeze
|
13
|
+
@selected_tags
|
14
|
+
end
|
15
|
+
before :prepare_general_params
|
16
|
+
attr_reader :selected_tags
|
17
|
+
helper_method :selected_tags
|
18
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Comments < Items
|
2
|
+
# prepare_model Comment, finder: :by_slug!, only: %w(show edit update destroy)
|
3
|
+
|
4
|
+
allow_get_for :show, :new, :edit
|
5
|
+
|
6
|
+
def show
|
7
|
+
require_permission :view, @model
|
8
|
+
end
|
9
|
+
|
10
|
+
def new
|
11
|
+
require_permission :create_comment
|
12
|
+
params.item_id.must_not_be.nil
|
13
|
+
@model = Models::Comment.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
require_permission :create_comment
|
18
|
+
@item = Models::Item.by_param! params.item_id
|
19
|
+
@model = Models::Comment.new params.model
|
20
|
+
@model.item = @item
|
21
|
+
@model.owner = Models::User.current
|
22
|
+
if @model.save
|
23
|
+
flash.info = t :comment_created
|
24
|
+
# render action: :new
|
25
|
+
else
|
26
|
+
render action: :new
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def edit
|
31
|
+
require_permission :update_comment, @model
|
32
|
+
end
|
33
|
+
|
34
|
+
def update
|
35
|
+
require_permission :update_comment, @model
|
36
|
+
if @model.set(params.model).save
|
37
|
+
flash.info = t :comment_updated
|
38
|
+
# render action: :update
|
39
|
+
else
|
40
|
+
render action: :edit
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def destroy
|
45
|
+
require_permission :destroy_comment, @model
|
46
|
+
@model.destroy
|
47
|
+
flash.info = t :comment_destroyed
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
class Items < Controllers::App
|
2
|
+
persist_params
|
3
|
+
|
4
|
+
before do |c|
|
5
|
+
model = workspace.model
|
6
|
+
model ||= Models::Item.by_param workspace.params.id if workspace.params.id?
|
7
|
+
c.instance_variable_set '@model', model
|
8
|
+
end
|
9
|
+
|
10
|
+
partials do
|
11
|
+
show :buttons, only: [:all, :show]
|
12
|
+
show :search, only: [:all, :show]
|
13
|
+
show :tags, only: [:all, :show]
|
14
|
+
show :context_menu, only: :show
|
15
|
+
|
16
|
+
show :comments, only: :show
|
17
|
+
end
|
18
|
+
|
19
|
+
helper Helpers::Kit::ItemHelper
|
20
|
+
|
21
|
+
layout '/kit/layout'
|
22
|
+
|
23
|
+
allow_get_for :redirect, :all
|
24
|
+
protect_from_forgery
|
25
|
+
|
26
|
+
allow_get_for :show, :new, :edit, :redirect
|
27
|
+
|
28
|
+
def redirect
|
29
|
+
url = rad.router.default_url
|
30
|
+
url = url_for(:all) if url == '/' or url.blank?
|
31
|
+
redirect_to url
|
32
|
+
end
|
33
|
+
|
34
|
+
def show
|
35
|
+
respond_to do |f|
|
36
|
+
if @model
|
37
|
+
require_permission :view, @model
|
38
|
+
|
39
|
+
f.html{@html_title = @model.name}
|
40
|
+
f.json{render json: @model}
|
41
|
+
else
|
42
|
+
f.html{render :not_found}
|
43
|
+
f.json{render :not_found}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def new
|
49
|
+
require_permission :create
|
50
|
+
@model = model_class.new
|
51
|
+
|
52
|
+
respond_to do |f|
|
53
|
+
f.js
|
54
|
+
f.json{render json: @model}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def create
|
59
|
+
require_permission :create
|
60
|
+
@model = model_class.new params.model
|
61
|
+
|
62
|
+
respond_to do |f|
|
63
|
+
if @model.save
|
64
|
+
flash.info = t :"#{model_class.alias.underscore}_created"
|
65
|
+
|
66
|
+
f.js{redirect_to(path(@model))}
|
67
|
+
f.json{render json: @model}
|
68
|
+
else
|
69
|
+
f.js{render action: :new}
|
70
|
+
f.json{render json: {errors: @model.errors}, status: :failed}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def edit
|
76
|
+
require_permission :update, @model
|
77
|
+
|
78
|
+
respond_to do |f|
|
79
|
+
f.js
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def update
|
84
|
+
require_permission :update, @model
|
85
|
+
|
86
|
+
respond_to do |f|
|
87
|
+
if @model.set(params.model).save
|
88
|
+
flash.info = t :"#{model_class.alias.underscore}_updated"
|
89
|
+
|
90
|
+
f.js
|
91
|
+
f.json{render :ok}
|
92
|
+
else
|
93
|
+
f.js{render action: :edit}
|
94
|
+
f.json{render json: {errors: @model.errors}, status: :failed}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def destroy
|
100
|
+
require_permission :destroy, @model
|
101
|
+
@model.destroy
|
102
|
+
flash.info = t :"#{model_class.alias.underscore}_destroyed"
|
103
|
+
|
104
|
+
respond_to do |f|
|
105
|
+
f.js{redirect_to(default_path)}
|
106
|
+
f.json{render :ok}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def all
|
111
|
+
respond_to do |f|
|
112
|
+
@page, @per_page = (params.page || 1).to_i, Models::Item::PER_PAGE
|
113
|
+
|
114
|
+
query = self.class.model_class.where(viewers: {_in: rad.user.major_roles}, dependent: {_exists: false})
|
115
|
+
query = query.where tags: {_all: selected_tags} unless selected_tags.empty?
|
116
|
+
@models = query.sort([:created_at, -1]).paginate(@page, @per_page).all
|
117
|
+
|
118
|
+
f.html{@html_title = rad.config.title}
|
119
|
+
f.json{render json: @models}
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
#
|
125
|
+
# Viewers and Collaborators
|
126
|
+
#
|
127
|
+
def viewers
|
128
|
+
require_permission :update_access, @model
|
129
|
+
remove_roles = (params.remove_roles || '').split("\n")
|
130
|
+
add_roles = (params.add_roles || '').split("\n")
|
131
|
+
partials.show :context_menu
|
132
|
+
|
133
|
+
remove_roles.each{|role| @model.remove_viewer role}
|
134
|
+
add_roles.each{|role| @model.add_viewer role}
|
135
|
+
|
136
|
+
respond_to do |format|
|
137
|
+
if @model.save
|
138
|
+
flash.info = t :viewers_updated
|
139
|
+
|
140
|
+
format.js{render action: :access} # "models/access"
|
141
|
+
format.json{render :ok}
|
142
|
+
else
|
143
|
+
flash.info = t :failed
|
144
|
+
|
145
|
+
format.js{render action: :access} # "models/access"
|
146
|
+
format.json{render :failed}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def collaborators
|
152
|
+
require_permission :update_access, @model
|
153
|
+
remove_roles = (params.remove_roles || '').split("\n")
|
154
|
+
add_roles = (params.add_roles || '').split("\n")
|
155
|
+
partials.show :context_menu
|
156
|
+
|
157
|
+
remove_roles.each{|role| @model.remove_collaborator role}
|
158
|
+
add_roles.each{|role| @model.add_collaborator role}
|
159
|
+
|
160
|
+
respond_to do |format|
|
161
|
+
if @model.save
|
162
|
+
flash.info = t :collaborators_updated
|
163
|
+
|
164
|
+
format.js{render action: :access} # "models/access"
|
165
|
+
format.json{render :ok}
|
166
|
+
else
|
167
|
+
flash.info = t :failed
|
168
|
+
|
169
|
+
format.js{render action: :access} # "models/access"
|
170
|
+
format.json{render :failed}
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
#
|
177
|
+
# Layout
|
178
|
+
#
|
179
|
+
def layout
|
180
|
+
require_permission :update, @model
|
181
|
+
|
182
|
+
@model.layout = params.value
|
183
|
+
|
184
|
+
respond_to do |format|
|
185
|
+
if @model.save
|
186
|
+
flash.info = t :layout_updated
|
187
|
+
|
188
|
+
format.js{reload_page}
|
189
|
+
format.json{render :ok}
|
190
|
+
else
|
191
|
+
flash.info = t :failed
|
192
|
+
|
193
|
+
format.js{}
|
194
|
+
format.json{render :failed}
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
#
|
201
|
+
# model_class
|
202
|
+
#
|
203
|
+
def self.model_class
|
204
|
+
@model_class ||= "Models::#{self.alias.singularize}".constantize
|
205
|
+
end
|
206
|
+
def model_class; self.class.model_class end
|
207
|
+
helper_method :model_class
|
208
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Authorization
|
2
|
+
def viewers_controls_for object
|
3
|
+
object.must_not_be.nil
|
4
|
+
|
5
|
+
all_selected_roles = []
|
6
|
+
all_avaliable_roles = []
|
7
|
+
|
8
|
+
# Ordinary Roles
|
9
|
+
controls = {
|
10
|
+
'member' => link_to(
|
11
|
+
t(:member_role),
|
12
|
+
viewers_path(object, remove_roles: 'user', add_roles: 'member', format: :js), method: :post
|
13
|
+
),
|
14
|
+
'user' => link_to(
|
15
|
+
t(:user_role),
|
16
|
+
viewers_path(object, remove_roles: 'member', add_roles: 'user', format: :js), method: :post
|
17
|
+
),
|
18
|
+
}
|
19
|
+
|
20
|
+
selected_role = Role.lower_role object.viewers
|
21
|
+
selected_role = nil if selected_role == 'manager'
|
22
|
+
avaliable_roles = Role::ORDERED_ROLES.select{|role| role != selected_role and role != 'manager'}
|
23
|
+
avaliable_roles = avaliable_roles.collect{|role| controls[role]}
|
24
|
+
|
25
|
+
all_selected_roles << t("#{selected_role}_role") if selected_role
|
26
|
+
all_avaliable_roles.push *avaliable_roles
|
27
|
+
|
28
|
+
# Custom Roles
|
29
|
+
custom_roles = rad.config.custom_roles
|
30
|
+
selected_roles = custom_roles.select{|role| object.viewers.include? role}
|
31
|
+
avaliable_roles = custom_roles - selected_roles
|
32
|
+
|
33
|
+
# selected_roles.collect! do |role|
|
34
|
+
# link_to(role, viewers_path(object, remove_roles: role, format: :js), method: :post)
|
35
|
+
# end
|
36
|
+
avaliable_roles.collect! do |role|
|
37
|
+
link_to(role, viewers_path(object, add_roles: role, format: :js), method: :post)
|
38
|
+
end
|
39
|
+
|
40
|
+
all_selected_roles.push *selected_roles
|
41
|
+
all_avaliable_roles.push *avaliable_roles
|
42
|
+
|
43
|
+
# Clear All
|
44
|
+
if all_selected_roles.blank?
|
45
|
+
all_selected_roles << t(:only_owner)
|
46
|
+
else
|
47
|
+
current_roles = object.viewers.select{|r| r != 'manager' and r != "user:#{object.owner_name}"}
|
48
|
+
all_avaliable_roles.unshift(
|
49
|
+
link_to(
|
50
|
+
t(:only_owner),
|
51
|
+
viewers_path(object, remove_roles: current_roles.join("\n"), format: :js), method: :post
|
52
|
+
)
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
[
|
57
|
+
%[#{t(:viewers)}: <span class='m_bold'>#{all_selected_roles.join(', ')}</span>],
|
58
|
+
%[<span class='m_tiny'>(#{all_avaliable_roles.join(', ')})</span>]
|
59
|
+
]
|
60
|
+
end
|
61
|
+
|
62
|
+
def collaborators_controls_for object
|
63
|
+
object.must_not_be.nil
|
64
|
+
|
65
|
+
all_selected_roles = []
|
66
|
+
all_avaliable_roles = []
|
67
|
+
|
68
|
+
# Ordinary Roles
|
69
|
+
controls = {
|
70
|
+
'member' => link_to(
|
71
|
+
t(:member_role),
|
72
|
+
collaborators_path(object, remove_roles: 'user', add_roles: 'member', format: :js), method: :post
|
73
|
+
),
|
74
|
+
'user' => link_to(
|
75
|
+
t(:user_role),
|
76
|
+
collaborators_path(object, remove_roles: 'member', add_roles: 'user', format: :js), method: :post
|
77
|
+
),
|
78
|
+
}
|
79
|
+
|
80
|
+
selected_role = Role.lower_role object.collaborators
|
81
|
+
selected_role = nil if selected_role == 'manager'
|
82
|
+
avaliable_roles = Role::ORDERED_ROLES.select{|role| role != selected_role and role != 'manager'}
|
83
|
+
avaliable_roles = avaliable_roles.collect{|role| controls[role]}
|
84
|
+
|
85
|
+
all_selected_roles << t("#{selected_role}_role") if selected_role
|
86
|
+
all_avaliable_roles.push *avaliable_roles
|
87
|
+
|
88
|
+
# Custom Roles
|
89
|
+
custom_roles = rad.config.custom_roles
|
90
|
+
selected_roles = custom_roles.select{|role| object.collaborators.include? role}
|
91
|
+
avaliable_roles = custom_roles - selected_roles
|
92
|
+
|
93
|
+
# selected_roles.collect! do |role|
|
94
|
+
# link_to(role, collaborators_path(object, remove_roles: role, format: :js), method: :post)
|
95
|
+
# end
|
96
|
+
avaliable_roles.collect! do |role|
|
97
|
+
link_to(role, collaborators_path(object, add_roles: role, format: :js), method: :post)
|
98
|
+
end
|
99
|
+
|
100
|
+
all_selected_roles.push *selected_roles
|
101
|
+
all_avaliable_roles.push *avaliable_roles
|
102
|
+
|
103
|
+
# Clear All
|
104
|
+
if all_selected_roles.blank?
|
105
|
+
all_selected_roles << t(:only_owner)
|
106
|
+
else
|
107
|
+
current_roles = object.collaborators.select{|r| r != 'manager' and r != "user:#{object.owner_name}"}
|
108
|
+
all_avaliable_roles.unshift(
|
109
|
+
link_to(
|
110
|
+
t(:only_owner),
|
111
|
+
collaborators_path(object, remove_roles: current_roles.join("\n"), format: :js), method: :post
|
112
|
+
)
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
[
|
117
|
+
%[#{t(:collaborators)}: <span class='m_bold'>#{all_selected_roles.join(', ')}</span>],
|
118
|
+
%[<span class='m_tiny'>(#{all_avaliable_roles.join(', ')})</span>]
|
119
|
+
]
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Captcha
|
2
|
+
def captcha_tag
|
3
|
+
return "" if rad.test?
|
4
|
+
|
5
|
+
captcha_html = recaptcha_tags public_key: config.recaptcha[:public_key],
|
6
|
+
display: {theme: :custom, custom_theme_widget: 'recaptcha_widget'}
|
7
|
+
|
8
|
+
render "/kit/captcha", locals: {captcha_html: captcha_html}
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module ControllerHelper
|
2
|
+
inherited do
|
3
|
+
helper_method :partials
|
4
|
+
end
|
5
|
+
|
6
|
+
class Partials
|
7
|
+
attr_reader :controller
|
8
|
+
|
9
|
+
def initialize controller
|
10
|
+
@controller = controller
|
11
|
+
end
|
12
|
+
|
13
|
+
def show? name
|
14
|
+
partials.include? name
|
15
|
+
end
|
16
|
+
|
17
|
+
def hide? name
|
18
|
+
!show?(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def show name
|
22
|
+
partials[name] = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def hide name
|
26
|
+
partials.delete name
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
def partials; controller.send(:_partials) end
|
31
|
+
end
|
32
|
+
|
33
|
+
def _partials
|
34
|
+
@_partials ||= {}
|
35
|
+
end
|
36
|
+
protected :_partials
|
37
|
+
|
38
|
+
def partials &block
|
39
|
+
if block
|
40
|
+
partials.instance_eval &block
|
41
|
+
else
|
42
|
+
@partials ||= ::Helpers::Kit::ControllerHelper::Partials.new self
|
43
|
+
end
|
44
|
+
end
|
45
|
+
protected :partials
|
46
|
+
|
47
|
+
module ClassMethods
|
48
|
+
class Partials
|
49
|
+
attr_reader :controller_class
|
50
|
+
|
51
|
+
def initialize controller_class
|
52
|
+
@controller_class = controller_class
|
53
|
+
end
|
54
|
+
|
55
|
+
def show name, options = {}
|
56
|
+
controller_class.send :before, options do |controller|
|
57
|
+
controller.send(:_partials)[name] = true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def hide name, options = {}
|
62
|
+
controller_class.send :before, options do |controller|
|
63
|
+
controller.send(:_partials).delete name
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def partials &block
|
69
|
+
if block
|
70
|
+
partials.instance_eval &block
|
71
|
+
else
|
72
|
+
@partials ||= ::Helpers::Kit::ControllerHelper::ClassMethods::Partials.new self
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module ItemHelper
|
2
|
+
|
3
|
+
#
|
4
|
+
# Tag Selector
|
5
|
+
#
|
6
|
+
def add_tag name
|
7
|
+
(selected_tags + [name]).join('-')
|
8
|
+
end
|
9
|
+
|
10
|
+
def remove_tag name
|
11
|
+
list = (selected_tags - [name]).join('-')
|
12
|
+
return nil if list.empty?
|
13
|
+
list
|
14
|
+
end
|
15
|
+
|
16
|
+
def render_item_tags item
|
17
|
+
# Tags
|
18
|
+
|
19
|
+
tags = item.tags.topic.collect{|tag_name| tag_link tag_name}
|
20
|
+
|
21
|
+
# Visibility
|
22
|
+
viewers = item.minor_viewers
|
23
|
+
owner_role = "user:#{item.owner_name}"
|
24
|
+
viewers = viewers.select{|role| role != owner_role}
|
25
|
+
if viewers.blank? # visible only to owner
|
26
|
+
tags << tag(:div, t(:owner_visibility), class: :m_owner_visibility)
|
27
|
+
else
|
28
|
+
viewers.each do |role|
|
29
|
+
if role == 'user'
|
30
|
+
# don't show public visibility
|
31
|
+
elsif role == 'member'
|
32
|
+
tags << tag(:div, t(:member_visibility), class: :m_member_visibility)
|
33
|
+
else
|
34
|
+
tags << tag(:div, role, class: :m_custom_visibility)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
tags
|
40
|
+
end
|
41
|
+
|
42
|
+
def tag_link tag_name, count = nil
|
43
|
+
# link = if current_item and current_item.is_a?(Selector)
|
44
|
+
# url_for(action_name, _tags: tag_name)
|
45
|
+
# else
|
46
|
+
# items_path(_tags: tag_name)
|
47
|
+
# end
|
48
|
+
|
49
|
+
link = items_path(_tags: tag_name)
|
50
|
+
|
51
|
+
if count
|
52
|
+
link_to(tag_name, link, title: t(:tags_count, count: count))
|
53
|
+
else
|
54
|
+
link_to(tag_name, link)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def render_item_details item, opt = {}
|
59
|
+
skip = Array(opt[:skip])
|
60
|
+
|
61
|
+
item.must_be.a Models::Item
|
62
|
+
details = []
|
63
|
+
details << item.created_at.time_ago_in_words unless skip.include? :created_at
|
64
|
+
details << t(:created_by, owner: link_to(item.owner_name, user_path(item.owner_name))) unless skip.include? :owner
|
65
|
+
details << t(:comments_count, count: item.comments_count) if item.comments_count > 0 and !skip.include?(:comments)
|
66
|
+
details
|
67
|
+
end
|
68
|
+
|
69
|
+
def form_title_for item
|
70
|
+
# return if embedded? or !item.new_record?
|
71
|
+
return unless item.new_record?
|
72
|
+
|
73
|
+
model_name = item.class.alias.underscore
|
74
|
+
t "create_#{model_name}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def common_fields_for_item form, opt = {}, &extra_fields
|
78
|
+
object = form.model #instance_variable_get '@object'
|
79
|
+
skip = Array(opt[:skip])
|
80
|
+
|
81
|
+
html = ""
|
82
|
+
html << form.text_field(:topics_as_string, label: t(:tags)) unless skip.include? :tags
|
83
|
+
more = ""
|
84
|
+
unless skip.include? :slug
|
85
|
+
slug_opt = object.new_record? ? {label: t(:slug)} : {label: t(:slug), description: t(:slug_description)}
|
86
|
+
# more << form.text_field(:slug, (object.new_record? ? '' : object.slug), slug_opt)
|
87
|
+
more << form.text_field(:slug, slug_opt)
|
88
|
+
end
|
89
|
+
more << capture(&extra_fields) if extra_fields
|
90
|
+
html << b.more(id: "form_for_#{object.class.name.underscore}", name: t(:show_more), 'content' => more)
|
91
|
+
# if extra_fields
|
92
|
+
# html << capture{b.more(id: "form_for_#{object.class.name.underscore}", name: t(:show_more), &extra_fields)}
|
93
|
+
# else
|
94
|
+
|
95
|
+
if extra_fields
|
96
|
+
concat html
|
97
|
+
else
|
98
|
+
html
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def item_layout_selector
|
103
|
+
current = (@model.layout || :default).to_sym
|
104
|
+
layouts = rad.face.availiable_layouts[theme.name] || []
|
105
|
+
layouts << current unless layouts.include? current
|
106
|
+
|
107
|
+
html_options = {class: 'm_autosubmit_on_change', 'data-action' => layout_path(@model, format: :js), 'data-remote' => true}
|
108
|
+
"#{t(:layout)}: #{select_tag(:layout, current, layouts.collect{|l| [l, l]}, html_options)}"
|
109
|
+
end
|
110
|
+
end
|