forked from radiant/radiant
/
admin_ui.rb
245 lines (212 loc) · 7.55 KB
/
admin_ui.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
require 'simpleton'
require 'ostruct'
module Radiant
class AdminUI
# This may be loaded before ActiveSupport, so do an explicit require
require 'radiant/admin_ui/region_set'
class DuplicateTabNameError < StandardError; end
# The NavTab Class holds the structure of a navigation tab (including
# its sub-nav items).
class NavTab < Array
attr_reader :name
def initialize(name)
@name = name
end
def [](id)
unless id.kind_of? Fixnum
self.find {|subnav_item| subnav_item.name.to_s.titleize == id.to_s.titleize }
else
super
end
end
def <<(*args)
options = args.extract_options!
item = args.size > 1 ? deprecated_add(*(args << caller)) : args.first
raise DuplicateTabNameError.new("duplicate tab name `#{item.name}'") if self[item.name]
item.tab = self if item.respond_to?(:tab=)
if options.empty?
super(item)
else
options.symbolize_keys!
before = options.delete(:before)
after = options.delete(:after)
tab_name = before || after
if self[tab_name]
_index = index(self[tab_name])
_index += 1 unless before
insert(_index, item)
else
super(item)
end
end
end
alias :add :<<
def add_item(*args)
options = args.extract_options!
options.symbolize_keys!
before = options.delete(:before)
after = options.delete(:after)
tab_name = before || after
if self[tab_name]
_index = index(self[tab_name])
_index += 1 unless before
insert(_index, NavSubItem.new(args.first, args.second))
else
add NavSubItem.new(args.first, args.second)
end
end
def visible?(user)
any? { |sub_item| sub_item.visible?(user) }
end
def deprecated_add(sym_name, name, url, caller)
ActiveSupport::Deprecation.warn("admin.tabs.add is no longer supported in Radiant 0.9.x. Please update your code to use admin.nav", caller)
NavSubItem.new(name, url)
end
end
# Simple structure for storing the properties of a tab's sub items.
class NavSubItem
attr_reader :name, :url
attr_accessor :tab
def initialize(name, url = "#")
@name, @url = name, url
end
def visible?(user)
visible_by_controller?(user)
end
def relative_url
File.join(ActionController::Base.relative_url_root || '', url)
end
private
def visible_by_controller?(user)
params = ActionController::Routing::Routes.recognize_path(url, :method => :get)
if params && params[:controller]
klass = "#{params[:controller].camelize}Controller".constantize
klass.user_has_access_to_action?(user, params[:action])
else
false
end
end
end
include Simpleton
attr_accessor :nav
def nav_tab(*args)
NavTab.new(*args)
end
def nav_item(*args)
NavSubItem.new(*args)
end
def tabs
nav[:content]
end
# Region sets
%w{page snippet layout user extension}.each do |controller|
attr_accessor controller
alias_method "#{controller}s", controller
end
def initialize
@nav = NavTab.new("Tab Container")
load_default_regions
end
def load_default_nav
content = nav_tab("Content")
content << nav_item("Pages", "/admin/pages")
nav << content
design = nav_tab("Design")
design << nav_item("Layouts", "/admin/layouts")
design << nav_item("Snippets", "/admin/snippets")
nav << design
# media = nav_tab("Assets")
# media << nav_item("All", "/admin/assets/")
# media << nav_item("Unattached", "/admin/assets/unattached/")
settings = nav_tab("Settings")
settings << nav_item("Personal", "/admin/preferences/edit")
settings << nav_item("Users", "/admin/users")
settings << nav_item("Extensions", "/admin/extensions")
nav << settings
end
def load_default_regions
@page = load_default_page_regions
@snippet = load_default_snippet_regions
@layout = load_default_layout_regions
@user = load_default_user_regions
@extension = load_default_extension_regions
end
private
def load_default_page_regions
returning OpenStruct.new do |page|
page.edit = RegionSet.new do |edit|
edit.main.concat %w{edit_header edit_form edit_popups}
edit.form.concat %w{edit_title edit_extended_metadata
edit_page_parts edit_layout_and_type}
edit.form_bottom.concat %w{edit_buttons edit_timestamp}
end
page.index = RegionSet.new do |index|
index.sitemap_head.concat %w{title_column_header status_column_header
modify_column_header}
index.node.concat %w{title_column status_column add_child_column remove_column}
end
page.remove = page.children = page.index
page.new = page._part = page.edit
end
end
def load_default_user_regions
returning OpenStruct.new do |user|
user.preferences = RegionSet.new do |preferences|
preferences.main.concat %w{edit_header edit_form}
preferences.form.concat %w{edit_name edit_email edit_username edit_password}
preferences.form_bottom.concat %w{edit_buttons}
end
user.edit = RegionSet.new do |edit|
edit.main.concat %w{edit_header edit_form}
edit.form.concat %w{edit_name edit_email edit_username edit_password
edit_roles edit_notes}
edit.form_bottom.concat %w{edit_buttons edit_timestamp}
end
user.index = RegionSet.new do |index|
index.thead.concat %w{title_header roles_header modify_header}
index.tbody.concat %w{title_cell roles_cell modify_cell}
index.bottom.concat %w{new_button}
end
user.new = user.edit
end
end
def load_default_snippet_regions
returning OpenStruct.new do |snippet|
snippet.edit = RegionSet.new do |edit|
edit.main.concat %w{edit_header edit_form}
edit.form.concat %w{edit_title edit_content edit_filter}
edit.form_bottom.concat %w{edit_buttons edit_timestamp}
end
snippet.index = RegionSet.new do |index|
index.thead.concat %w{title_header modify_header}
index.tbody.concat %w{title_cell modify_cell}
index.bottom.concat %w{new_button}
end
snippet.new = snippet.edit
end
end
def load_default_layout_regions
returning OpenStruct.new do |layout|
layout.edit = RegionSet.new do |edit|
edit.main.concat %w{edit_header edit_form}
edit.form.concat %w{edit_title edit_extended_metadata edit_content}
edit.form_bottom.concat %w{edit_buttons edit_timestamp}
end
layout.index = RegionSet.new do |index|
index.thead.concat %w{title_header modify_header}
index.tbody.concat %w{title_cell modify_cell}
index.bottom.concat %w{new_button}
end
layout.new = layout.edit
end
end
def load_default_extension_regions
returning OpenStruct.new do |extension|
extension.index = RegionSet.new do |index|
index.thead.concat %w{title_header website_header version_header}
index.tbody.concat %w{title_cell website_cell version_cell}
end
end
end
end
end