diff --git a/app/controllers/ingredients_controller.rb b/app/controllers/ingredients_controller.rb index 6cdd56d..cba1cc9 100644 --- a/app/controllers/ingredients_controller.rb +++ b/app/controllers/ingredients_controller.rb @@ -4,43 +4,47 @@ class IngredientsController < ApplicationController menu_item :body_trackers helper :body_trackers + helper_method :current_view before_action :init_session_filters before_action :find_project_by_project_id, - only: [:index, :nutrients, :create, :import, :filter, :filter_nutrients] + only: [:index, :new, :create, :nutrients, :filter, :import] before_action :find_quantity_by_quantity_id, only: [:toggle_column] - before_action :find_ingredient, only: [:destroy, :toggle] + before_action :find_ingredient, only: [:edit, :update, :destroy, :toggle] before_action :authorize def index + self.current_view = :ingredients + prepare_items + end + + def new @ingredient = @project.ingredients.new # passing attr for Nutrient after_initialize @ingredient.nutrients.new(ingredient: @ingredient) - - prepare_ingredients - @ingredients << @ingredient - end - - def nutrients - @ingredient = @project.ingredients.new - @ingredient.nutrients.new(ingredient: @ingredient) - prepare_nutrients - end - - def toggle_column - @project.nutrients_column_view.toggle_column!(@quantity) - prepare_nutrients end def create @ingredient = @project.ingredients.new(ingredient_params) if @ingredient.save flash[:notice] = 'Created new ingredient' - redirect_to :back + prepare_items else - prepare_ingredients @ingredient.nutrients.new(ingredient: @ingredient) if @ingredient.nutrients.empty? + render :new + end + end + + def edit + end + + def update + if @ingredient.update(ingredient_params) + flash[:notice] = 'Updated ingredient' + prepare_items render :index + else + render :edit end end @@ -48,25 +52,28 @@ class IngredientsController < ApplicationController if @ingredient.destroy flash[:notice] = 'Deleted ingredient' end - prepare_ingredients - render :toggle end def toggle @ingredient.toggle_hidden! - prepare_ingredients + prepare_items + end + + def nutrients + self.current_view = :nutrients + prepare_items + end + + def toggle_column + @project.nutrients_column_view.toggle_column!(@quantity) + prepare_items + render :index end def filter session[:i_filters] = params[:filters] - prepare_ingredients - render :toggle - end - - def filter_nutrients - session[:i_filters] = params[:filters] - prepare_nutrients - render :toggle_nutrient_column + prepare_items + render :index end def import @@ -216,4 +223,15 @@ class IngredientsController < ApplicationController @ingredients, @requested_n, @extra_n, @formula_q = @project.ingredients .filter(session[:i_filters], @quantities) end + + def prepare_items + (current_view == :nutrients) ? prepare_nutrients : prepare_ingredients + end + + def current_view + @current_view || (params[:view_mode] == "nutrients" ? :nutrients : :ingredients) + end + def current_view=(cv) + @current_view = cv + end end diff --git a/app/helpers/ingredients_helper.rb b/app/helpers/ingredients_helper.rb index 3c9a476..926823f 100644 --- a/app/helpers/ingredients_helper.rb +++ b/app/helpers/ingredients_helper.rb @@ -40,6 +40,8 @@ module IngredientsHelper end def action_links(i) + link_to(l(:button_edit), edit_ingredient_path(i, view_mode: current_view), + {remote: true, class: "icon icon-edit"}) + delete_link(ingredient_path(i), {remote: true, data: {}}) end end diff --git a/app/views/ingredients/_contextual.html.erb b/app/views/ingredients/_contextual.html.erb index 84eb9cf..0c22fcf 100644 --- a/app/views/ingredients/_contextual.html.erb +++ b/app/views/ingredients/_contextual.html.erb @@ -1,6 +1,7 @@ <% if User.current.allowed_to?(:manage_common, @project) %> <%= link_to t(".link_import_ingredients"), '#', class: 'icon icon-multiple', onclick: '$("#import-ingredients").show(); $("#filename").focus(); return false;' %> - <%= link_to t(".link_new_ingredient"), '#', class: 'icon icon-add', - onclick: '$("#add-ingredient").show(); $("#ingredient_name").focus(); return false;' %> + <%= link_to t(".link_new_ingredient"), + new_project_ingredient_path(@project, view_mode: current_view), + {remote: true, class: 'icon icon-add'} %> <% end %> diff --git a/app/views/ingredients/_edit_form.html.erb b/app/views/ingredients/_edit_form.html.erb new file mode 100644 index 0000000..bba364e --- /dev/null +++ b/app/views/ingredients/_edit_form.html.erb @@ -0,0 +1,15 @@ +<%= labelled_form_for @ingredient, + url: ingredient_path(@ingredient, view_mode: current_view), + method: :patch, remote: true, + html: {id: 'ingredient-edit-form', name: 'ingredient-edit-form'} do |f| %> + + <%= render partial: 'ingredients/form', locals: {f: f} %> + +
+

