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.
Files changed (61) hide show
  1. data/Rakefile +3 -2
  2. data/app/controllers/app.rb +5 -0
  3. data/app/controllers/base.rb +47 -0
  4. data/app/controllers/base_app.rb +18 -0
  5. data/app/controllers/comments.rb +49 -0
  6. data/app/controllers/items.rb +208 -0
  7. data/app/helpers/kit/authorization.rb +121 -0
  8. data/app/helpers/kit/captcha.rb +10 -0
  9. data/app/helpers/kit/controller_helper.rb +76 -0
  10. data/app/helpers/kit/item_helper.rb +110 -0
  11. data/app/helpers/kit/navigation_helper.rb +15 -0
  12. data/app/helpers/kit/pagination.rb +62 -0
  13. data/app/models/_item/attachments.rb +15 -0
  14. data/app/models/_item/container.rb +30 -0
  15. data/app/models/_item/slug.rb +28 -0
  16. data/app/models/attachment.rb +9 -0
  17. data/app/models/comment.rb +30 -0
  18. data/app/models/item.rb +136 -0
  19. data/app/models/secure_token.rb +45 -0
  20. data/app/models/tag.rb +71 -0
  21. data/app/static/kit/highlight.css +48 -0
  22. data/app/static/kit.css +3 -0
  23. data/app/static/kit.js +0 -0
  24. data/app/static/themes/default/objects.less +28 -0
  25. data/app/views/controllers/comments/_embedded.html.haml +13 -0
  26. data/app/views/controllers/comments/_form.html.haml +8 -0
  27. data/app/views/controllers/comments/actions.js.haml +22 -0
  28. data/app/views/controllers/comments/show.html.haml +11 -0
  29. data/app/views/controllers/items/_items.html.haml +2 -0
  30. data/app/views/controllers/items/actions.js.haml +23 -0
  31. data/app/views/controllers/items/all.html.haml +4 -0
  32. data/app/views/controllers/items/inherited_action.html.haml +1 -0
  33. data/app/views/kit/_bottom_panel.html.haml +9 -0
  34. data/app/views/kit/_debug.html.haml +13 -0
  35. data/app/views/kit/_messages.html.haml +4 -0
  36. data/app/views/kit/_navigation.html.haml +19 -0
  37. data/app/views/kit/_not_found.html.haml +1 -0
  38. data/app/views/kit/_top_panel.html.haml +19 -0
  39. data/app/views/kit/_web_analytics.html.erb +14 -0
  40. data/app/views/kit/aspects/_comments.html.haml +8 -0
  41. data/app/views/kit/captcha/_action.js.haml +2 -0
  42. data/app/views/kit/captcha/_form.html.haml +10 -0
  43. data/app/views/kit/layout.html.haml +22 -0
  44. data/app/views/kit/layout.js.haml +15 -0
  45. data/app/views/previews/_line.html.haml +8 -0
  46. data/app/views/previews/_thumb.html.haml +5 -0
  47. data/app/views/themes/default/file.html.haml +19 -0
  48. data/app/views/themes/default/folder.html.haml +15 -0
  49. data/app/views/themes/default/layout_definitions/default.yml +27 -0
  50. data/app/views/themes/default/list.html.haml +21 -0
  51. data/app/views/themes/default/list_item.html.haml +14 -0
  52. data/app/views/themes/default/page.html.haml +23 -0
  53. data/app/views/tools/_access.html.haml +12 -0
  54. data/app/views/tools/_buttons.html.haml +11 -0
  55. data/app/views/tools/_context_menu.html.haml +12 -0
  56. data/app/views/tools/_search.html.haml +5 -0
  57. data/app/views/tools/_tags.html.haml +10 -0
  58. data/config/locales/en.yml +136 -0
  59. data/config/locales/ru.yml +142 -0
  60. data/config/routes.rb +44 -0
  61. metadata +82 -23
