12398: add slide-out animation

This commit is contained in:
Ahmed Ejaz
2024-05-28 01:10:30 +05:00
parent 6a59d06de1
commit fb07794cf3
10 changed files with 81 additions and 33 deletions

View File

@@ -12,8 +12,7 @@ class ConfirmModalComponent < ModalComponent
confirm_button_class: :primary,
confirm_button_text: I18n.t('js.admin.modals.confirm'),
cancel_button_text: I18n.t('js.admin.modals.cancel'),
actions_alignment_class: 'justify-space-around',
confirm_submit_method: nil
actions_alignment_class: 'justify-space-around'
)
super(id:, close_button: true)
@confirm_actions = confirm_actions
@@ -25,7 +24,6 @@ class ConfirmModalComponent < ModalComponent
@confirm_button_text = confirm_button_text
@cancel_button_text = cancel_button_text
@actions_alignment_class = actions_alignment_class
@confirm_submit_method = confirm_submit_method
end
private

View File

@@ -7,9 +7,4 @@
%div{ class: "modal-actions #{@actions_alignment_class}" }
%input{ class: "button icon-plus #{close_button_class}", type: 'button', value: @cancel_button_text, "data-action": "click->modal#close" }
- # TODO: This if block needs to be removed when we completely get rid of Reflex
- # The button's form action will be dynamically set when the modal is opened via modal-link-controller
- if @confirm_submit_method
= button_to @confirm_button_text, '', id: 'modal-confirm-button', method: @confirm_submit_method, data: { action: @confirm_actions }
- else
%input{ id: 'modal-confirm-button', class: "button icon-plus #{@confirm_button_class}", type: 'button', value: @confirm_button_text, "data-action": @confirm_actions, "data-reflex": @confirm_reflexes }
%input{ id: 'modal-confirm-button', class: "button icon-plus #{@confirm_button_class}", type: 'button', value: @confirm_button_text, "data-action": @confirm_actions, "data-reflex": @confirm_reflexes }

View File

@@ -37,14 +37,16 @@ module Admin
{ id: params[:id] }
).find_product
status = :ok
if @record.destroy
flash[:success] = I18n.t('admin.products_v3.delete_product.success')
else
flash[:error] = I18n.t('admin.products_v3.delete_product.error')
status = :internal_server_error
end
respond_with do |format|
format.turbo_stream { render :destroy_product_variant }
format.turbo_stream { render :destroy_product_variant, status: }
end
# using flash with turbo stream doesn't clear it because the page is not refreshed.
@@ -56,14 +58,16 @@ module Admin
@record = Spree::Variant.active.find(params[:id])
authorize! :delete, @record
status = :ok
if VariantDeleter.new.delete(@record)
flash[:success] = I18n.t('admin.products_v3.delete_variant.success')
else
flash[:error] = I18n.t('admin.products_v3.delete_variant.error')
status = :internal_server_error
end
respond_with do |format|
format.turbo_stream { render :destroy_product_variant }
format.turbo_stream { render :destroy_product_variant, status: }
end
flash.discard

View File

@@ -5,9 +5,8 @@
cancel_button_text: t("#{base_translation_key}.cancellation_text"),
confirm_button_class: :red,
actions_alignment_class: 'justify-end',
confirm_reflexes: "click->products#delete_#{object_type}",
confirm_actions: "click->modal#close",
confirm_submit_method: :delete,
controller: "products",
confirm_actions: "click->products#delete_#{object_type} click->modal#close",
)
= render delete_modal do
%h2.margin-bottom-20.black-text

View File

@@ -43,5 +43,5 @@
= link_to t('admin.products_page.actions.clone'), clone_admin_product_path(product), 'data-turbo': false
%a{ "data-controller": "modal-link", "data-action": "click->modal-link#setModalDataSetOnConfirm click->modal-link#open",
"data-modal-link-target-value": "product-delete-modal", "class": "delete",
"data-modal-link-modal-dataset-value": {'data-path': admin_product_destroy_path(product)}.to_json }
"data-modal-link-modal-dataset-value": {'data-delete-path': admin_product_destroy_path(product)}.to_json }
= t('admin.products_page.actions.delete')

