Skip to content

Commit 7d6fc40

Browse files
RopRaptoralbozekKamilSznajdrowicz
authored
IBX-10609: Enhance notification deletion by integrating modal confirmation. (#1736)
Co-authored-by: Aleksandra Bozek <aleksandra.m.bozek@gmail.com> Co-authored-by: KamilSznajdrowicz <kamil.sznajdrowicz@ibexa.co>
1 parent 4007525 commit 7d6fc40

7 files changed

Lines changed: 83 additions & 16 deletions

File tree

src/bundle/Resources/public/js/scripts/admin.notifications.modal.js

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22
let currentPageLink = null;
33
let getNotificationsStatusErrorShowed = false;
44
let lastFailedCountFetchNotificationNode = null;
5+
let selectedNotificationId = null;
56
const SELECTOR_MODAL_ITEM = '.ibexa-notifications-modal__item';
67
const SELECTOR_MODAL_RESULTS = '.ibexa-notifications-modal__results .ibexa-scrollable-wrapper';
78
const SELECTOR_MODAL_TITLE = '.ibexa-side-panel__header';
89
const SELECTOR_LIST = '.ibexa-list--notifications';
910
const CLASS_MODAL_LOADING = 'ibexa-notifications-modal--loading';
1011
const INTERVAL = 30000;
1112
const panel = doc.querySelector('.ibexa-notifications-modal');
13+
const deleteConfirmationModal = doc.querySelector('#delete-notification-modal');
1214
const { showErrorNotification, showWarningNotification } = ibexa.helpers.notification;
1315
const { getJsonFromResponse, getTextFromResponse } = ibexa.helpers.request;
16+
const { controlManyZIndexes } = ibexa.helpers.modal;
1417
const handleNotificationClickRequest = (notification, response) => {
1518
if (response.status === 'success') {
1619
notification.classList.add('ibexa-notifications-modal__item--read');
@@ -214,9 +217,19 @@
214217

215218
currentTarget.textContent.trim() === markAsReadLabel ? markAsRead({ currentTarget }) : markAsUnread({ currentTarget });
216219
};
217-
const deleteNotification = ({ currentTarget }) => {
218-
const { notificationId } = currentTarget.dataset;
219-
const deleteLink = Routing.generate('ibexa.notifications.delete', { notificationId });
220+
const hidePopupMenu = (btn) => {
221+
const menuBranch = btn.closest('.ibexa-multilevel-popup-menu__branch');
222+
223+
if (!menuBranch?.menuInstanceElement) {
224+
return;
225+
}
226+
227+
const menuInstance = ibexa.helpers.objectInstances.getInstance(menuBranch.menuInstanceElement);
228+
229+
menuInstance.closeMenu();
230+
};
231+
const deleteNotification = () => {
232+
const deleteLink = Routing.generate('ibexa.notifications.delete', { notificationId: selectedNotificationId });
220233
const message = Translator.trans(
221234
/* @Desc("Cannot delete notification") */ 'notifications.modal.message.error.delete',
222235
{},
@@ -227,11 +240,10 @@
227240
.then(getJsonFromResponse)
228241
.then((response) => {
229242
if (response.status === 'success') {
230-
const notification = doc.querySelector(`.ibexa-notifications-modal__item[data-notification-id="${notificationId}"]`);
231-
const menuBranch = currentTarget.closest('.ibexa-multilevel-popup-menu__branch');
232-
const menuInstance = ibexa.helpers.objectInstances.getInstance(menuBranch.menuInstanceElement);
243+
const notification = doc.querySelector(
244+
`.ibexa-notifications-modal__item[data-notification-id="${selectedNotificationId}"]`,
245+
);
233246

234-
menuInstance.closeMenu();
235247
notification.remove();
236248
getNotificationsStatus();
237249
} else {
@@ -244,15 +256,19 @@
244256
};
245257
const attachActionsListeners = () => {
246258
const attachListener = (node, callback) => node.addEventListener('click', callback, false);
247-
const markAsButtons = doc.querySelectorAll('.ibexa-notifications-modal--mark-as');
248-
const deleteButtons = doc.querySelectorAll('.ibexa-notifications-modal--delete');
249-
250-
markAsButtons.forEach((markAsButton) => {
251-
attachListener(markAsButton, handleMarkAsAction);
259+
const markAsBtns = doc.querySelectorAll('.ibexa-notifications-modal--mark-as');
260+
const deleteBtns = doc.querySelectorAll('.ibexa-notifications-open-modal-button');
261+
const setNotificationId = ({ currentTarget }) => {
262+
hidePopupMenu(currentTarget);
263+
selectedNotificationId = currentTarget.dataset.notificationId;
264+
};
265+
266+
markAsBtns.forEach((markAsBtn) => {
267+
attachListener(markAsBtn, handleMarkAsAction);
252268
});
253269

254-
deleteButtons.forEach((deleteButton) => {
255-
attachListener(deleteButton, deleteNotification);
270+
deleteBtns.forEach((deleteBtn) => {
271+
attachListener(deleteBtn, setNotificationId);
256272
});
257273
};
258274
const showNotificationPage = (pageHtml) => {
@@ -308,8 +324,15 @@
308324
currentPageLink = notificationsTable.dataset.notifications;
309325
const interval = Number.parseInt(notificationsTable.dataset.notificationsCountInterval, 10) || INTERVAL;
310326

327+
if (deleteConfirmationModal) {
328+
controlManyZIndexes([{ container: panel, zIndex: '1040' }], deleteConfirmationModal);
329+
}
330+
311331
panel.querySelectorAll(SELECTOR_MODAL_RESULTS).forEach((link) => link.addEventListener('click', handleModalResultsClick, false));
312332
markAllAsReadBtn.addEventListener('click', markAllAsRead, false);
333+
deleteConfirmationModal
334+
?.querySelector('.ibexa-notifications-modal--delete--confirm')
335+
?.addEventListener('click', deleteNotification, false);
313336

314337
const getNotificationsStatusLoop = () => {
315338
getNotificationsStatus().finally(() => {

src/bundle/Resources/public/js/scripts/helpers/modal.helper.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
const controlZIndex = (container) => {
1+
const controlZIndex = (container, ZIndexValue) => {
22
const initialZIndex = getComputedStyle(container).zIndex;
3+
container.style.zIndex = ZIndexValue;
34

45
container.addEventListener('show.bs.modal', () => {
56
container.style.zIndex = 'initial';

src/bundle/Resources/translations/ibexa_notifications.en.xliff

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@
9696
<target state="new">Mark as unread</target>
9797
<note>key: notification.mark_as_unread</note>
9898
</trans-unit>
99+
<trans-unit id="1b5f287ab1b01d5f0402378d633e8924aad59c98" resname="notification.modal.delete.confirm_message">
100+
<source>Are you sure you want to delete this notification?</source>
101+
<target state="new">Are you sure you want to delete this notification?</target>
102+
<note>key: notification.modal.delete.confirm_message</note>
103+
</trans-unit>
99104
<trans-unit id="5b03625b8de51d296ad7f4bc980e631c964185d8" resname="notification.no_longer_available">
100105
<source>The Content item is no longer available</source>
101106
<target state="new">The Content item is no longer available</target>

src/bundle/Resources/views/themes/admin/account/notifications/list_item.html.twig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@
4747

4848
{% set popup_items = popup_items|merge([{
4949
label: 'notification.delete'|trans|desc('Delete'),
50-
action_attr: { class: 'ibexa-notifications-modal--delete', 'data-notification-id': notification.id },
50+
action_attr: {
51+
class: 'ibexa-notifications-open-modal-button',
52+
'data-notification-id': notification.id,
53+
'data-bs-toggle': 'modal',
54+
'data-bs-target': '#delete-notification-modal', }
5155
}]) %}
5256

5357
{% embed '@ibexadesign/ui/component/table/table_body_row.html.twig' with {

src/bundle/Resources/views/themes/admin/account/notifications/side_panel.html.twig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,14 @@
4444
</div>
4545
{% endblock %}
4646
{% endembed %}
47+
48+
{% embed '@ibexadesign/ui/modal/delete_confirmation.html.twig' with {
49+
id: 'delete-notification-modal',
50+
message: 'notification.modal.delete.confirm_message'|trans({}, 'ibexa_notifications')|desc('Are you sure you want to delete this notification?'),
51+
} %}
52+
{% block confirm_button %}
53+
<button class="btn ibexa-btn ibexa-btn--primary ibexa-notifications-modal--delete--confirm" data-bs-dismiss="modal">
54+
{{ 'modal.delete'|trans|desc('Delete') }}
55+
</button>
56+
{% endblock %}
57+
{% endembed %}

src/lib/Behat/BrowserContext/UserNotificationContext.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ public function iPerformNotificationAction(string $action): void
8282
$this->userNotificationPopup->clickActionButton($action);
8383
}
8484

85+
/**
86+
* @When I confirm deletion of notification
87+
*/
88+
public function iConfirmDeletionOfNotification(): void
89+
{
90+
$this->userNotificationPopup->confirmDeletion();
91+
}
92+
8593
/**
8694
* @Then the notification should have :expectedAction action available
8795
*/

src/lib/Behat/Component/UserNotificationPopup.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
namespace Ibexa\AdminUi\Behat\Component;
1010

11+
use Behat\Mink\Session;
1112
use Exception;
1213
use Ibexa\Behat\Browser\Component\Component;
1314
use Ibexa\Behat\Browser\Element\Action\MouseOverAndClick;
@@ -20,6 +21,14 @@
2021

2122
class UserNotificationPopup extends Component
2223
{
24+
private Dialog $dialog;
25+
26+
public function __construct(Session $session, Dialog $dialog)
27+
{
28+
parent::__construct($session);
29+
$this->dialog = $dialog;
30+
}
31+
2332
public function clickNotification(string $expectedType, string $expectedDescription)
2433
{
2534
$notifications = $this->getHTMLPage()->findAll($this->getLocator('notificationItem'));
@@ -123,6 +132,12 @@ public function clickActionButton(string $buttonText): void
123132
);
124133
}
125134

135+
public function confirmDeletion(): void
136+
{
137+
$this->dialog->verifyIsLoaded();
138+
$this->dialog->confirm();
139+
}
140+
126141
public function findActionButton(string $buttonText): ?ElementInterface
127142
{
128143
$this->getHTMLPage()

0 commit comments

Comments
 (0)