@@ -0,0 +1,62 @@
1
+ module Pagination
2
+ def paginator_for page, entries_count, per_page, &to_link
3
+ page.must_be >= 1
4
+ return if page == 1 and entries_count < per_page
5
+
6
+ opt = {
7
+ current_page: page,
8
+ pages: [], #(go_prev + [current] + go_next),
9
+ to_link: to_link
10
+ }
11
+
12
+ opt[:prev] = to_link.call(t(:go_prev), page - 1) if page > 1
13
+ opt[:next] = to_link.call(t(:go_next), page + 1)
14
+
15
+ b.paginator opt
16
+ end
17
+
18
+ # PAGINATOR_HALF_SIZE = 3
19
+ #
20
+ # def paginator_for current, total_entries, per_page, &to_link
21
+ # return "" if total_entries <= per_page
22
+ # total = (total_entries / (1.0 * per_page)).ceil
23
+ #
24
+ # from = current
25
+ # if current > 1
26
+ # from = current - PAGINATOR_HALF_SIZE
27
+ # if (right_size = total - current) < PAGINATOR_HALF_SIZE
28
+ # from -= (PAGINATOR_HALF_SIZE - right_size)
29
+ # end
30
+ # from = 1 if from < 0
31
+ # end
32
+ #
33
+ # to = current
34
+ # if current < total_entries
35
+ # to = current + PAGINATOR_HALF_SIZE
36
+ # if (left_size = current - 1) < PAGINATOR_HALF_SIZE
37
+ # to += (PAGINATOR_HALF_SIZE - left_size)
38
+ # end
39
+ # to = total if to > total
40
+ # end
41
+ #
42
+ # go_prev, go_next = [], []
43
+ # (from..to).each do |n|
44
+ # if n < current
45
+ # go_prev << to_link.call(n.to_s, n)
46
+ # elsif n > current
47
+ # go_next << to_link.call(n.to_s, n)
48
+ # end
49
+ # end
50
+ #
51
+ # opt = {
52
+ # current_page: current,
53
+ # pages: (go_prev + [current] + go_next),
54
+ # to_link: to_link
55
+ # }
56
+ #
57
+ # opt[:prev] = to_link.call(t(:go_prev), current - 1) if current > 1
58
+ # opt[:next] = to_link.call(t(:go_next), current + 1) if current < total
59
+ #
60
+ # b.paginator opt
61
+ # end
62
+ end
@@ -0,0 +1,15 @@
1
+ class Models::Item
2
+ def attachments
3
+ @attachments ||= []
4
+ end
5
+ mount_attachments(:attachments, :file){Models::Attachment.new}
6
+
7
+ assign :attachments_as_attachments, true
8
+
9
+ def attachments_as_images
10
+ # TODO3 remove sorting, use order defined in database
11
+ _cache[:attachments_as_images] ||= attachments.
12
+ sort{|a, b| a.file.name <=> b.file.name}.
13
+ collect{|o| {name: o.file.name, url: o.file.url, thumb_url: o.file.thumb.url, icon_url: o.file.icon.url}.to_openobject}
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ class Models::Item
2
+ attr_accessor :dependent
3
+ def dependent?; !!dependent end
4
+ def independent?; !dependent? end
5
+ def independent!; remove_instance_variable :@dependent end
6
+ def dependent!; self.dependent = true end
7
+
8
+
9
+ # field :dependent, type: Boolean, default: false # Indicates wheter or not Item depends on Container
10
+ # has_many :containers, class_name: 'Models::Item', foreign_key: :item_ids
11
+ #
12
+ # CONTAINER_INHERITABLE_ATTRIBUTES = %w{owner_name viewers collaborators}
13
+ # def inherit_container_attributes container, attributes = CONTAINER_INHERITABLE_ATTRIBUTES
14
+ # attributes.each{|attr| send "#{attr}=", container.send(attr)}
15
+ # end
16
+ #
17
+ # # serches independent container for this item (used in search)
18
+ # def independent_container
19
+ # unless independent_container = cache[:independent_container]
20
+ # if independent?
21
+ # independent_container = self
22
+ # else
23
+ # independent_container = containers.first
24
+ # raise "this dependent item dosn't have container!" unless independent_container
25
+ # end
26
+ # cache[:independent_container] = independent_container
27
+ # end
28
+ # independent_container
29
+ # end
30
+ end
@@ -0,0 +1,28 @@
1
+ class Models::Item
2
+ attr_writer :slug
3
+ def slug
4
+ @slug ||= generate_slug
5
+ end
6
+ before_create :slug
7
+ assign :slug, String, true
8
+
9
+ rad.extension :item_slug, self do
10
+ validates_uniqueness_of :slug
11
+ end
12
+
13
+ validates_format_of :slug, with: /^[0-9a-z\-]+$/
14
+ validates_presence_of :slug
15
+
16
+ def self.by_param! param
17
+ by_param(param) || raise(Mongo::NotFound, "object with slug #{param} not found!")
18
+ end
19
+
20
+ def self.by_param param
21
+ self.by_slug(param) || (BSON::ObjectId.legal?(param) && self.by_id(param))
22
+ end
23
+
24
+ protected
25
+ def generate_slug
26
+ "#{name.blank? ? String.random(6) : name.to_url[0..50]}-#{String.random}" #UUIDTools::UUID.random_create.hexdigest[0,6]
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ class Attachment
2
+ inherit Mongo::Model, Mongo::Model::FileModel
3
+
4
+ # embedded_in :item, class_name: 'Models::Item'
5
+ # attr_accessor :main_id
6
+ # validates_presence_of :main_id
7
+
8
+ mount_file :file, AttachmentFile
9
+ end
@@ -0,0 +1,30 @@
1
+ class Comment < Item
2
+
3
+ attr_accessor :item_id
4
+ validates_presence_of :item_id
5
+ def item= item
6
+ self.item_id = item._id
7
+ _cache[:item] = item
8
+ end
9
+ def item
10
+ _cache[:item] ||= Item.by_id item_id
11
+ end
12
+
13
+ after_create do |m|
14
+ Item.update({_id: m.item_id}, {_inc: {comments_count: 1}})
15
+ end
16
+ after_destroy do |m|
17
+ Item.update({_id: m.item_id}, {_inc: {comments_count: -1}})
18
+ end
19
+
20
+ available_as_markup :text
21
+ assign :original_text, String, true
22
+ validates_presence_of :text
23
+
24
+ before_save{|m| m.dependent!}
25
+
26
+ # TODO3 search
27
+ # searchable do
28
+ # text :text, using: :text_as_text
29
+ # end
30
+ end
@@ -0,0 +1,136 @@
1
+ class Item
2
+ inherit Mongo::Model
3
+ collection :items
4
+
5
+ rad.extension :item_model, self
6
+
7
+ # key :_id, String
8
+ # field :_type, String
9
+
10
+ #
11
+ # General Attributes
12
+ #
13
+ attr_accessor :name, :text
14
+ assign do
15
+ name String, true
16
+ text String, true
17
+ end
18
+
19
+ timestamps!
20
+
21
+
22
+ #
23
+ # Aspects
24
+ #
25
+ # TODO1 add support for security inheritance for comments
26
+ def comments
27
+ Comment.query({item_id: _id}, {sort: [[:created_at, -1]]})
28
+ end
29
+ after_destroy{|m| m.comments.each(&:destroy!)}
30
+
31
+ attr_writer :comments_count
32
+ def comments_count; @comments_count ||= 0 end
33
+
34
+
35
+ #
36
+ # Tags
37
+ #
38
+ inherit Models::TagsMixin
39
+
40
+ #
41
+ # Authorized Object
42
+ #
43
+ inherit Models::AuthorizedObject
44
+
45
+
46
+ #
47
+ # TextProcessor
48
+ #
49
+ inherit Mongo::Model::TextProcessor
50
+
51
+
52
+ #
53
+ # Identity
54
+ #
55
+ def to_param; slug end
56
+
57
+
58
+ #
59
+ # Teaser
60
+ #
61
+ TEASER_LENGTH = 350
62
+ def teaser
63
+ generate_teaser! unless @teaser
64
+ @teaser
65
+ end
66
+ attr_writer :teaser
67
+
68
+ def generate_teaser!
69
+ self.teaser = TextUtils.truncate text, TEASER_LENGTH if text # if new_record? or teaser_changed?
70
+ end
71
+ before_save :generate_teaser!
72
+
73
+
74
+ #
75
+ # Indexing
76
+ #
77
+ # TODO3 search
78
+ # include Sunspot::MongoMapper::Searchable
79
+ # searchable do
80
+ # text :name, stored: true, boost: 2.0
81
+ # text :teaser, stored: true
82
+ #
83
+ # string :tags, multiple: true
84
+ # string :dependent
85
+ # # string :model_name
86
+ # string :viewers, multiple: true
87
+ # time :created_at
88
+ # time :updated_at
89
+ #
90
+ # string(:space_id){space_id.to_s}
91
+ # string(:account_id){account_id.to_s}
92
+ # end
93
+
94
+
95
+ #
96
+ # Theme layout support
97
+ #
98
+ attr_accessor :layout
99
+ assign :layout, String, true
100
+
101
+
102
+ #
103
+ # Other
104
+ #
105
+ PER_PAGE = 14
106
+
107
+ # def inspect
108
+ # %{#<#{self.class.name} name: "#{name}", #{"slug: #{slug}, " unless slug.blank?}_id: #{_id}>}
109
+ # end
110
+ #
111
+ # def to_s
112
+ # inspect
113
+ # end
114
+
115
+ ALLOWED_KEYS = %w{
116
+ id _type slug
117
+ name text tags dependent
118
+ owner_name viewers
119
+ created_at updated_at
120
+ }
121
+ def to_json options = {}
122
+ options = options.symbolize_keys
123
+ options[:only] = ((options[:only] || []) + ALLOWED_KEYS).uniq
124
+
125
+ # TODO3 files
126
+ # options[:methods] = ((options[:methods] || []) + [:icon_url]).uniq
127
+
128
+ super options
129
+ end
130
+ end
131
+
132
+
133
+ #
134
+ # Helpers
135
+ #
136
+ Dir.glob("#{__FILE__.dirname}/_item/*.rb").each{|path| load path}
@@ -0,0 +1,45 @@
1
+ class SecureToken
2
+ inherit Mongo::Model
3
+ # TODO3 rename to :tokens
4
+ collection :secure_tokens
5
+
6
+ EXPIRES_IN = 30
7
+
8
+ rad.extension :secure_token, self
9
+
10
+ # attr_writer :values
11
+ # def values; @values ||= {} end
12
+ def [] k
13
+ instance_variable_get :"@#{k}"
14
+ end
15
+ def []= k, v
16
+ instance_variable_set :"@#{k}", v
17
+ end
18
+
19
+ attr_writer :token
20
+ def token; @token ||= String.secure_token end
21
+ validates_presence_of :token
22
+
23
+ attr_writer :expires_at
24
+ def expires_at; @expires_at ||= EXPIRES_IN.minutes.from_now end
25
+ validates_presence_of :expires_at
26
+
27
+ timestamps!
28
+
29
+ def expired?
30
+ expires_at >= Time.now.utc
31
+ end
32
+
33
+ class << self
34
+ def by_token token
35
+ return nil if token.blank?
36
+ first token: token, expires_at: {_gte: Time.now.utc}
37
+ end
38
+ alias_method :first_by_token, :by_token
39
+
40
+ def by_token! token
41
+ return by_token(token) || raise(Mongo::NotFound, "token #{token} not found!")
42
+ end
43
+ alias_method :first_by_token!, :by_token!
44
+ end
45
+ end
data/app/models/tag.rb ADDED
@@ -0,0 +1,71 @@
1
+ class Tag
2
+ inherit Mongo::Model
3
+ collection :tags
4
+
5
+ rad.extension :tag_model, self
6
+
7
+ FORBIDDEN_CHARACTERS = /<>,/
8
+ TAG_LIST_DELIMITER = ','
9
+
10
+ attr_accessor :name, :count
11
+ assign :name, String, true
12
+ validates_presence_of :name, :count
13
+ validate :validate_name
14
+
15
+ attr_reader :context
16
+ def context
17
+ if name.to_s =~ /:/
18
+ @context = name.split(/:/).first
19
+ else
20
+ remove_instance_variable :@context if instance_variable_defined? :@context
21
+ nil
22
+ end
23
+ end
24
+ before_save :context
25
+
26
+ def update_count!
27
+ new_count = Item.count tags: {_in: [name]}
28
+ unless count == new_count
29
+ self.count = new_count
30
+ self.save!
31
+ end
32
+ end
33
+
34
+ class << self
35
+ def valid_name? name
36
+ name.present? and name !~ FORBIDDEN_CHARACTERS
37
+ end
38
+
39
+ def create_tags! tags
40
+ tags.each do |name|
41
+ if tag = Tag.by_name(name)
42
+ # TODO3 preformance lost
43
+ tag.update_count!
44
+ else
45
+ tag = Tag.new name: name
46
+ tag.count = 1
47
+ tag.save!
48
+ end
49
+ end
50
+ end
51
+
52
+ def update_tags! before, after
53
+ create_tags! after - before
54
+ delete_tags! before - after
55
+ end
56
+
57
+ def delete_tags! tags
58
+ tags.each do |name|
59
+ if tag = Tag.by_name(name)
60
+ tag.update_count!
61
+ tag.destroy if tag.count == 0
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ protected
68
+ def validate_name
69
+ errors.add :name, t(:invalid_tag_name) unless Tag.valid_name?(name)
70
+ end
71
+ end
@@ -0,0 +1,48 @@
1
+ .hl_highlight * {font-family: courier, monospace !important;}
2
+
3
+ .hl_hll { background-color: #ffffcc }
4
+ .hl_c { color: #008800; font-style: italic } /* Comment */
5
+ .hl_err { color: #a61717; background-color: #e3d2d2 } /* Error */
6
+ .hl_k { color: #000080; font-weight: bold } /* Keyword */
7
+ .hl_cm { color: #008800; font-style: italic } /* Comment.hl_Multiline */
8
+ .hl_cp { color: #008080 } /* Comment.hl_Preproc */
9
+ .hl_c1 { color: #008800; font-style: italic } /* Comment.hl_Single */
10
+ .hl_cs { color: #008800; font-weight: bold } /* Comment.hl_Special */
11
+ .hl_gd { color: #000000; background-color: #ffdddd } /* Generic.hl_Deleted */
12
+ .hl_ge { font-style: italic } /* Generic.hl_Emph */
13
+ .hl_gr { color: #aa0000 } /* Generic.hl_Error */
14
+ .hl_gh { color: #999999 } /* Generic.hl_Heading */
15
+ .hl_gi { color: #000000; background-color: #ddffdd } /* Generic.hl_Inserted */
16
+ .hl_go { color: #888888 } /* Generic.hl_Output */
17
+ .hl_gp { color: #555555 } /* Generic.hl_Prompt */
18
+ .hl_gs { font-weight: bold } /* Generic.hl_Strong */
19
+ .hl_gu { color: #aaaaaa } /* Generic.hl_Subheading */
20
+ .hl_gt { color: #aa0000 } /* Generic.hl_Traceback */
21
+ .hl_kc { color: #000080; font-weight: bold } /* Keyword.hl_Constant */
22
+ .hl_kd { color: #000080; font-weight: bold } /* Keyword.hl_Declaration */
23
+ .hl_kn { color: #000080; font-weight: bold } /* Keyword.hl_Namespace */
24
+ .hl_kp { color: #000080; font-weight: bold } /* Keyword.hl_Pseudo */
25
+ .hl_kr { color: #000080; font-weight: bold } /* Keyword.hl_Reserved */
26
+ .hl_kt { color: #000080; font-weight: bold } /* Keyword.hl_Type */
27
+ .hl_m { color: #0000FF } /* Literal.hl_Number */
28
+ .hl_s { color: #0000FF } /* Literal.hl_String */
29
+ .hl_na { color: #FF0000 } /* Name.hl_Attribute */
30
+ .hl_nt { color: #000080; font-weight: bold } /* Name.hl_Tag */
31
+ .hl_ow { font-weight: bold } /* Operator.hl_Word */
32
+ .hl_w { color: #bbbbbb } /* Text.hl_Whitespace */
33
+ .hl_mf { color: #0000FF } /* Literal.hl_Number.hl_Float */
34
+ .hl_mh { color: #0000FF } /* Literal.hl_Number.hl_Hex */
35
+ .hl_mi { color: #0000FF } /* Literal.hl_Number.hl_Integer */
36
+ .hl_mo { color: #0000FF } /* Literal.hl_Number.hl_Oct */
37
+ .hl_sb { color: #0000FF } /* Literal.hl_String.hl_Backtick */
38
+ .hl_sc { color: #800080 } /* Literal.hl_String.hl_Char */
39
+ .hl_sd { color: #0000FF } /* Literal.hl_String.hl_Doc */
40
+ .hl_s2 { color: #0000FF } /* Literal.hl_String.hl_Double */
41
+ .hl_se { color: #0000FF } /* Literal.hl_String.hl_Escape */
42
+ .hl_sh { color: #0000FF } /* Literal.hl_String.hl_Heredoc */
43
+ .hl_si { color: #0000FF } /* Literal.hl_String.hl_Interpol */
44
+ .hl_sx { color: #0000FF } /* Literal.hl_String.hl_Other */
45
+ .hl_sr { color: #0000FF } /* Literal.hl_String.hl_Regex */
46
+ .hl_s1 { color: #0000FF } /* Literal.hl_String.hl_Single */
47
+ .hl_ss { color: #0000FF } /* Literal.hl_String.hl_Symbol */
48
+ .hl_il { color: #0000FF } /* Literal.hl_Number.hl_Integer.hl_Long */
@@ -0,0 +1,3 @@
1
+ /*
2
+ rad.assets.require '/kit/highlight.css'
3
+ */
data/app/static/kit.js ADDED
File without changes
@@ -0,0 +1,28 @@
1
+ .the_list {.t_list; .s_list; .s_box; .s_round;
2
+ .l_controls {.s_controls; .s_small_text;}
3
+ .l_item {
4
+ .l_content {}}
5
+ .l_list_item {}
6
+ .l_finished {
7
+ div, a {.s_small_text;}
8
+ .content {text-decoration: line-through;}}}
9
+
10
+
11
+ .the_file_t () {
12
+ > table.css_table {
13
+ > tbody {
14
+ > tr {
15
+ > td.css_td1 {width: @icon_size1;}
16
+ > td.css_td2 {}}}}}
17
+ .the_file {.the_file_t; .s_box; .s_round;
18
+ .l_image {width: @icon_size1; margin-right: @normal;}
19
+ .l_title {.s_a_link; font-weight: bold;}}
20
+
21
+
22
+ .the_page {.s_box; .s_round;
23
+ > .l_text {}
24
+ > .l_content {
25
+ > .m_title {.s_normal_text;}}}
26
+
27
+
28
+ .the_folder {.s_box; .s_round;}
@@ -0,0 +1,13 @@
1
+ - b.comment id: object.dom_id do |o|
2
+ - o.user link_to(object.owner_name, user_path(object.owner_name))
3
+
4
+ - avatar_img = image_tag(Models::User.avatar_url(object.owner_name), onerror: "this.style.display = 'none'")
5
+ - o.avatar link_to(avatar_img, user_path(object.owner_name))
6
+
7
+ - o.owner link_to(object.owner_name, user_path(object.owner_name))
8
+ - o.details render_item_details(object, skip: [:comments, :owner])
9
+ - o.text object.text
10
+ - o.controls do |a|
11
+ - a.add link_to(t(:edit), edit_path(object, format: :js)) if can? :update, object
12
+ - a.add link_to(t(:delete), destroy_path(object, format: :js), method: :post, confirm: t(:are_you_shure)) if can? :destroy, object
13
+ / - a.add link_to(t(:go), path(object))
@@ -0,0 +1,8 @@
1
+ - b.form_for :model, object, action: form_action do |f|
2
+ = hidden_field_tag :item_id, params.item_id if params.item_id
3
+
4
+ = f.error_messages
5
+
6
+ = f.text_area :original_text, label: false
7
+
8
+ = f.line ok_button, cancel_button
@@ -0,0 +1,22 @@
1
+ - case action_name
2
+ - when :destroy
3
+ rad.discussion().comment('##{@model.dom_id}').destroy();
4
+
5
+ - when :edit
6
+ - form = js render('form', object: @model, locals: {form_action: update_path(@model, format: :js)})
7
+ rad.discussion().comment('##{@model.dom_id}').edit('#{form}');
8
+
9
+ - when :new
10
+ - form = js render('form', object: @model, locals: {form_action: create_comment_path(format: :js)})
11
+ rad.discussion().anew('#{form}');
12
+
13
+ - when :create
14
+ - html = js render('embedded', object: @model)
15
+ rad.discussion().create("#{html}");
16
+
17
+ - when :update
18
+ - html = js render('embedded', object: @model)
19
+ rad.discussion().comment('##{@model.dom_id}').update('#{html}');
20
+
21
+ - else
22
+ - must_be.never_called
@@ -0,0 +1,11 @@
1
+ - b.comment id: @model.dom_id do |o|
2
+ - o.user link_to(@model.owner_name, user_path(@model.owner_name))
3
+
4
+ - avatar_img = image_tag(Models::User.avatar_url(@model.owner_name), onerror: "this.style.display = 'none'")
5
+ - o.avatar link_to(avatar_img, user_path(@model.owner_name))
6
+
7
+ - o.details render_item_details(@model, skip: :comments)
8
+ - o.text @model.text
9
+ - o.controls do |a|
10
+ - a.add link_to(t(:edit), edit_path(@model, format: :js)) if can? :update, @model
11
+ - a.add link_to(t(:delete), destroy_path(@model, format: :js), method: :post, confirm: t(:are_you_shure)) if can? :destroy, @model
@@ -0,0 +1,2 @@
1
+ - @models.each do |m|
2
+ = render "/previews/line", object: m
@@ -0,0 +1,23 @@
1
+ - case action_name
2
+ - when :new
3
+ - form = js render('form', locals: {form_action: url_for(:create, format: :js)})
4
+ rad.dialog().show('#{form}');
5
+
6
+ - when :edit
7
+ - form = js render('form', locals: {form_action: update_path(@model, format: :js)})
8
+ rad.inplace('##{@model.dom_id}').edit('#{form}');
9
+
10
+ - when :update
11
+ - html = js render('show', object: @model)
12
+ rad.inplace('##{@model.dom_id}').update('#{html}');
13
+
14
+ - when :access
15
+ - html = js render('/tools/access')
16
+ $("access_tool").replaceWith("#{html}");
17
+
18
+ - else
19
+ - must_be.never_called
20
+
21
+ / - when :context_menu
22
+ / - html = js render('/bag/slots/context_menu')
23
+ / $("#_context_menu").replaceWith("#{html}");
@@ -0,0 +1,4 @@
1
+ = render 'items'
2
+
3
+ - html = paginator_for(@page, @models.size, @per_page){|t, n| link_to t, url_for(action_name, page: n)}
4
+ - content_for :aspects, html unless html.blank?
@@ -0,0 +1 @@
1
+ = b.title "Inherited Action"
@@ -0,0 +1,9 @@
1
+ - bottom_text, powered_by = rad.config.bottom_text, rad.config.powered_by
2
+ - if bottom_text or powered_by or rad.development? or @debug
3
+ - b.bottom_panel do |o|
4
+ - if bottom_text or rad.development? or @debug
5
+ - o.left do
6
+ = bottom_text if bottom_text
7
+ = render '/kit/debug' if rad.development?
8
+ - if powered_by
9
+ - o.right t(:powered_by, company: powered_by)
@@ -0,0 +1,13 @@
1
+ Params: #{params.inspect}
2
+ - permissions = Models::User.current.effective_permissions.select{|op, perm| perm}.collect{|op, perm| op}.join(', ')
3
+ - if permissions.present?
4
+ %br
5
+ Permissions: #{permissions}
6
+ - if @model and Models::User.current.owner?(@model)
7
+ - opermissions = Models::User.current.effective_permissions_as_owner.to_a.select{|op, perm| perm}.collect{|op, perm| op}.join(', ')
8
+ - if opermissions.present?
9
+ %br
10
+ Permissions as Owner: #{}
11
+
12
+ - if @debug
13
+ %p= @debug
@@ -0,0 +1,4 @@
1
+ - if flash.info?
2
+ = javascript_tag %{rad.info("#{j(h(flash.info))}")}
3
+ - if flash.error?
4
+ = javascript_tag %{rad.error("#{j(h(flash.error))}")}
@@ -0,0 +1,19 @@
1
+ - menu, additional_menu = rad.config.menu, rad.config.additional_menu
2
+ - if menu or additional_menu
3
+ - b.navigation do |o|
4
+ / - o.items do ||
5
+ - if menu
6
+ - o.left do |a|
7
+ - menu.each do |name, link|
8
+ - if request.path.include? link
9
+ - a.add content: h(name), active: true
10
+ - else
11
+ - a.add link_to(h(name), h(link))
12
+
13
+ - if additional_menu
14
+ - o.right do |a|
15
+ - additional_menu.each do |name, link|
16
+ - if request.path.include? link
17
+ - a.add content: h(name), active: true
18
+ - else
19
+ - a.add link_to(h(name), h(link))
@@ -0,0 +1 @@
1
+ = b.title t(:page_not_found)