Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@ export default class extends Controller {
connect() {
this.wrapperClass =
this.data.get("wrapperClass") || "promo-condition-option-value";

this.element.querySelectorAll("." + this.wrapperClass).forEach((element) => this.buildSelects(element))
}

add_row(event) {
event.preventDefault();

var content = this.templateTarget.innerHTML;
this.linksTarget.insertAdjacentHTML("beforebegin", content);
this.buildSelects(this.linksTarget.previousElementSibling)
}

propagate_product_id_to_value_input(event) {
Expand All @@ -24,7 +21,9 @@ export default class extends Controller {
// we first need to greedily match all other square brackets
const regEx = /(\[.*\])\[.*?\]$/;
let wrapper = event.target.closest("." + this.wrapperClass);
let optionValuesInput = wrapper.querySelector(".option-values-select[type='hidden']");
let optionValuesInput = wrapper.querySelector("[is=option-value-picker]");
optionValuesInput.dataset.productId = event.target.value;
optionValuesInput.value = "";
optionValuesInput.name = optionValuesInput.name.replace(
regEx,
`$1[${event.target.value}]`
Expand All @@ -37,26 +36,4 @@ export default class extends Controller {
let wrapper = event.target.closest("." + this.wrapperClass);
wrapper.remove();
}

// helper functions

buildSelects(wrapper) {
let productSelect = wrapper.querySelector(".product-select")
let optionValueSelect = wrapper.querySelector(".option-values-select[type='hidden']")
this.buildProductSelect(productSelect)
$(optionValueSelect).optionValueAutocomplete({ productSelect });
}

buildProductSelect(productSelect) {
var jQueryProductSelect = $(productSelect)
jQueryProductSelect.productAutocomplete({
multiple: false,
})
// capture the jQuery "change" event and re-emit it as DOM event "select2Change"
// so that Stimulus can capture it
jQueryProductSelect.on('change', function () {
let event = new Event('select2Change', { bubbles: true }) // fire a native event
productSelect.dispatchEvent(event);
});
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
$.fn.optionValueAutocomplete = function (options) {
'use strict';
"use strict";

// Default options
options = options || {}
var multiple = typeof(options['multiple']) !== 'undefined' ? options['multiple'] : true;
var productSelect = options['productSelect'];

options = options || {};
var multiple = typeof options["multiple"] !== "undefined" ? options["multiple"] : true;
function formatOptionValue(option_value) {
return Select2.util.escapeMarkup(option_value.name);
}
Expand All @@ -14,39 +12,58 @@ $.fn.optionValueAutocomplete = function (options) {
minimumInputLength: 3,
multiple: multiple,
initSelection: function (element, callback) {
$.get(Spree.pathFor('api/option_values'), {
ids: element.val().split(','),
token: Spree.api_key
}, function (data) {
callback(multiple ? data : data[0]);
});
$.get(
Spree.pathFor("api/option_values"),
{
ids: element.val().split(","),
token: Spree.api_key,
},
function (data) {
callback(multiple ? data : data[0]);
}
);
},
ajax: {
url: Spree.pathFor('api/option_values'),
datatype: 'json',
url: Spree.pathFor("api/option_values"),
datatype: "json",
data: function (term, page) {
var productId = typeof(productSelect) !== 'undefined' ? $(productSelect).select2('val') : null;
var productId = this[0].dataset.productId;
return {
q: {
name_cont: term,
variants_product_id_eq: productId
variants_product_id_eq: productId,
},
token: Spree.api_key
token: Spree.api_key,
};
},
results: function (data, page) {
return { results: data };
}
},
},
formatResult: formatOptionValue,
formatSelection: formatOptionValue
formatSelection: formatOptionValue,
});
};

class OptionValuePicker extends HTMLInputElement {
connectedCallback() {
$(this).optionValueAutocomplete();

this.observer = new MutationObserver((muts) => {
for (const m of muts) {
if (m.attributeName.startsWith("data-product-id")) {
this.restart();
}
}
});

this.observer.observe(this, { attributes: true });
}

restart() {
$(this).select2("destroy");
$(this).optionValueAutocomplete();
}
}

customElements.define('option-value-picker', OptionValuePicker, { extends: 'input' });
customElements.define("option-value-picker", OptionValuePicker, { extends: "input" });
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
class ProductPicker extends HTMLInputElement {
connectedCallback() {
$(this).productAutocomplete();
const multiple = this.dataset.multiple !== "false";
$(this).productAutocomplete({ multiple });
$(this).on("change", (_) => {
let event = new Event('select2Change', { bubbles: true }) // fire a native event
this.dispatchEvent(event)
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion promotions/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ en:
solidus_promotions/conditions/one_use_per_user: One Use Per User
solidus_promotions/conditions/order_option_value: Order matches selected option values
solidus_promotions/conditions/option_value: Order matches selected option values, restricts line items
solidus_promotions/conditions/line_item_option_value: Line Item variant matches options values
solidus_promotions/conditions/line_item_option_value: Line Item variant matches option values
solidus_promotions/conditions/order_product: Order contains selected products
solidus_promotions/conditions/product: Order contains selected products, restricts line items
solidus_promotions/conditions/line_item_product: Line item has selected product
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@
<div class="field promo-condition-option-values">
<div class="param-prefix hidden" data-param-prefix="<%= param_prefix %>"></div>
<div class="row">
<div class="col-6"><%= label_tag nil, Spree::Product.model_name.human %></div>
<div class="col-5"><%= label_tag nil, Spree::Product.model_name.human %></div>
<div class="col-6"><%= label_tag nil, plural_resource_name(Spree::OptionValue) %></div>
<div class="col-1">&nbsp;</div>
</div>

<div class="form-group">
<div data-controller="product-option-values">
<template data-product-option-values-target="template">
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form: form %>
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form: form, index: 0 %>
</template>
<% form.object.preferred_eligible_values.each do |product_option_values| %>
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: product_option_values, form: form %>
<% form.object.preferred_eligible_values.each.with_index do |product_option_values, index| %>
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values:, form:, index: %>
<% end %>
<div class="mb-3" data-product-option-values-target="links">
<div class="mt-3" data-product-option-values-target="links">
<%= 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" } %>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@
<div class="field promo-condition-option-values">
<div class="param-prefix hidden" data-param-prefix="<%= param_prefix %>"></div>
<div class="row">
<div class="col-6"><%= label_tag nil, Spree::Product.model_name.human %></div>
<div class="col-5"><%= label_tag nil, Spree::Product.model_name.human %></div>
<div class="col-6"><%= label_tag nil, plural_resource_name(Spree::OptionValue) %></div>
<div class="col-1">&nbsp;</div>
</div>

<div class="form-group">
<div data-controller="product-option-values">
<template data-product-option-values-target="template">
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form: form %>
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: [nil, []], form:, index: 0 %>
</template>
<% form.object.preferred_eligible_values.each do |product_option_values| %>
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values: product_option_values, form: form %>
<% form.object.preferred_eligible_values.each.with_index do |product_option_values, index| %>
<%= render "solidus_promotions/admin/condition_fields/line_item_option_value/option_value_fields", product_option_values:, form:, index: %>
<% end %>
<div class="mb-3" data-product-option-values-target="links">
<div class="mt-3" data-product-option-values-target="links">
<%= link_to t(:add_product, scope: [:solidus_promotions, :option_value_condition]), "#", class: "btn btn-outline-primary", data: { action: "click->product-option-values#add_row" } %>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
<div class="fullwidth promo-condition-option-value d-flex align-content-stretch mb-3">
<div class="mr-2" style="flex-grow: 1;">
<div class="promo-condition-option-value row">
<div class="col-5">
<input
is="product-picker"
id="ov-product-picker-<%= index %>"
class="w-100"
data-action="select2Change->product-option-values#propagate_product_id_to_value_input"
data-multiple="false"
type="hidden"
value="<%= product_option_values[0] %>"
>
</div>
<div class="mr-2 ml-2" style="flex-grow: 1;">
<div class="col-6">
<input
is="option-value-picker"
id="option-value-picker-<%= index %>"
class="fullwidth"
name="<%= form.object_name %>[preferred_eligible_values][<%= product_option_values[0] %>]"
type="hidden"
data-product-id="<%= product_option_values[0] %>"
value="<%= product_option_values[1].join(",") %>"
>
</div>
<a class="fa fa-trash remove p-2" data-action="click->product-option-values#remove_row"></a>
<div class="col-1">
<a class="fa fa-trash remove p-2 float-right" data-action="click->product-option-values#remove_row"></a>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,28 @@
expect(page).to have_content("Benefit has been successfully removed!")
end
end

describe "Adding a benefit condition" do
let!(:promotion_with_benefit) { create(:solidus_promotion, :with_adjustable_benefit) }
let!(:product) { create(:product) }
let!(:option_value) { create(:option_value) }
let!(:variant) { create(:variant, product: product, option_values: [option_value]) }

it "allows adding an option value condition", :js do
visit solidus_promotions.edit_admin_promotion_path(promotion_with_benefit)
click_link "Add Condition"
select("Line Item variant matches option values", from: "Condition Type")
click_button "Add"
expect(page).to have_content("Line Item variant matches option values")
click_link "Add product"
within(".promo-condition-option-value") do
targetted_select2_search(product.name, from: "#s2id_ov-product-picker-0")
targetted_select2_search(option_value.name, from: "#s2id_option-value-picker-0")
end
within("#benefits_adjust_line_item_#{promotion_with_benefit.benefits.first.id}_conditions") do
click_button("Update")
end
expect(page).to have_content("Condition has been successfully updated!")
end
end
end
Loading