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); | ||||
| } | ||||
| 
 | ||||
|  | @ -88,12 +88,7 @@ class GenericRequestProcessor | |||
|             $this->{$action} = $reflection->newInstance(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     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
	
	 mokaddem
						mokaddem