From 55eb876fe63ad96803515bf2ee06f8c5424a0819 Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Tue, 12 Nov 2019 18:29:43 +0100 Subject: [PATCH 1/3] Use the already selected object for initial selection If a user has already selected a product or variant we do not need to query it via the API. --- .../alchemy/solidus/admin/product_select.js | 2 +- .../alchemy/solidus/admin/select2_config.js | 13 ++++--------- .../essences/_essence_spree_product_editor.html.erb | 8 +++++++- .../essences/_essence_spree_variant_editor.html.erb | 8 +++++++- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/alchemy/solidus/admin/product_select.js b/app/assets/javascripts/alchemy/solidus/admin/product_select.js index 7e07356..105f870 100644 --- a/app/assets/javascripts/alchemy/solidus/admin/product_select.js +++ b/app/assets/javascripts/alchemy/solidus/admin/product_select.js @@ -25,7 +25,7 @@ $.fn.alchemyProductSelect = function(options) { } } }, - formatSelection: function (product) { + formatSelection: function(product) { return product.text || product.name } })) diff --git a/app/assets/javascripts/alchemy/solidus/admin/select2_config.js b/app/assets/javascripts/alchemy/solidus/admin/select2_config.js index aff588d..07083a9 100644 --- a/app/assets/javascripts/alchemy/solidus/admin/select2_config.js +++ b/app/assets/javascripts/alchemy/solidus/admin/select2_config.js @@ -9,15 +9,10 @@ Alchemy.Solidus.getSelect2Config = function(options) { return { placeholder: options.placeholder, minimumInputLength: 3, - initSelection: function($element, callback) { - $.ajax({ - url: options.baseUrl + '/' + $element.val(), - headers: headers, - success: callback, - error: function (_xhr, _textStatus, errorThrown) { - console.error(errorThrown) - } - }) + initSelection: function(_$el, callback) { + if (options.initialSelection) { + callback(options.initialSelection) + } }, ajax: { url: options.baseUrl, diff --git a/app/views/alchemy/essences/_essence_spree_product_editor.html.erb b/app/views/alchemy/essences/_essence_spree_product_editor.html.erb index 93565f6..007bf92 100644 --- a/app/views/alchemy/essences/_essence_spree_product_editor.html.erb +++ b/app/views/alchemy/essences/_essence_spree_product_editor.html.erb @@ -13,6 +13,12 @@ placeholder: "<%= Alchemy.t(:search_product, scope: 'solidus') %>", apiToken: "<%= current_alchemy_user.spree_api_key %>", baseUrl: "<%= spree.api_products_path %>", - query_params: <%== content.settings[:query_params].to_json %> + query_params: <%== content.settings[:query_params].to_json %>, + <% if content.essence.product %> + initialSelection: { + id: <%= content.essence.spree_product_id %>, + text: "<%= content.essence.product.name %>" + } + <% end %> }) diff --git a/app/views/alchemy/essences/_essence_spree_variant_editor.html.erb b/app/views/alchemy/essences/_essence_spree_variant_editor.html.erb index 140cf95..5f4664b 100644 --- a/app/views/alchemy/essences/_essence_spree_variant_editor.html.erb +++ b/app/views/alchemy/essences/_essence_spree_variant_editor.html.erb @@ -13,6 +13,12 @@ placeholder: "<%= Alchemy.t(:search_variant, scope: 'solidus') %>", apiToken: "<%= current_alchemy_user.spree_api_key %>", baseUrl: "<%= spree.api_variants_path %>", - query_params: <%== content.settings[:query_params].to_json %> + query_params: <%== content.settings[:query_params].to_json %>, + <% if content.essence.variant %> + initialSelection: { + id: <%= content.essence.variant_id %>, + text: "<%= content.essence.variant.name %>" + } + <% end %> }) From d56a47af417a6bdea71407ed3cc24b0dfc28f847 Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Tue, 12 Nov 2019 18:31:12 +0100 Subject: [PATCH 2/3] Refactor implementation of EssenceSpreeTaxon This way it passes the essence examples. --- app/models/alchemy/essence_spree_taxon.rb | 28 ++++++--- .../alchemy/essence_spree_taxon_spec.rb | 63 +++++++++++++++++++ 2 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 spec/models/alchemy/essence_spree_taxon_spec.rb diff --git a/app/models/alchemy/essence_spree_taxon.rb b/app/models/alchemy/essence_spree_taxon.rb index ad8c170..e745721 100644 --- a/app/models/alchemy/essence_spree_taxon.rb +++ b/app/models/alchemy/essence_spree_taxon.rb @@ -1,14 +1,28 @@ +# frozen_string_literal: true + module Alchemy class EssenceSpreeTaxon < ActiveRecord::Base - belongs_to :taxon, class_name: "Spree::Taxon", foreign_key: 'taxon_id' + TAXON_ID = /\A\d+\z/ + + belongs_to :taxon, class_name: 'Spree::Taxon', + optional: true, foreign_key: 'taxon_id' - acts_as_essence( - ingredient_column: 'taxon_id', - preview_text_method: 'name' - ) + acts_as_essence(ingredient_column: :taxon) + + def ingredient=(taxon_or_id) + case taxon_or_id + when TAXON_ID + self.taxon_id = taxon_or_id + when Spree::Taxon + self.taxon = taxon_or_id + else + super + end + end - def ingredient - taxon + def preview_text(_maxlength) + return unless taxon + taxon.name end end end diff --git a/spec/models/alchemy/essence_spree_taxon_spec.rb b/spec/models/alchemy/essence_spree_taxon_spec.rb new file mode 100644 index 0000000..60d439c --- /dev/null +++ b/spec/models/alchemy/essence_spree_taxon_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'alchemy/test_support/essence_shared_examples' +require 'alchemy/test_support/factories/page_factory' +require 'alchemy/test_support/factories/element_factory' +require 'alchemy/test_support/factories/content_factory' +require 'spree/testing_support/factories/taxon_factory' + +require_dependency 'alchemy/site' + +RSpec.describe Alchemy::EssenceSpreeTaxon, type: :model do + let(:taxon) { build_stubbed(:taxon) } + let(:essence) { described_class.new(taxon: taxon) } + + it_behaves_like 'an essence' do + let(:ingredient_value) { taxon } + end + + describe 'ingredient=' do + context 'when String value is only a number' do + let(:value) { '101' } + + before do + essence.ingredient = value + end + + it 'sets taxon_id with that id' do + expect(essence.taxon_id).to eq(101) + end + end + + context 'when value is an Spree Variant' do + let(:value) { taxon } + + before do + essence.ingredient = value + end + + it 'sets taxon to that taxon' do + expect(essence.taxon).to eq(taxon) + end + end + + context 'when value is not only a number' do + let(:value) { 'taxon1' } + + it do + expect { + essence.ingredient = value + }.to raise_error(ActiveRecord::AssociationTypeMismatch) + end + end + end + + describe '#preview_text' do + subject { essence.preview_text(nil) } + + it 'returns the taxons name' do + is_expected.to eq(taxon.name) + end + end +end From 2af623f214873433ef7791206053b03ecd76da93 Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Tue, 12 Nov 2019 18:32:07 +0100 Subject: [PATCH 3/3] Use select2 ajax search for EssenceSpreeTaxon As with the product and variant essences we also make use of the select2 ajax feature to query the Solidus API for selecting taxons. --- .../javascripts/alchemy/solidus/admin.js | 1 + .../alchemy/solidus/admin/taxon_select.js | 32 +++++++++++++++++ .../_essence_spree_taxon_editor.html.erb | 31 +++++++++++------ config/locales/alchemy_solidus_en.yml | 1 + .../essence_spree_taxon_editor_spec.rb | 34 +++++++++++++++++++ 5 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 app/assets/javascripts/alchemy/solidus/admin/taxon_select.js create mode 100644 spec/views/alchemy/essences/essence_spree_taxon_editor_spec.rb diff --git a/app/assets/javascripts/alchemy/solidus/admin.js b/app/assets/javascripts/alchemy/solidus/admin.js index 9e74dcf..fcf76f5 100644 --- a/app/assets/javascripts/alchemy/solidus/admin.js +++ b/app/assets/javascripts/alchemy/solidus/admin.js @@ -1,2 +1,3 @@ //= require alchemy/solidus/admin/product_select //= require alchemy/solidus/admin/variant_select +//= require alchemy/solidus/admin/taxon_select diff --git a/app/assets/javascripts/alchemy/solidus/admin/taxon_select.js b/app/assets/javascripts/alchemy/solidus/admin/taxon_select.js new file mode 100644 index 0000000..0a3a62b --- /dev/null +++ b/app/assets/javascripts/alchemy/solidus/admin/taxon_select.js @@ -0,0 +1,32 @@ +//= require alchemy/solidus/admin/select2_config + +$.fn.alchemyTaxonSelect = function(options) { + var config = Alchemy.Solidus.getSelect2Config(options) + + this.select2($.extend(true, config, { + ajax: { + data: function(term, page) { + return { + q: $.extend({ + name_cont: term + }, options.query_params), + page: page + } + }, + results: function(data, page) { + return { + results: data.taxons.map(function(taxon) { + return { + id: taxon.id, + text: taxon.name + } + }), + more: page * data.per_page < data.total_count + } + } + }, + formatSelection: function(taxon) { + return taxon.text || taxon.name + } + })) +} diff --git a/app/views/alchemy/essences/_essence_spree_taxon_editor.html.erb b/app/views/alchemy/essences/_essence_spree_taxon_editor.html.erb index 0ccfbb8..31414f7 100644 --- a/app/views/alchemy/essences/_essence_spree_taxon_editor.html.erb +++ b/app/views/alchemy/essences/_essence_spree_taxon_editor.html.erb @@ -1,15 +1,24 @@ -
+
<%= content_label(content) %> - <%= select_tag( + <%= text_field_tag( content.form_field_name, - options_from_collection_for_select( - local_assigns.fetch(:options, {})[:taxons] || Spree::Taxon.all, - :id, - :pretty_name, - content.essence.taxon_id - ), - include_blank: t(".none"), - class: ["alchemy_selectbox", "essence_editor_select", html_options[:class]].join(' '), - style: html_options[:style] + content.essence.taxon_id, + id: content.form_field_id, + class: 'alchemy_selectbox full_width' ) %>
+ + diff --git a/config/locales/alchemy_solidus_en.yml b/config/locales/alchemy_solidus_en.yml index f1ffa92..4276a29 100644 --- a/config/locales/alchemy_solidus_en.yml +++ b/config/locales/alchemy_solidus_en.yml @@ -3,6 +3,7 @@ en: solidus: search_variant: Search a variant by name or sku search_product: Search a product by name + search_taxon: Search a taxon by name spree: admin: tab: diff --git a/spec/views/alchemy/essences/essence_spree_taxon_editor_spec.rb b/spec/views/alchemy/essences/essence_spree_taxon_editor_spec.rb new file mode 100644 index 0000000..a888485 --- /dev/null +++ b/spec/views/alchemy/essences/essence_spree_taxon_editor_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'alchemy/essences/_essence_spree_taxon_editor' do + let(:content) { Alchemy::Content.new(essence: essence) } + let(:essence) { Alchemy::EssenceSpreeTaxon.new } + + before do + view.class.send(:include, Alchemy::Admin::EssencesHelper) + allow(view).to receive(:content_label) { content.name } + end + + subject do + render 'alchemy/essences/essence_spree_taxon_editor', + content: content, + spree: double(api_taxons_path: '/api/taxons'), + current_alchemy_user: double(spree_api_key: '123') + rendered + end + + it "renders a taxon input" do + is_expected.to have_css('input.alchemy_selectbox.full_width') + end + + context 'with a taxon related to essence' do + let(:taxon) { Spree::Taxon.new(id: 1) } + let(:essence) { Alchemy::EssenceSpreeTaxon.new(taxon_id: taxon.id) } + + it "sets taxon id as value" do + is_expected.to have_css('input.alchemy_selectbox[value="1"]') + end + end +end