date_book 0.0.1

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 (203) hide show
  1. checksums.yaml +7 -0
  2. data/.idea/vcs.xml +6 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +23 -0
  5. data/.rubocop_todo.yml +7 -0
  6. data/.ruby-gemset +1 -0
  7. data/.ruby-version +1 -0
  8. data/.travis.yml +3 -0
  9. data/Gemfile +94 -0
  10. data/Gemfile.lock +385 -0
  11. data/LICENSE.txt +20 -0
  12. data/README.md +64 -0
  13. data/Rakefile +30 -0
  14. data/VERSION +1 -0
  15. data/app/assets/images/date_book/.keep +0 -0
  16. data/app/assets/javascripts/date_book.js +21 -0
  17. data/app/assets/javascripts/date_book/calendar_events.js +57 -0
  18. data/app/assets/javascripts/date_book/event_form.js +31 -0
  19. data/app/assets/javascripts/date_book/popovers.js +3 -0
  20. data/app/assets/javascripts/date_book/wysiwyg.js +8 -0
  21. data/app/assets/stylesheets/date_book.css.scss +46 -0
  22. data/app/controllers/date_book/calendars_controller.rb +60 -0
  23. data/app/controllers/date_book/date_book_controller.rb +24 -0
  24. data/app/controllers/date_book/events_controller.rb +105 -0
  25. data/app/controllers/date_book/graphql_controller.rb +35 -0
  26. data/app/graphql/date_book_schema.rb +18 -0
  27. data/app/graphql/types/calendar_type.rb +14 -0
  28. data/app/graphql/types/date_time_type.rb +7 -0
  29. data/app/graphql/types/event_occurrence_type.rb +11 -0
  30. data/app/graphql/types/event_type.rb +19 -0
  31. data/app/graphql/types/mutation_type.rb +5 -0
  32. data/app/graphql/types/profile_type.rb +7 -0
  33. data/app/graphql/types/query_type.rb +57 -0
  34. data/app/helpers/date_book/application_helper.rb +35 -0
  35. data/app/helpers/date_book/calendar_helper.rb +4 -0
  36. data/app/helpers/date_book/events_helper.rb +42 -0
  37. data/app/jobs/date_book/application_job.rb +6 -0
  38. data/app/mailers/date_book/application_mailer.rb +9 -0
  39. data/app/views/date_book/application/_all_day_checkbox.html.haml +1 -0
  40. data/app/views/date_book/application/_date_range.html.haml +8 -0
  41. data/app/views/date_book/application/_wysiwyg.html.haml +65 -0
  42. data/app/views/date_book/calendars/_form.html.haml +6 -0
  43. data/app/views/date_book/calendars/edit.html.haml +5 -0
  44. data/app/views/date_book/calendars/index.html.haml +28 -0
  45. data/app/views/date_book/calendars/new.html.haml +5 -0
  46. data/app/views/date_book/calendars/show.html.haml +28 -0
  47. data/app/views/date_book/events/_event.json.jbuilder +12 -0
  48. data/app/views/date_book/events/_form.html.haml +16 -0
  49. data/app/views/date_book/events/_occurrence_dates.html.haml +11 -0
  50. data/app/views/date_book/events/edit.html.haml +5 -0
  51. data/app/views/date_book/events/fields/_date.html.haml +1 -0
  52. data/app/views/date_book/events/fields/_day.html.haml +1 -0
  53. data/app/views/date_book/events/fields/_day_of_week.html.haml +19 -0
  54. data/app/views/date_book/events/fields/_duration.html.haml +6 -0
  55. data/app/views/date_book/events/fields/_interval.html.haml +1 -0
  56. data/app/views/date_book/events/fields/_time.html.haml +1 -0
  57. data/app/views/date_book/events/index.html.haml +16 -0
  58. data/app/views/date_book/events/new.html.haml +5 -0
  59. data/app/views/date_book/events/popover.html.haml +7 -0
  60. data/app/views/date_book/events/rules/_daily.html.haml +4 -0
  61. data/app/views/date_book/events/rules/_monthly.html.haml +5 -0
  62. data/app/views/date_book/events/rules/_singular.html.haml +4 -0
  63. data/app/views/date_book/events/rules/_weekly.html.haml +5 -0
  64. data/app/views/date_book/events/show.html.haml +16 -0
  65. data/app/views/layouts/_date_book_scripts.html.haml +4 -0
  66. data/app/views/layouts/blank.html.haml +1 -0
  67. data/bin/rails +15 -0
  68. data/config/locales/en.yml +44 -0
  69. data/config/routes.rb +12 -0
  70. data/date_book.gemspec +337 -0
  71. data/db/migrate/20170807133845_create_calendars.rb +11 -0
  72. data/db/migrate/20170807133846_create_events.rb +20 -0
  73. data/db/migrate/20170807133847_create_schedules.rb +25 -0
  74. data/db/migrate/20170807133848_add_fields_to_schedule.rb +6 -0
  75. data/db/migrate/20170807133849_create_event_occurrences.rb +16 -0
  76. data/db/migrate/20170807133850_add_fields_to_event_occurrences.rb +5 -0
  77. data/lib/date_book.rb +40 -0
  78. data/lib/date_book/concerns/ability.rb +27 -0
  79. data/lib/date_book/concerns/acts_as_calendar.rb +29 -0
  80. data/lib/date_book/concerns/acts_as_event.rb +66 -0
  81. data/lib/date_book/concerns/acts_as_event_occurrence.rb +67 -0
  82. data/lib/date_book/concerns/acts_as_ownable.rb +29 -0
  83. data/lib/date_book/concerns/acts_as_owner.rb +18 -0
  84. data/lib/date_book/concerns/acts_as_schedule.rb +44 -0
  85. data/lib/date_book/configuration.rb +43 -0
  86. data/lib/date_book/engine.rb +40 -0
  87. data/lib/date_book/localization.rb +32 -0
  88. data/lib/date_book/version.rb +8 -0
  89. data/lib/generators/date_book/install/install_generator.rb +110 -0
  90. data/lib/generators/date_book/install/templates/app/models/ability.rb +16 -0
  91. data/lib/generators/date_book/install/templates/app/models/calendar.rb +3 -0
  92. data/lib/generators/date_book/install/templates/app/models/event.rb +3 -0
  93. data/lib/generators/date_book/install/templates/app/models/event_occurrence.rb +3 -0
  94. data/lib/generators/date_book/install/templates/app/models/schedule.rb +3 -0
  95. data/lib/generators/date_book/install/templates/config/initializers/date_book.rb +5 -0
  96. data/lib/generators/date_book/utils.rb +25 -0
  97. data/lib/tasks/date_book_tasks.rake +5 -0
  98. data/spec/abilities/calendar_spec.rb +39 -0
  99. data/spec/abilities/event_spec.rb +44 -0
  100. data/spec/controllers/date_book/calendars_controller_spec.rb +259 -0
  101. data/spec/controllers/date_book/events_controller_spec.rb +283 -0
  102. data/spec/dummy/Rakefile +9 -0
  103. data/spec/dummy/app/assets/config/manifest.js +5 -0
  104. data/spec/dummy/app/assets/images/.keep +0 -0
  105. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  106. data/spec/dummy/app/assets/stylesheets/application.css.scss +4 -0
  107. data/spec/dummy/app/assets/stylesheets/bootstrap-everything.scss +54 -0
  108. data/spec/dummy/app/controllers/application_controller.rb +21 -0
  109. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  110. data/spec/dummy/app/helpers/application_helper.rb +4 -0
  111. data/spec/dummy/app/mailers/application_mailer.rb +6 -0
  112. data/spec/dummy/app/models/ability.rb +16 -0
  113. data/spec/dummy/app/models/application_record.rb +5 -0
  114. data/spec/dummy/app/models/calendar.rb +3 -0
  115. data/spec/dummy/app/models/concerns/.keep +0 -0
  116. data/spec/dummy/app/models/event.rb +3 -0
  117. data/spec/dummy/app/models/event_occurrence.rb +3 -0
  118. data/spec/dummy/app/models/role.rb +13 -0
  119. data/spec/dummy/app/models/schedule.rb +3 -0
  120. data/spec/dummy/app/models/user.rb +9 -0
  121. data/spec/dummy/app/views/application/403.html.haml +9 -0
  122. data/spec/dummy/app/views/application/404.html.haml +9 -0
  123. data/spec/dummy/app/views/layouts/application.html.haml +43 -0
  124. data/spec/dummy/app/views/pages/index.html.haml +1 -0
  125. data/spec/dummy/bin/bundle +5 -0
  126. data/spec/dummy/bin/rails +6 -0
  127. data/spec/dummy/bin/rake +6 -0
  128. data/spec/dummy/bin/setup +36 -0
  129. data/spec/dummy/bin/update +31 -0
  130. data/spec/dummy/config.ru +7 -0
  131. data/spec/dummy/config/application.rb +38 -0
  132. data/spec/dummy/config/boot.rb +7 -0
  133. data/spec/dummy/config/cable.yml +9 -0
  134. data/spec/dummy/config/database.yml +25 -0
  135. data/spec/dummy/config/environment.rb +7 -0
  136. data/spec/dummy/config/environments/development.rb +60 -0
  137. data/spec/dummy/config/environments/test.rb +45 -0
  138. data/spec/dummy/config/initializers/application_controller_renderer.rb +7 -0
  139. data/spec/dummy/config/initializers/assets.rb +14 -0
  140. data/spec/dummy/config/initializers/backtrace_silencers.rb +10 -0
  141. data/spec/dummy/config/initializers/bootstrap_leather.rb +9 -0
  142. data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
  143. data/spec/dummy/config/initializers/date_book.rb +5 -0
  144. data/spec/dummy/config/initializers/devise.rb +277 -0
  145. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  146. data/spec/dummy/config/initializers/high_voltage.rb +3 -0
  147. data/spec/dummy/config/initializers/inflections.rb +17 -0
  148. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  149. data/spec/dummy/config/initializers/new_framework_defaults.rb +29 -0
  150. data/spec/dummy/config/initializers/rolify.rb +7 -0
  151. data/spec/dummy/config/initializers/session_store.rb +5 -0
  152. data/spec/dummy/config/initializers/wrap_parameters.rb +17 -0
  153. data/spec/dummy/config/locales/devise.en.yml +64 -0
  154. data/spec/dummy/config/locales/en.yml +23 -0
  155. data/spec/dummy/config/puma.rb +49 -0
  156. data/spec/dummy/config/routes.rb +15 -0
  157. data/spec/dummy/config/secrets.yml +22 -0
  158. data/spec/dummy/config/spring.rb +8 -0
  159. data/spec/dummy/db/migrate/20170728171103_create_users_table.rb +7 -0
  160. data/spec/dummy/db/migrate/20170807134122_add_devise_to_users.rb +49 -0
  161. data/spec/dummy/db/migrate/20170807134128_rolify_create_roles.rb +19 -0
  162. data/spec/dummy/db/migrate/20170807134137_create_calendars.date_book.rb +12 -0
  163. data/spec/dummy/db/migrate/20170807134138_create_events.date_book.rb +21 -0
  164. data/spec/dummy/db/migrate/20170807134139_create_schedules.date_book.rb +26 -0
  165. data/spec/dummy/db/migrate/20170807134140_add_fields_to_schedule.date_book.rb +7 -0
  166. data/spec/dummy/db/migrate/20170807134141_create_event_occurrences.date_book.rb +17 -0
  167. data/spec/dummy/db/migrate/20170807134142_add_fields_to_event_occurrences.date_book.rb +6 -0
  168. data/spec/dummy/db/schema.rb +101 -0
  169. data/spec/dummy/db/seeds.rb +0 -0
  170. data/spec/dummy/db/seeds/calendars.seeds.rb +22 -0
  171. data/spec/dummy/db/seeds/events.seeds.rb +89 -0
  172. data/spec/dummy/db/seeds/users.seeds.rb +16 -0
  173. data/spec/dummy/lib/assets/.keep +0 -0
  174. data/spec/dummy/lib/basic_benchmark.rb +9 -0
  175. data/spec/dummy/log/.keep +0 -0
  176. data/spec/factories/calendars.rb +11 -0
  177. data/spec/factories/events.rb +12 -0
  178. data/spec/factories/roles.rb +5 -0
  179. data/spec/factories/users.rb +9 -0
  180. data/spec/features/calendars_spec.rb +185 -0
  181. data/spec/features/events_spec.rb +201 -0
  182. data/spec/helpers/date_book/calendar_helper_spec.rb +17 -0
  183. data/spec/helpers/date_book/events_helper_spec.rb +17 -0
  184. data/spec/models/calendar_spec.rb +26 -0
  185. data/spec/models/event_spec.rb +67 -0
  186. data/spec/models/role_spec.rb +5 -0
  187. data/spec/rails_helper.rb +116 -0
  188. data/spec/requests/date_book/events_spec.rb +56 -0
  189. data/spec/routing/date_book/calendars_routing_spec.rb +49 -0
  190. data/spec/routing/date_book/events_routing_spec.rb +54 -0
  191. data/spec/spec_helper.rb +102 -0
  192. data/spec/support/controller_behaviors.rb +101 -0
  193. data/spec/support/controller_macros.rb +25 -0
  194. data/spec/support/factory_girl.rb +3 -0
  195. data/spec/support/feature_behaviors.rb +150 -0
  196. data/spec/support/loaded_site.rb +5 -0
  197. data/spec/support/loaded_site/calendars.rb +5 -0
  198. data/spec/support/loaded_site/events.rb +6 -0
  199. data/spec/support/loaded_site/users.rb +5 -0
  200. data/spec/support/request_behaviors.rb +89 -0
  201. data/spec/support/shared_connection.rb +14 -0
  202. data/spec/support/utilities.rb +53 -0
  203. metadata +817 -0
