Measurement improvements
Added 'new' action. Separated js views for new/create/edit. Displaying taken_at in local time. Fixed readout destruction on edit.
This commit is contained in:
parent
65d811d9fb
commit
681c0279fb
@ -1,33 +1,31 @@
|
||||
class MeasurementsController < ApplicationController
|
||||
menu_item :body_trackers
|
||||
|
||||
before_action :find_project_by_project_id, only: [:index, :create]
|
||||
before_action :find_project_by_project_id, only: [:index, :new, :create]
|
||||
before_action :find_measurement, only: [:edit, :update, :destroy, :retake]
|
||||
before_action :authorize
|
||||
|
||||
def index
|
||||
prepare_measurements
|
||||
end
|
||||
|
||||
def new
|
||||
@measurement = @project.measurements.new
|
||||
@measurement.readouts.new
|
||||
|
||||
prepare_measurements
|
||||
@measurements << @measurement
|
||||
end
|
||||
|
||||
def create
|
||||
@measurement = @project.measurements.new(measurement_params)
|
||||
if @measurement.save
|
||||
flash[:notice] = 'Created new measurement'
|
||||
redirect_to :back
|
||||
else
|
||||
prepare_measurements
|
||||
else
|
||||
@measurement.readouts.new if @measurement.readouts.empty?
|
||||
render :index
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
prepare_measurements
|
||||
render :index
|
||||
end
|
||||
|
||||
def update
|
||||
|
@ -10,7 +10,9 @@ class Measurement < ActiveRecord::Base
|
||||
# Readout quantity_id + unit_id uniqueness validation. Cannot be effectively
|
||||
# checked on Readout model level.
|
||||
validate do
|
||||
quantities = self.readouts.map { |r| [r.quantity_id, r.unit_id] }
|
||||
quantities = self.readouts.map do |r|
|
||||
[r.quantity_id, r.unit_id] unless r.marked_for_destruction?
|
||||
end
|
||||
if quantities.length != quantities.uniq.length
|
||||
errors.add(:readouts, :duplicated_quantity_unit_pair)
|
||||
end
|
||||
@ -31,14 +33,14 @@ class Measurement < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def taken_at_date
|
||||
self.taken_at
|
||||
self.taken_at.getlocal
|
||||
end
|
||||
def taken_at_date=(value)
|
||||
self.taken_at = Time.parse(value, self.taken_at)
|
||||
end
|
||||
|
||||
def taken_at_time
|
||||
self.taken_at
|
||||
self.taken_at.getlocal
|
||||
end
|
||||
def taken_at_time=(value)
|
||||
self.taken_at = Time.parse(value, self.taken_at)
|
||||
|
15
app/views/measurements/_edit_form.html.erb
Normal file
15
app/views/measurements/_edit_form.html.erb
Normal file
@ -0,0 +1,15 @@
|
||||
<%= labelled_form_for @measurement,
|
||||
url: measurement_path(@measurement),
|
||||
method: :patch, remote: true,
|
||||
html: {id: 'measurement-edit-form', name: 'measurement-edit-form'} do |f| %>
|
||||
|
||||
<%= render partial: 'measurements/form', locals: {f: f} %>
|
||||
|
||||
<div class="tabular">
|
||||
<p>
|
||||
<%= submit_tag l(:button_save) %>
|
||||
<%= link_to l(:button_cancel), "#",
|
||||
onclick: '$(this).closest("tr").remove(); return false;' %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
@ -6,7 +6,7 @@
|
||||
<p><%= f.text_field :name, size: 40, required: true %></p>
|
||||
<p>
|
||||
<%= f.date_field :taken_at_date, required: true %>
|
||||
<%= f.time_field :taken_at_time, value: @measurement.taken_at.strftime("%H:%M"),
|
||||
<%= f.time_field :taken_at_time, value: @measurement.taken_at.getlocal.strftime("%R"),
|
||||
required: true, label: '' %>
|
||||
</p>
|
||||
<% @measurement.readouts.each_with_index do |r, index| %>
|
||||
@ -26,35 +26,35 @@
|
||||
<% end %>
|
||||
<% end %>
|
||||
<p>
|
||||
<%= link_to t(".button_add_readout"), '#', class: 'icon icon-add',
|
||||
onclick: 'addReadout(); return false;' %>
|
||||
<%= link_to t(".button_new_readout"), '#', class: 'icon icon-add',
|
||||
onclick: 'newReadout(); return false;' %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<%= javascript_tag do %>
|
||||
function addReadout() {
|
||||
var row = $('p.readout:visible:last');
|
||||
function newReadout() {
|
||||
var form = $(event.target).closest('form');
|
||||
var row = form.find('p.readout:visible:last');
|
||||
var new_row = row.clone().insertAfter(row);
|
||||
new_row.find('input[id$=__id], input[id$=__value], select[id$=_quantity__id]').val('');
|
||||
new_row.find('select[id$=__unit_id]').val(row.find('select[id$=__unit_id]').val());
|
||||
new_row.find('input[id$=__destroy]').val('false');
|
||||
new_row.find('label:first').text('');
|
||||
if ($('p.readout:visible').length > 1) {
|
||||
$('p.readout a.icon-del').show();
|
||||
}
|
||||
new_row.find('input[id$=__destroy]').val('');
|
||||
new_row.find('label:first').hide();
|
||||
form.find('p.readout:visible a.icon-del').show();
|
||||
}
|
||||
|
||||
function deleteReadout() {
|
||||
var form = $(event.target).closest('form');
|
||||
var row = $(event.target).closest('p.readout');
|
||||
if (row.find('input[id$=__id]').val()) {
|
||||
row.hide();
|
||||
row.find('input[id$=__destroy]').val('true');
|
||||
row.find('input[id$=__destroy]').val('1');
|
||||
} else {
|
||||
row.remove();
|
||||
}
|
||||
$('p.readout:visible:first label:first').text('<%= t "field_readouts" %>');
|
||||
if ($('p.readout:visible').length <= 1) {
|
||||
$('p.readout a.icon-del').hide();
|
||||
form.find('p.readout:visible:first label:first').show();
|
||||
if (form.find('p.readout:visible').length <= 1) {
|
||||
form.find('p.readout:visible a.icon-del').hide();
|
||||
}
|
||||
}
|
||||
<% end %>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<% @measurements.each do |m| %>
|
||||
<% next if m.new_record? %>
|
||||
<tr id="measurement-<%= m.id %>" class="measurement <%= 'hidden' if m.hidden %>">
|
||||
<td class="date"><%= m.taken_at.strftime("%F %R") %></td>
|
||||
<td class="date"><%= m.taken_at.getlocal.strftime("%F %R") %></td>
|
||||
<td class="name">
|
||||
<div style="float:left;"><%= m.name %></div>
|
||||
<div style="float:right;">
|
||||
@ -32,30 +32,15 @@
|
||||
<%= delete_link measurement_path(m), {remote: true, data: {}} %>
|
||||
</td>
|
||||
</tr>
|
||||
<% next unless (m == @measurement) &&
|
||||
((action_name == "edit") ||
|
||||
(action_name == "update" && @measurement.errors.present?)) %>
|
||||
<tr>
|
||||
<td class="form" colspan="5">
|
||||
<div id="edit-measurement">
|
||||
<%= labelled_form_for @measurement,
|
||||
url: measurement_path(@measurement),
|
||||
method: :patch, remote: true,
|
||||
html: {id: 'measurement-edit-form', name: 'measurement-edit-form'} do |f| %>
|
||||
|
||||
<%= render partial: 'measurements/form', locals: {f: f} %>
|
||||
|
||||
<div class="tabular">
|
||||
<p>
|
||||
<%= submit_tag l(:button_save) %>
|
||||
<%= link_to l(:button_cancel), "#",
|
||||
onclick: '$(this).closest("tr").remove(); return false;' %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<% if (m == @measurement) && @measurement.errors.present? %>
|
||||
<tr>
|
||||
<td class="form" colspan="5">
|
||||
<div id="edit-measurement">
|
||||
<%= render partial: 'measurements/edit_form' %>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
18
app/views/measurements/_new_form.html.erb
Normal file
18
app/views/measurements/_new_form.html.erb
Normal file
@ -0,0 +1,18 @@
|
||||
<h2><%= t ".heading_new_measurement" %></h2>
|
||||
|
||||
<%= labelled_form_for @measurement,
|
||||
url: project_measurements_path(@project),
|
||||
remote: true,
|
||||
html: {id: 'new-measurement-form', name: 'new-measurement-form'} do |f| %>
|
||||
|
||||
<%= render partial: 'measurements/form', locals: {f: f} %>
|
||||
|
||||
<div class="tabular">
|
||||
<p>
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<%= link_to l(:button_cancel), "#",
|
||||
onclick: '$("#new-measurement").empty(); return false;' %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
<hr>
|
4
app/views/measurements/create.js.erb
Normal file
4
app/views/measurements/create.js.erb
Normal file
@ -0,0 +1,4 @@
|
||||
$('div[id^=flash_]').remove();
|
||||
$('#content').prepend('<%= j render_flash_messages %>');
|
||||
$('#new-measurement').empty();
|
||||
$('#measurements').html('<%= j render partial: 'measurements/index' %>');
|
3
app/views/measurements/edit.js.erb
Normal file
3
app/views/measurements/edit.js.erb
Normal file
@ -0,0 +1,3 @@
|
||||
$('div[id^=flash_]').remove();
|
||||
$('#content').prepend('<%= j render_flash_messages %>');
|
||||
$('tr[id=measurement-<%= @measurement.id %>]').after('<tr><td class="form" colspan="5"><div id="edit-measurement"><%= j render partial: "measurements/edit_form" %></div></td></tr>');
|
@ -4,31 +4,14 @@
|
||||
|
||||
<div class="contextual">
|
||||
<% if User.current.allowed_to?(:manage_common, @project) %>
|
||||
<%= link_to t(".link_new_measurement"), '#', class: 'icon icon-add',
|
||||
onclick: '$("#add-measurement").toggle(); $("#measurement_name").focus(); return false;'
|
||||
%>
|
||||
<%= link_to t(".link_new_measurement"), new_project_measurement_path(@project), {
|
||||
remote: true,
|
||||
class: 'icon icon-add'
|
||||
} %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% hide_add_form = @measurement.errors.empty? && (action_name != "retake") %>
|
||||
<div id="add-measurement" <%= 'style=display:none;' if hide_add_form %>>
|
||||
<h2><%= t ".heading_new_measurement" %></h2>
|
||||
|
||||
<%= labelled_form_for @measurement,
|
||||
url: project_measurements_path(@project),
|
||||
html: {id: 'measurement-add-form', name: 'measurement-add-form'} do |f| %>
|
||||
|
||||
<%= render partial: 'measurements/form', locals: {f: f} %>
|
||||
|
||||
<div class="tabular">
|
||||
<p>
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<%= link_to l(:button_cancel), "#",
|
||||
onclick: '$("#add-measurement").hide(); return false;' %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
<hr>
|
||||
<div id="new-measurement">
|
||||
</div>
|
||||
|
||||
<h2><%= t ".heading" %></h2>
|
||||
|
@ -1,3 +1,3 @@
|
||||
$('div[id^=flash_]').remove();
|
||||
$('#content').prepend('<%= escape_javascript(render_flash_messages) %>');
|
||||
$('#measurements').html('<%= escape_javascript(render partial: 'measurements/index') %>');
|
||||
$('#content').prepend('<%= j render_flash_messages %>');
|
||||
$('#measurements').html('<%= j render partial: 'measurements/index' %>');
|
||||
|
3
app/views/measurements/new.js.erb
Normal file
3
app/views/measurements/new.js.erb
Normal file
@ -0,0 +1,3 @@
|
||||
$('div[id^=flash_]').remove();
|
||||
$('#content').prepend('<%= j render_flash_messages %>');
|
||||
$('#new-measurement').html('<%= j render partial: 'measurements/new_form' %>');
|
@ -59,12 +59,13 @@ en:
|
||||
confirm_defaults: 'This will load default quantities and units. Continue?'
|
||||
measurements:
|
||||
form:
|
||||
button_add_readout: 'Add readout'
|
||||
button_new_readout: 'Add readout'
|
||||
button_delete_readout: 'Delete'
|
||||
null_source: '- unspecified -'
|
||||
new_form:
|
||||
heading_new_measurement: 'New measurement'
|
||||
index:
|
||||
heading: 'Measurements'
|
||||
heading_new_measurement: 'New measurement'
|
||||
link_new_measurement: 'New measurement'
|
||||
ingredients:
|
||||
contextual:
|
||||
|
@ -5,7 +5,7 @@ resources :projects, shallow: true do
|
||||
resources :body_trackers, only: [:index] do
|
||||
collection do
|
||||
post 'defaults'
|
||||
resources :measurements, only: [:index, :create, :edit, :update, :destroy] do
|
||||
resources :measurements, only: [:index, :new, :create, :edit, :update, :destroy] do
|
||||
get 'retake', on: :member
|
||||
end
|
||||
resources :ingredients, only: [:index, :create, :destroy] do
|
||||
|
2
init.rb
2
init.rb
@ -24,7 +24,7 @@ Redmine::Plugin.register :body_tracking do
|
||||
}, read: true
|
||||
permission :manage_common, {
|
||||
body_trackers: [:defaults],
|
||||
measurements: [:create, :edit, :update, :destroy, :retake],
|
||||
measurements: [:new, :create, :edit, :update, :destroy, :retake],
|
||||
ingredients: [:create, :destroy, :toggle, :import, :toggle_nutrient_column],
|
||||
sources: [:create, :destroy],
|
||||
quantities: [:create, :edit, :update, :destroy, :toggle, :move],
|
||||
|
Reference in New Issue
Block a user