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
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 @@ -162,6 +162,30 @@
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 Option Value(s)", from: "Condition Type")
click_button "Add"
expect(page).to have_content("Line Item Option Value(s)")
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

describe "Rendering the promotion edit page with the PercentWithCap calculator" do
let(:promotion) { create(:solidus_promotion, name: "My capped promotion", benefits: [benefit]) }
let(:benefit) { SolidusPromotions::Benefits::AdjustLineItem.new(calculator:) }
Expand Down
Loading