Skip to content

Commit 0a6fb46

Browse files
committed
Show confirmation modal on contact unlink
1 parent b682b26 commit 0a6fb46

5 files changed

Lines changed: 162 additions & 25 deletions

File tree

components/ILIAS/Contact/BuddySystem/classes/class.ilBuddySystemGUI.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818

1919
declare(strict_types=1);
2020

21+
use ILIAS\Filesystem\Stream\Streams;
22+
use ILIAS\HTTP\Response\ResponseHeader;
2123
use ILIAS\HTTP\Services;
24+
use ILIAS\UI\Factory as UIFactory;
25+
use ILIAS\UI\Renderer as UIRenderer;
2226

2327
/**
2428
* Class ilBuddySystemGUI
@@ -39,6 +43,8 @@ class ilBuddySystemGUI
3943
protected ilLanguage $lng;
4044
protected Services $http;
4145
private readonly ilGlobalTemplateInterface $main_tpl;
46+
private UIFactory $ui_factory;
47+
private UIRenderer $ui_renderer;
4248

4349
public function __construct()
4450
{
@@ -49,6 +55,8 @@ public function __construct()
4955
$this->ctrl = $DIC['ilCtrl'];
5056
$this->user = $DIC['ilUser'];
5157
$this->lng = $DIC['lng'];
58+
$this->ui_factory = $DIC->ui()->factory();
59+
$this->ui_renderer = $DIC->ui()->renderer();
5260

5361
$this->buddyList = ilBuddyList::getInstanceByGlobalUser();
5462
$this->stateFactory = ilBuddySystemRelationStateFactory::getInstance();
@@ -68,8 +76,14 @@ public static function initializeFrontend(ilGlobalTemplateInterface $page): void
6876
$DIC->language()->loadLanguageModule('buddysystem');
6977

7078
$page->addJavaScript('./assets/js/buddy_system.js');
79+
$page->addJavaScript('./assets/js/modal.min.js');
7180

7281
$config = new stdClass();
82+
$config->async_get_unlink_modal_confirmation_html = $DIC->ctrl()->getLinkTargetByClass([
83+
ilUIPluginRouterGUI::class,
84+
self::class
85+
], 'asyncGetUnlinkModalConfirmationHtml', '', true, false);
86+
7387
$config->http_post_url = $DIC->ctrl()->getFormActionByClass([
7488
ilUIPluginRouterGUI::class,
7589
self::class
@@ -87,6 +101,32 @@ public static function initializeFrontend(ilGlobalTemplateInterface $page): void
87101
}
88102
}
89103

104+
public function asyncGetUnlinkModalConfirmationHtmlCommand(): never
105+
{
106+
$confirmation_modal = $this->ui_factory->modal()->interruptive(
107+
$this->lng->txt('confirmation'),
108+
$this->lng->txt('buddy_confirm_unlink'),
109+
''
110+
)
111+
->withActionButtonLabel($this->lng->txt('confirm'));
112+
113+
$this->http->saveResponse(
114+
$this->http->response()->withBody(
115+
Streams::ofString(
116+
json_encode([
117+
"html" => $this->ui_renderer->renderAsync($confirmation_modal),
118+
"signals" => [
119+
"show" => $confirmation_modal->getShowSignal()->getId(),
120+
"close" => $confirmation_modal->getCloseSignal()->getId()
121+
]
122+
], JSON_THROW_ON_ERROR)
123+
)
124+
)->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
125+
);
126+
$this->http->sendResponse();
127+
$this->http->close();
128+
}
129+
90130
/**
91131
* @throws RuntimeException
92132
*/

components/ILIAS/Contact/classes/class.ilContactGUI.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,40 @@ private function updateState(): void
375375
return;
376376
}
377377

378+
if ($action === 'unlink') {
379+
$this->ctrl->setParameterByClass(self::class, 'user_id', current($user_ids));
380+
$this->ctrl->redirectByClass(self::class, 'confirmUnlinkContact');
381+
}
382+
378383
$this->updateRelationState(current($user_ids), $action);
379384
}
380385

