chg: [requestProcessor] UI improvements and simplified creation of
processorspull/41/head
parent
0a1294bbee
commit
f3f73a475b
|
@ -8,7 +8,7 @@ interface GenericProcessorActionI
|
|||
{
|
||||
public function create($requestData);
|
||||
public function process($requestID, $serverRequest);
|
||||
public function discard($requestID);
|
||||
public function discard($requestID ,$requestData);
|
||||
public function setViewVariables($controller, $request);
|
||||
}
|
||||
|
||||
|
@ -89,11 +89,6 @@ class GenericRequestProcessor
|
|||
}
|
||||
}
|
||||
|
||||
public function checkLoading()
|
||||
{
|
||||
return 'Assimilation successful!';
|
||||
}
|
||||
|
||||
protected function setViewVariablesConfirmModal($controller, $id, $title='', $question='', $actionName='')
|
||||
{
|
||||
$controller->set('title', !empty($title) ? $title : __('Process request {0}', $id));
|
||||
|
@ -102,6 +97,63 @@ class GenericRequestProcessor
|
|||
$controller->set('path', ['controller' => 'inbox', 'action' => 'process', $id]);
|
||||
}
|
||||
|
||||
protected function genActionResult($data, $success, $message, $errors=[])
|
||||
{
|
||||
return [
|
||||
'data' => $data,
|
||||
'success' => $success,
|
||||
'message' => $message,
|
||||
'errors' => $errors,
|
||||
];
|
||||
}
|
||||
|
||||
public function genHTTPReply($controller, $processResult, $request, $redirect=null)
|
||||
{
|
||||
if (is_array($request)) {
|
||||
$scope = $request['scope'];
|
||||
$action = $request['action'];
|
||||
} else {
|
||||
$scope = $request->scope;
|
||||
$action = $request->action;
|
||||
}
|
||||
if ($processResult['success']) {
|
||||
$message = !empty($processResult['message']) ? $processResult['message'] : __('Request {0} successfully processed.', $id);
|
||||
if ($controller->ParamHandler->isRest()) {
|
||||
$response = $controller->RestResponse->viewData($processResult, 'json');
|
||||
} else if ($controller->ParamHandler->isAjax()) {
|
||||
$response = $controller->RestResponse->ajaxSuccessResponse('RequestProcessor', "{$scope}.{$action}", $processResult['data'], $message);
|
||||
} else {
|
||||
$controller->Flash->success($message);
|
||||
if (!is_null($redirect)) {
|
||||
$response = $controller->redirect($redirect);
|
||||
} else {
|
||||
$response = $controller->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$message = !empty($processResult['message']) ? $processResult['message'] : __('Request {0} could not be processed.', $id);
|
||||
if ($controller->ParamHandler->isRest()) {
|
||||
$response = $controller->RestResponse->viewData($processResult, 'json');
|
||||
} else if ($controller->ParamHandler->isAjax()) {
|
||||
$response = $controller->RestResponse->ajaxFailResponse('RequestProcessor', "{$scope}.{$action}", $processResult['data'], $message, $processResult['errors']);
|
||||
} else {
|
||||
$controller->Flash->error($message);
|
||||
if (!is_null($redirect)) {
|
||||
$response = $controller->redirect($redirect);
|
||||
} else {
|
||||
$response = $controller->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function checkLoading()
|
||||
{
|
||||
return 'Assimilation successful!';
|
||||
}
|
||||
|
||||
public function create($requestData)
|
||||
{
|
||||
$requestData['scope'] = $this->scope;
|
||||
|
@ -109,17 +161,22 @@ class GenericRequestProcessor
|
|||
$requestData['description'] = $this->description;
|
||||
$request = $this->generateRequest($requestData);
|
||||
$savedRequest = $this->Inbox->save($request);
|
||||
if ($savedRequest !== false) {
|
||||
// log here
|
||||
}
|
||||
return $this->genActionResult(
|
||||
$savedRequest,
|
||||
$savedRequest !== false,
|
||||
__('{0} request for {1} created', $this->scope, $this->action),
|
||||
$request->getErrors()
|
||||
);
|
||||
}
|
||||
|
||||
public function discard($requestData)
|
||||
public function discard($id, $requestData)
|
||||
{
|
||||
$request = $this->generateRequest($requestData);
|
||||
$savedRequest = $this->Inbox->save($request);
|
||||
if ($savedRequest !== false) {
|
||||
// log here
|
||||
}
|
||||
$request = $this->Inbox->get($id);
|
||||
$this->Inbox->delete($request);
|
||||
return $this->genActionResult(
|
||||
[],
|
||||
true,
|
||||
__('{0}.{1} request #{2} discarded', $this->scope, $this->action, $id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ class UserRequestProcessor extends GenericRequestProcessor
|
|||
|
||||
public function create($requestData)
|
||||
{
|
||||
parent::create($requestData);
|
||||
return parent::create($requestData);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ class RegistrationProcessor extends UserRequestProcessor implements GenericProce
|
|||
public function create($requestData) {
|
||||
$this->validateRequestData($requestData);
|
||||
$requestData['title'] = __('User account creation requested for {0}', $requestData['data']['email']);
|
||||
parent::create($requestData);
|
||||
return parent::create($requestData);
|
||||
}
|
||||
|
||||
public function setViewVariables($controller, $request)
|
||||
|
@ -77,39 +77,42 @@ class RegistrationProcessor extends UserRequestProcessor implements GenericProce
|
|||
$controller->set(compact('dropdownData'));
|
||||
}
|
||||
|
||||
public function process($id, $serverRequest)
|
||||
public function process($id, $requestData)
|
||||
{
|
||||
$data = $serverRequest->getData();
|
||||
if ($data['individual_id'] == -1) {
|
||||
if ($requestData['individual_id'] == -1) {
|
||||
$individual = $this->Users->Individuals->newEntity([
|
||||
'uuid' => $data['uuid'],
|
||||
'email' => $data['email'],
|
||||
'first_name' => $data['first_name'],
|
||||
'last_name' => $data['last_name'],
|
||||
'position' => $data['position'],
|
||||
'uuid' => $requestData['uuid'],
|
||||
'email' => $requestData['email'],
|
||||
'first_name' => $requestData['first_name'],
|
||||
'last_name' => $requestData['last_name'],
|
||||
'position' => $requestData['position'],
|
||||
]);
|
||||
$individual = $this->Users->Individuals->save($individual);
|
||||
} else {
|
||||
$individual = $this->Users->Individuals->get($data['individual_id']);
|
||||
$individual = $this->Users->Individuals->get($requestData['individual_id']);
|
||||
}
|
||||
$user = $this->Users->newEntity([
|
||||
'individual_id' => $individual->id,
|
||||
'username' => $data['username'],
|
||||
'username' => $requestData['username'],
|
||||
'password' => '~PASSWORD_TO_BE_REPLACED~',
|
||||
'role_id' => $data['role_id'],
|
||||
'disabled' => $data['disabled'],
|
||||
'role_id' => $requestData['role_id'],
|
||||
'disabled' => $requestData['disabled'],
|
||||
]);
|
||||
$user = $this->Users->save($user);
|
||||
return [
|
||||
'data' => $user,
|
||||
'success' => $user !== false,
|
||||
'message' => $user !== false ? __('User `{0}` created', $user->username) : __('Could not create user `{0}`.', $user->username),
|
||||
'errors' => $user->getErrors()
|
||||
];
|
||||
|
||||
if ($user !== false) {
|
||||
$this->discard($id, $requestData);
|
||||
}
|
||||
return $this->genActionResult(
|
||||
$user,
|
||||
$user !== false,
|
||||
$user !== false ? __('User `{0}` created', $user->username) : __('Could not create user `{0}`.', $user->username),
|
||||
$user->getErrors()
|
||||
);
|
||||
}
|
||||
|
||||
public function discard($id)
|
||||
public function discard($id, $requestData)
|
||||
{
|
||||
parent::discard($id);
|
||||
return parent::discard($id, $requestData);
|
||||
}
|
||||
}
|
|
@ -59,6 +59,13 @@ class InboxController extends AppController
|
|||
|
||||
public function delete($id)
|
||||
{
|
||||
if ($this->request->is('post')) {
|
||||
$request = $this->Inbox->get($id);
|
||||
$this->requestProcessor = TableRegistry::getTableLocator()->get('RequestProcessor');
|
||||
$processor = $this->requestProcessor->getProcessor($request->scope, $request->action);
|
||||
$discardResult = $processor->discard($id, $request);
|
||||
return $processor->genHTTPReply($this, $discardResult, $request);
|
||||
}
|
||||
$this->set('deletionTitle', __('Discard request'));
|
||||
$this->set('deletionText', __('Are you sure you want to discard request #{0}?', $id));
|
||||
$this->set('deletionConfirm', __('Discard'));
|
||||
|
@ -75,17 +82,10 @@ class InboxController extends AppController
|
|||
$scope = $request->scope;
|
||||
$action = $request->action;
|
||||
$this->requestProcessor = TableRegistry::getTableLocator()->get('RequestProcessor');
|
||||
$processor = $this->requestProcessor->getProcessor($scope, $action);
|
||||
$processor = $this->requestProcessor->getProcessor($request->scope, $request->action);
|
||||
if ($this->request->is('post')) {
|
||||
$processResult = $processor->process($id, $this->request);
|
||||
if ($processResult['success']) {
|
||||
$message = !empty($processResult['message']) ? $processResult['message'] : __('Request {0} processed.', $id);
|
||||
$response = $this->RestResponse->ajaxSuccessResponse('RequestProcessor', "{$scope}.{$action}", $processResult['data'], $message);
|
||||
} else {
|
||||
$message = !empty($processResult['message']) ? $processResult['message'] : __('Request {0} could not be processed.', $id);
|
||||
$response = $this->RestResponse->ajaxFailResponse('RequestProcessor', "{$scope}.{$action}", $processResult['data'], $message, $processResult['errors']);
|
||||
}
|
||||
return $response;
|
||||
$processResult = $processor->process($id, $this->request->getData());
|
||||
return $processor->genHTTPReply($this, $processResult, $request);
|
||||
} else {
|
||||
$this->requestProcessor->render($this, $processor, $request);
|
||||
}
|
||||
|
|
|
@ -150,8 +150,7 @@ class UsersController extends AppController
|
|||
'last_name' => 'bar',
|
||||
],
|
||||
];
|
||||
$processor->create($data);
|
||||
$this->Flash->success(__('Entry created'));
|
||||
return $this->redirect(['controller' => 'Inbox', 'action' => 'index']);
|
||||
$processorResult = $processor->create($data);
|
||||
return $processor->genHTTPReply($this, $processorResult, ['scope' => 'User', 'action' => 'Registration'], ['controller' => 'Inbox', 'action' => 'index']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -721,7 +721,7 @@ class BoostrapModal extends BootstrapGeneric {
|
|||
'footerClass' => [''],
|
||||
'type' => 'ok-only',
|
||||
'variant' => '',
|
||||
'confirmFunction' => '',
|
||||
'confirmFunction' => '', // Will be called with the following arguments confirmFunction(modalObject, tmpApi)
|
||||
'cancelFunction' => ''
|
||||
];
|
||||
|
||||
|
@ -847,10 +847,10 @@ class BoostrapModal extends BootstrapGeneric {
|
|||
$buttonConfirm = (new BoostrapButton([
|
||||
'variant' => $variant,
|
||||
'text' => h($this->options['confirmText']),
|
||||
'class' => 'modal-confirm-button',
|
||||
'params' => [
|
||||
'data-dismiss' => $this->options['confirmFunction'] ? '' : 'modal',
|
||||
// 'onclick' => sprintf('(function(clicked) { %s.finally( () => { $(clicked).closest(\'.modal\').data(\'modalObject\').hide() }) }(this))', $this->options['confirmFunction'])
|
||||
'onclick' => sprintf('closeModalOnFunctionCompletion(this, function(clicked) { return %s })', $this->options['confirmFunction'])
|
||||
'data-confirmFunction' => sprintf('%s', $this->options['confirmFunction'])
|
||||
]
|
||||
]))->button();
|
||||
return $buttonCancel . $buttonConfirm;
|
||||
|
|
|
@ -77,17 +77,20 @@ echo $this->element('genericElements/IndexTable/index_table', [
|
|||
[
|
||||
'url' => '/inbox/view',
|
||||
'url_params_data_paths' => ['id'],
|
||||
'icon' => 'eye'
|
||||
'icon' => 'eye',
|
||||
'title' => __('View request')
|
||||
],
|
||||
[
|
||||
'open_modal' => '/inbox/process/[onclick_params_data_path]',
|
||||
'modal_params_data_path' => 'id',
|
||||
'icon' => 'cogs'
|
||||
'icon' => 'cogs',
|
||||
'title' => __('Process request')
|
||||
],
|
||||
[
|
||||
'open_modal' => '/inbox/delete/[onclick_params_data_path]',
|
||||
'modal_params_data_path' => 'id',
|
||||
'icon' => 'trash'
|
||||
'icon' => 'trash',
|
||||
'title' => __('Discard request')
|
||||
],
|
||||
]
|
||||
]
|
||||
|
|
|
@ -81,17 +81,14 @@
|
|||
$formIndividual
|
||||
),
|
||||
'confirmText' => __('Create user'),
|
||||
'confirmFunction' => 'submitRegistration(clicked)'
|
||||
'confirmFunction' => 'submitRegistration'
|
||||
]);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function submitRegistration(clicked) {
|
||||
const tmpApi = new AJAXApi({
|
||||
statusNode: clicked
|
||||
})
|
||||
const $forms = $(clicked).closest('.modal').find('form')
|
||||
function submitRegistration(modalObject, tmpApi) {
|
||||
const $forms = modalObject.$modal.find('form')
|
||||
const url = $forms[0].action
|
||||
const data1 = getFormData($forms[0])
|
||||
const data2 = getFormData($forms[1])
|
||||
|
|
|
@ -688,8 +688,11 @@ class ModalFactory {
|
|||
}
|
||||
|
||||
/** Attach the submission click listener for modals that have been generated by raw HTML */
|
||||
findSubmitButtonAndAddListener(clearOnclick=true) {
|
||||
const $submitButton = this.$modal.find('.modal-footer #submitButton')
|
||||
findSubmitButtonAndAddListener() {
|
||||
let $submitButton = this.$modal.find('.modal-footer #submitButton')
|
||||
if (!$submitButton[0]) {
|
||||
$submitButton = this.$modal.find('.modal-footer .modal-confirm-button')
|
||||
}
|
||||
if ($submitButton[0]) {
|
||||
const formID = $submitButton.data('form-id')
|
||||
let $form
|
||||
|
@ -698,26 +701,43 @@ class ModalFactory {
|
|||
} else {
|
||||
$form = this.$modal.find('form')
|
||||
}
|
||||
if (clearOnclick) {
|
||||
if ($submitButton.data('confirmfunction') !== undefined && $submitButton.data('confirmfunction') !== '') {
|
||||
const clickHandler = window[$submitButton.data('confirmfunction')]
|
||||
this.options.APIConfirm = (tmpApi) => {
|
||||
return clickHandler(this, tmpApi)
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
this.options.POSTSuccessCallback(data)
|
||||
} else { // Validation error
|
||||
this.injectFormValidationFeedback(form, data.errors)
|
||||
return Promise.reject('Validation error');
|
||||
}
|
||||
})
|
||||
.catch((errorMessage) => {
|
||||
this.options.POSTFailCallback(errorMessage)
|
||||
return Promise.reject(errorMessage);
|
||||
})
|
||||
}
|
||||
} else {
|
||||
$submitButton[0].removeAttribute('onclick')
|
||||
}
|
||||
|
||||
this.options.APIConfirm = (tmpApi) => {
|
||||
return tmpApi.postForm($form[0])
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
this.options.POSTSuccessCallback(data)
|
||||
} else { // Validation error
|
||||
this.injectFormValidationFeedback(form, data.errors)
|
||||
return Promise.reject('Validation error');
|
||||
}
|
||||
})
|
||||
.catch((errorMessage) => {
|
||||
this.options.POSTFailCallback(errorMessage)
|
||||
return Promise.reject(errorMessage);
|
||||
})
|
||||
this.options.APIConfirm = (tmpApi) => {
|
||||
return tmpApi.postForm($form[0])
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
this.options.POSTSuccessCallback(data)
|
||||
} else { // Validation error
|
||||
this.injectFormValidationFeedback(form, data.errors)
|
||||
return Promise.reject('Validation error');
|
||||
}
|
||||
})
|
||||
.catch((errorMessage) => {
|
||||
this.options.POSTFailCallback(errorMessage)
|
||||
return Promise.reject(errorMessage);
|
||||
})
|
||||
}
|
||||
}
|
||||
$submitButton.click(this.getConfirmationHandlerFunction())
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,17 +66,6 @@ function attachTestConnectionResultHtml(result, $container) {
|
|||
return $testResultDiv
|
||||
}
|
||||
|
||||
function closeModalOnFunctionCompletion(clicked, fun) {
|
||||
const result = fun(clicked)
|
||||
if (result === undefined) {
|
||||
$(clicked).closest('.modal').data('modalObject').hide()
|
||||
} else {
|
||||
result.finally( () => {
|
||||
$(clicked).closest('.modal').data('modalObject').hide()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var UI
|
||||
$(document).ready(() => {
|
||||
if (typeof UIFactory !== "undefined") {
|
||||
|
|
Loading…
Reference in New Issue