diff --git a/app/controllers/targets_controller.rb b/app/controllers/targets_controller.rb index c256d05..c5520b1 100644 --- a/app/controllers/targets_controller.rb +++ b/app/controllers/targets_controller.rb @@ -5,8 +5,8 @@ class TargetsController < ApplicationController include Concerns::Finders - before_action :find_goal_by_goal_id, - only: [:index, :new, :create, :edit, :update, :destroy, :reapply, :toggle_exposure] + before_action :find_goal_by_goal_id, only: [:index, :new, :create, :show, :edit, :update, + :destroy, :reapply, :toggle_exposure] before_action :find_quantity_by_quantity_id, only: [:toggle_exposure, :subthresholds] before_action :authorize #before_action :set_view_params @@ -42,6 +42,24 @@ class TargetsController < ApplicationController end end + def show + # TODO: take into account nullified targets, after introduced + @effective_from = params[:date].to_date + targets = @goal.targets.joins(:quantity).where( + "(quantity_id, effective_from) IN (?)", + @goal.targets.select(:quantity_id, 'MAX(effective_from) as effective_from') + .where("effective_from <= ?", @effective_from).group(:quantity_id) + ).reorder('quantities.depth DESC') + + @quantities = {} + targets.each do |t| + unless @quantities.has_key?(t.quantity.parent) + t.quantity.ancestors.each { |q| @quantities[q] = nil } + end + @quantities[t.quantity] = t + end + end + def edit @effective_from = params[:date].to_date @targets = @goal.targets.joins(:quantity).where(effective_from: @effective_from) @@ -123,7 +141,7 @@ class TargetsController < ApplicationController @targets_by_date = Hash.new { |h,k| h[k] = {} } @goal.targets.includes(:item, thresholds: [:quantity]).reject(&:new_record?) - .each { |t| @targets_by_date[t.effective_from][t.thresholds.first.quantity] = t } + .each { |t| @targets_by_date[t.effective_from][t.quantity] = t } end def set_view_params diff --git a/app/helpers/targets_helper.rb b/app/helpers/targets_helper.rb index 4b3bcc3..22f96fa 100644 --- a/app/helpers/targets_helper.rb +++ b/app/helpers/targets_helper.rb @@ -1,4 +1,17 @@ module TargetsHelper + def target_markup(date, quantity, target) + content = "#{' '*quantity.depth}#{quantity.name} #{target.to_s}" + + classes = [] + if date == target&.effective_from + classes << 'bolded' if @goal.quantities.include?(quantity) + else + classes << 'dimmed' + end + + content_tag(:span, content, {class: classes}, false) + end + def action_links(date) link_to(l(:button_reapply), reapply_goal_target_path(@goal, date, @view_params), {remote: true, class: "icon icon-reload"}) + diff --git a/app/models/target.rb b/app/models/target.rb index 3c6aaee..01ced78 100644 --- a/app/models/target.rb +++ b/app/models/target.rb @@ -37,7 +37,8 @@ class Target < ActiveRecord::Base end def to_s - thresholds.last.quantity.description % - thresholds.map { |t| [t.quantity.name, "#{t.value} [#{t.unit.shortname}]"] }.to_h + thresholds.last.quantity.description % thresholds.map do |t| + [t.quantity.name.to_sym, "#{t.value} [#{t.unit.shortname}]"] + end.to_h end end diff --git a/app/views/foods/_index.html.erb b/app/views/foods/_index.html.erb index d6cd417..fcf1b22 100644 --- a/app/views/foods/_index.html.erb +++ b/app/views/foods/_index.html.erb @@ -18,9 +18,8 @@ <% @foods.each do |f| %> <% next if f.new_record? %> - - + + <%= link_to '', toggle_food_path(f), { remote: true, method: :post, @@ -29,13 +28,13 @@ <%= f.name %> <%= f.notes %> - <%= f.ref_amount %> [<%= f.ref_unit.shortname %>] + <%= f.ref_amount %> [<%= f.ref_unit.shortname %>] <%= f.group %> <%= f.source.name if f.source.present? %> <%= ", #{f.source_ident}" if f.source_ident.present? %> - <%= action_links(f, :index) %> + <%= action_links(f, :index) %> <% end %> diff --git a/app/views/foods/_nutrients.html.erb b/app/views/foods/_nutrients.html.erb index 46a45f7..cf5d8fa 100644 --- a/app/views/foods/_nutrients.html.erb +++ b/app/views/foods/_nutrients.html.erb @@ -34,19 +34,19 @@ <% extra_quantities = @foods.values.first.keys - @quantities %> <% @foods.each do |food, nutrients| %> - <% row_class = "food#{' hidden' if food.hidden} #{cycle('odd', 'even')}" %> + <% row_class = "food#{' dimmed' if food.hidden} #{cycle('odd', 'even')}" %> - <%= food.name %> <% @quantities.each do |q| %> - + <%= format_value(nutrients[q], @food_summary[:precision][q], @food_summary[:mfu_unit][q]) %> <% end %> - <%= action_links(food, :nutrients) %> + <%= action_links(food, :nutrients) %> @@ -55,17 +55,17 @@ else rows = 1 end %> - <%= food.name %> <% @quantities.each do |q| %> - + <%= q.name %> -