@@ -0,0 +1,11 @@
1
+ class CreateCalendars < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :calendars do |t|
4
+ t.string :name
5
+ t.string :slug
6
+ t.text :description
7
+ t.string :css_class
8
+ end
9
+ add_index :calendars, :slug, unique: true
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ class CreateEvents < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :events do |t|
4
+ t.references :calendar
5
+
6
+ t.string :name
7
+ t.string :slug, unique: true
8
+ t.text :description
9
+ t.string :css_class
10
+
11
+ t.date :start_date
12
+ t.time :start_time
13
+
14
+ t.integer :duration
15
+ t.boolean :all_day
16
+
17
+ t.timestamps
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ class CreateSchedules < ActiveRecord::Migration[5.1]
2
+ def self.up
3
+ create_table :schedules do |t|
4
+ t.references :schedulable, polymorphic: true
5
+
6
+ t.date :date
7
+ t.time :time
8
+
9
+ t.string :rule
10
+ t.string :interval
11
+
12
+ t.text :day
13
+ t.text :day_of_week
14
+
15
+ t.datetime :until
16
+ t.integer :count
17
+
18
+ t.timestamps
19
+ end
20
+ end
21
+
22
+ def self.down
23
+ drop_table :schedules
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ class AddFieldsToSchedule < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :schedules, :duration, :integer, default: 3600
4
+ add_column :schedules, :all_day, :boolean, default: false
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ class CreateEventOccurrences < ActiveRecord::Migration[5.1]
2
+ def self.up
3
+ create_table :event_occurrences do |t|
4
+
5
+ t.references :schedulable, polymorphic: true
6
+ t.datetime :date
7
+
8
+ t.timestamps
9
+
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :event_occurrences
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ class AddFieldsToEventOccurrences < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :event_occurrences, :end_date, :datetime
4
+ end
5
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date_book/engine'
4
+
5
+ module DateBook
6
+ require 'rails-i18n'
7
+
8
+ require 'devise' # Needs to be required before paid_up/mixins
9
+ require 'cancan'
10
+ require 'rolify'
11
+
12
+ require 'sass'
13
+ require 'haml-rails'
14
+ require 'bootstrap_leather'
15
+ require 'bootstrap_form'
16
+ require 'bootstrap-wysihtml5-rails'
17
+
18
+ require 'schedulable'
19
+ require 'fullcalendar-rails'
20
+
21
+ require 'date_book/configuration'
22
+ require 'date_book/engine'
23
+ require 'date_book/localization'
24
+ require 'date_book/version'
25
+
26
+ require 'date_book/concerns/ability'
27
+ require 'date_book/concerns/acts_as_calendar'
28
+ require 'date_book/concerns/acts_as_event'
29
+ require 'date_book/concerns/acts_as_event_occurrence'
30
+ require 'date_book/concerns/acts_as_ownable'
31
+ require 'date_book/concerns/acts_as_owner'
32
+ require 'date_book/concerns/acts_as_schedule'
33
+ end
34
+
35
+ ActiveRecord::Base.send(:extend, DateBook::ActsAsOwnable)
36
+ ActiveRecord::Base.send(:extend, DateBook::ActsAsOwner)
37
+ ActiveRecord::Base.send(:extend, DateBook::ActsAsCalendar)
38
+ ActiveRecord::Base.send(:extend, DateBook::ActsAsEvent)
39
+ ActiveRecord::Base.send(:extend, DateBook::ActsAsEventOccurrence)
40
+ ActiveRecord::Base.send(:extend, DateBook::ActsAsSchedule)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DateBook
4
+ # DateBook Ability model
5
+ module Ability
6
+ include CanCan::Ability
7
+
8
+ def initialize_date_book(user)
9
+ alias_action :index, :show, :popover, to: :read
10
+ if user.has_role? :admin
11
+ can :manage, :all
12
+ elsif user.new_record?
13
+ can :read, Calendar
14
+ can :read, Event
15
+ else
16
+ can :read, Calendar
17
+ can :create, Calendar
18
+ can :manage, Calendar, id: Calendar.with_role(:owner, user).ids
19
+
20
+ can :read, Event
21
+ cannot :create, Event
22
+ can :manage, Event, calendar_id: Calendar.with_role(:owner, user).ids
23
+ can :manage, Event, id: Event.with_role(:owner, user).ids
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module DateBook
2
+ module ActsAsCalendar
3
+ def acts_as_calendar(options = {})
4
+ acts_as_ownable
5
+
6
+ validates_presence_of :name, :slug
7
+
8
+ # FriendlyId Gem
9
+ extend FriendlyId
10
+ friendly_id :name, use: :slugged
11
+
12
+ # Relationships
13
+ has_many :events, dependent: :destroy
14
+
15
+ include InstanceMethods
16
+ extend ClassMethods
17
+ end
18
+
19
+ module InstanceMethods
20
+ def event_occurrences
21
+ events.as_occurrences.ascending
22
+ end
23
+ end
24
+
25
+ module ClassMethods
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,66 @@
1
+ module DateBook
2
+ module ActsAsEvent
3
+ def acts_as_event(options = {})
4
+ acts_as_ownable
5
+
6
+ delegate :all_day, :duration, to: :schedule
7
+
8
+ validates_presence_of :name, :slug, :calendar
9
+
10
+ # FriendlyId Gem
11
+ extend FriendlyId
12
+ friendly_id :name, use: :slugged
13
+
14
+ # Schedulable Gem
15
+ acts_as_schedulable :schedule, occurrences: :event_occurrences
16
+
17
+ # Relationships
18
+ belongs_to :calendar
19
+
20
+ # Nested Forms gem
21
+ accepts_nested_attributes_for :schedule
22
+
23
+ # Scopes
24
+ scope :ending_after, -> (start_date) {
25
+ where id: ::EventOccurrence.ending_after(start_date).event_ids
26
+ }
27
+ scope :starting_before, -> (end_date) {
28
+ where id: ::EventOccurrence.starting_before(end_date).event_ids
29
+ }
30
+
31
+ include InstanceMethods
32
+ extend ClassMethods
33
+ end
34
+
35
+ module InstanceMethods
36
+ def schedule
37
+ super || build_schedule(date: Time.now.to_date, time: Time.now.to_s(:time))
38
+ end
39
+
40
+ def previous_occurrence(occurrence = nil)
41
+ before = occurrence.present? ? occurrence.start_date : Time.now
42
+ event_occurrences.starting_before(before).descending.first
43
+ end
44
+
45
+ def next_occurrence(occurrence = nil)
46
+ after = occurrence.present? ? occurrence.end_date + 1.second : Time.now
47
+ event_occurrences.ending_after(after).ascending.first
48
+ end
49
+
50
+ def url(occurrence = nil)
51
+ DateBook::Engine.routes.url_helpers.calendar_event_path(calendar, slug, occurrence_id: occurrence.id)
52
+ end
53
+
54
+ def popover_url(occurrence = nil)
55
+ DateBook::Engine.routes.url_helpers.popover_calendar_event_path(calendar, slug, occurrence_id: occurrence.id)
56
+ end
57
+ end
58
+
59
+ module ClassMethods
60
+ def as_occurrences
61
+ ::EventOccurrence.for_schedulables('Event', ids)
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,67 @@
1
+ module DateBook
2
+ module ActsAsEventOccurrence
3
+ def acts_as_event_occurrence(options = {})
4
+ before_save :set_end_date
5
+
6
+ alias_attribute :start_date, :date
7
+
8
+ belongs_to :schedulable, polymorphic: true
9
+ alias_attribute :event, :schedulable
10
+ delegate :schedule, to: :schedulable
11
+
12
+ # Scopes
13
+ scope :remaining, -> { where('date >= ?',Time.now) }
14
+ scope :previous, -> { where('date < ?',Time.now) }
15
+ scope :ending_after, -> (start_date) { (where 'end_date >= ?', start_date) }
16
+ scope :starting_before, -> (end_date) { where 'date < ?', end_date }
17
+ scope :for_events, -> { where(schedulable_type: 'Event') }
18
+ scope :for_schedulables, -> (model_name, ids) { where(schedulable_type: model_name).where('schedulable_id IN (?)', ids) }
19
+ scope :ascending, -> { order date: :asc }
20
+ scope :descending, -> { order date: :desc }
21
+
22
+ include InstanceMethods
23
+ extend ClassMethods
24
+ end
25
+
26
+ module InstanceMethods
27
+ def url
28
+ event.url(self)
29
+ end
30
+
31
+ def popover_url
32
+ event.popover_url(self)
33
+ end
34
+
35
+ def start_moment
36
+ if schedule.all_day
37
+ I18n.localize date, format: :moment_date
38
+ else
39
+ I18n.localize date, format: :moment_datetime
40
+ end
41
+ end
42
+ alias_method :start, :start_moment
43
+
44
+ def end_moment
45
+ if schedule.all_day
46
+ I18n.localize end_date, format: :moment_date
47
+ else
48
+ I18n.localize end_date, format: :moment_datetime
49
+ end
50
+ end
51
+ alias_method :end, :end_moment
52
+
53
+ private
54
+
55
+ def set_end_date
56
+ self.end_date = date + schedulable.schedule.duration
57
+ end
58
+ end
59
+
60
+ module ClassMethods
61
+ def event_ids
62
+ for_events.pluck(:schedulable_id).uniq
63
+ end
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,29 @@
1
+ module DateBook
2
+ module ActsAsOwnable
3
+ def acts_as_ownable(options = {})
4
+ # Rolify Gem
5
+ resourcify
6
+
7
+ scope :readable_by, ->(user) { accessible_by(::Ability.new(user)) }
8
+
9
+ include InstanceMethods
10
+ end
11
+
12
+ module InstanceMethods
13
+ def owners
14
+ User.with_role(:owner, self)
15
+ end
16
+
17
+ def owners=(revised_owners)
18
+ # Remove owners not listed in new value
19
+ owners.each do |owner|
20
+ owner.remove_role(:owner, self) unless revised_owners.include? owner
21
+ end
22
+ # Add owners not previously held
23
+ revised_owners.each do |revised_owner|
24
+ revised_owner.add_role(:owner, self) unless owners.include? revised_owner
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,18 @@
1
+ module DateBook
2
+ module ActsAsOwner
3
+ def acts_as_owner(options = {})
4
+ include InstanceMethods
5
+ extend ClassMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def calendars
10
+ Calendar.with_role(:owner, self)
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,44 @@
1
+ module DateBook
2
+ module ActsAsSchedule
3
+ def acts_as_schedule(options = {})
4
+ include InstanceMethods
5
+ end
6
+
7
+ module InstanceMethods
8
+ def duration_attributes
9
+ OpenStruct.new count: duration_count, unit: duration_unit
10
+ end
11
+
12
+ def duration_attributes=(value)
13
+ if value.is_a? Hash
14
+ self.duration = value['count'].to_i.send(value['unit'].to_sym).to_i
15
+ end
16
+ super value
17
+ end
18
+
19
+ def duration_count
20
+ duration / 1.send(duration_unit.singularize.to_sym).to_i
21
+ end
22
+
23
+ def duration_unit
24
+ return 'seconds' if duration == 0
25
+ DateBook.configuration.duration_units.select { |x| is_unit? x }.first || 'seconds'
26
+ end
27
+
28
+ def human_date
29
+ I18n.localize date, format: :human_date
30
+ end
31
+
32
+ def human_time
33
+ I18n.localize time, format: :human_time
34
+ end
35
+
36
+ private
37
+
38
+ def is_unit?(unit)
39
+ duration % 1.send(unit.singularize.to_sym).to_i == 0
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # DateBook Module
4
+ module DateBook
5
+ def self.configure(configuration = DateBook::Configuration.new)
6
+ block_given? && yield(configuration)
7
+ @configuration = configuration
8
+ end
9
+
10
+ def self.configuration
11
+ @configuration ||= DateBook::Configuration.new
12
+ end
13
+
14
+ def self.weekdays
15
+ @weekdays ||= Date::DAYNAMES
16
+ .map
17
+ .with_index do |x, i|
18
+ OpenStruct.new(id: i, name: x, slug: x.downcase)
19
+ end
20
+ .sort_by do |value|
21
+ (value.id - week_start_index) % 7
22
+ end
23
+ end
24
+
25
+ def self.week_start_index
26
+ @week_start_index ||= Date::DAYNAMES.find_index(configuration.week_starts_on)
27
+ end
28
+
29
+ # DateBook Configuration
30
+ class Configuration
31
+ attr_accessor(
32
+ :week_starts_on,
33
+ :rules,
34
+ :duration_units
35
+ )
36
+
37
+ def initialize
38
+ self.week_starts_on = 'Sunday'
39
+ self.rules = %w(singular daily weekly monthly)
40
+ self.duration_units = %w(years months weeks days hours minutes seconds)
41
+ end
42
+ end
43
+ end