386+
private function confirmUnlinkContact(): void
387+
{
388+
$this->activateTab('my_contacts');
389+
$this->tabs_gui->activateSubTab('buddy_view_table');
390+
391+
$user_id = $this->http->wrapper()->query()->retrieve('user_id', $this->refinery->kindlyTo()->int());
392+
393+
$confirmation_gui = new ilConfirmationGUI();
394+
$confirmation_gui->setHeaderText($this->lng->txt('buddy_confirm_unlink'));
395+
$confirmation_gui->addItem('user_id', (string) $user_id, ilObjUser::_lookupLogin($user_id));
396+
$confirmation_gui->setConfirm($this->lng->txt('confirm'), 'unlinkContact');
397+
$confirmation_gui->setCancel($this->lng->txt('cancel'), 'showContacts');
398+
$confirmation_gui->setFormAction($this->ctrl->getFormActionByClass(self::class, 'showContacts'));
399+
400+
$this->tpl->setContent($confirmation_gui->getHTML());
401+
$this->tpl->printToStdout();
402+
}
403+
404+
private function unlinkContact(): void
405+
{
406+
$user_id = $this->http->wrapper()->post()->retrieve('user_id', $this->refinery->kindlyTo()->int());
407+
408+
$this->updateRelationState($user_id, 'unlink');
409+
$this->ctrl->redirectByClass(self::class, 'showContacts');
410+
}
411+
381412
private function updateRelationState(int $user, string $action): void
382413
{
383414
$login = ilObjUser::_lookupLogin($user);

components/ILIAS/Contact/resources/buddy_system.js

Lines changed: 89 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@
2525

2626
const BuddySystemButton = {
2727
config: {},
28+
unlinkConfirmationModal: {
29+
signals: {
30+
show: '',
31+
close: '',
32+
}
33+
},
34+
modal: null,
35+
setupConfirmationModal: false,
2836

2937
setConfig(config) {
3038
this.config = config;
@@ -40,34 +48,90 @@
4048

4149
const triggerButton = e.target.closest(triggerSelector);
4250
const container = triggerButton.closest(`.${this.config.bnt_class}`);
43-
if (triggerButton.dataset.submitted === 'true') return Promise.resolve();
44-
45-
const values = new FormData();
46-
values.append('usr_id', container.dataset.buddyId);
47-
values.append('action', triggerButton.dataset.action);
48-
values.append(`cmd[${BuddySystem.config.transition_state_cmd}]`, 1);
49-
50-
return disableButtons(container)
51-
.then(() => fetch(BuddySystem.config.http_post_url, {
52-
method: 'POST',
53-
headers: { Accept: 'application/json' },
54-
body: values,
55-
}))
56-
.then((response) => {
57-
if (!response.ok) throw new Error('Request failed');
58-
return response.json();
59-
})
60-
.then((data) => processResponse(container, data))
61-
.then(() => {
62-
container.querySelector(toggleSelector)?.focus();
63-
})
64-
.catch((error) => {
65-
console.error(error);
66-
enableButtons(container);
67-
container.querySelector(toggleSelector)?.focus();
51+
52+
const widgetClickAction = () => {
53+
if (triggerButton.dataset.submitted === 'true') return Promise.resolve();
54+
55+
const values = new FormData();
56+
values.append('usr_id', container.dataset.buddyId);
57+
values.append('action', triggerButton.dataset.action);
58+
values.append(`cmd[${BuddySystem.config.transition_state_cmd}]`, 1);
59+
60+
return disableButtons(container)
61+
.then(() => fetch(BuddySystem.config.http_post_url, {
62+
method: 'POST',
63+
headers: { Accept: 'application/json' },
64+
body: values,
65+
}))
66+
.then((response) => {
67+
if (!response.ok) throw new Error('Request failed');
68+
return response.json();
69+
})
70+
.then((data) => processResponse(container, data))
71+
.then(() => {
72+
container.querySelector(toggleSelector)?.focus();
73+
})
74+
.catch((error) => {
75+
console.error(error);
76+
enableButtons(container);
77+
container.querySelector(toggleSelector)?.focus();
78+
});
79+
};
80+
81+
if (triggerButton.dataset.action === 'unlink') {
82+
return showUnlinkConfirmationModal().then(() => {
83+
return widgetClickAction();
6884
});
85+
}
86+
87+
return widgetClickAction();
6988
};
7089

90+
const showUnlinkConfirmationModal = () => new Promise((resolve) => {
91+
if (!this.setupConfirmationModal) {
92+
fetch(BuddySystem.config.async_get_unlink_modal_confirmation_html)
93+
.then((response) => {
94+
if (!response.ok) throw new Error('Request failed');
95+
return response.json();
96+
})
97+
.then((data) => {
98+
const wrapper = document.createElement('div');
99+
const modalFragment = document.createRange().createContextualFragment(data.html);
100+
101+
wrapper.appendChild(modalFragment);
102+
document.body.append(wrapper)
103+
this.modal = wrapper.querySelector("dialog");
104+
105+
this.unlinkConfirmationModal.signals.show = data.signals.show;
106+
this.unlinkConfirmationModal.signals.close = data.signals.close
107+
108+
this.modal.querySelector('input[type="submit"]').addEventListener(
109+
'click',
110+
(event) => onModalSubmitClicked(event, resolve),
111+
{once: true}
112+
);
113+
}).then(() => {
114+
this.setupConfirmationModal = true;
115+
global.jQuery(document).trigger(this.unlinkConfirmationModal.signals.show, {});
116+
})
117+
return;
118+
}
119+
120+
const submitButton = this.modal.querySelector('input[type="submit"]');
121+
submitButton.addEventListener(
122+
'click',
123+
(event) => onModalSubmitClicked(event, resolve),
124+
{once: true}
125+
);
126+
global.jQuery(document).trigger(this.unlinkConfirmationModal.signals.show, {});
127+
});
128+
129+
const onModalSubmitClicked = (event, resolve) => {
130+
event.preventDefault();
131+
global.jQuery(document).trigger(this.unlinkConfirmationModal.signals.close, {});
132+
resolve();
133+
}
134+
71135
const disableButtons = (container) => new Promise((resolve) => {
72136
document.querySelectorAll(`.${this.config.bnt_class}`).forEach((btnContainer) => {
73137
if (btnContainer.dataset.buddyId === container.dataset.buddyId) {

lang/ilias_de.lang

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2727,6 +2727,7 @@ buddysystem#:#buddy_bs_state_requested_p#:#Angefragt
27272727
buddysystem#:#buddy_bs_state_unlinked#:#Nicht vernetzt
27282728
buddysystem#:#buddy_bs_state_unlinked_a#:#Nicht vernetzt
27292729
buddysystem#:#buddy_bs_state_unlinked_p#:#Nicht vernetzt
2730+
buddysystem#:#buddy_confirm_unlink#:#Möchten Sie die Verbindung zu diesem Kontakt wirklich aufheben?
27302731
buddysystem#:#buddy_enable#:#Aktiviere „Benutzerkontakte“
27312732
buddysystem#:#buddy_enable_info#:#Falls aktiviert, können Benutzer im System über Kontaktanfragen miteinander in Verbindung treten. Eine zusätzliche persönliche Einstellung ermöglicht jedem Benutzer, Kontaktaufnahmen zuzulassen oder zu verhindern.
27322733
buddysystem#:#buddy_handle_contact_request#:#Kontaktanfrage

lang/ilias_en.lang

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,6 +2728,7 @@ buddysystem#:#buddy_bs_state_requested_p#:#Requested
27282728
buddysystem#:#buddy_bs_state_unlinked#:#Unlinked
27292729
buddysystem#:#buddy_bs_state_unlinked_a#:#Unlinked
27302730
buddysystem#:#buddy_bs_state_unlinked_p#:#Unlinked
2731+
buddysystem#:#buddy_confirm_unlink#:#Do you really want to disconnect from this contact?
27312732
buddysystem#:#buddy_enable#:#Activate ‘Contacts’
27322733
buddysystem#:#buddy_enable_info#:#If enabled, users are allowed to contact each other by initiating contact requests. Additionally, there is a personal user setting to allow or prevent being contacted.
27332734
buddysystem#:#buddy_handle_contact_request#:#Contact Request

0 commit comments

Comments
 (0)