<%= format_value(nutrients[q]) %>

+

<%= format_value(nutrients[q]) %>

<% end %> - + <%= action_links(food, :nutrients) %> @@ -74,9 +74,9 @@ <% extra_quantities.each_slice(@quantities.length) do |eqs| %> <% eqs.each do |q| %> - + <%= q.name if nutrients[q] %> -

<%= format_value(nutrients[q]) %>

+

<%= format_value(nutrients[q]) %>

<% end %> <% if @quantities.length > eqs.length %> diff --git a/app/views/goals/_index.html.erb b/app/views/goals/_index.html.erb index ad6afd8..a9c8647 100644 --- a/app/views/goals/_index.html.erb +++ b/app/views/goals/_index.html.erb @@ -10,7 +10,7 @@ <% @goals.each do |g| %> - +
<%= checked_image g.is_binding %><%= link_to g.name, goal_targets_path(g) %>
@@ -20,7 +20,7 @@ <%= g.description %> - + <%= delete_link(g, {remote: true, data: {}}) unless g.is_binding %> diff --git a/app/views/meals/_show.html.erb b/app/views/meals/_show.html.erb index 99a0714..858d010 100644 --- a/app/views/meals/_show.html.erb +++ b/app/views/meals/_show.html.erb @@ -1,6 +1,6 @@ - + <%= "#{t '.label_meal'} ##{index+1}" %> <% if m.eaten_at %> <%= " at #{m.eaten_at.strftime('%R')}" %> @@ -34,12 +34,12 @@ <% end %> - + <% @quantities.each do |q| %> - + <%= format_value(@ingredient_summary[m][q], @ingredient_summary[:precision][q]) %> <% end %> - <%= meal_links(m) %> + <%= meal_links(m) %> diff --git a/app/views/meals/_show_date.html.erb b/app/views/meals/_show_date.html.erb index 008ed16..23daa09 100644 --- a/app/views/meals/_show_date.html.erb +++ b/app/views/meals/_show_date.html.erb @@ -1,12 +1,12 @@ - +

<%= date == Date.current ? 'Today' : date.strftime('%F') %>

- + <% @quantities.each do |q| %> - + <%= format_value(@ingredient_summary[date][q], @ingredient_summary[:precision][q]) %> <% end %> diff --git a/app/views/meals/_show_ingredient.html.erb b/app/views/meals/_show_ingredient.html.erb index d284b69..6547c22 100644 --- a/app/views/meals/_show_ingredient.html.erb +++ b/app/views/meals/_show_ingredient.html.erb @@ -1,17 +1,15 @@ - <%= i.food.name %> - + <%= i.food.name %> + <%= "%g" % i.amount %> <%= "[#{i.food.ref_unit.shortname}]" unless i.food.ref_unit == @amount_mfu_unit %> <% @quantities.each do |q| %> - + <%= format_value(@ingredients[i][q], @ingredient_summary[:precision][q], @ingredient_summary[:mfu_unit][q]) %> <% end %> - - <%# Moved to helper to avoid spaces between buttons %> - <%= adjustment_buttons(i) %> - + <%# Moved buttons to helper to avoid spaces between buttons %> + <%= adjustment_buttons(i) %> diff --git a/app/views/measurements/_index.html.erb b/app/views/measurements/_index.html.erb index 69ea208..bcbcdee 100644 --- a/app/views/measurements/_index.html.erb +++ b/app/views/measurements/_index.html.erb @@ -18,8 +18,8 @@ <% @measurements.each do |m| %> <% next if m.new_record? %> - <%= format_datetime(m) %> - + <%= format_datetime(m) %> +
<%= link_to m.routine.name, readouts_measurement_routine_path(m.routine) %>
@@ -29,7 +29,7 @@ <%= m.notes %> <%= m.source.name if m.source.present? %> - <%= action_links(m) %> + <%= action_links(m) %> <% end %> diff --git a/app/views/measurements/_readouts.html.erb b/app/views/measurements/_readouts.html.erb index 8c74fa9..a055e8b 100644 --- a/app/views/measurements/_readouts.html.erb +++ b/app/views/measurements/_readouts.html.erb @@ -32,14 +32,14 @@ <% @measurements.each do |measurement, readouts| %> <% row_class = "measurement #{cycle('odd', 'even')}" %> - <%= format_datetime(measurement) %> <% @quantities.each do |q| %> - <%= format_value(readouts[q]) %> + <%= format_value(readouts[q]) %> <% end %> - <%= action_links(measurement) %> + <%= action_links(measurement) %> @@ -48,17 +48,17 @@ else rows = 1 end %> - <%= format_datetime(measurement) %> <% @quantities.each do |q| %> - + <%= q.name %> -

