Add wide view and inline editing to Measurements page

The Measurements page gains a compact/wide view toggle (persisted in
localStorage). The wide view is a pivot table: rows = time points,
columns = quantity names (alphabetical), cells = value + delete button.

Clicking a value in either view opens an inline edit panel (Turbo Stream)
without leaving the page. The panel shows the quantity name, value input,
unit selector, taken_at picker, and Update/Cancel buttons.

Changes:
- MeasurementsController: add edit/update actions; order by taken_at desc
- measurements/index: compact table + wide container, view-toggle buttons
- measurements/_readout: data-* attributes for JS pivot builder; edit link
- measurements/_edit_panel, _edit_form, _edit_form_close,
  edit.turbo_stream, update.turbo_stream: inline edit views
- application.js: groupMeasurements, buildWideTable (alphabetical cols),
  getMeasurementsView / setMeasurementsView, editMeasurementWide,
  readoutUnitChanged, setDefaultUnit
- application.css: compact/wide visibility rules, .wide-cell flex layout,
  button.link reset, .items-table .form td alignment
- Pictograms: view-rows.svg, view-columns.svg (view-toggle icons)
- Locale: view_compact/view_wide toggle labels, edit link, update.success
- Tests: system tests for compact inline edit and wide view edit panel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-03 22:03:10 +00:00
parent 3702e24153
commit bfd427c9b2
15 changed files with 492 additions and 13 deletions

View File

@@ -0,0 +1,64 @@
require "application_system_test_case"
class MeasurementsTest < ApplicationSystemTestCase
setup do
@user = sign_in(user: users(:alice))
@quantity = @user.quantities.create!(name: 'Weight')
@unit = @user.units.create!(symbol: 'kg')
@readout = @user.readouts.create!(quantity: @quantity, unit: @unit, value: 82.5)
visit measurements_path
end
test "index shows quantity name as edit link for active user" do
within 'tbody' do
assert_selector :link, exact_text: @quantity.name
end
end
test "edit opens inline form on quantity link click" do
within 'tbody' do
click_on @quantity.name
assert_selector ':focus'
assert_selector 'input[name="readout[value]"]'
end
end
test "edit and update measurement value" do
within 'tbody' do
click_on @quantity.name
fill_in 'readout[value]', with: '83.1'
assert_difference ->{ @readout.reload.value }, 83.1 - @readout.value do
click_on t('helpers.submit.update')
end
assert_no_selector :fillable_field
assert_selector :link, exact_text: @quantity.name
end
assert_selector '.flash.notice', text: t('measurements.update.success')
end
test "cancel edit restores original row" do
within 'tbody' do
click_on @quantity.name
assert_selector 'input[name="readout[value]"]'
click_on t(:cancel)
assert_no_selector :fillable_field
assert_selector :link, exact_text: @quantity.name
end
end
test "wide view edit opens panel form" do
@readout.update!(taken_at: Time.now)
visit measurements_path
execute_script("localStorage.removeItem('measurements-view')")
visit measurements_path
find('button[data-view="wide"]').click
within '#measurements-wide' do
assert_text format("%.10g", 82.5), wait: 3
find('button.link').click
end
assert_selector '#measurement_edit_form input[name="readout[value]"]', wait: 5
end
end