View File

@@ -66,7 +66,7 @@
- if variant.product.variants.size > 1
%a{ "data-controller": "modal-link", "data-action": "click->modal-link#setModalDataSetOnConfirm click->modal-link#open",
"data-modal-link-target-value": "variant-delete-modal", "class": "delete",
"data-modal-link-modal-dataset-value": {'data-path': admin_destroy_variant_path(variant)}.to_json }
"data-modal-link-modal-dataset-value": {'data-delete-path': admin_destroy_variant_path(variant)}.to_json }
= t('admin.products_page.actions.delete')
- else
%a{ 'data-action': "nested-form#remove", class: 'delete' }

View File

@@ -1,3 +1,6 @@
- # @record can either be Product or Variant
= turbo_stream.remove dom_id(@record)
= render partial: "admin/shared/flashes", locals: { flashes: flash } if defined? flash
- unless flash[:error]
= turbo_stream.remove(dom_id(@record))
-# Without +formats+ option here, by default render is trying to render the equivalant turbo stream
-# It's strange that it works just fine if I remove the +unless+ above
= render(partial: 'admin/shared/flashes', locals: { flashes: flash }, formats: [:html])

View File

@@ -17,9 +17,6 @@ export default class extends Controller {
const modalId = this.targetValue;
const moodalConfirmButtonQuery = `#${modalId} #modal-confirm-button`;
const confirmButton = document.querySelector(moodalConfirmButtonQuery);
this.#setPathToFormAction(confirmButton);
Object.keys(this.modalDatasetValue).forEach((datasetKey) => {
confirmButton.setAttribute(datasetKey, this.modalDatasetValue[datasetKey]);
});
@@ -33,16 +30,4 @@ export default class extends Controller {
getIdentifier() {
return "modal";
}
#setPathToFormAction(confirmButton) {
const isSubmitButton = confirmButton.type === 'submit';
const path = this.modalDatasetValue['data-path'];
if(isSubmitButton && path){
const form = confirmButton.parentElement;
form.setAttribute('action', path);
delete this.modalDatasetValue['data-path'];
}
}
}

View File

@@ -17,6 +17,14 @@ export default class extends ApplicationController {
this.hideLoading();
}
delete_product() {
this.#deleteByRecordType('product');
}
delete_variant() {
this.#deleteByRecordType('variant');
}
showLoading = () => {
if (this.getLoadingController()) {
this.getLoadingController().showLoading();
@@ -39,4 +47,45 @@ export default class extends ApplicationController {
"loading"
));
};
// +recordType+ can either be 'product' or 'variant'
#deleteByRecordType(recordType) {
const deletePath = document.querySelector(`#${recordType}-delete-modal #modal-confirm-button`).getAttribute('data-delete-path');
const elementToBeRemoved = this.#getElementToBeRemoved(deletePath, recordType);
const handleSlideOutAnimationEnd = async () => {
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
try {
const response = await fetch(deletePath, {
method: 'DELETE',
headers: {
Accept: 'text/vnd.turbo-stream.html',
'X-CSRF-Token': csrfToken,
}
});
// need to render the turboStream message, that's why not throwing error here
if(response.status === 500) elementToBeRemoved.classList.remove('slide-out');
const responseTurboStream = await response.text();
Turbo.renderStreamMessage(responseTurboStream);
} catch(error) {
console.error(error.message);
elementToBeRemoved.classList.remove('slide-out');
}
finally {
elementToBeRemoved.removeEventListener('animationend', handleSlideOutAnimationEnd);
}
};
elementToBeRemoved.classList.add('slide-out');
elementToBeRemoved.addEventListener('animationend', handleSlideOutAnimationEnd);
};
#getElementToBeRemoved(path, recordType) {
const recordId = path.substring(path.lastIndexOf('/') + 1);
const elementDomId = `${recordType}_${recordId}`;
return document.getElementById(elementDomId);
};
}

View File

@@ -413,4 +413,19 @@
}
}
}
@keyframes slideOutLeft {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(-100%);
opacity: 0;
}
}
.slide-out {
animation: slideOutLeft 0.5s forwards;
}
}