event_calendar_engine 0.1.11 → 0.2.0

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 (45) hide show
  1. data/Gemfile.lock +39 -35
  2. data/VERSION +1 -1
  3. data/app/controllers/event_revisions_controller.rb +1 -1
  4. data/app/controllers/events_controller.rb +21 -36
  5. data/app/controllers/links_controller.rb +62 -0
  6. data/app/helpers/event_calendar/application_helper.rb +73 -4
  7. data/app/models/event.rb +21 -43
  8. data/app/models/event_instance_methods.rb +40 -9
  9. data/app/models/link.rb +19 -0
  10. data/app/views/event_revisions/_list_group.html.erb +1 -1
  11. data/app/views/events/_details.html.erb +2 -1
  12. data/app/views/events/_event.html.erb +2 -0
  13. data/app/views/events/_event_details.html.erb +22 -17
  14. data/app/views/events/_form.html.erb +47 -3
  15. data/app/views/events/_list_group.html.erb +1 -1
  16. data/app/views/events/_one_day_list_event.html.erb +1 -1
  17. data/app/views/events/edit.html.erb +1 -1
  18. data/app/views/links/_form.html.erb +18 -0
  19. data/app/views/links/_link.html.erb +6 -0
  20. data/app/views/links/_links.html.erb +6 -0
  21. data/app/views/links/create.js.rjs +14 -0
  22. data/app/views/links/edit.html.erb +3 -0
  23. data/app/views/links/new.html.erb +3 -0
  24. data/app/views/links/show.html.erb +3 -0
  25. data/app/views/links/update.js.rjs +15 -0
  26. data/config/routes.rb +1 -56
  27. data/db/migrate/20110204223256_add_presenters_facilitators_to_events.rb +11 -0
  28. data/db/migrate/20110206000427_create_event_calendar_links.rb +23 -0
  29. data/db/schema.rb +18 -1
  30. data/public/javascripts/event_calendar/event_calendar.js +7 -0
  31. data/public/javascripts/event_calendar/event_calendar_behaviors.js +92 -23
  32. data/public/stylesheets/event_calendar/blueprint/screen.css +1 -0
  33. data/spec/controllers/events_controller_spec.rb +4 -2
  34. data/spec/controllers/links_controller_spec.rb +140 -0
  35. data/spec/fixtures/event_calendar_events.yml +12 -2
  36. data/spec/fixtures/event_calendar_events_links.yml +3 -0
  37. data/spec/fixtures/event_calendar_links.yml +4 -0
  38. data/spec/helpers/event_calendar/application_helper_spec.rb +4 -4
  39. data/spec/models/event_instance_methods_spec.rb +58 -0
  40. data/spec/models/event_revision_spec.rb +11 -10
  41. data/spec/models/event_spec.rb +31 -65
  42. data/spec/models/link_spec.rb +31 -0
  43. data/spec/spec_helpers/helpers.rb +15 -0
  44. metadata +29 -6
  45. data/app/views/events/_times.html.erb +0 -5
data/Gemfile.lock CHANGED
@@ -1,6 +1,6 @@
1
1
  GIT
2
2
  remote: git://github.com/inertialbit/acts_as_revisable.git
3
- revision: 4f4cba5de4faf87c9196afde9b4e16fa83915ef8
3
+ revision: ac928ff786fbf0deb415ee9d8e7034b4d4b031ac
4
4
  branch: rails3
5
5
  specs:
6
6
  acts_as_revisable (1.1.2)
@@ -39,9 +39,9 @@ GEM
39
39
  acts_as_fu (0.0.7.2)
40
40
  activerecord
41
41
  sqlite3-ruby
42
- arel (2.0.4)
42
+ arel (2.0.7)
43
43
  builder (2.1.2)
44
- capybara (0.4.0)
44
+ capybara (0.4.1.1)
45
45
  celerity (>= 0.7.9)
46
46
  culerity (>= 0.2.4)
47
47
  mime-types (>= 1.16)
@@ -49,19 +49,19 @@ GEM
49
49
  rack (>= 1.0.0)
50
50
  rack-test (>= 0.5.4)
