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
@@ -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,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
|
data/app/models/item.rb
ADDED
@@ -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 */
|
data/app/static/kit.css
ADDED
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,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,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 @@
|
|
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,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)
|