mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-17 00:07:24 +00:00
Add OutOfStockModalComponent
It encapsulate the logic for the out of stock modal
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// please update the modal html in app/view/checkout/edit.html.haml if updating this template
|
||||
// please update the modal html in app/components/out_of_stock_modal_component/out_of_stock_modal_component.html.haml if updating this template
|
||||
%a.close-reveal-modal{"ng-click" => "$close()"}
|
||||
%i.ofn-i_009-close
|
||||
|
||||
|
||||
10
app/components/out_of_stock_modal_component.rb
Normal file
10
app/components/out_of_stock_modal_component.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OutOfStockModalComponent < ModalComponent
|
||||
def initialize(id:, variants: [], redirect: false)
|
||||
super(id:, modal_class: "medium", instant: true)
|
||||
|
||||
@variants = variants
|
||||
@redirect = redirect
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
%div{ id: @id, "data-controller": "modal out-of-stock-modal", "data-action": "keyup@document->modal#closeIfEscapeKey modal:closing->out-of-stock-modal#redirect", "data-modal-instant-value": @instant, "data-out-of-stock-modal-redirect-value": @redirect }
|
||||
.reveal-modal-bg.fade{ "data-modal-target": "background", "data-action": "click->modal#close" }
|
||||
.reveal-modal.fade.modal-component{ "data-modal-target": "modal", class: @modal_class }
|
||||
- # please update app/assets/javascripts/templates/out_of_stock.html.haml if updating this view
|
||||
%a.close-reveal-modal{"data-action": "click->modal#close" }
|
||||
%i.ofn-i_009-close
|
||||
%h3
|
||||
= t("js.out_of_stock.reduced_stock_available")
|
||||
%p
|
||||
= t("js.out_of_stock.out_of_stock_text")
|
||||
- @variants.each do |variant|
|
||||
- if variant.on_hand == 0
|
||||
%p
|
||||
%em
|
||||
= "#{variant.name_to_display} - #{variant.unit_to_display}"
|
||||
%span
|
||||
= t("js.out_of_stock.now_out_of_stock")
|
||||
- if variant.on_hand > 0
|
||||
%p
|
||||
%em
|
||||
= "#{variant.name_to_display} - #{variant.unit_to_display}"
|
||||
%span
|
||||
= t("js.out_of_stock.only_n_remaining", num: variant.on_hand)
|
||||
|
||||
.text-center
|
||||
%input{ class: "button icon-plus #{close_button_class}", type: 'button', value: t('js.admin.modals.close'), "data-action": "click->modal#close" }
|
||||
19
app/webpacker/controllers/out_of_stock_modal_controller.js
Normal file
19
app/webpacker/controllers/out_of_stock_modal_controller.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
// This is meant to be used with the "modal:closing" event, ie:
|
||||
//
|
||||
// <div data-controller="out-of-stock-modal"
|
||||
// data-action="moda:closing@out-of-stock-modal#redirect"
|
||||
// data-out-of-stock-modal-redirect-value="true"
|
||||
// >
|
||||
// </div>
|
||||
//
|
||||
export default class extends Controller {
|
||||
static values = { redirect: { type: Boolean, default: false } };
|
||||
|
||||
redirect() {
|
||||
if (this.redirectValue) {
|
||||
window.location.pathname = "/shop";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @jest-environment jsdom
|
||||
*/
|
||||
|
||||
import { Application } from "stimulus";
|
||||
import out_of_stock_modal_controller from "../../../app/webpacker/controllers/out_of_stock_modal_controller";
|
||||
|
||||
describe("OutOfStockModalController", () => {
|
||||
beforeAll(() => {
|
||||
const application = Application.start();
|
||||
application.register("out-of-stock-modal", out_of_stock_modal_controller);
|
||||
});
|
||||
|
||||
let originalWindowLocation = window.location;
|
||||
|
||||
beforeEach(() => {
|
||||
Object.defineProperty(window, "location", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: new URL(window.location.href),
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
Object.defineProperty(window, "location", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: originalWindowLocation,
|
||||
});
|
||||
});
|
||||
|
||||
// We use window to dispatch the closing event so we don't need to set up another controller
|
||||
describe("#redirect", () => {
|
||||
describe("when redirect value is false", () => {
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = `
|
||||
<div data-controller="out-of-stock-modal"
|
||||
data-action="closing@window->out-of-stock-modal#redirect"
|
||||
data-out-of-stock-modal-redirect-value="false"
|
||||
>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
it("does not redirect", () => {
|
||||
const event = new Event("closing");
|
||||
window.dispatchEvent(event);
|
||||
|
||||
expect(window.location.href).not.toBe("/shop");
|
||||
});
|
||||
});
|
||||
|
||||
describe("when redirect value is true", () => {
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = `
|
||||
<div data-controller="out-of-stock-modal"
|
||||
data-action="closing@window->out-of-stock-modal#redirect"
|
||||
data-out-of-stock-modal-redirect-value="true"
|
||||
>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
it("redirects to /shop", () => {
|
||||
const event = new Event("closing");
|
||||
window.dispatchEvent(event);
|
||||
|
||||
expect(window.location.pathname).toBe("/shop");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user