Skip to content

Commit 2768bad

Browse files
authored
Merge pull request #6233 from manleyac/fix-line-item-option-condition-params
Fix line item option condition params
2 parents 2c4263a + b0eda8b commit 2768bad

File tree

8 files changed

+92
-61
lines changed

8 files changed

+92
-61
lines changed

promotions/app/javascript/backend/solidus_promotions/controllers/product_option_values_controller.js

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ export default class extends Controller {
66
connect() {
77
this.wrapperClass =
88
this.data.get("wrapperClass") || "promo-condition-option-value";
9-
10-
this.element.querySelectorAll("." + this.wrapperClass).forEach((element) => this.buildSelects(element))
119
}
1210

1311
add_row(event) {
1412
event.preventDefault();
1513

1614
var content = this.templateTarget.innerHTML;
1715
this.linksTarget.insertAdjacentHTML("beforebegin", content);
18-
this.buildSelects(this.linksTarget.previousElementSibling)
1916
}
2017

2118
propagate_product_id_to_value_input(event) {
@@ -24,7 +21,9 @@ export default class extends Controller {
2421
// we first need to greedily match all other square brackets
2522
const regEx = /(\[.*\])\[.*?\]$/;
2623
let wrapper = event.target.closest("." + this.wrapperClass);
27-
let optionValuesInput = wrapper.querySelector(".option-values-select[type='hidden']");
24+
let optionValuesInput = wrapper.querySelector("[is=option-value-picker]");
25+
optionValuesInput.dataset.productId = event.target.value;
26+
optionValuesInput.value = "";
2827
optionValuesInput.name = optionValuesInput.name.replace(
2928
regEx,
3029
`$1[${event.target.value}]`
@@ -37,26 +36,4 @@ export default class extends Controller {
3736
let wrapper = event.target.closest("." + this.wrapperClass);
3837
wrapper.remove();
3938
}
40-
41-
// helper functions
42-
43-
buildSelects(wrapper) {
44-
let productSelect = wrapper.querySelector(".product-select")
45-
let optionValueSelect = wrapper.querySelector(".option-values-select[type='hidden']")
46-
this.buildProductSelect(productSelect)
47-
$(optionValueSelect).optionValueAutocomplete({ productSelect });
48-
}
49-
50-
buildProductSelect(productSelect) {
51-
var jQueryProductSelect = $(productSelect)
52-
jQueryProductSelect.productAutocomplete({
53-
multiple: false,
54-
})
55-
// capture the jQuery "change" event and re-emit it as DOM event "select2Change"
56-
// so that Stimulus can capture it
57-
jQueryProductSelect.on('change', function () {
58-
let event = new Event('select2Change', { bubbles: true }) // fire a native event
59-
productSelect.dispatchEvent(event);
60-
});
61-
}
6239
}
Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
$.fn.optionValueAutocomplete = function (options) {
2-
'use strict';
2+
"use strict";
33

44
// Default options
5-
options = options || {}
6-
var multiple = typeof(options['multiple']) !== 'undefined' ? options['multiple'] : true;
7-
var productSelect = options['productSelect'];
8-
5+
options = options || {};
6+
var multiple = typeof options["multiple"] !== "undefined" ? options["multiple"] : true;
97
function formatOptionValue(option_value) {
108
return Select2.util.escapeMarkup(option_value.name);
119
}
@@ -14,39 +12,58 @@ $.fn.optionValueAutocomplete = function (options) {
1412
minimumInputLength: 3,
1513
multiple: multiple,
1614
initSelection: function (element, callback) {
17-
$.get(Spree.pathFor('api/option_values'), {
18-
ids: element.val().split(','),
19-
token: Spree.api_key
20-
}, function (data) {
21-
callback(multiple ? data : data[0]);
22-
});
15+
$.get(
16+
Spree.pathFor("api/option_values"),
17+
{
18+
ids: element.val().split(","),
19+
token: Spree.api_key,
20+
},
21+
function (data) {
22+
callback(multiple ? data : data[0]);
23+
}
24+
);
2325
},
2426
ajax: {
25-
url: Spree.pathFor('api/option_values'),
26-
datatype: 'json',
27+
url: Spree.pathFor("api/option_values"),
28+
datatype: "json",
2729
data: function (term, page) {
28-
var productId = typeof(productSelect) !== 'undefined' ? $(productSelect).select2('val') : null;
30+
var productId = this[0].dataset.productId;
2931
return {
3032
q: {
3133
name_cont: term,
32-
variants_product_id_eq: productId
34+
variants_product_id_eq: productId,
3335
},
34-
token: Spree.api_key
36+
token: Spree.api_key,
3537
};
3638
},
3739
results: function (data, page) {
3840
return { results: data };
39-
}
41+
},
4042
},
4143
formatResult: formatOptionValue,
42-
formatSelection: formatOptionValue
44+
formatSelection: formatOptionValue,
4345
});
4446
};
4547

4648
class OptionValuePicker extends HTMLInputElement {
4749
connectedCallback() {
4850
$(this).optionValueAutocomplete();
51+
52+
this.observer = new MutationObserver((muts) => {
53+
for (const m of muts) {
54+
if (m.attributeName.startsWith("data-product-id")) {
55+
this.restart();
56+
}
57+
}
58+
});
59+
60+
this.observer.observe(this, { attributes: true });
61+
}
62+
63+
restart() {
64+
$(this).select2("destroy");
65+
$(this).optionValueAutocomplete();
4966
}
5067
}
5168

52-
customElements.define('option-value-picker', OptionValuePicker, { extends: 'input' });
69+
customElements.define("option-value-picker", OptionValuePicker, { extends: "input" });

promotions/app/javascript/backend/solidus_promotions/web_components/product_picker.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
class ProductPicker extends HTMLInputElement {
22
connectedCallback() {
3-
$(this).productAutocomplete();
3+
const multiple = this.dataset.multiple !== "false";
4+
$(this).productAutocomplete({ multiple });
5+
$(this).on("change", (_) => {
6+
let event = new Event('select2Change', { bubbles: true }) // fire a native event
7+
this.dispatchEvent(event)
8+
})
49
}
510
}
611

promotions/config/locales/en.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ en:
210210
solidus_promotions/conditions/one_use_per_user: One Use Per User
211211
solidus_promotions/conditions/order_option_value: Order matches selected option values
212212
solidus_promotions/conditions/option_value: Order matches selected option values, restricts line items
213-
solidus_promotions/conditions/line_item_option_value: Line Item variant matches options values
213+
solidus_promotions/conditions/line_item_option_value: Line Item variant matches option values
214214
solidus_promotions/conditions/order_product: Order contains selected products
215215
solidus_promotions/conditions/product: Order contains selected products, restricts line items
216216
solidus_promotions/conditions/line_item_product: Line item has selected product

promotions/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_option_value.html.erb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55
<div class="field promo-condition-option-values">
66
<div class="param-prefix hidden" data-param-prefix="<%= param_prefix %>"></div>
77
<div class="row">
8-
<div class="col-6"><%= label_tag nil, Spree::Product.model_name.human %></div>
8+
<div class="col-5"><%= label_tag nil, Spree::Product.model_name.human %></div>
99
<div class="col-6"><%= label_tag nil, plural_resource_name(Spree::OptionValue) %></div>
10+
<div class="col-1">&nbsp;</div>
1011
</div>
1112

1213
<div class="form-group">
1314
<div data-controller="product-option-values">
1415
<template data-product-option-values-target="template">
15-
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form: form %>
16+
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form: form, index: 0 %>
1617
</template>
17-
<% form.object.preferred_eligible_values.each do |product_option_values| %>
18-
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: product_option_values, form: form %>
18+
<% form.object.preferred_eligible_values.each.with_index do |product_option_values, index| %>
19+
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values:, form:, index: %>
1920
<% end %>
20-
<div class="mb-3" data-product-option-values-target="links">
21+
<div class="mt-3" data-product-option-values-target="links">
2122
<%= link_to t(:add_product, scope: [:solidus_promotions, :line_item_option_value_condition]), "#", class: "btn btn-outline-primary", data: { action: "click->product-option-values#add_row" } %>
2223
</div>
2324
</div>

promotions/lib/views/backend/solidus_promotions/admin/condition_fields/_option_value.html.erb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,20 @@
77
<div class="field promo-condition-option-values">
88
<div class="param-prefix hidden" data-param-prefix="<%= param_prefix %>"></div>
99
<div class="row">
10-
<div class="col-6"><%= label_tag nil, Spree::Product.model_name.human %></div>
10+
<div class="col-5"><%= label_tag nil, Spree::Product.model_name.human %></div>
1111
<div class="col-6"><%= label_tag nil, plural_resource_name(Spree::OptionValue) %></div>
12+
<div class="col-1">&nbsp;</div>
1213
</div>
1314

1415
<div class="form-group">
1516
<div data-controller="product-option-values">
1617
<template data-product-option-values-target="template">
17-
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form: form %>
18+
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form:, index: 0 %>
1819
</template>
19-
<% form.object.preferred_eligible_values.each do |product_option_values| %>
20-
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: product_option_values, form: form %>
20+
<% form.object.preferred_eligible_values.each.with_index do |product_option_values, index| %>
21+
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values:, form:, index: %>
2122
<% end %>
22-
<div class="mb-3" data-product-option-values-target="links">
23+
<div class="mt-3" data-product-option-values-target="links">
2324
<%= link_to t(:add_product, scope: [:solidus_promotions, :option_value_condition]), "#", class: "btn btn-outline-primary", data: { action: "click->product-option-values#add_row" } %>
2425
</div>
2526
</div>
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
1-
<div class="fullwidth promo-condition-option-value d-flex align-content-stretch mb-3">
2-
<div class="mr-2" style="flex-grow: 1;">
1+
<div class="promo-condition-option-value row">
2+
<div class="col-5">
33
<input
44
is="product-picker"
5+
id="ov-product-picker-<%= index %>"
56
class="w-100"
67
data-action="select2Change->product-option-values#propagate_product_id_to_value_input"
8+
data-multiple="false"
79
type="hidden"
810
value="<%= product_option_values[0] %>"
911
>
1012
</div>
11-
<div class="mr-2 ml-2" style="flex-grow: 1;">
13+
<div class="col-6">
1214
<input
1315
is="option-value-picker"
16+
id="option-value-picker-<%= index %>"
1417
class="fullwidth"
1518
name="<%= form.object_name %>[preferred_eligible_values][<%= product_option_values[0] %>]"
1619
type="hidden"
20+
data-product-id="<%= product_option_values[0] %>"
1721
value="<%= product_option_values[1].join(",") %>"
1822
>
1923
</div>
20-
<a class="fa fa-trash remove p-2" data-action="click->product-option-values#remove_row"></a>
24+
<div class="col-1">
25+
<a class="fa fa-trash remove p-2 float-right" data-action="click->product-option-values#remove_row"></a>
26+
</div>
2127
</div>

promotions/spec/system/solidus_promotions/backend/promotions_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,28 @@
161161
expect(page).to have_content("Benefit has been successfully removed!")
162162
end
163163
end
164+
165+
describe "Adding a benefit condition" do
166+
let!(:promotion_with_benefit) { create(:solidus_promotion, :with_adjustable_benefit) }
167+
let!(:product) { create(:product) }
168+
let!(:option_value) { create(:option_value) }
169+
let!(:variant) { create(:variant, product: product, option_values: [option_value]) }
170+
171+
it "allows adding an option value condition", :js do
172+
visit solidus_promotions.edit_admin_promotion_path(promotion_with_benefit)
173+
click_link "Add Condition"
174+
select("Line Item variant matches option values", from: "Condition Type")
175+
click_button "Add"
176+
expect(page).to have_content("Line Item variant matches option values")
177+
click_link "Add product"
178+
within(".promo-condition-option-value") do
179+
targetted_select2_search(product.name, from: "#s2id_ov-product-picker-0")
180+
targetted_select2_search(option_value.name, from: "#s2id_option-value-picker-0")
181+
end
182+
within("#benefits_adjust_line_item_#{promotion_with_benefit.benefits.first.id}_conditions") do
183+
click_button("Update")
184+
end
185+
expect(page).to have_content("Condition has been successfully updated!")
186+
end
187+
end
164188
end

0 commit comments

Comments
 (0)