chg: [component:CRUD] Improved flexibility
parent
2d26bc597f
commit
899fa27a45
|
@ -49,6 +49,23 @@ class CRUDComponent extends Component
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getResponsePayload Returns the adaquate response payload based on the request context
|
||||
*
|
||||
* @return false or Array
|
||||
*/
|
||||
public function getResponsePayload()
|
||||
{
|
||||
if ($this->Controller->ParamHandler->isRest()) {
|
||||
return $this->Controller->restResponsePayload;
|
||||
} else if ($this->Controller->ParamHandler->isAjax() && $this->request->is(['post', 'put'])) {
|
||||
if (empty($this->Controller->isFailResponse) || empty($this->Controller->ajax_with_html_on_failure)) {
|
||||
return $this->Controller->ajaxResponsePayload;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getMetaTemplates()
|
||||
{
|
||||
$metaTemplates = [];
|
||||
|
@ -301,8 +318,9 @@ class CRUDComponent extends Component
|
|||
if ($this->Table->delete($data)) {
|
||||
$message = __('{0} deleted.', $this->ObjectAlias);
|
||||
if ($this->Controller->ParamHandler->isRest()) {
|
||||
$data = $this->Table->get($id);
|
||||
$this->Controller->restResponsePayload = $this->RestResponse->saveSuccessResponse($this->TableAlias, 'delete', $id, 'json', $message);
|
||||
$this->Controller->restResponsePayload = $this->RestResponse->viewData($data, 'json');
|
||||
} else if ($this->Controller->ParamHandler->isAjax()) {
|
||||
$this->Controller->ajaxResponsePayload = $this->Controller->RestResponse->ajaxSuccessResponse($this->ObjectAlias, 'delete', $data, $message);
|
||||
} else {
|
||||
$this->Controller->Flash->success($message);
|
||||
$this->Controller->redirect($this->Controller->referer());
|
||||
|
@ -493,8 +511,17 @@ class CRUDComponent extends Component
|
|||
}
|
||||
}
|
||||
|
||||
private function getFilteringContextFromField($context)
|
||||
private function getFilteringContextFromField($field)
|
||||
{
|
||||
return $this->Table->find()->distinct([$context])->all()->extract($context)->toList();
|
||||
$exploded = explode('.', $field);
|
||||
if (count($exploded) > 1) {
|
||||
$model = $exploded[0];
|
||||
$subField = $exploded[1];
|
||||
return $this->Table->{$model}->find()
|
||||
->distinct([$subField])
|
||||
->extract($subField)->toList();
|
||||
} else {
|
||||
return $this->Table->find()->distinct([$field])->all()->extract($field)->toList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,14 @@ class IndividualsController extends AppController
|
|||
public function index()
|
||||
{
|
||||
$this->CRUD->index([
|
||||
'filters' => ['uuid', 'email', 'first_name', 'last_name', 'position', 'Organisations.id'],
|
||||
'filters' => ['uuid', 'email', 'first_name', 'last_name', 'position', 'Organisations.id', 'Alignments.type'],
|
||||
'quickFilters' => ['uuid', 'email', 'first_name', 'last_name', 'position'],
|
||||
'contextFilters' => [
|
||||
'allow_all' => true,
|
||||
'fields' => [
|
||||
'Alignments.type'
|
||||
]
|
||||
],
|
||||
'contain' => ['Alignments' => 'Organisations']
|
||||
]);
|
||||
if ($this->ParamHandler->isRest()) {
|
||||
|
@ -29,8 +35,9 @@ class IndividualsController extends AppController
|
|||
public function add()
|
||||
{
|
||||
$this->CRUD->add();
|
||||
if ($this->ParamHandler->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
$this->set('metaGroup', 'ContactDB');
|
||||
}
|
||||
|
@ -38,8 +45,9 @@ class IndividualsController extends AppController
|
|||
public function view($id)
|
||||
{
|
||||
$this->CRUD->view($id, ['contain' => ['Alignments' => 'Organisations']]);
|
||||
if ($this->ParamHandler->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
$this->set('metaGroup', 'ContactDB');
|
||||
}
|
||||
|
@ -47,10 +55,9 @@ class IndividualsController extends AppController
|
|||
public function edit($id)
|
||||
{
|
||||
$this->CRUD->edit($id);
|
||||
if ($this->ParamHandler->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
} else if($this->ParamHandler->isAjax() && $this->request->is(['post', 'put'])) {
|
||||
return $this->ajaxResponsePayload;
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
$this->set('metaGroup', 'ContactDB');
|
||||
$this->render('add');
|
||||
|
@ -59,8 +66,9 @@ class IndividualsController extends AppController
|
|||
public function delete($id)
|
||||
{
|
||||
$this->CRUD->delete($id);
|
||||
if ($this->ParamHandler->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
$this->set('metaGroup', 'ContactDB');
|
||||
}
|
||||
|
|
|
@ -23,12 +23,9 @@ class UsersController extends AppController
|
|||
public function add()
|
||||
{
|
||||
$this->CRUD->add();
|
||||
if ($this->ParamHandler->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
} else if ($this->ParamHandler->isAjax() && $this->request->is(['post', 'put'])) {
|
||||
if (empty($this->isFailResponse) || empty($this->ajax_with_html_on_failure)) {
|
||||
return $this->ajaxResponsePayload;
|
||||
}
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
$dropdownData = [
|
||||
'role' => $this->Users->Roles->find('list', [
|
||||
|
@ -78,8 +75,9 @@ class UsersController extends AppController
|
|||
$params['fields'][] = 'role_id';
|
||||
}
|
||||
$this->CRUD->edit($id, $params);
|
||||
if ($this->ParamHandler->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
$dropdownData = [
|
||||
'role' => $this->Users->Roles->find('list', [
|
||||
|
@ -94,11 +92,21 @@ class UsersController extends AppController
|
|||
$this->render('add');
|
||||
}
|
||||
|
||||
public function toggle($id, $fieldName = 'disabled')
|
||||
{
|
||||
$this->CRUD->toggle($id, $fieldName);
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$this->CRUD->delete($id);
|
||||
if ($this->ParamHandler->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
$this->set('metaGroup', $this->isAdmin ? 'Administration' : 'Cerebrate');
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@ echo $this->element('genericElements/IndexTable/index_table', [
|
|||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'context_filters',
|
||||
'context_filters' => $filteringContexts
|
||||
],
|
||||
[
|
||||
'type' => 'search',
|
||||
'button' => __('Filter'),
|
||||
|
@ -68,12 +72,12 @@ echo $this->element('genericElements/IndexTable/index_table', [
|
|||
'icon' => 'eye'
|
||||
],
|
||||
[
|
||||
'onclick' => 'populateAndLoadModal(\'/individuals/edit/[onclick_params_data_path]\');',
|
||||
'onclick' => 'openModalFromURL(\'/individuals/edit/[onclick_params_data_path]\');',
|
||||
'onclick_params_data_path' => 'id',
|
||||
'icon' => 'edit'
|
||||
],
|
||||
[
|
||||
'onclick' => 'populateAndLoadModal(\'/individuals/delete/[onclick_params_data_path]\');',
|
||||
'onclick' => 'openModalFromURL(\'/individuals/delete/[onclick_params_data_path]\');',
|
||||
'onclick_params_data_path' => 'id',
|
||||
'icon' => 'trash'
|
||||
]
|
||||
|
|
|
@ -3,7 +3,6 @@ echo $this->element('genericElements/IndexTable/index_table', [
|
|||
'data' => [
|
||||
'data' => $data,
|
||||
'top_bar' => [
|
||||
'pull' => 'right',
|
||||
'children' => [
|
||||
[
|
||||
'type' => 'simple',
|
||||
|
@ -31,6 +30,22 @@ echo $this->element('genericElements/IndexTable/index_table', [
|
|||
'sort' => 'id',
|
||||
'data_path' => 'id',
|
||||
],
|
||||
[
|
||||
'name' => __('Disabled'),
|
||||
'sort' => 'disabled',
|
||||
'data_path' => 'disabled',
|
||||
'element' => 'toggle',
|
||||
'url' => '/users/toggle/{{0}}',
|
||||
'url_params_vars' => ['id'],
|
||||
'toggle_data' => [
|
||||
'editRequirement' => [
|
||||
'function' => function($row, $options) {
|
||||
return true;
|
||||
},
|
||||
],
|
||||
'skip_full_reload' => true
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => __('Username'),
|
||||
'sort' => 'username',
|
||||
|
@ -71,12 +86,12 @@ echo $this->element('genericElements/IndexTable/index_table', [
|
|||
'icon' => 'eye'
|
||||
],
|
||||
[
|
||||
'onclick' => 'populateAndLoadModal(\'/users/edit/[onclick_params_data_path]\');',
|
||||
'onclick' => 'openModalFromURL(\'/users/edit/[onclick_params_data_path]\');',
|
||||
'onclick_params_data_path' => 'id',
|
||||
'icon' => 'edit'
|
||||
],
|
||||
[
|
||||
'onclick' => 'populateAndLoadModal(\'/users/delete/[onclick_params_data_path]\');',
|
||||
'onclick' => 'openModalFromURL(\'/users/delete/[onclick_params_data_path]\');',
|
||||
'onclick_params_data_path' => 'id',
|
||||
'icon' => 'trash'
|
||||
]
|
||||
|
|
|
@ -75,9 +75,6 @@
|
|||
...correctOptions,
|
||||
APIConfirm: (tmpApi) => {
|
||||
return submitForm(tmpApi, url)
|
||||
.catch(e => {
|
||||
// Provide feedback inside modal?
|
||||
})
|
||||
},
|
||||
}
|
||||
UI.modal(modalOptions)
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
empty($data['value']) ? '' : h($data['value'])
|
||||
);
|
||||
echo sprintf(
|
||||
'<div class="input-group" data-table-random-value="%s">%s%s</div>',
|
||||
'<div class="input-group" data-table-random-value="%s" style="margin-left: auto;">%s%s</div>',
|
||||
h($tableRandomValue),
|
||||
$input,
|
||||
$button
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<?php
|
||||
$groups = '';
|
||||
$hasGroupSearch = false;
|
||||
foreach ($data['children'] as $group) {
|
||||
$groups .= $this->element('/genericElements/ListTopBar/group_' . (empty($group['type']) ? 'simple' : h($group['type'])), array('data' => $group, 'tableRandomValue' => $tableRandomValue));
|
||||
$hasGroupSearch = $hasGroupSearch || (!empty($group['type']) && $group['type'] == 'search');
|
||||
}
|
||||
$tempClass = "btn-toolbar";
|
||||
if (count($data['children']) > 1) {
|
||||
if (count($data['children']) > 1 && !$hasGroupSearch) {
|
||||
$tempClass .= ' justify-content-between';
|
||||
} else if (!empty($data['pull'])) {
|
||||
$tempClass .= ' float-' . h($data['pull']);
|
||||
|
|
|
@ -35,7 +35,7 @@ if (isset($menu[$metaGroup])) {
|
|||
}
|
||||
$active = ($scope === $this->request->getParam('controller') && $action === $this->request->getParam('action'));
|
||||
if (!empty($data['popup'])) {
|
||||
$link_template = '<a href="#" onClick="populateAndLoadModal(\'%s\')" class="list-group-item list-group-item-action %s %s pl-3 border-0 %s">%s</a>';
|
||||
$link_template = '<a href="#" onClick="openModalFromURL(\'%s\')" class="list-group-item list-group-item-action %s %s pl-3 border-0 %s">%s</a>';
|
||||
} else {
|
||||
$link_template = '<a href="%s" class="list-group-item list-group-item-action %s %s pl-3 border-0 %s">%s</a>';
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<?= $this->Form->postLink(
|
||||
'Delete',
|
||||
['action' => 'delete', $id],
|
||||
['class' => 'btn btn-primary button-execute']
|
||||
['class' => 'btn btn-primary button-execute', 'id' => 'submitButton']
|
||||
)
|
||||
?>
|
||||
<button type="button" class="btn btn-secondary cancel-button" data-dismiss="modal"><?= __('Cancel') ?></button>
|
||||
|
|
|
@ -114,3 +114,8 @@
|
|||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
.btn-group > .btn:last-of-type:not(.dropdown-toggle), .btn-group > .btn-group:not(:last-of-type) > .btn {
|
||||
border-top-right-radius: 0.2rem;
|
||||
border-bottom-right-radius: 0.2rem;
|
||||
}
|
|
@ -142,7 +142,7 @@ class AJAXApi {
|
|||
try {
|
||||
const response = await fetch(url, AJAXApi.genericRequestConfigGET);
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok')
|
||||
throw new Error(`Network response was not ok. \`${response.statusText}\``)
|
||||
}
|
||||
const dataHtml = await response.text();
|
||||
this.provideFeedback({
|
||||
|
@ -179,7 +179,7 @@ class AJAXApi {
|
|||
try {
|
||||
const response = await fetch(url, AJAXApi.genericRequestConfigGET);
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok')
|
||||
throw new Error(`Network response was not ok. \`${response.statusText}\``)
|
||||
}
|
||||
const formHtml = await response.text();
|
||||
let tmpNode = document.createElement("div");
|
||||
|
@ -231,7 +231,7 @@ class AJAXApi {
|
|||
};
|
||||
const response = await fetch(form.action, options);
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok')
|
||||
throw new Error(`Network response was not ok. \`${response.statusText}\``)
|
||||
}
|
||||
const clonedResponse = response.clone()
|
||||
try {
|
||||
|
@ -268,7 +268,7 @@ class AJAXApi {
|
|||
}, true, feedbackShown);
|
||||
toReturn = Promise.reject(error);
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error) { // -> probably not useful
|
||||
toReturn = Promise.reject(error);
|
||||
} finally {
|
||||
if (!skipRequestHooks) {
|
||||
|
|
|
@ -503,7 +503,7 @@ class ModalFactory {
|
|||
}
|
||||
|
||||
/** Attach the submission click listener for modals that have been generated by raw HTML */
|
||||
findSubmitButtonAndAddListener() {
|
||||
findSubmitButtonAndAddListener(clearOnclick=true) {
|
||||
const $submitButton = this.$modal.find('.modal-footer #submitButton')
|
||||
const formID = $submitButton.data('form-id')
|
||||
let $form
|
||||
|
@ -512,6 +512,9 @@ class ModalFactory {
|
|||
} else {
|
||||
$form = this.$modal.find('form')
|
||||
}
|
||||
if (clearOnclick) {
|
||||
$submitButton[0].removeAttribute('onclick')
|
||||
}
|
||||
|
||||
this.options.APIConfirm = (tmpApi) => {
|
||||
tmpApi.mergeOptions({forceHTMLOnValidationFailure: true})
|
||||
|
|
Loading…
Reference in New Issue