aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorZog2018-01-19 08:22:24 +0100
committerZog2018-02-02 14:31:32 +0100
commitc13c94fe665fdbe2c434c8bfadd44a0988ecea60 (patch)
treecbf70b0af9dd0bbbe4129384adcf5db39117fe33 /app
parent9f30b2debe7ece403d9e588df9763c119436d967 (diff)
downloadchouette-core-c13c94fe665fdbe2c434c8bfadd44a0988ecea60.tar.bz2
Refs #3542 @4h; First UI
Still missing: - Pagination - Filters
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/components/_referential_overview.sass171
-rw-r--r--app/helpers/referentials_helper.rb5
-rw-r--r--app/services/referential_overview.rb218
-rw-r--r--app/views/referentials/_overview.html.slim31
-rw-r--r--app/views/referentials/show.html.slim2
5 files changed, 427 insertions, 0 deletions
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
new file mode 100644
index 000000000..0af5a99f7
--- /dev/null
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -0,0 +1,171 @@
+.referential-overview
+ display: flex
+ margin-top: 50px
+ $left-size: 100px
+ .head
+ height: $left-size
+ border-top: 1px solid $lightgrey
+ .line
+ height: 80px
+ .left
+ flex: 0 0
+ background: $lightgrey
+ min-width: $left-size
+ overflow: hidden
+ border-right: 1px solid white
+ .head
+ position: relative
+ border-bottom: 1px solid white
+ border-right: 1px solid $lightgrey
+ .dates, .lines
+ position: absolute
+ font-size: 0.8em
+ z-index: 2
+ .dates
+ right: 20px
+ top: 20px
+ .lines
+ left: 20px
+ bottom: 20px
+ &:after
+ position: absolute
+ border-left: ($left-size - 2px)/2 solid transparent
+ border-bottom: ($left-size - 2px)/2 solid transparent
+ border-right: ($left-size - 2px)/2 solid white
+ border-top: ($left-size - 2px)/2 solid white
+ z-index: 1
+ top: 0
+ right: 0
+ width: 0
+ content: ""
+ .line
+ padding: 15px 10px 10px
+ border-bottom: 1px solid white
+ font-size: 0.8em
+ &:last-child
+ border-bottom: 1px solid $grey
+ .number
+ border-radius: 100px
+ display: inline-block
+ width: 20px
+ height: 20px
+ text-align: center
+ padding-top: 1px
+ text-decoration: none
+ color: black
+ border: 1px solid $grey
+ .name
+ display: inline-block
+ width: $left-size - 50px()
+ white-space: nowrap
+ line-height: 20px
+ margin-left: 5px
+ text-overflow: ellipsis
+ overflow: hidden
+ vertical-align: bottom
+ color: black
+ text-decoration: none
+
+ .company, .mode
+ font-size: 0.9em
+ margin-top: 5px
+ white-space: nowrap
+ text-overflow: ellipsis
+ overflow: hidden
+
+ .mode
+ margin-top: 0
+ text-transform: uppercase
+ color: $grey
+ font-weight: bold
+ .right
+ flex: 1 1
+ overflow-x: scroll
+ overflow-y: hidden
+ .head
+ white-space: nowrap
+ .week
+ display: inline-block
+ position: relative
+ height: 100%
+ .week-span
+ left: 5px
+ top: 10px
+ right: 30px
+ white-space: nowrap
+ overflow: hidden
+ text-overflow: ellipsis
+ position: absolute
+
+ .week-number
+ background-color: lightgrey
+ color: white
+ position: absolute
+ top: 0
+ right: 0
+ padding: 2px 4px
+
+ &:after
+ position: absolute
+ right: 0
+ top: 0
+ bottom: 0
+ background: $grey
+ width: 1px
+ content: ""
+
+ .days
+ position: relative
+ top: 50%
+ height: 50%
+ border-top: 1px solid $grey
+ border-bottom: 1px solid $grey
+
+ .day
+ float: left
+ border-left: 1px solid $grey
+ box-sizing: border-box
+ padding-left: 5px
+ padding-top: 3px
+ position: relative
+ height: 100%
+ .name, .number
+ position: absolute
+ left: 10px
+ right: 10px
+ top: 50%
+ transform: translateY(-50%)
+ margin-top: 10px
+ .name
+ font-weight: bold
+ font-size: 0.8em
+ margin-top: -10px
+ &:first-child
+ border: none
+ &.weekend
+ background: $lightgrey
+
+ .line
+ border-bottom: 1px solid $grey
+ position: relative
+ overflow: hidden
+
+ .period
+ height: 100%
+ top: 0
+ background: rgb(219, 249, 196)
+ position: absolute
+ &:before
+ content: ""
+ border-right: 1px dashed $grey
+ top: -100%
+ bottom: -100%
+ position: absolute
+ right: -1px
+ z-index: 10
+ &.empty
+ background: rgb(244, 67, 67)
+ background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#e49393 10px,#e49393 20px)
+ &.accepted
+ background: #f19039
+ background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#f19039 10px,#f19039 20px)
diff --git a/app/helpers/referentials_helper.rb b/app/helpers/referentials_helper.rb
index 01e5a5879..8251377aa 100644
--- a/app/helpers/referentials_helper.rb
+++ b/app/helpers/referentials_helper.rb
@@ -10,4 +10,9 @@ module ReferentialsHelper
t('true')
end
end
+
+ def referential_overview referential
+ service = ReferentialOverview.new referential, self
+ render partial: "referentials/overview", locals: {referential: referential, overview: service}
+ end
end
diff --git a/app/services/referential_overview.rb b/app/services/referential_overview.rb
new file mode 100644
index 000000000..5b0e144db
--- /dev/null
+++ b/app/services/referential_overview.rb
@@ -0,0 +1,218 @@
+class ReferentialOverview
+ attr_reader :h
+
+ def initialize referential, h
+ @referential = referential
+ @page = 1
+ @h = h
+ end
+
+ def lines
+ @referential.metadatas_lines.includes(:company).page(@page).map{|l| Line.new(l, @referential, period.first, h)}
+ end
+
+ def period
+ @period ||= @referential.metadatas_period || []
+ end
+
+ def weeks
+ @weeks = {}
+ period.map do |d|
+ @weeks[Week.key(d)] ||= Week.new(d, period.last, h)
+ end
+ @weeks.values
+ end
+
+ class Line
+ attr_reader :h
+ attr_reader :referential_line
+
+ delegate :name, :number, :company, :color, :transport_mode, to: :referential_line
+
+ def initialize line, referential, start, h
+ @referential_line = line
+ @referential = referential
+ @start = start
+ @h = h
+ end
+
+ def period
+ @period ||= @referential.metadatas_period || []
+ end
+
+ def referential_periods
+ @referential_periods ||= @referential.metadatas.include_lines([@referential_line.id]).map(&:periodes).flatten.sort{|p1, p2| p1.first <=> p2.first}
+ end
+
+ def periods
+ @periods ||= begin
+ periods = referential_periods.flatten.map{|p| Period.new p, @start, h}
+ periods = fill_periods periods
+ periods = merge_periods periods
+ periods
+ end
+ end
+
+ def fill_periods periods
+ [].tap do |out|
+ previous = OpenStruct.new(end: period.first - 1.day)
+ (periods + [OpenStruct.new(start: period.last + 1.day)]).each do |p|
+ if p.start > previous.end + 1.day
+ out << Period.new((previous.end+1.day..p.start-1.day), @start, h).tap{|p| p.empty = true}
+ end
+ out << p if p.respond_to?(:end)
+ previous = p
+ end
+ end
+ end
+
+ def merge_periods periods
+ [].tap do |out|
+ current = periods.first
+ periods[1..-1].each do |p|
+ if p.start <= current.end
+ current.end = p.end
+ else
+ out << current
+ current = p
+ end
+ end
+ out << current
+ end
+ end
+
+ def width
+ period.count * Day::WIDTH
+ end
+
+ def html_style
+ {
+ width: "#{width}px"
+ }.map{|k, v| "#{k}: #{v}"}.join("; ")
+ end
+
+ def html_class
+ out = []
+ out
+ end
+
+ class Period
+ attr_accessor :empty
+ attr_accessor :h
+
+ def initialize period, start, h
+ @period = period
+ @start = start
+ @empty = false
+ @h = h
+ end
+
+ def start
+ @period.first
+ end
+
+ def end
+ @period.last
+ end
+
+ def end= val
+ @period = (start..val)
+ end
+
+ def width
+ @period.count * Day::WIDTH
+ end
+
+ def left
+ (@period.first - @start).to_i * Day::WIDTH
+ end
+
+ def html_style
+ {
+ width: "#{width}px",
+ left: "#{left}px",
+ }.map{|k, v| "#{k}: #{v}"}.join("; ")
+ end
+
+ def empty?
+ @empty
+ end
+
+ def accepted?
+ @period.count < 7
+ end
+
+ def title
+ h.l(self.start, format: :short) + " - " + h.l(self.end, format: :short)
+ end
+
+ def html_class
+ out = []
+ out << "empty" if empty?
+ out << "accepted" if accepted?
+ out
+ end
+ end
+ end
+
+ class Week
+ attr_reader :h
+ attr_reader :start_date
+ attr_reader :end_date
+
+ def initialize start_date, boundary, h
+ @start_date = start_date.to_date
+ @end_date = [start_date.end_of_week, boundary].min.to_date
+ @h = h
+ end
+
+ def self.key date
+ date.beginning_of_week.to_s
+ end
+
+ def span
+ h.l(@start_date, format: "#{@start_date.day}-#{@end_date.day} %b")
+ end
+
+ def number
+ h.l(@start_date, format: "%W")
+ end
+
+ def period
+ (@start_date..@end_date)
+ end
+
+ def days
+ period.map {|d| Day.new d, h }
+ end
+ end
+
+ class Day
+ attr_reader :h
+
+ WIDTH=50
+
+ def initialize date, h
+ @date = date
+ @h = h
+ end
+
+ def html_style
+ {width: "#{WIDTH}px"}.map{|k, v| "#{k}: #{v}"}.join("; ")
+ end
+
+ def html_class
+ out = []
+ out << "weekend" if [0, 6].include?(@date.wday)
+ out
+ end
+
+ def short_name
+ h.l(@date, format: "%a")
+ end
+
+ def number
+ @date.day
+ end
+ end
+end
diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim
new file mode 100644
index 000000000..03c72752e
--- /dev/null
+++ b/app/views/referentials/_overview.html.slim
@@ -0,0 +1,31 @@
+.referential-overview
+ .left
+ .head
+ .dates= I18n.t("referentials.overview.head.dates")
+ .lines= I18n.t("referentials.overview.head.lines")
+ .lines
+ - overview.lines.each do |line|
+ .line
+ a.number style="background-color: #{line.color.present? ? "##{line.color}" : 'whitesmoke'}" title=line.name
+ = line.number
+ - unless line.number == line.name
+ a.name title=line.name
+ = line.name
+ .company= line.company&.name
+ .mode= line.transport_mode
+ .right
+ .head
+ - overview.weeks.each do |week|
+ .week
+ .week-span= week.span
+ .week-number= week.number
+ .days
+ - week.days.each do |day|
+ .day style=day.html_style class=day.html_class
+ .name= day.short_name
+ .number= day.number
+ .lines
+ - overview.lines.each do |line|
+ .line style=line.html_style class=line.html_class
+ - line.periods.each do |period|
+ .period style=period.html_style class=period.html_class title=period.title
diff --git a/app/views/referentials/show.html.slim b/app/views/referentials/show.html.slim
index 6c88f5b81..289e802d7 100644
--- a/app/views/referentials/show.html.slim
+++ b/app/views/referentials/show.html.slim
@@ -67,6 +67,8 @@
= replacement_msg t('referential_lines.search_no_results')
+ = referential_overview resource
+
/ Modal(s)
= modalbox 'purgeModal' do
= simple_form_for [@referential, CleanUp.new] do |f|