rad_kit 0.0.9 → 0.0.10
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/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
|