+ <%= submit_tag l(:button_save) %> + <%= link_to l(:button_cancel), "#", + onclick: '$(this).closest("tr").remove(); return false;' %> +

+
+<% end %> diff --git a/app/views/ingredients/_form.html.erb b/app/views/ingredients/_form.html.erb index c0d766d..6168319 100644 --- a/app/views/ingredients/_form.html.erb +++ b/app/views/ingredients/_form.html.erb @@ -1,79 +1,70 @@ -
> -

<%= t ".heading_new_ingredient" %>

+<%= error_messages_for @ingredient %> - <%= labelled_form_for @ingredient, - url: project_ingredients_path(@project), - html: {id: 'ingredient-add-form', name: 'ingredient-add-form'} do |f| %> - - <%= error_messages_for @ingredient %> - -
-

<%= f.text_field :name, size: 40, required: true %>

-

<%= f.text_area :comment, cols: 40, rows: 3, required: false, - style: "width: 100%;" %>

-

- <%= f.number_field :ref_amount, size: 8, required: true, min: 0, - label: :field_reference %> - <%= f.select :ref_unit_id, unit_options, {label: '', required: true} %> -

-

<%= f.select :group, group_options, required: true %>

-
-
-

- <%= f.select :source_id, source_options, required: false, include_blank: true %> -

-
-
-

<%= f.text_field :source_ident, size: 25, required: false %>

-
-
- <% @ingredient.nutrients.each_with_index do |n, index| %> - <%= f.fields_for 'nutrients_attributes', n, index: '' do |ff| %> -

- <%= ff.select :quantity_id, quantity_options, - {include_blank: true, label: (index > 0 ? '' : :field_nutrients)} %> - <%= ff.number_field :amount, {size: 8, min: 0, step: :any, label: ''} %> - <%= ff.select :unit_id, unit_options, {label: ''} %> - <%= ff.check_box :_destroy, {style: "display:none", label: ''} %> - <%= link_to t(".button_delete_nutrient"), '#', - class: 'icon icon-del', - style: (@ingredient.nutrients.length > 1 ? "" : "display:none"), - onclick: "deleteNutrient(); return false;" %> -

- <% end %> - <% end %> -

- <%= link_to t(".button_add_nutrient"), '#', class: 'icon icon-add', - onclick: 'addNutrient(); return false;' %> -

+
+

<%= f.text_field :name, size: 40, required: true %>

+

<%= f.text_area :comment, cols: 40, rows: 3, required: false, + style: "width: 100%;" %>

+

+ <%= f.number_field :ref_amount, size: 8, required: true, min: 0, + label: :field_reference %> + <%= f.select :ref_unit_id, unit_options, {label: '', required: true} %> +

+

<%= f.select :group, group_options, required: true %>

+
+
+

<%= f.select :source_id, source_options, + {required: false, include_blank: t('.null_source')} %>

- <%= submit_tag l(:button_create) %> - <%= link_to l(:button_cancel), "#", - onclick: '$("#add-ingredient").hide(); return false;' %> +
+

<%= f.text_field :source_ident, size: 25, required: false %>