51
51
  selenium-webdriver (>= 0.0.27)
52
- xpath (~> 0.1.2)
53
- celerity (0.8.4)
54
- childprocess (0.1.4)
52
+ xpath (~> 0.1.3)
53
+ celerity (0.8.7)
54
+ childprocess (0.1.6)
55
55
  ffi (~> 0.6.3)
56
- cucumber (0.9.4)
57
- builder (~> 2.1.2)
56
+ cucumber (0.10.0)
57
+ builder (>= 2.1.2)
58
58
  diff-lcs (~> 1.1.2)
59
- gherkin (~> 2.2.9)
59
+ gherkin (~> 2.3.2)
60
60
  json (~> 1.4.6)
61
61
  term-ansicolor (~> 1.0.5)
62
62
  cucumber-rails (0.3.2)
63
63
  cucumber (>= 0.8.0)
64
- culerity (0.2.12)
64
+ culerity (0.2.15)
65
65
  diff-lcs (1.1.2)
66
66
  engineer (0.2.3)
67
67
  jeweler (>= 1.4.0)
@@ -69,24 +69,23 @@ GEM
69
69
  abstract (>= 1.0.0)
70
70
  ffi (0.6.3)
71
71
  rake (>= 0.8.7)
72
- formtastic (1.2.1)
72
+ formtastic (1.2.3)
73
73
  actionpack (>= 2.3.7)
74
74
  activesupport (>= 2.3.7)
75
- i18n (>= 0.4.0)
76
- gherkin (2.2.9)
75
+ i18n (~> 0.4)
76
+ gherkin (2.3.3)
77
77
  json (~> 1.4.6)
78
- term-ansicolor (~> 1.0.5)
79
78
  git (1.2.5)
80
- i18n (0.4.2)
81
- jeweler (1.5.1)
79
+ i18n (0.5.0)
80
+ jeweler (1.5.2)
82
81
  bundler (~> 1.0.0)
83
82
  git (>= 1.2.5)
84
83
  rake
85
84
  json (1.4.6)
86
- json_pure (1.4.6)
87
- mail (2.2.10)
85
+ json_pure (1.5.1)
86
+ mail (2.2.15)
88
87
  activesupport (>= 2.3.6)
89
- i18n (~> 0.4.1)
88
+ i18n (>= 0.4.0)
90
89
  mime-types (~> 1.16)
91
90
  treetop (~> 1.4.8)
92
91
  mime-types (1.16)
@@ -98,7 +97,7 @@ GEM
98
97
  rack (1.2.1)
99
98
  rack-mount (0.6.13)
100
99
  rack (>= 1.0.0)
101
- rack-test (0.5.6)
100
+ rack-test (0.5.7)
102
101
  rack (>= 1.0)
103
102
  rails (3.0.3)
104
103
  actionmailer (= 3.0.3)
@@ -115,31 +114,36 @@ GEM
115
114
  thor (~> 0.14.4)
116
115
  rake (0.8.7)
117
116
  rcov (0.9.9)
118
- rdiscount (1.6.5)
119
- rspec (2.1.0)
120
- rspec-core (~> 2.1.0)
121
- rspec-expectations (~> 2.1.0)
122
- rspec-mocks (~> 2.1.0)
123
- rspec-core (2.1.0)
124
- rspec-expectations (2.1.0)
117
+ rdiscount (1.6.8)
118
+ rspec (2.5.0)
119
+ rspec-core (~> 2.5.0)
120
+ rspec-expectations (~> 2.5.0)
121
+ rspec-mocks (~> 2.5.0)
122
+ rspec-core (2.5.0)
123
+ rspec-expectations (2.5.0)
125
124
  diff-lcs (~> 1.1.2)
126
- rspec-mocks (2.1.0)
127
- rspec-rails (2.1.0)
128
- rspec (~> 2.1.0)
125
+ rspec-mocks (2.5.0)
126
+ rspec-rails (2.5.0)
127
+ actionpack (~> 3.0)
128
+ activesupport (~> 3.0)
129
+ railties (~> 3.0)
130
+ rspec (~> 2.5.0)
129
131
  rubyzip (0.9.4)
