user_announcements 0.0.1 → 0.0.2

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/README.md CHANGED
@@ -1,5 +1,71 @@
1
- # UserAnnouncements
1
+ # user_announcements
2
2
 
3
- Manage and display site-wide announcements by user, role and announcement type.
3
+ [![Gem Version](https://badge.fury.io/rb/user_announcements.png)](http://badge.fury.io/rb/user_announcements)
4
+ [![Code Climate](https://codeclimate.com/github/stevedowney/user_announcements.png)](https://codeclimate.com/github/stevedowney/user_announcements)
4
5
 
5
- ## Under construction
6
+ Manage and display site-wide announcements on a per-user basis.
7
+
8
+ Coming soon, scope by user role and announcement type.
9
+
10
+ ### Acknowledgements
11
+
12
+ This gem was inspired by the [Site-Wide Announcements (revised)](http://railscasts.com/episodes/103-site-wide-announcements-revised)
13
+ episode of [RailsCasts](http://railscasts.com/). If you don't have a premium account you can see the
14
+ [original episode](http://railscasts.com/episodes/103-site-wide-announcements).
15
+
16
+ ## Installation
17
+
18
+ Add it to your Gemfile:
19
+
20
+ ```ruby
21
+ gem "user_announcements"
22
+ ```
23
+
24
+ Run bundler:
25
+
26
+ ```sh
27
+ bundle install
28
+ ```
29
+
30
+ Install files:
31
+
32
+ ```sh
33
+ rails generate user_announcements:install
34
+ ```
35
+
36
+ By default, Bootstrap styling is applied. This can be turned on/off:
37
+
38
+ ```ruby
39
+ # ../config/initializers/user_announcements.rb
40
+
41
+ # control Bootstrap styling
42
+ # c.bootstrap = false
43
+ c.bootstrap = true
44
+
45
+ ```
46
+
47
+ Don't forget to restart your Rails server.
48
+
49
+ ## Getting Going
50
+
51
+ To create an announcement go to:
52
+
53
+ ```
54
+ http://<your app>/admin/announcements
55
+ ```
56
+
57
+ To see the announcment add the helper method to your views, e.g.:
58
+
59
+ ```erb
60
+ #../layouts/application.html.erb
61
+
62
+ <body>
63
+ <%= user_announcements %>
64
+ ...
65
+ ```
66
+
67
+ Non-admin users can see (and unhide) announcements they have hidden:
68
+
69
+ ```
70
+ http://<your app>/announcements
71
+ ```
@@ -2,7 +2,7 @@ class Admin::AnnouncementsController < Admin::BaseController
2
2
  before_filter :find_announcement, :only => [:edit, :update, :destroy]
3
3
 
4
4
  def index
5
- @announcements = Announcement.all#AnnouncementFinder.ordered
5
+ @announcements = AnnouncementFinder.ordered
6
6
  end
7
7
 
8
8
  def new
@@ -1,10 +1,7 @@
1
1
  module UserAnnouncementsHelper
2
2
 
3
-
4
- # style: "warning"
5
- # type: "blog"
6
- # role: "admin super-admin"
7
- def announcements(options={})
3
+ # Helper method for displaying messages for +current_user+.
4
+ def user_announcements(options={})
8
5
  return if controller.controller_name == 'user_announcements'
9
6
 
10
7
  announcements_rows = AnnouncementFinder.current_for_user(current_user)
@@ -16,21 +13,27 @@ module UserAnnouncementsHelper
16
13
  end
17
14
 
18
15
  def announcement_div(announcement)
19
- # <div class="alert">
20
- # <button type="button" class="close" data-dismiss="alert">&times;</button>
21
- # <strong>Warning!</strong> Best check yo self, you're not looking too good.
22
- # </div>
23
-
16
+ if bootstrap?
17
+ announcement_div_bootstrap(announcement)
18
+ else
19
+ announcement_div_non_bootstrap(announcement)
20
+ end
21
+ end
22
+
23
+ def announcement_div_bootstrap(announcement)
24
24
  div_for announcement, class: 'alert', style: 'width:40em' do
25
25
  link_to(hide_user_announcement_path(announcement), remote: true) do
26
- content_tag(:button, raw('&times;'), type: 'button', class: 'close', data: {dismissx: 'alert'})
26
+ content_tag(:button, raw('&times;'), type: 'button', class: 'close')
27
27
  end +
28
- announcement.body.html_safe
28
+ announcement.message.html_safe
29
+ end
30
+ end
31
+
32
+ def announcement_div_non_bootstrap(announcement)
33
+ div_for(announcement, class: 'non-bootstrap') do
34
+ announcement.message.html_safe +
35
+ link_to("hide announcement", hide_user_announcement_path(announcement), remote: true)
29
36
  end
30
- # div_for(announcement) do
31
- # announcement.body.html_safe +
32
- # link_to("hide announcement", 'hide_announcement_path(announcement)', remote: true)
33
- # end
34
37
  end
35
38
 
36
39
  def unhide_announcement_link(announcement)
@@ -41,6 +44,20 @@ module UserAnnouncementsHelper
41
44
  end
42
45
  end
43
46
 
47
+ def ua_table_attrs
48
+ if bootstrap?
49
+ {class: "table table-striped table-bordered table-condensed table-hover"}
50
+ else
51
+ {class: 'ua-table'}
52
+ end
53
+ end
54
+
55
+ def ua_table_tag(options={})
56
+ content_tag(:table, options.merge(ua_table_attrs)) do
57
+ yield
58
+ end
59
+ end
60
+
44
61
  def boolean_display(boolean)
45
62
  ( boolean ? '&#10004;' : '&nbsp;' ).html_safe
46
63
  end
@@ -63,4 +80,11 @@ module UserAnnouncementsHelper
63
80
  end
64
81
  end
65
82
 
83
+ def bootstrap?
84
+ if params.has_key?(:bootstrap)
85
+ params[:bootstrap] == 'true'
86
+ else
87
+ UserAnnouncements.config.bootstrap
88
+ end
89
+ end
66
90
  end
@@ -1,17 +1,18 @@
1
1
  class Announcement < ActiveRecord::Base
2
- attr_accessible :body, :starts_at, :ends_at, :active
2
+ attr_accessible :message, :starts_at, :ends_at, :active
3
3
 
4
4
  has_many :user_announcements, :dependent => :destroy
5
5
 
6
- validates_presence_of :body, :starts_at, :ends_at
6
+ validates_presence_of :message, :starts_at, :ends_at
7
7
 
8
-
8
+ INACTIVE = 'inactive'
9
9
  PAST = 'past'
10
10
  CURRENT = 'current'
11
11
  FUTURE = 'future'
12
12
 
13
13
  def status
14
14
  case
15
+ when active.presence.nil? then INACTIVE
15
16
  when ends_at.try(:past?) then PAST
16
17
  when starts_at.try(:future?) then FUTURE
17
18
  else CURRENT
@@ -23,18 +24,21 @@ class Announcement < ActiveRecord::Base
23
24
  end
24
25
 
25
26
  def status_order
26
- { FUTURE => 1, CURRENT => 2, PAST => 3 }[status]
27
+ { FUTURE => 1, CURRENT => 2, PAST => 3, INACTIVE => 4 }[status]
27
28
  end
28
29
 
29
30
  class << self
30
31
 
32
+ def active
33
+ where(active: true)
34
+ end
35
+
31
36
  def new_with_defaults
32
37
  new do |ann|
33
38
  ann.active = true
34
39
  ann.starts_at = Time.now.at_beginning_of_day
35
40
  ann.ends_at = 1.week.from_now.at_midnight
36
41
  end
37
-
38
42
  end
39
43
 
40
44
  end
@@ -2,17 +2,22 @@ class AnnouncementFinder
2
2
 
3
3
  class << self
4
4
 
5
-
6
- # def ordered
7
- # Announcement.all.sort_by(&:status_order)
8
- # end
5
+ def ordered
6
+ Announcement.all.sort_by(&:status_order)
7
+ end
9
8
 
10
9
  def current
11
- Announcement.where("(starts_at is null or starts_at < :now) and (ends_at is null or ends_at > :now)", :now => DateTime.now)
10
+ Announcement
11
+ .active
12
+ .where("starts_at is null or starts_at < :now", now: DateTime.now)
13
+ .where("ends_at is null or ends_at > :now", now: DateTime.now)
12
14
  end
13
15
 
14
16
  def past_or_current
15
- Announcement.where("(starts_at is null or starts_at < :now)", :now => DateTime.now).order('created_at desc')
17
+ Announcement
18
+ .active
19
+ .where("(starts_at is null or starts_at < :now)", :now => DateTime.now)
20
+ .order('created_at desc')
16
21
  end
17
22
 
18
23
  def current_for_user(user)
@@ -1,7 +1,7 @@
1
1
  <tr id="<%= dom_id(announcement) %>" class='<%= announcement.status %>'>
2
- <td><%=raw announcement.body %></td>
3
- <td><%= announcement.starts_at.try(:to_s, :db) %></td>
4
- <td><%= announcement.ends_at.try(:to_s, :db) %></td>
2
+ <td><%=raw announcement.message %></td>
3
+ <td class='date'><%= announcement.starts_at.try(:to_s, :db) %></td>
4
+ <td class='date'><%= announcement.ends_at.try(:to_s, :db) %></td>
5
5
  <td><%= announcement.status %></td>
6
6
  <td><%= boolean_display(announcement.active)%></td>
7
7
  <td><%= link_to('edit', edit_admin_announcement_path(announcement), :class => 'btn btn-mini') %></td>
@@ -4,8 +4,8 @@
4
4
  <%#= f.input(:starts_at, :as => :string, :input_html => {class: 'datepicker'}) %>
5
5
  <%#= f.input(:ends_at, :as => :string, :input_html => {class: 'datepicker'}) %>
6
6
  <p>
7
- <%= f.label(:body) %>
8
- <%= f.text_area :body, size: "60x10", class: 'span6' %>
7
+ <%= f.label(:message) %>
8
+ <%= f.text_area :message, size: "60x10", class: 'span6' %>
9
9
  </p>
10
10
 
11
11
  <%= ua_datetime_p(f, :starts_at) %>
@@ -1,10 +1,10 @@
1
- <h1>Announcements</h1>
1
+ <h1>Administer Announcements</h1>
2
2
 
3
3
  <p>
4
4
  <%= link_to('New Announcement', new_admin_announcement_path(), :class => 'btn btn-primary') %>
5
5
  </p>
6
6
 
7
- <table id="admin-announcements" class="table table-striped table-bordered table-condensed table-hover">
7
+ <%= ua_table_tag(id: 'admin-announcements') do %>
8
8
  <thead>
9
9
  <tr>
10
10
  <th>Announcement</th>
@@ -19,4 +19,4 @@
19
19
  <tbody>
20
20
  <%= render @announcements %>
21
21
  </tbody>
22
- </table>
22
+ <% end %>
@@ -1,14 +1,8 @@
1
+
1
2
  <tr id="<%= dom_id(announcement) %>">
2
3
  <td class='date'><%= announcement.created_at.try(:to_s, :db) %></td>
3
4
  <td>
4
- <%= announcement.body.html_safe %>
5
+ <%= announcement.message.html_safe %>
5
6
  <%= unhide_announcement_link(announcement) %>
6
7
  </td>
7
- </tr>
8
-
9
- <style>
10
- td.date {
11
- white-space: nowrap;
12
- vertical-align: top;
13
- }
14
- </style>
8
+ </tr>
@@ -1,6 +1,6 @@
1
1
  <h1>Announcements</h1>
2
2
 
3
- <table border="1" cellspacing="0" cellpadding="4">
3
+ <%= ua_table_tag(id: 'user-announcements') do %>
4
4
  <thead>
5
5
  <tr>
6
6
  <th>Date</th>
@@ -10,4 +10,5 @@
10
10
  <tbody>
11
11
  <%= render partial: 'user_announcements/announcement', collection: @announcements %>
12
12
  </tbody>
13
- </table>
13
+ <% end %>
14
+
@@ -0,0 +1,27 @@
1
+ require 'rails/generators/active_record/migration'
2
+
3
+ module UserAnnouncements
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+ extend ActiveRecord::Generators::Migration
8
+ source_root File.join(File.dirname(__FILE__), "templates")
9
+
10
+ desc <<DESC
11
+ Description:
12
+ Copies stylesheet to 'app/assets/stylesheets/user_announcements.css.scss'
13
+ Copies configuration to 'config/initializers/user_announcements.rb'
14
+ Copies db migration to 'db/migrate/<timestamp>/create_user_announcement_tables.rb'
15
+
16
+ DESC
17
+
18
+ def install
19
+ copy_file "css.scss", 'app/assets/stylesheets/user_announcements.css.scss'
20
+ copy_file "initializer.rb", 'config/initializers/user_announcements.rb'
21
+ migration_template "migration.rb", "db/migrate/create_user_announcement_tables.rb"
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,29 @@
1
+ table.ua-table {
2
+ border: 1px solid black;
3
+
4
+ th, td {
5
+ border: 1px solid black;
6
+ padding: 0.5em;
7
+ }
8
+
9
+ td {
10
+ vertical-align: top;
11
+
12
+ &.date {
13
+ white-space: nowrap;
14
+ }
15
+ }
16
+ }
17
+
18
+ .announcement.non-bootstrap {
19
+ width: 100%;
20
+ background-color: #F1F094;
21
+ border-bottom: solid 1px black;
22
+ padding: 10px;
23
+ text-align: center;
24
+ a {
25
+ font-size: 12px;
26
+ margin-left: 5px;
27
+ color: #6E5910;
28
+ }
29
+ }
@@ -0,0 +1,6 @@
1
+ UserAnnouncements.config do |c|
2
+
3
+ # uncomment to user Bootstrap styling
4
+ # c.bootstrap = true
5
+
6
+ end
@@ -1,10 +1,12 @@
1
1
  class CreateUserAnnouncementTables < ActiveRecord::Migration
2
2
  def change
3
3
  create_table :announcements do |t|
4
- t.text :body
4
+ t.text :message
5
5
  t.datetime :starts_at
6
6
  t.datetime :ends_at
7
7
  t.boolean :active
8
+ t.text :roles
9
+ t.text :types
8
10
  t.timestamps
9
11
  end
10
12
 
@@ -13,5 +15,8 @@ class CreateUserAnnouncementTables < ActiveRecord::Migration
13
15
  t.integer :announcement_id
14
16
  t.timestamps
15
17
  end
18
+
19
+ add_index :user_announcements, :user_id
20
+ add_index :user_announcements, :announcement_id
16
21
  end
17
22
  end
@@ -2,5 +2,12 @@ module UserAnnouncements
2
2
  class Engine < ::Rails::Engine
3
3
  config.generators.integration_tool :rspec
4
4
  config.generators.test_framework :rspec
5
+
6
+ config.bootstrap = false
7
+ end
8
+
9
+ def self.config(&block)
10
+ yield Engine.config if block
11
+ Engine.config
5
12
  end
6
13
  end
@@ -1,3 +1,3 @@
1
1
  module UserAnnouncements
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: user_announcements
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -290,9 +290,10 @@ files:
290
290
  - app/views/user_announcements/hide.js.erb
291
291
  - app/views/user_announcements/index.html.erb
292
292
  - config/routes.rb
293
- - db/migrate/20130521175710_create_announcements.rb
294
- - lib/generators/templates/create_user_announcement_tables.rb
295
- - lib/generators/user_announcements_generator.rb
293
+ - lib/generators/user_announcements/install_generator.rb
294
+ - lib/generators/user_announcements/templates/css.scss
295
+ - lib/generators/user_announcements/templates/initializer.rb
296
+ - lib/generators/user_announcements/templates/migration.rb
296
297
  - lib/tasks/user_announcements_tasks.rake
297
298
  - lib/user_announcements/engine.rb
298
299
  - lib/user_announcements/version.rb
@@ -313,18 +314,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
313
314
  - - ! '>='
314
315
  - !ruby/object:Gem::Version
315
316
  version: '0'
316
- segments:
317
- - 0
318
- hash: -1264060976197441369
319
317
  required_rubygems_version: !ruby/object:Gem::Requirement
320
318
  none: false
321
319
  requirements:
322
320
  - - ! '>='
323
321
  - !ruby/object:Gem::Version
324
322
  version: '0'
325
- segments:
326
- - 0
327
- hash: -1264060976197441369
328
323
  requirements: []
329
324
  rubyforge_project:
330
325
  rubygems_version: 1.8.25
@@ -1,9 +0,0 @@
1
- class CreateUserAnnouncementTables < ActiveRecord::Migration
2
- def change
3
- create_table :announcements do |t|
4
- t.text :body
5
-
6
- t.timestamps
7
- end
8
- end
9
- end
@@ -1,32 +0,0 @@
1
- require 'rails/generators/active_record/migration'
2
-
3
- class UserAnnouncementsGenerator < Rails::Generators::Base
4
- include Rails::Generators::Migration
5
- extend ActiveRecord::Generators::Migration
6
-
7
- desc "Put the code"
8
- source_root File.join(File.dirname(__FILE__), "templates")
9
-
10
- def install
11
- # copy_javascript if needs_js_copied?
12
- migration_template "create_user_announcement_tables.rb", "db/migrate/create_user_announcement_tables.rb"
13
- end
14
-
15
- private
16
-
17
- def copy_javascript
18
- copy_file File.join(javascript_path, 'announcements.js'), js_destination
19
- end
20
-
21
- def javascript_path
22
- File.join(%w(.. .. .. .. app assets javascripts))
23
- end
24
-
25
- def needs_js_copied?
26
- ::Rails.version < '3.1' || !::Rails.application.config.assets.enabled
27
- end
28
-
29
- def js_destination
30
- 'public/javascripts/announcements.js'
31
- end
32
- end