caboose-cms 0.4.42 → 0.4.43

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/javascripts/caboose/jquery.fileupload.js +1441 -0
  3. data/app/assets/javascripts/caboose/lodash.min.js +56 -0
  4. data/app/assets/javascripts/caboose/s3upload.js +124 -0
  5. data/app/controllers/caboose/ab_variants_controller.rb +1 -1
  6. data/app/controllers/caboose/application_controller.rb +1 -1
  7. data/app/controllers/caboose/images_controller.rb +269 -0
  8. data/app/controllers/caboose/pages_controller.rb +21 -12
  9. data/app/controllers/caboose/permissions_controller.rb +1 -1
  10. data/app/controllers/caboose/roles_controller.rb +1 -1
  11. data/app/controllers/caboose/settings_controller.rb +1 -1
  12. data/app/controllers/caboose/sites_controller.rb +156 -0
  13. data/app/controllers/caboose/users_controller.rb +1 -1
  14. data/app/models/caboose/asset.rb +2 -2
  15. data/app/models/caboose/core_plugin.rb +7 -6
  16. data/app/models/caboose/domain.rb +8 -0
  17. data/app/models/caboose/media_category.rb +18 -0
  18. data/app/models/caboose/media_file.rb +9 -0
  19. data/app/models/caboose/media_image.rb +16 -0
  20. data/app/models/caboose/page.rb +16 -9
  21. data/app/models/caboose/schema.rb +191 -158
  22. data/app/models/caboose/site.rb +9 -0
  23. data/app/models/caboose/site_membership.rb +12 -0
  24. data/app/views/caboose/blocks/admin_edit.html.erb +2 -1
  25. data/app/views/caboose/blocks/admin_new.html.erb +5 -1
  26. data/app/views/caboose/images/admin_index.html.erb +24 -0
  27. data/app/views/caboose/images/admin_new.html.erb +63 -0
  28. data/app/views/caboose/pages/admin_index.html.erb +6 -3
  29. data/app/views/caboose/sites/admin_edit.html.erb +199 -0
  30. data/app/views/caboose/sites/admin_index.html.erb +31 -0
  31. data/app/views/caboose/sites/admin_new.html.erb +33 -0
  32. data/config/routes.rb +25 -0
  33. data/lib/caboose/version.rb +1 -1
  34. metadata +18 -2
@@ -0,0 +1,9 @@
1
+
2
+ class Caboose::Site < ActiveRecord::Base
3
+ self.table_name = "sites"
4
+
5
+ has_many :site_memberships, :class_name => 'Caboose::SiteMembership', :dependent => :delete_all
6
+ has_many :domains, :class_name => 'Caboose::Domain', :dependent => :delete_all
7
+ attr_accessible :id, :name, :description
8
+
9
+ end
@@ -0,0 +1,12 @@
1
+
2
+ class Caboose::SiteMembership < ActiveRecord::Base
3
+ self.table_name = "site_membership"
4
+
5
+ belongs_to :site, :class_name => 'Caboose::Site'
6
+ belongs_to :user, :class_name => 'Caboose::User'
7
+ attr_accessible :id, :site_id, :user_id, :role
8
+
9
+ ROLE_ADMIN = 'Admin'
10
+ ROLE_USER = 'User'
11
+
12
+ end
@@ -18,7 +18,7 @@ end
18
18
  <!--<h2 style='margin-top: 0; padding-top: 0;'>Edit <%= @block.name ? @block.name : @block.block_type.description %></h2>-->
19
19
  <h2 style='margin-top: 0; padding-top: 0;'><%= raw crumbs.reverse.join(' > ') %></h2>
20
20
  <p id='block_type_container'><div id='block_<%= @block.id %>_block_type_id'></div></p>
21
-
21
+
22
22
  <% if @block.block_type.use_render_function_for_layout %>
23
23
  <!-- Start -->