130
- selenium-webdriver (0.1.0)
131
- childprocess (= 0.1.4)
132
+ selenium-webdriver (0.1.2)
133
+ childprocess (~> 0.1.5)
132
134
  ffi (~> 0.6.3)
133
135
  json_pure
134
136
  rubyzip
135
- sqlite3-ruby (1.3.2)
137
+ sqlite3 (1.3.3)
138
+ sqlite3-ruby (1.3.3)
139
+ sqlite3 (>= 1.3.3)
136
140
  term-ansicolor (1.0.5)
137
141
  thor (0.14.6)
138
142
  treetop (1.4.9)
139
143
  polyglot (>= 0.3.1)
140
- tzinfo (0.3.23)
144
+ tzinfo (0.3.24)
141
145
  will_paginate (3.0.pre2)
142
- xpath (0.1.2)
146
+ xpath (0.1.3)
143
147
  nokogiri (~> 1.3)
144
148
 
145
149
  PLATFORMS
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.11
1
+ 0.2.0
@@ -15,7 +15,7 @@ class EventRevisionsController < EventCalendar::ApplicationController
15
15
 
16
16
  def restore
17
17
  @event_revision = EventRevision.find(params[:id])
18
- if @event_revision.restore
18
+ if @event_revision.restore
19
19
  flash[:notice] = "Event <em>#{@event_revision.name}</em> restored.".html_safe
20
20
  redirect_to(event_path(@event_revision))
21
21
  else
@@ -30,12 +30,21 @@ class EventsController < EventCalendar::ApplicationController
30
30
  start_min = params[:event].delete :"start_time(5i)"
31
31
  end_hour = params[:event].delete :"end_time(4i)"
32
32
  end_min = params[:event].delete :"end_time(5i)"
33
- start_date = Date.parse(params[:event][:start_date])
34
- end_date = Date.parse(params[:event][:end_date])
35
- params[:event][:start_on] = Time.local(nil, start_min, start_hour, start_date.day, start_date.month, start_date.year, nil, nil, nil, params[:event][:timezone])
36
- params[:event][:end_on] = Time.local(nil, end_min, end_hour, end_date.day, end_date.month, end_date.year, nil, nil, nil, params[:event][:timezone])
37
- params[:event][:start_time] = params[:event][:start_on]
38
- params[:event][:end_time] = params[:event][:end_on]
33
+ if params[:event][:start_date].present?
34
+ start_date = Date.parse(params[:event][:start_date])
35
+ params[:event][:start_on] = Time.utc(start_date.year, start_date.month, start_date.day, start_hour, start_min)
36
+ if params[:event][:end_date].present?
37
+ end_date = Date.parse(params[:event][:end_date])
38
+ else
39
+ end_date = start_date
40
+ end
41
+ params[:event][:end_on] = Time.utc(end_date.year, end_date.month, end_date.day, end_hour, end_min)
42
+ params[:event][:start_time] = params[:event][:start_on]
43
+ params[:event][:end_time] = params[:event][:end_on]
44
+ else
45
+ params[:event][:start_time] = ''
46
+ params[:event][:end_time] = ''
47
+ end
39
48
  end
40
49
  protected
41
50
  public
@@ -46,8 +55,8 @@ class EventsController < EventCalendar::ApplicationController
46
55
  if params[:start] && params[:end]
47
56
  @events = Event.between(Time.at(params[:start].to_i), Time.at(params[:end].to_i))
48
57
  else
49
- @past_events = Event.past.order("start_on DESC")
50
- @current_events = Event.current.order("start_on DESC")
58
+ @past_events = Event.past.order("start_on ASC")
59
+ @current_events = Event.current.order("start_on ASC")
51
60
  end
52
61
 
53
62
  respond_to do |format|
@@ -68,6 +77,7 @@ class EventsController < EventCalendar::ApplicationController
68
77
  def show
69
78
  # @event = Event.find(params[:id], :include => :file_attachments)
70
79
  @event = Event.find(params[:id])
80
+ @link = @event.links.build
71
81
 
72
82
  respond_to do |format|
73
83
  format.html # show.html.erb
