chg: [inbox] Added bulk deletion support

pull/59/head
mokaddem 2021-06-23 11:19:56 +02:00
parent 18e32730d2
commit 2c58de4712
2 changed files with 114 additions and 9 deletions

View File

@ -57,17 +57,46 @@ class InboxController extends AppController
} }
} }
public function delete($id) public function delete($id=false)
{ {
if ($this->request->is('post')) { if ($this->request->is('post')) { // cannot rely on CRUD's delete as inbox's processor discard function is responsible to handle their messages
$request = $this->Inbox->get($id, ['contain' => ['Users' => ['Individuals' => ['Alignments' => 'Organisations']]]]); $ids = $this->CRUD->getIdsOrFail($id);
$this->inboxProcessors = TableRegistry::getTableLocator()->get('InboxProcessors'); $discardSuccesses = 0;
$processor = $this->inboxProcessors->getProcessor($request->scope, $request->action); $discardResults = [];
$discardResult = $processor->discard($id, $request); $discardErrors = [];
return $processor->genHTTPReply($this, $discardResult); foreach ($ids as $id) {
$request = $this->Inbox->get($id, ['contain' => ['Users' => ['Individuals' => ['Alignments' => 'Organisations']]]]);
$this->inboxProcessors = TableRegistry::getTableLocator()->get('InboxProcessors');
$processor = $this->inboxProcessors->getProcessor($request->scope, $request->action);
$discardResult = $processor->discard($id, $request);
$discardResults[] = $discardResult;
if ($discardResult['success']) {
$discardSuccesses++;
} else {
$discardErrors[] = $discardResult;
}
}
if (count($ids) == 1) {
return $processor->genHTTPReply($this, $discardResult);
} else {
$success = $discardSuccesses == count($ids);
$message = __('{0} {1} have been discarded.',
$discardSuccesses == count($ids) ? __('All') : sprintf('%s / %s', $discardSuccesses, count($ids)),
sprintf('%s %s', Inflector::singularize($this->Inbox->getAlias()), __('messages'))
);
$this->CRUD->setResponseForController('delete', $success, $message, $discardResults, $discardResults);
$responsePayload = $this->CRUD->getResponsePayload();
if (!empty($responsePayload)) {
return $responsePayload;
}
}
} }
$this->set('deletionTitle', __('Discard request')); $this->set('deletionTitle', __('Discard request'));
$this->set('deletionText', __('Are you sure you want to discard request #{0}?', $id)); if (!empty($id)) {
$this->set('deletionText', __('Are you sure you want to discard request #{0}?', $id));
} else {
$this->set('deletionText', __('Are you sure you want to discard the selected requests?'));
}
$this->set('deletionConfirm', __('Discard')); $this->set('deletionConfirm', __('Discard'));
$this->CRUD->delete($id); $this->CRUD->delete($id);
$responsePayload = $this->CRUD->getResponsePayload(); $responsePayload = $this->CRUD->getResponsePayload();

View File

@ -8,6 +8,16 @@ echo $this->element('genericElements/IndexTable/index_table', [
'data' => $data, 'data' => $data,
'top_bar' => [ 'top_bar' => [
'children' => [ 'children' => [
[
'children' => [
[
'text' => __('Discard request'),
'variant' => 'danger',
'onclick' => 'discardRequests',
]
],
'type' => 'multi_select_actions',
],
[ [
'type' => 'context_filters', 'type' => 'context_filters',
'context_filters' => !empty($filteringContexts) ? $filteringContexts : [] 'context_filters' => !empty($filteringContexts) ? $filteringContexts : []
@ -23,6 +33,15 @@ echo $this->element('genericElements/IndexTable/index_table', [
] ]
], ],
'fields' => [ 'fields' => [
[
'element' => 'selector',
'class' => 'short',
'data' => [
'id' => [
'value_path' => 'id'
]
]
],
[ [
'name' => '#', 'name' => '#',
'sort' => 'id', 'sort' => 'id',
@ -95,5 +114,62 @@ echo $this->element('genericElements/IndexTable/index_table', [
] ]
] ]
]); ]);
echo '</div>';
?> ?>
<script>
function discardRequests(idList, selectedData, $table) {
const successCallback = function([data, modalObject]) {
UI.reload('/inbox/index', UI.getContainerForTable($table), $table)
}
const failCallback = ([data, modalObject]) => {
const tableData = selectedData.map(row => {
entryInError = data.filter(error => error.data.id == row.id)[0]
$faIcon = $('<i class="fa"></i>').addClass(entryInError.success ? 'fa-check text-success' : 'fa-times text-danger')
return [row.id, row.scope, row.action, row.title, entryInError.message, JSON.stringify(entryInError.errors), $faIcon]
});
handleMessageTable(
modalObject.$modal,
['<?= __('ID') ?>', '<?= __('Scope') ?>', '<?= __('Action') ?>', '<?= __('Title') ?>', '<?= __('Message') ?>', '<?= __('Error') ?>', '<?= __('State') ?>'],
tableData
)
const $footer = $(modalObject.ajaxApi.statusNode).parent()
modalObject.ajaxApi.statusNode.remove()
const $cancelButton = $footer.find('button[data-dismiss="modal"]')
$cancelButton.text('<?= __('OK') ?>').removeClass('btn-secondary').addClass('btn-primary')
}
UI.submissionModal('/inbox/delete', successCallback, failCallback).then(([modalObject, ajaxApi]) => {
const $idsInput = modalObject.$modal.find('form').find('input#ids-field')
$idsInput.val(JSON.stringify(idList))
const tableData = selectedData.map(row => {
return [row.id, row.scope, row.action, row.title]
});
handleMessageTable(
modalObject.$modal,
['<?= __('ID') ?>', '<?= __('Scope') ?>', '<?= __('Action') ?>', '<?= __('Title') ?>'],
tableData
)
})
function constructMessageTable(header, data) {
return HtmlHelper.table(
header,
data,
{
small: true,
borderless: true,
tableClass: ['message-table', 'mt-4 mb-0'],
}
)
}
function handleMessageTable($modal, header, data) {
const $modalBody = $modal.find('.modal-body')
const $messageTable = $modalBody.find('table.message-table')
const messageTableHTML = constructMessageTable(header, data)[0].outerHTML
if ($messageTable.length) {
$messageTable.html(messageTableHTML)
} else {
$modalBody.append(messageTableHTML)
}
}
}
</script>