24
24
  <%= raw @block.render(@block, {
@@ -88,6 +88,7 @@ $(window).load(function() {
88
88
 
89
89
  var controller = false;
90
90
  $(document).ready(function() {
91
+ modal = new CabooseModal(800);
91
92
  controller = new BlockController({
92
93
  block: <%= raw Caboose.json(@block.js_hash) %>,
93
94
  authenticity_token: '<%= form_authenticity_token %>',
@@ -35,7 +35,11 @@ b = @block
35
35
 
36
36
  var modal = false;
37
37
  $(window).load(function() {
38
- modal = new CabooseModal(800);
38
+ modal = new CabooseModal(800);
39
+ });
40
+
41
+ $(document).ready(function() {
42
+ modal = new CabooseModal(800);
39
43
  });
40
44
 
41
45
  function add_child_block()
@@ -0,0 +1,24 @@
1
+ <h1>Images</h1>
2
+
3
+ <% if @domain && @media_category %>
4
+ <p>
5
+ <a href='/admin/images/new'>Upload Images</a> |
6
+ <a href='/admin/images/new-category?parent_id=<%= @media_category.id %>'>New Category</a>
7
+ </p>
8
+ <% if @media_category.children.count > 0 || @media_category.media_images.count > 0 %>
9
+ <ul class='media'>
10
+ <% @media_category.children.each do |cat| %>
11
+ <li class='category' id='cat<%= cat.id %>'><a href='/admin/images?media_category_id=<%= cat.id %>'><%= cat.name %></a></li>
12
+ <% end %>
13
+ <% @media_category.media_images.each do |mi| %>
14
+ <li class='image' id='image<%= mi.id %>'><a href='/admin/images/<%= mi.id %>'><img src='<%= mi.image.url(:thumb) %>' /><span><%= img.name %></span></a></li>
15
+ <% end %>
16
+ </ul>
17
+ <% else %>
18
+ <p>This category is empty.</p>
19
+ <% end %>
20
+ <% elsif @domain && @media_category.nil? %>
21
+ <p>Invalid media category.</p>
22
+ <% else %>
23
+ <p>It doesn't look like this site is configured for the current domain. Please <a href='/admin/sites'>configure your sites</a>.</p>
24
+ <% end %>
@@ -0,0 +1,63 @@
1
+
2
+ <h1>Upload Images</h1>
3
+
4
+ <input type="file" id="file" onchange="s3_upload();"/>
5
+ <p id="status">Please select a file</p>
6
+ <div id="preview"><img src="/static/default.png" /></div>
7
+
8
+ <% content_for :caboose_css do %>
9
+ <style type='text/css'>
10
+ .progress { max-width: 600px; margin: 0.2em 0 0.2em 0; }
11
+ .progress .bar { height: 1.2em; padding: 0.2em; color: white; display: none; }
12
+ </style>
13
+ <% end %>
14
+
15
+ <% content_for :caboose_js do %>
16
+ <%= javascript_include_tag 'jquery.ui.all' %>
17
+ <%= javascript_include_tag 'caboose/jquery.fileupload.js' %>
18
+ <script type='text/javascript'>
19
+
20
+ $(function() {
21
+ $('.directUpload').find("input:file").each(function(i, elem) {
22
+
23
+ var fileInput = $(elem);
24
+ var form = $(fileInput.parents('form:first'));
25
+ var submitButton = form.find('input[type="submit"]');
26
+ var progressBar = $("<div class='bar'></div>");
27
+ var barContainer = $("<div class='progress'></div>").append(progressBar);
28
+
29
+ fileInput.after(barContainer);
30
+ fileInput.fileupload({
31
+ fileInput: fileInput,
32
+ url: '', // @s3_direct_post.url
33
+ type: 'POST',
34
+ autoUpload: true,
35
+ formData: '', // @s3_direct_post.fields.to_json.html_safe
36
+ paramName: 'file', // S3 does not like nested name fields i.e. name="user[avatar_url]"
37
+ dataType: 'XML', // S3 returns XML if success_action_status is set to 201
38
+ replaceFileInput: false,
39
+ fileuploadsubmit: function() {
40
+ alert('Testing');
41
+ },
42
+ progressall: function (e, data) {
43
+ var progress = parseInt(data.loaded / data.total * 100, 10);
44
+ progressBar.css('width', progress + '%')
45
+ },
46
+ start: function (e) {
47
+ submitButton.prop('disabled', true);
48
+ progressBar.css('background', 'green').css('display', 'block').css('width', '0%').text("Loading...");
49
+ },
50
+ done: function(e, data) {
51
+ submitButton.prop('disabled', false);
52
+ progressBar.text("Uploading done");
53
+ },
54
+ fail: function(e, data) {
55
+ submitButton.prop('disabled', false);
56
+ progressBar.css("background", "red").text("Failed");
57
+ }
58
+ });
59
+ });
60
+ });
61
+
62
+ </script>
63
+ <% end %>
@@ -1,5 +1,8 @@
1
1
  <h1>Pages</h1>
2
2
 
3
- <p><a href='/admin/pages/new'>New Page</a></p>
4
-
5
- <%= raw pages_list(@home_page) %>
3
+ <% if @domain %>
4
+ <p><a href='/admin/pages/new'>New Page</a></p>
5
+ <%= raw pages_list(@home_page) %>
6
+ <% else %>
7
+ <p>It doesn't look like this site is configured for the current domain. Please <a href='/admin/sites'>configure your sites</a>.</p>
8
+ <% end %>
@@ -0,0 +1,199 @@
1
+ <%
2
+ s = @site
3
+ admin_ids = Caboose::SiteMembership.where(:site_id => s.id, :role => Caboose::SiteMembership::ROLE_ADMIN).pluck(:user_id)
4
+ user_ids = Caboose::SiteMembership.where(:site_id => s.id, :role => Caboose::SiteMembership::ROLE_USER ).pluck(:user_id)
5
+ admin_ids = [] if admin_ids.nil?
6
+ user_ids = [] if user_ids.nil?
7
+ %>
8
+ <h1>Edit Site</h1>
9
+
10
+ <p><div id='site_<%= @site.id %>_name' ></div></p>
11
+ <p><div id='site_<%= @site.id %>_description' ></div></p>
12
+
13
+ <h2>Domains</h2>
14
+ <p><a href='#' onclick="add_domain(<%= @site.id %>);">New Domain</a></p>
15
+ <div id='new_domain_container'></div>
16
+ <% if @site.domains && @site.domains.count > 0 %>
17
+ <table class='data'>
18
+ <tr>
19
+ <th>Domain</th>
20
+ <th>Primary</th>
21
+ <th>Delete</th>
22
+ </tr>
23
+ <% @site.domains.all.each do |d| %>
24
+ <tr>
25
+ <td><%= d.domain %></td>
26
+ <td align='center'><input type='radio' name='primary_domain' <%= d.primary? ? "checked='true'" : '' %> onclick="set_primary_domain(<%= s.id %>, <%= d.id %>);" /></td>
27
+ <td align='center'><input type='button' value='Delete' onclick="delete_domain(<%= @site.id %>, <%= d.id %>);" /></td>
28
+ </tr>
29
+ <% end %>
30
+ </table>
31
+ <% else %>
32
+ <p>This site doesn't have any domains yet.</p>
33
+ <% end %>
34
+ <div id='domain_message'></div>
35
+
36
+ <h2>Members</h2>
37
+ <div id='members'>
38
+ <table class='data'>
39
+ <tr><th>User</th><th>None</th><th>User</th><th>Admin</th></tr>
40
+ <% Caboose::User.reorder('last_name, first_name').all.each do |u| %>
41
+ <tr>
42
+ <td><%= u.first_name %> <%= u.last_name %> (<%= u.email %>)</td>
43
+ <td align='center'><input type='radio' name='user<%= u.id %>' <%= !admin_ids.include?(u.id) && !user_ids.include?(u.id) ? "checked='true'" : '' %> onclick="remove_site_membership(<%= s.id %>, <%= u.id %>);" /></td>
44
+ <td align='center'><input type='radio' name='user<%= u.id %>' <%= user_ids.include?(u.id) ? "checked='true'" : '' %> onclick="add_site_membership(<%= s.id %>, <%= u.id %>, 'User');" /></td>
45
+ <td align='center'><input type='radio' name='user<%= u.id %>' <%= admin_ids.include?(u.id) ? "checked='true'" : '' %> onclick="add_site_membership(<%= s.id %>, <%= u.id %>, 'Admin');" /></td>
46
+ </tr>
47
+ <% end %>
48
+ </table>
49
+ </div>
50
+
51
+ <div id='message'></div>
52
+ <div id='controls'>
53
+ <input type='button' value='Back' onclick="window.location='/admin/sites';" />
54
+ <input type='button' value='Delete Site' onclick="delete_site(<%= @site.id %>);" />
55
+ </div>
56
+
57
+ <% content_for :caboose_css do %>
58
+ <style type='text/css'>
59
+ #content input[type=checkbox] { position: relative; }
60
+ #members { height: 200px; overflow-y: scroll; margin-bottom: 20px; }
61
+ </style>
62
+ <% end %>
63
+ <% content_for :caboose_js do %>
64
+ <%= javascript_include_tag "caboose/model/all" %>
65
+ <script type="text/javascript">
66
+
67
+ $(document).ready(function() {
68
+ new ModelBinder({
69
+ name: 'Site',
70
+ id: <%= @site.id %>,
71
+ update_url: '/admin/sites/<%= @site.id %>',
72
+ authenticity_token: '<%= form_authenticity_token %>',
73
+ attributes: [
74
+ { name: 'name' , nice_name: 'Name' , type: 'text' , value: <%= raw Caboose.json(@site.name) %>, width: 400 },
75
+ { name: 'description' , nice_name: 'Description' , type: 'textarea' , value: <%= raw Caboose.json(@site.description) %>, width: 600, height: 75 }
76
+ ]
77
+ });
78
+ });
79
+
80
+ function delete_site(site_id, confirm)
81
+ {
82
+ if (!confirm)
83
+ {
84
+ var p = $('<p/>').addClass('note confirm')
85
+ .append('Are you sure you want to delete the site? ')
86
+ .append($('<input/>').attr('type','button').val('Yes').click(function() { delete_site(site_id, true); })).append(' ')
87
+ .append($('<input/>').attr('type','button').val('No').click(function() { $('#message').empty(); }));
88
+ $('#message').empty().append(p);
89
+ return;
90
+ }
91
+ $('#message').html("<p class='loading'>Deleting site...</p>");
92
+ $.ajax({
93
+ url: '/admin/sites/' + site_id,
94
+ type: 'delete',
95
+ success: function(resp) {
96
+ if (resp.error) $('#message').html("<p class='note error'>" + resp.error + "</p>");
97
+ if (resp.redirect) window.location = resp.redirect;
98
+ }
99
+ });
100
+ }
101
+
102
+ function add_site_membership(site_id, user_id, role)
103
+ {
104
+ $.ajax({
105
+ url: '/admin/sites/' + site_id +'/members',
106
+ type: 'post',
107
+ data: {
108
+ user_id: user_id,
109
+ role: role
110
+ },
111
+ succes: function(resp) {}
112
+ });
113
+ }
114
+
115
+ function remove_site_membership(site_id, user_id)
116
+ {
117
+ $.ajax({
118
+ url: '/admin/sites/' + site_id +'/members/' + user_id,
119
+ type: 'delete',
120
+ succes: function(resp) {}
121
+ });
122
+ }
123
+
124
+ function add_domain(site_id, domain)
125
+ {
126
+ if (!domain)
127
+ {
128
+ var div = $('<div/>')
129
+ .append($('<p/>')
130
+ .addClass('note warning')
131
+ .append("What domain would you like to add?<br />")
132
+ .append($('<input/>').attr('type','text').attr('id','new_domain').css('width', '200px')).append(' ')
133
+ .append($('<input/>').attr('type','button').val('Add').click(function() { add_domain(site_id, $('#new_domain').val()); })).append(' ')
134
+ .append($('<input/>').attr('type','button').val('Cancel').click(function() { $('#new_domain_container').empty(); }))
135
+ )
136
+ .append($('<div/>').attr('id', 'new_domain_message'));
137
+ $('#new_domain_container').empty().append(div);
138
+ return;
139
+ }
140
+ $('#new_domain_message').empty().html("<p class='loading'>Adding domain...</p>");
141
+ $.ajax({
142
+ url: '/admin/sites/' + site_id + '/domains',
143
+ type: 'post',
144
+ data: { domain: domain },
145
+ success: function(resp) {
146
+ if (resp.error) $('#new_domain_message').html("<p class='note error'>" + resp.error + "<br /></p>");
147
+ if (resp.refresh) window.location.reload(true);
148
+ }
149
+ });
150
+ }
151
+
152
+ function delete_domain(site_id, domain_id, confirm)
153
+ {
154
+ if (!confirm)
155
+ {
156
+ var p = $('<p/>').addClass('note confirm')
157
+ .append('Are you sure you want to delete the domain? ')
158
+ .append($('<input/>').attr('type','button').val('Yes').click(function() { delete_domain(site_id, domain_id, true); })).append(' ')
159
+ .append($('<input/>').attr('type','button').val('No').click(function() { $('#domain_message').empty(); }));
160
+ $('#domain_message').empty().append(p);
161
+ return;
162
+ }
163
+ $('#domain_message').html("<p class='loading'>Deleting domain...</p>");
164
+ $.ajax({
165
+ url: '/admin/sites/' + site_id + '/domains/' + domain_id,
166
+ type: 'delete',
167
+ success: function(resp) {
168
+ if (resp.error) $('#message').html("<p class='note error'>" + resp.error + "</p>");
169
+ if (resp.refresh) window.location.reload(true);
170
+ }
171
+ });
172
+ }
173
+
174
+ function set_primary_domain(site_id, domain_id)
175
+ {
176
+ $.ajax({
177
+ url: '/admin/sites/' + site_id + '/domains/' + domain_id + '/set-primary',
178
+ type: 'put',
179
+ success: function(resp) {}
180
+ });
181
+ }
182
+
183
+ </script>
184
+ <% end %>
185
+
186
+ <% content_for :caboose_css do %>
187
+ <style type='text/css'>
188
+ #gravatar {
189
+ float: right;
190
+ width: 150px;
191
+ text-align: right;
192
+ margin: 0 4px 0 0;
193
+ padding: 0;
194
+ }
195
+ #gravatar img {
196
+ border: #fff 2px solid;
197
+ }
198
+ </style>
199
+ <% end %>
@@ -0,0 +1,31 @@
1
+ <h1>Sites</h1>
2
+
3
+ <form action='/admin/sites' method='get' class='search_form'>
4
+ <input type='text' name='name_like' placeholder='Name' />
5
+ <input type='submit' value='Search' />
6
+ </form>
7
+
8
+ <p><a href='/admin/sites/new'>New Site</a></p>
9
+
10
+ <% if @sites && @sites.count > 0 %>
11
+ <table class='data' id='users_table'>
12
+ <tr>
13
+ <%= raw @pager.sortable_table_headings({
14
+ 'name' => 'Name',
15
+ 'description' => 'Description',
16
+ 'name, description' => 'Domains'
17
+ })
18
+ %>
19
+ </tr>
20
+ <% @sites.each do |site| %>
21
+ <tr onclick="window.location='/admin/sites/<%= site.id %>';">
22
+ <td><%= site.name %></td>
23
+ <td><%= site.description %></td>
24
+ <td><%= raw site.domains ? site.domains.collect{ |d| d.domain }.join('<br />') : '' %></td>
25
+ </tr>
26
+ <% end %>
27
+ </table>
28
+ <p><%= raw @pager.generate %></p>
29
+ <% else %>
30
+ <p>There are no sites right now.</p>
31
+ <% end %>
@@ -0,0 +1,33 @@
1
+
2
+ <h1>New Site</h1>
3
+
4
+ <form action='/admin/sites' method='post' id='new_site_form'>
5
+ <input type='hidden' name='authenticity_token' value='<%= form_authenticity_token %>' />
6
+ <p><input type='text' name='name' id='name' placeholder='Name' value='' style='width: 400px;' /></p>
7
+ <div id='message'></div>
8
+ <p><input type='submit' value='Add Site' /></p>
9
+ </form>
10
+
11
+ <% content_for :caboose_js do %>
12
+ <script type='text/javascript'>
13
+
14
+ $(document).ready(function() {
15
+ $('#new_site_form').submit(function() { add_site(); return false; });
16
+ });
17
+
18
+ function add_site()
19
+ {
20
+ $('#message').html("<p class='loading'>Adding site...</p>");
21
+ $.ajax({
22
+ url: '/admin/sites',
23
+ type: 'post',
24
+ data: $('#new_site_form').serialize(),
25
+ success: function(resp) {
26
+ if (resp.error) $('#message').html("<p class='note error'>" + resp.error + "</p>");
27
+ if (resp.redirect) window.location = resp.redirect;
28
+ }
29
+ });
30
+ }
31
+
32
+ </script>
33
+ <% end %>
@@ -21,6 +21,21 @@ Caboose::Engine.routes.draw do
21
21
  get "my-account" => "users#my_account"
22
22
  put "my-account" => "users#update_my_account"
23
23
 
24
+ post "admin/sites/:id/members" => "sites#admin_add_member"
25
+ delete "admin/sites/:id/members/:user_id" => "sites#admin_remove_member"
26
+
27
+ post "admin/sites/:id/domains" => "sites#admin_add_domain"
28
+ put "admin/sites/:id/domains/:domain_id/set-primary" => "sites#admin_set_primary_domain"
29
+ delete "admin/sites/:id/domains/:domain_id" => "sites#admin_remove_domain"
30
+
31
+ get "admin/sites/options" => "sites#options"
32
+ get "admin/sites" => "sites#admin_index"
33
+ get "admin/sites/new" => "sites#admin_new"
34
+ get "admin/sites/:id" => "sites#admin_edit"
35
+ put "admin/sites/:id" => "sites#admin_update"
36
+ post "admin/sites" => "sites#admin_add"
37
+ delete "admin/sites/:id" => "sites#admin_delete"
38
+
24
39
  get "admin/users" => "users#index"
25
40
  get "admin/users/options" => "users#options"
26
41
  get "admin/users/new" => "users#new"
@@ -47,6 +62,16 @@ Caboose::Engine.routes.draw do
47
62
  post "admin/roles/:id/permissions/:permission_id" => "roles#add_permission"
48
63
  delete "admin/roles/:id/permissions/:permission_id" => "roles#remove_permission"
49
64
 
65
+ get "admin/images" => "images#admin_index"
66
+ get "admin/images/sign-s3" => "images#admin_sign_s3"
67
+ get "admin/images/new" => "images#admin_new"
68
+ get "admin/images/:id" => "images#admin_edit"
69
+ put "admin/images/:id" => "images#admin_update"
70
+ post "admin/images/:id/image" => "images#admin_update_image"
71
+ post "admin/images" => "images#admin_add"
72
+ delete "admin/images/:id" => "images#admin_delete"
73
+
74
+
50
75
  get "admin/permissions" => "permissions#index"
51
76
  get "admin/permissions/options" => "permissions#options"
52
77
  get "admin/permissions/new" => "permissions#new"