+
+
+ <% @ingredient.nutrients.each_with_index do |n, index| %> + <%= f.fields_for 'nutrients_attributes', n, index: '' do |ff| %> +

+ <%= ff.hidden_field :id %> + <%= ff.select :quantity_id, quantity_options, + {include_blank: true, required: true, label: (index > 0 ? '' : :field_nutrients)} %> + <%= ff.number_field :amount, {size: 8, min: 0, step: :any, label: ''} %> + <%= ff.select :unit_id, unit_options, {label: ''} %> + <%= ff.hidden_field :_destroy %> + <%= link_to t(".button_delete_nutrient"), '#', + class: 'icon icon-del', + style: (@ingredient.nutrients.length > 1 ? "" : "display:none"), + onclick: "deleteNutrient(); return false;" %> +

+ <% end %> <% end %> -
+

+ <%= link_to t(".button_new_nutrient"), '#', class: 'icon icon-add', + onclick: 'newNutrient(); return false;' %> +

<%= javascript_tag do %> - function addNutrient() { - var row = $('p.nutrient:visible:last'); + function newNutrient() { + var form = $(event.target).closest('form'); + var row = form.find('p.nutrient:visible:last'); var new_row = row.clone().insertAfter(row); - new_row.find('input[id$=_amount], select[id$=_quantity_id]').val(''); - new_row.find('select[id$=_unit_id]').val(row.find('select[id$=_unit_id]').val()); - new_row.find('label:first').text(''); - if ($('p.nutrient:visible').length > 1) { - $('p.nutrient a.icon-del').show(); - } + new_row.find('input[id$=__id], input[id$=__amount], 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(''); + new_row.find('label:first').hide(); + form.find('p.nutrient:visible a.icon-del').show(); } function deleteNutrient() { + var form = $(event.target).closest('form'); var row = $(event.target).closest('p.nutrient'); - row.find('[id$=_destroy]').val(1); - // FIXME: should only hide() row if record already saved (to send _destroy to backend) - row.remove(); - $('p.nutrient:visible:first label:first').text('<%= t "field_nutrients" %>'); - if ($('p.nutrient:visible').length <= 1) { - $('p.nutrient a.icon-del').hide(); + if (row.find('input[id$=__id]').val()) { + row.hide(); + row.find('input[id$=__destroy]').val('1'); + } else { + row.remove(); + } + form.find('p.nutrient:visible:first label:first').show(); + if (form.find('p.nutrient:visible').length <= 1) { + form.find('p.nutrient:visible a.icon-del').hide(); } } <% end %> diff --git a/app/views/ingredients/_index.html.erb b/app/views/ingredients/_index.html.erb index a3c0bd3..f51ab1f 100644 --- a/app/views/ingredients/_index.html.erb +++ b/app/views/ingredients/_index.html.erb @@ -16,7 +16,8 @@ <% @ingredients.each do |i| %> <% next if i.new_record? %> - + <%= link_to '', toggle_ingredient_path(i), { remote: true, diff --git a/app/views/ingredients/_new_form.html.erb b/app/views/ingredients/_new_form.html.erb new file mode 100644 index 0000000..79b5904 --- /dev/null +++ b/app/views/ingredients/_new_form.html.erb @@ -0,0 +1,18 @@ +

<%= t ".heading_new_ingredient" %>

+ +<%= labelled_form_for @ingredient, + url: project_ingredients_path(@project, view_mode: current_view), + remote: true, + html: {id: 'new-ingredient-form', name: 'new-ingredient-form'} do |f| %> + + <%= render partial: 'ingredients/form', locals: {f: f} %> + +
+

+ <%= submit_tag l(:button_create) %> + <%= link_to l(:button_cancel), "#", + onclick: '$("#new-ingredient").empty(); return false;' %> +

+
+<% end %> +
diff --git a/app/views/ingredients/_nutrients.html.erb b/app/views/ingredients/_nutrients.html.erb index 3c801d5..2c3e039 100644 --- a/app/views/ingredients/_nutrients.html.erb +++ b/app/views/ingredients/_nutrients.html.erb @@ -1,5 +1,5 @@ <%= render partial: 'ingredients/filters', - locals: {url: filter_nutrients_project_ingredients_path(@project)} %> + locals: {url: filter_project_ingredients_path(@project, view_mode: current_view)} %> <% if @ingredients.any? %> <%= render partial: 'ingredients/options' %> @@ -13,7 +13,8 @@
<%= link_to '', - toggle_column_project_ingredients_path(@project, quantity_id: q.id), + toggle_column_project_ingredients_path(@project, quantity_id: q.id, + view_mode: current_view), {class: "icon icon-close", method: :post, remote: true} %>
<%= q.name %> diff --git a/app/views/ingredients/_options.html.erb b/app/views/ingredients/_options.html.erb index 9b9708e..35de053 100644 --- a/app/views/ingredients/_options.html.erb +++ b/app/views/ingredients/_options.html.erb @@ -1,7 +1,7 @@
<%= l(:label_options) %>
- <%= form_tag toggle_column_project_ingredients_path(@project), + <%= form_tag toggle_column_project_ingredients_path(@project, view_mode: current_view), id: 'toggle-column-form', name: 'toggle-column-form', method: :post, remote: true do %> diff --git a/app/views/ingredients/create.js.erb b/app/views/ingredients/create.js.erb new file mode 100644 index 0000000..09f1b54 --- /dev/null +++ b/app/views/ingredients/create.js.erb @@ -0,0 +1,7 @@ +<%= render partial: 'body_trackers/flash' %> +$('#new-ingredient').empty(); +<% if current_view == :nutrients %> + $('#nutrients').html('<%= j render partial: 'ingredients/nutrients' %>'); +<% else %> + $('#ingredients').html('<%= j render partial: 'ingredients/index' %>'); +<% end %> diff --git a/app/views/ingredients/destroy.js.erb b/app/views/ingredients/destroy.js.erb new file mode 100644 index 0000000..76a9a10 --- /dev/null +++ b/app/views/ingredients/destroy.js.erb @@ -0,0 +1,4 @@ +<%= render partial: 'body_trackers/flash' %> +<% if @ingredient.destroyed? %> + $('tr[id=ingredient-<%= @ingredient.id %>]').nextUntil('tr.primary').addBack().remove(); +<% end %> diff --git a/app/views/ingredients/edit.js.erb b/app/views/ingredients/edit.js.erb new file mode 100644 index 0000000..8a7f575 --- /dev/null +++ b/app/views/ingredients/edit.js.erb @@ -0,0 +1,9 @@ +<%= render partial: 'body_trackers/flash' %> +$('tr[id=ingredient-<%= @ingredient.id %>]').nextUntil('tr.primary', ':not(.ingredient)') + .remove(); +var columns = $('table > thead > tr > th').length; +$('tr[id=ingredient-<%= @ingredient.id %>]').nextAll('tr.primary').first().before( + '' + + '
<%= j render partial: "ingredients/edit_form" %>
' + + '' +); diff --git a/app/views/ingredients/index.html.erb b/app/views/ingredients/index.html.erb index e56fa40..43fee3b 100644 --- a/app/views/ingredients/index.html.erb +++ b/app/views/ingredients/index.html.erb @@ -6,7 +6,8 @@ <%= render partial: 'ingredients/import' %> -<%= render partial: 'ingredients/form' %> +
+

<%= t ".heading" %>

diff --git a/app/views/ingredients/index.js.erb b/app/views/ingredients/index.js.erb new file mode 100644 index 0000000..d8c0cbb --- /dev/null +++ b/app/views/ingredients/index.js.erb @@ -0,0 +1,6 @@ +<%= render partial: 'body_trackers/flash' %> +<% if current_view == :nutrients %> + $('#nutrients').html('<%= j render partial: 'ingredients/nutrients' %>'); +<% else %> + $('#ingredients').html('<%= j render partial: 'ingredients/index' %>'); +<% end %> diff --git a/app/views/ingredients/new.js.erb b/app/views/ingredients/new.js.erb new file mode 100644 index 0000000..5176d41 --- /dev/null +++ b/app/views/ingredients/new.js.erb @@ -0,0 +1,2 @@ +<%= render partial: 'body_trackers/flash' %> +$('#new-ingredient').html('<%= j render partial: 'ingredients/new_form' %>'); diff --git a/app/views/ingredients/nutrients.html.erb b/app/views/ingredients/nutrients.html.erb index 6218582..547dbcc 100644 --- a/app/views/ingredients/nutrients.html.erb +++ b/app/views/ingredients/nutrients.html.erb @@ -6,7 +6,8 @@ <%= render partial: 'ingredients/import' %> -<%= render partial: 'ingredients/form' %> +
+

<%= t ".heading" %>

diff --git a/app/views/ingredients/toggle.js.erb b/app/views/ingredients/toggle.js.erb index b78ba15..84822aa 100644 --- a/app/views/ingredients/toggle.js.erb +++ b/app/views/ingredients/toggle.js.erb @@ -1,3 +1,2 @@ -$('div[id^=flash_]').remove(); -$('#content').prepend('<%= escape_javascript(render_flash_messages) %>'); -$('#ingredients').html('<%= escape_javascript(render partial: 'ingredients/index') %>'); +<%= render partial: 'body_trackers/flash' %> +$('#ingredients').html('<%= j render partial: 'ingredients/index' %>'); diff --git a/app/views/ingredients/toggle_nutrient_column.js.erb b/app/views/ingredients/toggle_nutrient_column.js.erb deleted file mode 100644 index 06a87bd..0000000 --- a/app/views/ingredients/toggle_nutrient_column.js.erb +++ /dev/null @@ -1,3 +0,0 @@ -$('div[id^=flash_]').remove(); -$('#content').prepend('<%= escape_javascript(render_flash_messages) %>'); -$('#nutrients').html('<%= escape_javascript(render partial: 'ingredients/nutrients') %>'); diff --git a/config/locales/en.yml b/config/locales/en.yml index ab2d241..68b4938 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -86,12 +86,14 @@ en: Sample data row: "Brussels,100[g],other,3.4,300[mg],9". Unit given in data row has precedence over that specified in header.' form: - heading_new_ingredient: 'New ingredient' - button_add_nutrient: 'Add nutrient' + button_new_nutrient: 'Add nutrient' button_delete_nutrient: 'Delete' + null_source: '- unspecified -' groups: other: 'other' meat: 'meat' + new_form: + heading_new_ingredient: 'New ingredient' index: heading: 'Ingredients' heading_nutrient_view: 'Nutrient view' diff --git a/config/routes.rb b/config/routes.rb index acc2c91..b03b8fb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -15,14 +15,13 @@ resources :projects, shallow: true do get 'filter' end end - resources :ingredients, only: [:index, :create, :destroy] do + resources :ingredients, only: [:index, :new, :create, :edit, :update, :destroy] do post 'toggle', on: :member collection do get 'nutrients' - get 'filter' - get 'filter_nutrients' - post 'import' post 'toggle_column' + get 'filter' + post 'import' end end resources :sources, only: [:index, :create, :destroy] diff --git a/init.rb b/init.rb index 6ab3b67..f306c43 100644 --- a/init.rb +++ b/init.rb @@ -17,7 +17,7 @@ Redmine::Plugin.register :body_tracking do permission :view_body_trackers, { body_trackers: [:index], measurements: [:index, :readouts, :filter], - ingredients: [:index, :nutrients, :filter, :filter_nutrients], + ingredients: [:index, :nutrients, :filter], sources: [:index], quantities: [:index, :parents, :filter], units: [:index], @@ -25,7 +25,8 @@ Redmine::Plugin.register :body_tracking do permission :manage_common, { body_trackers: [:defaults], measurements: [:new, :create, :edit, :update, :destroy, :retake, :toggle_column], - ingredients: [:create, :destroy, :toggle, :import, :toggle_column], + ingredients: [:new, :create, :edit, :update, :destroy, :toggle, :toggle_column, + :import], sources: [:create, :destroy], quantities: [:create, :edit, :update, :destroy, :move], units: [:create, :destroy],