8000 Improve QI component by mparvazi · Pull Request #350 · PrestaShop/hummingbird · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Improve QI component #350

8000
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 1, 2022
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
15 changes: 14 additions & 1 deletion src/js/components/useQuantityInput.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('useQuantityInput', () => {
const incrementButton = getHTMLElement<HTMLButtonElement>(selectorsMap.qtyInput.increment);
incrementButton.click();
await debounceTimeout();
const productLineAlert = getHTMLElement<HTMLDivElement>(selectorsMap.qtyInput.alert(Quantify.ProductId));
const productLineAlert = getHTMLElement<HTMLDivElement>(selectorsMap.qtyInput.alert(Quantify.AlertId));
mockedIncrementFetch.mockReset();

expect(productLineAlert.innerHTML).not.toBe('');
Expand Down Expand Up @@ -81,6 +81,19 @@ describe('useQuantityInput', () => {
expect(decreasedValue).toEqual(qtyMin);
});

it('should revert the value if is not an integer number', async () => {
const qtyInput = getHTMLElement<HTMLInputElement>('input');
const baseValue = qtyInput.value;
qtyInput.value = '1.1';
qtyInput.dispatchEvent(new Event('keyup'));

const incrementButton = getHTMLElement<HTMLButtonElement>(selectorsMap.qtyInput.increment);
incrementButton.click();
await debounceTimeout();

expect(qtyInput.value).toEqual(baseValue);
});

it('should display confirmation buttons on keyup', () => {
const qtyInput = getHTMLElement<HTMLInputElement>('input');
qtyInput.value = '1';
Expand Down
23 changes: 12 additions & 11 deletions src/js/components/useQuantityInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ const useQuantityInput: Theme.QuantityInput.Function = (
});
};

const isValidInputNum = (inputNum: number) => !Number.isNaN(inputNum) && Number.isInteger(inputNum);

const changeQuantity = (qtyInput: HTMLInputElement, change: number, keyboard = false) => {
const {mode} = qtyInput.dataset;

Expand All @@ -85,7 +87,7 @@ const changeQuantity = (qtyInput: HTMLInputElement, change: number, keyboard = f
const currentValue = Number(qtyInput.value);
const min = (qtyInput.dataset.updateUrl === undefined) ? Number(qtyInput.getAttribute('min')) : 0;
const newValue = Math.max(currentValue + change, min);
qtyInput.value = String(!isNaN(newValue) ? newValue : baseValue);
qtyInput.value = String(isValidInputNum(newValue) ? newValue : baseValue);
}
};

Expand All @@ -103,7 +105,7 @@ const updateQuantity = async (qtyInputGroup: Theme.QuantityInput.InputGroup, cha
const baseValue = Number(qtyInput.getAttribute('value'));
const quantity = targetValue - baseValue;

if (Number.isNaN(targetValue) === false && quantity !== 0) {
if (isValidInputNum(targetValue) && quantity !== 0) {
const requestUrl = qtyInput.dataset.updateUrl;

if (requestUrl !== undefined) {
Expand All @@ -113,8 +115,6 @@ const updateQuantity = async (qtyInputGroup: Theme.QuantityInput.InputGroup, cha

toggleButtonSpinner(targetButton, targetButtonIcon, targetButtonSpinner);

const {productId} = qtyInput.dataset;

try {
const response = await sendUpdateCartRequest(requestUrl, quantity);

Expand All @@ -123,7 +123,7 @@ const updateQuantity = async (qtyInputGroup: Theme.QuantityInput.InputGroup, cha

if (data.hasError) {
const errors = data.errors as Array<string>;
const productAlertSelector = resetAlertContainer(Number(productId));
const productAlertSelector = resetAlertContainer(qtyInput);

if (errors && productAlertSelector) {
errors.forEach((error: string) => {
Expand Down Expand Up @@ -156,7 +156,7 @@ const updateQuantity = async (qtyInputGroup: Theme.QuantityInput.InputGroup, cha

if (errorData.status !== undefined) {
const errorMsg = `${errorData.statusText}: ${errorData.url}`;
const productAlertSelector = resetAlertContainer(Number(productId));
const productAlertSelector = resetAlertContainer(qtyInput);
useAlert(errorMsg, {type: 'danger', selector: productAlertSelector}).show();

prestashop.emit(events.handleError, {
Expand All @@ -170,8 +170,7 @@ const updateQuantity = async (qtyInputGroup: Theme.QuantityInput.InputGroup, cha
}
}
} else {
// The input value is not a correct number so revert to the value in the DOM
qtyInput.value = String(baseValue);
// The input value is not a correct number
showSpinButtons(qtyInputGroup);
}
}
Expand All @@ -183,9 +182,11 @@ const getTargetButton = (qtyInputGroup: Theme.QuantityInput.InputGroup, change:
return (change > 0) ? incrementButton : decrementButton;
};

const resetAlertContainer = (productId: number) => {
if (productId) {
const productAlertSelector = quantityInputMap.alert(productId);
const resetAlertContainer = (qtyInput: HTMLInputElement) => {
const {alertId} = qtyInput.dataset;

if (alertId) {
const productAlertSelector = quantityInputMap.alert(alertId);
const productAlertContainer = document.querySelector<HTMLDivElement>(productAlertSelector);

if (productAlertContainer) {
Expand Down
6 changes: 4 additions & 2 deletions src/js/constants/mocks/useQuantityInput-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
*/

export const delay = 5;
export const ProductId = 1;
export const ProductId = '1';
export const AlertId = '99999';

export const ProductLineTemplate = `
<div class="product-line">
<div id="js-product-line-alert--${ProductId}"></div>
<div id="js-product-line-alert--${AlertId}"></div>
<div class="product-line__informations">
<div class="row">
<div class="quantity-button js-quantity-button">
Expand All @@ -21,6 +22,7 @@ export const ProductLineTemplate = `
<input
data-update-url="#"
data-product-id="${ProductId}"
data-alert-id="${AlertId}"
value="1"
min="1"
type="text"
Expand Down
2 changes: 1 addition & 1 deletion src/js/constants/selectors-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export const qtyInput = {
confirm: '.confirmation',
icon: '.material-icons',
spinner: '.spinner-border',
alert: (id: number): string => `#js-product-line-alert--${id}`,
alert: (param: string): string => `#js-product-line-alert--${param}`,
};

export const formValidation = {
Expand Down
92 changes: 92 additions & 0 deletions templates/catalog/_partials/product-customization-modal.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@

{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'product-customization-modal'}

<div class="{$componentName}__content">
{assign var=customization_modal_id value="{$componentName}--{$product.id_customization|intval}"}
<button type="button" class="btn btn-sm btn-outline-primary mb-2"
data-bs-toggle="modal"
data-bs-target="#{$customization_modal_id}"
>
{l s='Customized' d='Shop.Theme.Checkout'}
</button>
<div class="modal fade" id="{$customization_modal_id}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-fullscreen-sm-down">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">{l s='Product customization' d='Shop.Theme.Checkout'}</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{l s='Close' d='Shop.Theme.Global'}"></button>
</div>
<div class="modal-body">
{assign var=image_modals value=[]}
{foreach from=$product.customizations item="customization"}
{foreach from=$customization.fields item="field"}
<div class="{$componentName}__line{if !$field@last} mb-3{/if}">
<p class="mb-2 text-dark">{$field.label}</p>
{if $field.type == 'text'}
<p class="mb-0">
{if $field.id_module|intval}
{$field.text nofilter}
{else}
{$field.text}
{/if}
</p>
{elseif $field.type == 'image'}
{assign var=image_modal_id value="{$componentName}_image--{mt_rand()}"}
<a href="#{$image_modal_id}" data-bs-toggle="modal" data-bs-dismiss="modal" >
<img class="rounded-3" src="{$field.image.small.url}">
</a>
{append var='image_modals'
value=[
"id"=>$image_modal_id,
"title"=>$field.label,
"image_url"=>$field.image.large.url,
"image_info"=>getimagesize($field.image.large.url),
"back_id"=>$customization_modal_id
]
}
{/if}
</div>
{/foreach}
{/foreach}
</div>
</div>
</div>
</div>
</div>

{if isset($image_modals) && count($image_modals)}
<div class="{$componentName}__popup">
{foreach from=$image_modals item="image_modal"}
<div class="modal fade" id="{$image_modal['id']}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-fullscreen-sm-down mw-100">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">{$image_modal['title']}</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{l s='Close' d='Shop.Theme.Global'}"></button>
</div>
<div class="modal-body">
<img class="img-fluid" src="{$image_modal['image_url']}">
</div>
<div class="modal-footer border-1 d-flex flex-wrap justify-content-between w-100">
<div class="d-inline-flex">
<span>{$image_modal['image_info'][0]} x {$image_modal['image_info'][1]}</span>
<span class="text-muted ms-2">({$image_modal['image_info']['mime']})</span>
</div>
<button type="button" class="btn btn-primary"
data-bs-target="#{$image_modal['back_id']}"
data-bs-toggle="modal"
data-bs-dismiss="modal"
>
{l s='Back' d='Shop.Theme.Global'}
</button>
</div>
</div>
</div>
</div>
{/foreach}
</div>
{/if}
34 changes: 10 additions & 24 deletions templates/checkout/_partials/cart-detailed-product-line.tpl
Original file line number Diff line number Diff line change
@@ -1,30 +1,11 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*}
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}

<div class="product-line row">
<div id="js-product-line-alert--{$product.id_product}"></div>
{assign var=product_line_alert_id value=10|mt_rand:100000}
<div id="js-product-line-alert--{$product_line_alert_id}"></div>
<div class="product-line__image col-4 col-sm-2">
<a class="product-line__title product-line__item" href="{$product.url}"
data-id_customization="{$product.id_customization|intval}">
Expand All @@ -43,6 +24,10 @@
{$product.name}
</a>

{if is_array($product.customizations) && $product.customizations|count}
{include file="catalog/_partials/product-customization-modal.tpl" product=$product}
{/if}

{foreach from=$product.attributes key="attribute" item="value"}
<div class="product-line__info product-line__item {$attribute|lower}">
<span class="label">{$attribute}:</span>
Expand Down Expand Up @@ -90,6 +75,7 @@
"name"=>"product-quantity-spin",
"data-update-url"=>"{$product.update_quantity_url}",
"data-product-id"=>"{$product.id_product}",
"data-alert-id"=>"{$product_line_alert_id}",
"value"=>"{$product.quantity}",
"min"=>"{$product.minimal_quantity}"
]
Expand Down
7 changes: 1 addition & 6 deletions templates/checkout/_partials/order-confirmation-table.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,7 @@
{/if}

{if is_array($product.customizations) && $product.customizations|count}
{foreach from=$product.customizations item="customization"}
<div class="customizations">
<a href="#" data-bs-toggle="modal" data-target="#product-customizations-modal-{$customization.id_customization}">{l s='Product customization' d='Shop.Theme.Catalog'}</a>
</div>
{include file='catalog/_partials/customization-modal.tpl' customization=$customization}
{/foreach}
{include file="catalog/_partials/product-customization-modal.tpl" product=$product}
{/if}

{hook h='displayProductPriceBlock' product=$product type="unit_price"}
Expand Down
0