@@ -79,7 +89,7 @@ class EventsController < EventCalendar::ApplicationController
79
89
  # GET /events/new.xml
80
90
  def new
81
91
  @event = Event.new
82
-
92
+ @event.start_time = Time.local(Date.current.year, Date.current.month, Date.current.day, 06, 00)
83
93
  respond_to do |format|
84
94
  format.html # new.html.erb
85
95
  format.xml { render :xml => @event }
@@ -103,6 +113,7 @@ class EventsController < EventCalendar::ApplicationController
103
113
  format.html { redirect_to(event_path(@event)) }
104
114
  format.xml { render :xml => @event, :status => :created, :location => @event }
105
115
  else
116
+ flash.now[:notice] = @event.errors.full_messages
106
117
  format.html { render :action => "new" }
107
118
  format.xml { render :xml => @event.errors, :status => :unprocessable_entity }
108
119
  end
@@ -115,12 +126,12 @@ class EventsController < EventCalendar::ApplicationController
115
126
  @event = Event.find(params[:id])
116
127
 
117
128
  respond_to do |format|
118
- # if @event.update_attributes(params[:event].merge(:modified_by_user => current_user))
119
129
  if @event.update_attributes(params[:event])
120
130
  flash[:notice] = 'Event was successfully updated.'
121
131
  format.html { redirect_to(@event) }
122
132
  format.xml { head :ok }
123
133
  else
134
+ flash.now[:notice] = @event.errors.full_messages
124
135
  format.html { render :action => "edit" }
125
136
  format.xml { render :xml => @event.errors, :status => :unprocessable_entity }
126
137
  end
@@ -138,30 +149,4 @@ class EventsController < EventCalendar::ApplicationController
138
149
  format.xml { head :ok }
139
150
  end
140
151
  end
141
-
142
- # def drop_contact
143
- # @event = Event.find(params[:id])
144
- # if @event.drop_attendees(params[:contact_ids] || params[:contact_id])
145
- # flash[:notice] = "Contact(s) removed from #{@event.name} roster."
146
- # else
147
- # flash[:warning] = "Failed to remove contact(s) from #{@event.name} roster. (#{@event.errors.full_messages.join('; ')}"
148
- # end
149
- # redirect_to @event
150
- # end
151
-
152
- # def add_attendees
153
- # @event = Event.find(params[:id])
154
- # @contacts_not_in_group = Contact.find(:all, :order => 'last_name, first_name',
155
- # :conditions => 'last_name IS NOT NULL AND last_name != ""') - @event.contacts
156
- # end
157
-
158
- # def add_contacts
159
- # @event = Event.find(params[:id])
160
- # if @event.add_attendees(params[:contact_ids])
161
- # flash[:notice] = "Contacts(s) added to #{@event.name}."
162
- # else
163
- # flash[:warning] = "Failed to add contact(s) to #{@event.name}. (#{@event.errors.full_messages.join('; ')}"
164
- # end
165
- # redirect_to @event
166
- # end
167
152
  end
@@ -0,0 +1,62 @@
1
+ class LinksController < EventCalendar::ApplicationController
2
+ private
3
+ def event
4
+ @event ||= Event.find(params[:event_id])
5
+ end
6
+ def link
7
+ @link ||= if params[:id].present?
8
+ Link.find(params[:id])
9
+ else
10
+ event.links.build(params[:link])
11
+ end
12
+ end
13
+ def load_resources
14
+ event
15
+ link
16
+ end
17
+ def redirect_to_event
18
+ redirect_to event_path params[:event_id]
19
+ end
20
+ def respond(&block)
21
+ respond_to do |format|
22
+ format.html{ yield }
23
+ format.js
24
+ end
25
+ end
26
+ protected
27
+ public
28
+ def new
29
+ load_resources
30
+ end
31
+ def show
32
+ load_resources
33
+ end
34
+ def edit
35
+ load_resources
36
+ end
37
+ def update
38
+ if link.update_attributes(params[:link])
39
+ flash[:notice] = "Link successfully updated." unless request.xhr?
40
+ event if request.xhr?
41
+ respond{ redirect_to_event }
42
+ else
43
+ event
44
+ respond{ render :edit and return }
45
+ end
46
+ end
47
+ def create
48
+ load_resources
49
+ begin
50
+ event.save!(:without_revision => true)
51
+ flash[:notice] = "Link successfully created." unless request.xhr?
52
+ respond{ redirect_to_event }
53
+ rescue ActiveRecord::RecordInvalid
54
+ respond{ render 'events/show' and return }
55
+ end
56
+ end
57
+ def destroy
58
+ link.destroy
59
+ flash[:notice] = "Link successfully deleted."
60
+ redirect_to_event
61
+ end
62
+ end
@@ -33,21 +33,70 @@ module EventCalendar::ApplicationHelper
33
33
  ActiveSupport::TimeZone.us_zones.map(&:name).each do |us_zone|
