simple_calendar-timeslot 0.3.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6707f6b5e80e3b24e0329d17e629cfef2d39179c3e725baad3a60d526503963a
4
- data.tar.gz: c05379b32ca660ac1cee7d0c44ee09c2666c0bbbbf60759c169127e057c90d1d
3
+ metadata.gz: e642f680ea5441076624a829e2e672a1cbb57f8b2ffffcf161dd658ae8b5b17c
4
+ data.tar.gz: 39caf7b4c9a72da1e11e8b21c12fb2fd8c7928ef86d18a572afaa6a0d9709d0c
5
5
  SHA512:
6
- metadata.gz: 74c59bce0c06b79e65b9838b39c4222b5e481546f43a577acaf56cda80781bf553a86d29bfd21366aeb0b0daa226fe5b7e630b482f5e435bd3280dd438316e6a
7
- data.tar.gz: 7c7583c4197f06951d76bc784a7444ec3c2c17bfcad0e466d7d3c3449407ec1de3f93b314f83c1e40c83322106554edabe6f5f6f8239916b8529308cf0d65e90
6
+ metadata.gz: ae67297856bc7d27e71ab6740c9b73b7e033d24a5cd7f3b5d9d3f4cc032fa0e7f36f1b5f63375529aa954af4f6a34be0385cbdf5d2d8abeabfe997aaff44bbf2
7
+ data.tar.gz: 05126f7fe63a2027f731f56138bffd965aebf46e0943da182b2d35cb337f6df860a0e097bc1293522ce4256706ae429fd944071aa0543516ed16641ca7ecba26
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.6.0] - 2021-11-15
4
+ ### Added
5
+ - Added option horizontal_scroll_split to view helper, which defaults to false. This option affects
6
+ horizontal orientation only. If set to false, the
7
+ different days of the calendar scroll together horizontally, which is more consistent with the
8
+ behaviour of the vertical layout. If set to true, the days scroll independently.
9
+
10
+ ## [0.5.1] - 2021-11-15
11
+ ### Fixed
12
+ - Fixed reliance of calendar on legacy function to
13
+ calculate event height
14
+
15
+ ## [0.5.0] - 2021-11-14
16
+ - Removed images for the README from the gem, sry :(
17
+
18
+ ## [0.4.0] - 2021-11-14
19
+ ### Added
20
+ - Added compatibilty with the attribute and end_attribute options in the view helper
21
+ - Added documentation to README
22
+
3
23
  ## [0.3.0] - 2021-11-14
4
24
  ### Fixed
5
25
  - Fix issue with css styles when including style of this gem and simple_calendar
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- simple_calendar-timeslot (0.3.0)
4
+ simple_calendar-timeslot (0.6.0)
5
5
  simple_calendar (~> 2.0)
6
6
 
7
7
  GEM
@@ -90,6 +90,8 @@ GEM
90
90
  nokogiri (1.12.5)
91
91
  mini_portile2 (~> 2.6.1)
92
92
  racc (~> 1.4)
93
+ nokogiri (1.12.5-x86_64-darwin)
94
+ racc (~> 1.4)
93
95
  parallel (1.21.0)
94
96
  parser (3.0.2.0)
95
97
  ast (~> 2.4.1)
data/README.md CHANGED
@@ -2,10 +2,18 @@
2
2
 
3
3
  This is an extension of the rubygem `simple_calendar` by Chris Oliver aka excid3. It allows
4
4
  for simple calendar creation in a Ruby on Rails app with an timeslot representation of events
5
- in a 24h day. This helps to visually grasps the length of events and the time between them. In case of overlapping, the respective events are shown side-by-side. It is also possible to categorise events in buckets according to some function, then they will be shown next to one another in the 24h timeline.
5
+ in a 24h day.
6
+
7
+ This helps to visually grasps the length of events and the time between them. In case of overlapping, the respective events are shown side-by-side. It is also possible to categorise events in buckets according to some function, then they will be shown next to one another in the 24h timeline.
8
+
6
9
  Horizontal and vertical layout is selectable via options, just like many other ones.
7
10
 
8
- TODO: show examples
11
+ Horizontal example
12
+ ![Horizontal Calendar](https://github.com/1klap/simple_calendar-timeslot/blob/96475bf7c354b7e0318a9421e155588d96517fc3/img/simple_calendar-timeslot_horizontal.png?raw=true)
13
+
14
+ Vertical example
15
+ ![Vertical Calendar](https://github.com/1klap/simple_calendar-timeslot/blob/96475bf7c354b7e0318a9421e155588d96517fc3/img/simple_calendar-timeslot_vertical.png?raw=true)
16
+
9
17
 
10
18
  ## Installation
11
19
 
@@ -23,12 +31,56 @@ Or install it yourself as:
23
31
 
24
32
  $ gem install simple_calendar-timeslot
25
33
 
26
- TODO: include stylesheet, show sprockets and scss usecases
34
+
35
+ **Important** Then include the stylesheet in your rails app.
36
+
37
+ If you have an `application.css` file, include the following:
38
+ ```ruby
39
+ *= require simple_calendar-timeslot
40
+ ```
41
+ If you use an SCSS file (`application.scss`), add the following line instead:
42
+ ```ruby
43
+ @import 'simple_calendar-timeslot';
44
+ ```
27
45
 
28
46
  ## Usage
29
47
 
30
48
  TODO: Write usage instructions here
31
49
 
50
+ Your model must implement a `start_time` and `end_time` function,
51
+ or you can specify alternatives as options to the call below
52
+ as `attribute: :my_start_time` and `end_attribute: :my_end_time`.
53
+
54
+ ```erb
55
+ <%= timeslot_calendar(events: @events,
56
+ number_of_days: 2,
57
+ px_per_minute: 1.5,
58
+ orientation: :horizontal,
59
+ horizontal_height_px: 250,
60
+ # attribute: :my_start_time,
61
+ # display_grid: false,
62
+ # display_bucket_title: :event_type,
63
+ # bucket_title_size: 30,
64
+ # grid_width: "20px",
65
+ # split_by_type: :event_type
66
+ ) do |event| %>
67
+ <div class="timeslot-event">
68
+ <%= event.title %>
69
+ </div>
70
+ <% end %>
71
+
72
+ ```
73
+
74
+ Shortversion in the meantime:
75
+ - orientation (:vertical, :horizontal, default: :vertical)
76
+ - horizontal_height_px default: 300
77
+ - split_by_type (model function to call in case of bucketung f.ex.`:event_type`, default: false)
78
+ - px_per_minute default: 0.65
79
+ - display_bucket_title (model function to call in case of bucketung f.ex.`:event_type_name`, default: false)
80
+ - bucket_title_size default: 20
81
+ - grid_width default: 20px
82
+ - display_grid default: true
83
+
32
84
  ## Development
33
85
 
34
86
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -9,6 +9,10 @@
9
9
  display: flex;
10
10
  flex-direction: column;
11
11
  }
12
+ .timeslot-calendar .days-wrapper-horizontal.scroll-link {
13
+ overflow-x: auto;
14
+ overflow-y: hidden;
15
+ }
12
16
  .timeslot-calendar .day-wrapper {
13
17
  flex: 1 1 0;
14
18
  }
@@ -21,6 +25,8 @@
21
25
  display: flex;
22
26
  flex-direction: column;
23
27
  position: relative;
28
+ }
29
+ .timeslot-calendar .day-content-horizontal.scroll-split {
24
30
  overflow-x: auto;
25
31
  overflow-y: hidden;
26
32
  }
@@ -66,7 +66,7 @@
66
66
  <% end %>
67
67
  </div>
68
68
  <% elsif calendar.orientation == :horizontal %>
69
- <div class="days-wrapper-horizontal">
69
+ <div class="days-wrapper-horizontal <%= calendar.horizontal_scroll_split ? "" : "scroll-link" %>">
70
70
  <% date_range.slice(0, 7).each do |day| %>
71
71
  <div class="day-wrapper">
72
72
  <div class="day-title-row">
@@ -78,7 +78,7 @@
78
78
  </span>
79
79
  </div>
80
80
  <%= content_tag :div, class: calendar.td_classes_for(day) do %>
81
- <div class="day-content-horizontal">
81
+ <div class="day-content-horizontal <%= calendar.horizontal_scroll_split ? "scroll-split" : "" %>">
82
82
  <div class="day-content-horizontal-inner" style="width:<%=calendar.height%>px;height:<%=calendar.horizontal_height_px%>px">
83
83
  <% if calendar.display_grid %>
84
84
  <div class="hour-indicator-col-horizontal" style="z-index:-10;">
@@ -1,53 +1,31 @@
1
1
  require "simple_calendar"
2
2
 
3
3
  module SimpleCalendar
4
- module Timeslot
4
+ module Timeslot
5
5
  class TimeslotCalendar < SimpleCalendar::Calendar
6
6
  MINUTE_HEIGHT_PX = 0.65
7
7
  FIRST_HOUR_SLOT = 0
8
-
9
- def height
10
- h = (24 - TimeslotCalendar::FIRST_HOUR_SLOT) * 60 * px_per_minute
11
- h = h+bucket_title_size if display_bucket_title
12
- h
13
- end
14
-
15
- def event_height(event, day)
16
- minutes = if event.start_time.to_date != day
17
- (event.end_time - event.end_time.midnight)/60
18
- elsif event.start_time.to_date < event.end_time.to_date
19
- (event.end_time.midnight - 60 - event.start_time)/60
20
- else
21
- event.duration
22
- end
23
- minutes * px_per_minute
24
- end
25
-
26
- def event_top_distance(event, day)
27
- return 0 if event.start_time.to_date != day
28
- (event.start_time.hour - TimeslotCalendar::FIRST_HOUR_SLOT) * 60 * px_per_minute + event.start_time.min * px_per_minute
29
- end
30
-
8
+
31
9
  def orientation
32
10
  @options.fetch(:orientation, :vertical)
33
11
  end
34
-
12
+
35
13
  def horizontal_height_px
36
14
  @options.fetch(:horizontal_height_px, 300)
37
15
  end
38
-
16
+
39
17
  def split_by_type
40
18
  @options.fetch(:split_by_type, false)
41
19
  end
42
-
20
+
43
21
  def px_per_minute
44
22
  @options.fetch(:px_per_minute, TimeslotCalendar::MINUTE_HEIGHT_PX)
45
23
  end
46
-
24
+
47
25
  def display_bucket_title
48
26
  @options.fetch(:display_bucket_title, false)
49
27
  end
50
-
28
+
51
29
  def bucket_title_size
52
30
  if display_bucket_title
53
31
  @options.fetch(:bucket_title_size, 20)
@@ -55,11 +33,11 @@ module SimpleCalendar
55
33
  0
56
34
  end
57
35
  end
58
-
36
+
59
37
  def grid_top_offset(hour)
60
38
  4.16666667 * hour
61
39
  end
62
-
40
+
63
41
  def grid_width
64
42
  if display_grid
65
43
  @options.fetch(:grid_width, "20px")
@@ -67,11 +45,39 @@ module SimpleCalendar
67
45
  0
68
46
  end
69
47
  end
70
-
48
+
71
49
  def display_grid
72
50
  @options.fetch(:display_grid, true)
73
51
  end
74
-
52
+
53
+ def horizontal_scroll_split
54
+ @options.fetch(:horizontal_scroll_split, false)
55
+ end
56
+
57
+ def height
58
+ #h = (24 - TimeslotCalendar::FIRST_HOUR_SLOT) * 60 * px_per_minute
59
+ h = 24 * 60 * px_per_minute
60
+ h = h+bucket_title_size if display_bucket_title
61
+ h
62
+ end
63
+
64
+ def event_height(event, day)
65
+ minutes = if event.send(attribute).to_date != day
66
+ (event.send(end_attribute) - event.send(end_attribute).midnight)/60
67
+ elsif event.send(attribute).to_date < event.send(end_attribute).to_date
68
+ (event.send(end_attribute).midnight - 60 - event.send(attribute))/60
69
+ else
70
+ (event.send(end_attribute) - event.send(attribute))/60
71
+ end
72
+ minutes * px_per_minute
73
+ end
74
+
75
+ def event_top_distance(event, day)
76
+ return 0 if event.send(attribute).to_date != day
77
+ #(event.send(attribute).hour - TimeslotCalendar::FIRST_HOUR_SLOT) * 60 * px_per_minute + event.send(attribute).min * px_per_minute
78
+ event.send(attribute).hour * 60 * px_per_minute + event.send(attribute).min * px_per_minute
79
+ end
80
+
75
81
  def split_into_buckets(events)
76
82
  if split_by_type
77
83
  events.group_by{|e| e.send split_by_type}.values
@@ -79,33 +85,34 @@ module SimpleCalendar
79
85
  [events]
80
86
  end
81
87
  end
82
-
88
+
83
89
  def slot_events(events, day)
84
90
  r = {}
85
91
  events.each do |event|
86
92
  r[event] = [0, 0, event_height(event, day), event_top_distance(event, day)]
87
93
  end
88
- #
94
+ # Credit: https://stackoverflow.com/questions/11311410/visualization-of-calendar-events-algorithm-to-layout-events-with-maximum-width
95
+ # Author: Markus Jarderot (https://stackoverflow.com/users/22364/markus-jarderot)
89
96
  columns = [[]]
90
97
  last_event_ending = nil
91
98
  events.each do |event|
92
- if(!last_event_ending.nil? && event.start_time > last_event_ending)
99
+ if !last_event_ending.nil? && event.send(attribute) > last_event_ending
93
100
  pack_events(r, columns)
94
- colums = [[]]
101
+ columns = [[]]
95
102
  last_event_ending = nil
96
103
  end
97
104
  placed = false
98
105
  columns.each do |col|
99
- if !events_collide(r, col.last, event)
106
+ unless events_collide(r, col.last, event)
100
107
  col << event
101
108
  placed = true
102
109
  break
103
110
  end
104
111
  end
105
- if !placed
112
+ unless placed
106
113
  columns << [event]
107
114
  end
108
- event_end_time = event.start_time + event.duration.minutes
115
+ event_end_time = event.send(end_attribute)
109
116
  if last_event_ending.nil? || event_end_time > last_event_ending
110
117
  last_event_ending = event_end_time
111
118
  end
@@ -115,7 +122,9 @@ module SimpleCalendar
115
122
  end
116
123
  r
117
124
  end
118
-
125
+
126
+ private
127
+
119
128
  def pack_events(r, columns)
120
129
  num_columns = columns.size.to_f
121
130
  columns.each_with_index do |col, iter_col|
@@ -126,14 +135,14 @@ module SimpleCalendar
126
135
  end
127
136
  end
128
137
  end
129
-
138
+
130
139
  def events_collide(r, event1, event2)
131
140
  return false if event1.nil? || event2.nil?
132
141
  event1_bottom = r[event1][3] + r[event1][2]
133
142
  event2_bottom = r[event2][3] + r[event2][2]
134
143
  event1_bottom > r[event2][3] && r[event1][3] < event2_bottom
135
144
  end
136
-
145
+
137
146
  def expand_event(r, event, iter_col, columns)
138
147
  col_span = 1
139
148
  columns.each_with_index do |column, index|
@@ -146,8 +155,6 @@ module SimpleCalendar
146
155
  end
147
156
  col_span
148
157
  end
149
-
150
- private
151
158
  end
152
159
  end
153
160
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module SimpleCalendar
4
4
  module Timeslot
5
- VERSION = "0.3.0"
5
+ VERSION = "0.6.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_calendar-timeslot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kim Laplume
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-14 00:00:00.000000000 Z
11
+ date: 2021-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simple_calendar