event_calendar_engine 0.1.11 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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