34
34
  next unless us_zone =~ /Pacific|Mountain|Central|Eastern/
35
35
  key = time.in_time_zone(us_zone).strftime("%Z")
36
+ key = timezone_in_words(key.strip)
36
37
  # out[key] = time.in_time_zone(us_zone).strftime(format)
37
38
  out << [key, time.in_time_zone(us_zone).strftime(TIME_BASE)]
38
39
  end
39
40
  out.reverse
40
41
  end
42
+
43
+ def timezone_in_words(zone)
44
+ pac_regex = /^P(S|D)T$/
45
+ mnt_regex = /^M(S|D)T$/
46
+ ctr_regex = /^C(S|D)T$/
47
+ est_regex = /^E(S|D)T$/
48
+ case zone
49
+ when pac_regex
50
+ zone.gsub(pac_regex, 'Pacific')
51
+ when mnt_regex
52
+ zone.gsub(mnt_regex, 'Mountain')
53
+ when ctr_regex
54
+ zone.gsub(ctr_regex, 'Central')
55
+ when est_regex
56
+ zone.gsub(est_regex, 'Eastern')
57
+ else
58
+ zone
59
+ end
60
+ end
61
+
62
+ def event_times(event)
63
+ t = []
64
+ event_times = times_with_zones(event)
65
+ event_times.first.each_with_index do |z_t, i|
66
+ t << "#{z_t.last} - #{event_times.last[i].last} " + content_tag(:em, z_t.first)
67
+ end
68
+ t.join(" / ").html_safe
69
+ end
41
70
 
42
71
  def times_with_zones(event)
43
- begin
44
72
  [
45
73
  time_with_zones(event.start_time),
46
74
  time_with_zones(event.end_time)
47
75
  ]
48
- rescue NoMethodError => e
49
- raise "#{e.message} - #{event.inspect}"
50
- end
76
+ end
77
+
78
+ def hour_options
79
+ [
80
+ ['6 AM','6'],
81
+ ['7 AM','7'],
82
+ ['8 AM','8'],
83
+ ['9 AM','9'],
84
+ ['10 AM','10'],
85
+ ['11 AM','11'],
86
+ ['12 PM','12'],
87
+ ['1 PM','13'],
88
+ ['2 PM','14'],
89
+ ['3 PM','15'],
90
+ ['4 PM','16'],
91
+ ['5 PM','17'],
92
+ ['6 PM','18'],
93
+ ['7 PM','19'],
94
+ ['8 PM','20']
95
+ ]
96
+ end
97
+
98
+ def minute_options
99
+ ['00', '15', '30', '45']
51
100
  end
52
101
 
53
102
  def link_to_events(wrapper_options={}, link_options={})
@@ -95,6 +144,26 @@ module EventCalendar::ApplicationHelper
95
144
  :link_text => "Edit <em>#{h(event.name)}</em>".html_safe
96
145
  }.merge!(link_options))
97
146
  end
147
+
148
+ def link_to_edit_link(event, link, wrapper_options={}, link_options={})
149
+ return unless has_authorization?(:update, link)
150
+ link_wrapper(edit_event_link_path(event, link), {
151
+ :no_wrapper => true
152
+ }.merge!(wrapper_options), {
153
+ :link_text => "edit"
154
+ }.merge!(link_options))
155
+ end
156
+
157
+ def link_to_delete_link(event, link, wrapper_options={}, link_options={})
158
+ return unless has_authorization?(:delete, link)
159
+ link_wrapper(event_link_path(event, link), {
160
+ :no_wrapper => true
161
+ }.merge!(wrapper_options), {
162
+ :link_text => 'delete',
163
+ :confirm => "Are you sure you want to permanently delete the #{link.name} link?",
164
+ :method => "delete"
165
+ }.merge!(link_options))
166
+ end
98
167
 