<%= format_value(readouts[q]) %>

+

<%= format_value(readouts[q]) %>

<% end %> - + <%= action_links(measurement) %> @@ -67,9 +67,9 @@ <% extra_quantities.each_slice(@quantities.length) do |eqs| %> <% eqs.each do |q| %> - + <%= q.name if readouts[q] %> -

<%= format_value(readouts[q]) %>

+

<%= format_value(readouts[q]) %>

<% end %> <% if @quantities.length > eqs.length %> diff --git a/app/views/quantities/_index.html.erb b/app/views/quantities/_index.html.erb index cae4169..54ad648 100644 --- a/app/views/quantities/_index.html.erb +++ b/app/views/quantities/_index.html.erb @@ -15,23 +15,19 @@ <% Quantity.each_with_level(@quantities) do |q, level| %> - <% - next if q.new_record? - quantity_class = "quantity" - quantity_class += " primary" unless q.exposures.empty? - quantity_class += " project idnt idnt-#{level+1}" - %> - - -
+ <% next if q.new_record? %> + + <%# NOTE: 'name' class only for proper indentation by 'idnt-N' %> + +
<%= q.name %>
<%= order_links(q) %> <%= q.domain %> - <%= q.description %> + <%= q.description %> <%= checked_image q.formula %> - <%= action_links(q) %> + <%= action_links(q) %> <% end %> diff --git a/app/views/quantities/edit.js.erb b/app/views/quantities/edit.js.erb index db7ef28..20c160f 100644 --- a/app/views/quantities/edit.js.erb +++ b/app/views/quantities/edit.js.erb @@ -1,7 +1,7 @@ $('tr[id=quantity-<%= @quantity.id %>]').nextUntil('tr.quantity').remove(); var columns = $('table > thead > tr > th').length; $('tr[id=quantity-<%= @quantity.id %>]').nextUntil('tr.quantity').addBack().last().after( - '' + - '
<%= j render partial: "quantities/edit_form" %>
' + + '' + + '
<%= j render partial: "quantities/edit_form" %>
' + '' ); diff --git a/app/views/sources/index.html.erb b/app/views/sources/index.html.erb index 86eb926..8e658f7 100644 --- a/app/views/sources/index.html.erb +++ b/app/views/sources/index.html.erb @@ -33,9 +33,9 @@ <% @sources.each do |s| %> <% next if s.new_record? %> - <%= s.name %> + <%= s.name %> <%= s.description %> - <%= delete_link source_path(s), data: {} %> + <%= delete_link source_path(s), data: {} %> <% end %> diff --git a/app/views/targets/_edit_form.html.erb b/app/views/targets/_edit_form.html.erb index bd621d2..4edc839 100644 --- a/app/views/targets/_edit_form.html.erb +++ b/app/views/targets/_edit_form.html.erb @@ -9,7 +9,8 @@

<%= submit_tag l(:button_save) %> <%= link_to l(:button_cancel), "#", - onclick: '$(this).closest("tr").remove(); return false;' %> + onclick: '$(this).closest("tr").nextUntil("tr.date", "tr.details").show() + .addBack().first().remove(); return false;' %>

<% end %> diff --git a/app/views/targets/_index.html.erb b/app/views/targets/_index.html.erb index 0a25b56..6e9827d 100644 --- a/app/views/targets/_index.html.erb +++ b/app/views/targets/_index.html.erb @@ -15,7 +15,7 @@ <% header.each_with_index do |row, i| %> <% if i == 0 %> - + <%= l(:field_effective_from) %> <% end %> @@ -56,53 +56,16 @@ <% @targets_by_date.each do |date, targets| %> - <% row_class = "date #{cycle('odd', 'even')}" %> - - - <%= format_date(date) %> + + + <%= link_to(format_date(date), goal_target_path(@goal, date), + {remote: true, class: 'icon icon-arrow-right'}) %> <% @quantities.each do |q| %> - <%= targets[q] %> + <%= raw targets[q].to_s %> <% end %> - <%= action_links(date) %> + <%= action_links(date) %> - - - <% rows = @quantities.empty? ? 1 : (targets.length - 1) / @quantities.length + 1 %> - - <%= format_date(date) %> - - <% @quantities.each do |q| %> - - <%= q.name %>

<%= targets.delete(q) %>

- - <% end %> - - <%= action_links(date) %> - - - - <% next if @quantities.empty? %> - <% targets.each_slice(@quantities.length) do |extras| %> - - <% extras.each do |q, t| %> - - <%= q.name %>

<%= t %>

- - <% end %> - <% if @quantities.length > extras.length %> - - <% end %> - - <% end %> - <% end %> diff --git a/app/views/targets/_show.html.erb b/app/views/targets/_show.html.erb new file mode 100644 index 0000000..7041dc7 --- /dev/null +++ b/app/views/targets/_show.html.erb @@ -0,0 +1,12 @@ + + + <%= link_to l(:button_close), "#", {class: 'icon icon-close', + onclick: '$(this).closest("tr").nextUntil("tr.date", "tr:not(.details)").show() + .addBack().first().remove(); return false;'} %> + + <% content = @quantities.keys.sort_by(&:lft).inject('') do |output, q| %> + <% raw "#{output}#{target_markup(@effective_from, q, @quantities[q])}\n" %> + <% end %> + <%= content %> + diff --git a/app/views/targets/edit.js.erb b/app/views/targets/edit.js.erb index 9098be4..3b35569 100644 --- a/app/views/targets/edit.js.erb +++ b/app/views/targets/edit.js.erb @@ -1,7 +1,9 @@ -$('tr[id=date-<%= @effective_from %>]').nextUntil('tr.primary', ':not(.date)').remove(); -var columns = $('table > thead > tr > th').length; -$('tr[id=date-<%= @effective_from %>]').nextUntil('tr.primary').addBack().last().after( - '
' + - '<%= j render partial: 'targets/edit_form' %>' + - '
' -); +$('tr[id=date-<%= @effective_from %>]').nextUntil('tr.date').remove('tr:not(.details)') + .hide().addBack().first().after( + '' + + '' + + '<%= j render partial: 'targets/edit_form' %>' + + '' + + '' + ); diff --git a/app/views/targets/show.js.erb b/app/views/targets/show.js.erb new file mode 100644 index 0000000..dd24bc8 --- /dev/null +++ b/app/views/targets/show.js.erb @@ -0,0 +1,4 @@ +var row = $('tr[id=date-<%= @effective_from %>]'); +row.nextUntil('tr.date').remove('tr.details').hide(); +row.after('<%= j render partial: 'targets/show' %>').next() + .addClass(row.hasClass('even') ? 'even' : 'odd'); diff --git a/app/views/units/index.html.erb b/app/views/units/index.html.erb index 36a7191..b6d5c3c 100644 --- a/app/views/units/index.html.erb +++ b/app/views/units/index.html.erb @@ -35,7 +35,7 @@ <%= u.shortname %> <%= u.name %> - <%= delete_link unit_path(u), data: {} %> + <%= delete_link unit_path(u), data: {} %> <% end %> diff --git a/assets/stylesheets/body_tracking.css b/assets/stylesheets/body_tracking.css index bfa10e4..3422131 100644 --- a/assets/stylesheets/body_tracking.css +++ b/assets/stylesheets/body_tracking.css @@ -1,10 +1,6 @@ -table.list tr.quantity.primary td.name {font-weight: bold;} +table.list .bolded {font-weight: bold;} +table.list .dimmed {opacity: 0.4} -table.list tr.food.hidden {opacity: 0.4} - -table.list .date, -table.list .name, -table.list td.quantity {text-align: left;} /* TODO: merge with .closable and/or remove .closable */ /* TODO: replace .quantity(head)(empty) with th.interim/.empty */ table.list .quantityhead {border-bottom: none;} @@ -12,8 +8,12 @@ table.list .quantityheadempty {border-top: none; border-bottom: none;} table.list th.interim {border-bottom: none;} table.list th.empty {border-top: none;} -table.list .action, -table.list .value {text-align: right; padding-right: 2px;} +table.list td.topleft {text-align: left; vertical-align: top; padding-left: 4px;} +table.list td.symmetric {padding-right: 4px;} +/* .right used with 'p' in _readouts/_nutrients; scope to 'td' after changing + * format of these views after _targets */ +table.list .right {text-align: right; padding-right: 2px; padding-left: 4px;} +table.list td.shrunk {width: 1px;} table.list .closable {padding-right: 0;} table.list .unwrappable {white-space: nowrap;} @@ -25,11 +25,6 @@ table.list .ellipsible { } table.list tr.buttonable {line-height: 1.8em;} -table.list td.form { - padding-right: 2px; - text-align: left; -} - table.list tbody tr.header:hover {background-color: unset;} table.list tbody tr.header:hover td {border: none;} diff --git a/init.rb b/init.rb index 2d140b4..adb0434 100644 --- a/init.rb +++ b/init.rb @@ -16,7 +16,7 @@ Redmine::Plugin.register :body_tracking do permission :view_body_trackers, { body_trackers: [:index], goals: [:index], - targets: [:index], + targets: [:index, :show], meals: [:index], measurement_routines: [:show], measurements: [:index, :readouts, :filter],