99
168
  def link_to_delete_event(event, wrapper_options={}, link_options={})
100
169
  return unless has_authorization?(:delete, event)
data/app/models/event.rb CHANGED
@@ -6,6 +6,7 @@ class Event < ActiveRecord::Base
6
6
  include EventInstanceMethods
7
7
 
8
8
  has_many :attendees
9
+ has_and_belongs_to_many :links, :join_table => 'event_calendar_events_links'
9
10
 
10
11
  validates_presence_of :name, :event_type, :start_on
11
12
 
@@ -23,7 +24,16 @@ class Event < ActiveRecord::Base
23
24
 
24
25
  validate :sane_dates
25
26
 
26
- before_save :set_timezone
27
+ before_validation do
28
+ if one_day? && ((end_on.present? && start_on.present? && end_on <= start_on) ||
29
+ (end_on.blank? && start_on.present?))
30
+ unless changed_attributes.include?(:revisable_deleted_at)
31
+ self.end_on = start_on + 1.hour
32
+ end
33
+ end
34
+ end
35
+
36
+ before_save :adjust_to_utc_from_timezone
27
37
 
28
38
  private
29
39
 
@@ -33,12 +43,19 @@ class Event < ActiveRecord::Base
33
43
  end
34
44
  end
35
45
 
36
- def set_timezone
37
- Time.zone = timezone
46
+ def adjust_to_utc_from_timezone
47
+ return true if deleted?
48
+ tz_offset = start_on.in_time_zone(timezone).utc_offset
49
+ self.start_on = self.start_on - tz_offset
50
+ self.end_on = self.end_on - tz_offset
38
51
  end
39
-
40
52
  protected
41
53
  public
54
+
55
+ def self.existing_event_types
56
+ select('DISTINCT event_type').map(&:event_type).reject { |ev| ev.blank? }.sort
57
+ end
58
+
42
59
  def participants
43
60
  return [] if attendees.count == 0
44
61
  attendees.all.collect do |attendee|
@@ -46,46 +63,7 @@ class Event < ActiveRecord::Base
46
63
  end
47
64
  end
48
65
 
49
- def self.existing_event_types
50
- select('DISTINCT event_type').map(&:event_type).reject { |ev| ev.blank? }.sort
51
- end
52
-
53
- # def update_roster
54
- # self.attendee_roster = attendees.collect{|a| a.contact_id}.join(',')
55
- # end
56
-
57
- # def drop_attendees(drop_contact_ids)
58
- # drop_contact_ids = [*drop_contact_ids].compact.map(&:to_i)
59
- # changeset! do |event|
60
- # event.attendees.find(:all, {
61
- # :select => 'id',
62
- # :conditions => ["contact_id IN (?)", drop_contact_ids]
63
- # }).each{|a| a.destroy && !a.destroyed?}
64
- # event.update_roster
65
- # event.save
66
- # end
67
- # end
68
-
69
- # def add_attendees(from_contact_ids)
70
- # changeset! do |event|
71
- # from_contact_ids.each do |c_id|
72
- # event.attendees.build(:contact_id => c_id)
73
- # end
74
- # event.update_roster
75
- # event.save
76
- # end
77
- # end
78
-
79
66
  def to_s
80
67
  "#{name} (#{start_on} #{end_on ? ' - ' + end_on.to_s : ''})"
81
68
  end
82
-
83
- # list all groups that had least one member in attendance at this event
84
- # def contact_groups_represented
85
- # @contact_groups_represented ||= contacts.map(&:contact_groups).flatten.uniq
86
- # end
87
-
88
- # def name_and_file_count
89
- # "#{name} (#{pluralize(file_attachments.count, 'file')})"
90
- # end
91
69
  end