Merge branch 'develop' into main

feature/docker-ci v0.3
iglocska 2021-06-30 17:06:29 +02:00
commit efbf5f0d2c
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
8 changed files with 214 additions and 16 deletions

View File

@ -98,7 +98,7 @@ class ACLComponent extends Component
'connectLocal' => ['perm_admin'],
'delete' => ['perm_admin'],
'edit' => ['perm_admin'],
'exposedTools' => ['perm_admin'],
'exposedTools' => ['OR' => ['perm_admin', 'perm_sync']],
'index' => ['perm_admin'],
'connectorIndex' => ['perm_admin'],
'view' => ['perm_admin'],

View File

@ -165,7 +165,8 @@ class CRUDComponent extends Component
}
} else {
$this->Controller->isFailResponse = true;
$validationMessage = $this->prepareValidationError($data);
$validationErrors = $data->getErrors();
$validationMessage = $this->prepareValidationMessage($validationErrors);
$message = __(
'{0} could not be added.{1}',
$this->ObjectAlias,
@ -174,7 +175,7 @@ class CRUDComponent extends Component
if ($this->Controller->ParamHandler->isRest()) {
$this->Controller->restResponsePayload = $this->RestResponse->viewData($message, 'json');
} else if ($this->Controller->ParamHandler->isAjax()) {
$this->Controller->ajaxResponsePayload = $this->RestResponse->ajaxFailResponse($this->ObjectAlias, 'add', $data, $message, $validationMessage);
$this->Controller->ajaxResponsePayload = $this->RestResponse->ajaxFailResponse($this->ObjectAlias, 'add', $data, $message, $validationErrors);
} else {
$this->Controller->Flash->error($message);
}
@ -183,6 +184,21 @@ class CRUDComponent extends Component
$this->Controller->set('entity', $data);
}
private function prepareValidationMessage($errors)
{
$validationMessage = '';
if (!empty($errors)) {
if (count($errors) == 1) {
$field = array_keys($errors)[0];
$fieldError = implode(', ', array_values($errors[$field]));
$validationMessage = __('{0}: {1}', $field, $fieldError);
} else {
$validationMessage = __('There has been validation issues with multiple fields');
}
}
return $validationMessage;
}
private function prepareValidationError($data)
{
$validationMessage = '';
@ -192,7 +208,7 @@ class CRUDComponent extends Component
foreach ($errorData as $key => $value) {
$errorMessages[] = $value;
}
$validationMessage .= __(' {1}', $field, implode(',', $errorMessages));
$validationMessage .= __('{0}: {1}', $field, implode(',', $errorMessages));
}
}
return $validationMessage;
@ -261,14 +277,15 @@ class CRUDComponent extends Component
}
}
} else {
$validationMessage = $this->prepareValidationError($data);
$validationErrors = $data->getErrors();
$validationMessage = $this->prepareValidationMessage($validationErrors);
$message = __(
__('{0} could not be modified.'),
$this->ObjectAlias
);
if ($this->Controller->ParamHandler->isRest()) {
} else if ($this->Controller->ParamHandler->isAjax()) {
$this->Controller->ajaxResponsePayload = $this->RestResponse->ajaxFailResponse($this->ObjectAlias, 'edit', $data, $message, $data->getErrors());
$this->Controller->ajaxResponsePayload = $this->RestResponse->ajaxFailResponse($this->ObjectAlias, 'edit', $data, $message, $validationErrors);
} else {
$this->Controller->Flash->error($message);
}
@ -699,7 +716,8 @@ class CRUDComponent extends Component
}
}
} else {
$validationMessage = $this->prepareValidationError($data);
$validationErrors = $data->getErrors();
$validationMessage = $this->prepareValidationMessage($validationErrors);
$message = __(
'{0} could not be modified.{1}',
$this->ObjectAlias,
@ -707,7 +725,7 @@ class CRUDComponent extends Component
);
if ($this->Controller->ParamHandler->isRest()) {
} else if ($this->Controller->ParamHandler->isAjax()) {
$this->Controller->ajaxResponsePayload = $this->RestResponse->ajaxFailResponse($this->ObjectAlias, 'toggle', $message, $validationMessage);
$this->Controller->ajaxResponsePayload = $this->RestResponse->ajaxFailResponse($this->ObjectAlias, 'toggle', $message, $validationErrors);
} else {
$this->Controller->Flash->error($message);
if (empty($params['redirect'])) {

View File

@ -0,0 +1,171 @@
<?php
// set a namespace for the module
namespace SkeletonConnector;
// These can be left as is. We want to have access to the commonconnector tools as well as basic http / exception functions
require_once(ROOT . '/src/Lib/default/local_tool_connectors/CommonConnectorTools.php');
use CommonConnectorTools\CommonConnectorTools;
use Cake\Http\Client;
use Cake\Http\Exception\NotFoundException;
use Cake\Http\Exception\MethodNotAllowedException;
use Cake\Http\Client\Response;
class SkeletonConnector extends CommonConnectorTools
{
/*
*
* ====================================== Metainformation block ======================================
*
*/
public $description = '';
public $connectorName = 'SkeletonConnector';
public $name = 'Skeleton';
public $version = '0.1';
// exposed function list and configuration
public $exposedFunctions = [
'myIndexAction' => [
'type' => 'index',
'scope' => 'child',
'params' => [
'quickFilter',
'sort',
'direction',
'page',
'limit'
]
],
'myFormAction' => [
'type' => 'formAction',
'scope' => 'childAction',
'params' => [
'setting',
'value'
],
'redirect' => 'serverSettingsAction'
]
];
public function health(Object $connection): array
{
/*
returns an array with 2 keys:
[
status: the numeric response code (0: UNKNOWN, 1: OK, 2: ISSUES, 3: ERROR),
message: status message shown
]
*/
return $health;
}
/*
*
* ====================================== Exposed custom functions ======================================
*
*/
public function myIndexAction(array $params): array
{
// $data = get data from local tool
//if we want to filter it via the quicksearch
if (!empty($params['quickFilter'])) {
// filter $data
}
// return the data embedded in a generic index parameter array
return [
'type' => 'index',
'title' => false,
'description' => false,
'data' => [
'data' => $data,
'skip_pagination' => 1,
'top_bar' => [
'children' => [
[
'type' => 'search',
'button' => __('Filter'),
'placeholder' => __('Enter value to search'),
'data' => '',
'searchKey' => 'value',
'additionalUrlParams' => $urlParams
]
]
],
'fields' => [
[
'name' => 'field1_name',
'sort' => 'field1.path',
'data_path' => 'field1.path',
]
],
'pull' => 'right',
'actions' => [
[
'open_modal' => '/localTools/action/' . h($params['connection']['id']) . '/myForm?myKey={{0}}',
'modal_params_data_path' => ['myKey'],
'icon' => 'font_awesome_icon_name',
'reload_url' => '/localTools/action/' . h($params['connection']['id']) . '/myIndex'
]
]
]
];
}
public function myFormAction(array $params): array
{
if ($params['request']->is(['get'])) {
return [
'data' => [
'title' => __('My Form Title'),
'description' => __('My form description'),
'submit' => [
'action' => $params['request']->getParam('action')
],
'url' => ['controller' => 'localTools', 'action' => 'action', h($params['connection']['id']), 'myFormAction']
]
];
} elseif ($params['request']->is(['post'])) {
// handle posted data
if ($success) {
return ['success' => 1, 'message' => __('Action successful.')];
} else {
return ['success' => 0, 'message' => __('Action failed spectacularly.')];
}
}
throw new MethodNotAllowedException(__('Invalid http request type for the given action.'));
}
/*
*
* ====================================== Inter connection functions ======================================
*
*/
public function initiateConnection(array $params): array
{
// encode initial connection in local tool
// build and return initiation payload
return $payload;
}
public function acceptConnection(array $params): array
{
// encode acceptance of the connection request in local tool, based on the payload from the initiation
// return payload for remote to encode the connection
return $payload;
}
public function finaliseConnection(array $params): bool
{
// based on the payload from the acceptance, finalise the connection
// return true on success
return $success;
}
}
?>

View File

@ -26,7 +26,12 @@ class BroodsTable extends AppTable
public function validationDefault(Validator $validator): Validator
{
return $validator;
return $validator
->requirePresence(['name', 'url', 'organisation_id'], 'create')
->notEmptyString('name')
->notEmptyString('url')
->url('url', __('The provided value is not a valid URL'))
->naturalNumber('organisation_id', false);
}
public function genHTTPClient(Object $brood, array $options=[]): Object

View File

@ -26,7 +26,8 @@
'field' => 'organisation_id',
'label' => __('Owner organisation'),
'options' => $dropdownData['organisation'],
'type' => 'dropdown'
'type' => 'dropdown',
'empty' => __('-- pick one --')
),
array(
'field' => 'trusted',

View File

@ -1,6 +1,7 @@
<?php
$controlParams = [
'options' => $fieldData['options'],
'empty' => $fieldData['empty'] ?? false,
'class' => ($fieldData['class'] ?? '') . ' formDropdown custom-select'
];
echo $this->FormFieldMassage->prepareFormElement($this->Form, $controlParams, $fieldData);

View File

@ -107,7 +107,7 @@
.click(function() {
const url = `/${controller}/filtering`
const reloadUrl = `/${controller}/index${additionalUrlParams}`
openFilteringModal(this, url, reloadUrl, $(`#table-container-${randomValue}`));
openFilteringModal(this, url, reloadUrl, $(`#index-table-${randomValue}`));
})
function doFilter($button) {
@ -151,7 +151,8 @@
}
function openFilteringModal(clicked, url, reloadUrl, tableId) {
UI.overlayUntilResolve(clicked, UI.submissionModalForIndex(url, reloadUrl, tableId))
const modalPromise = UI.submissionModalForIndex(url, reloadUrl, tableId)
UI.overlayUntilResolve(clicked, modalPromise)
}
});
</script>

View File

@ -996,21 +996,22 @@ class FormValidationHelper {
injectValidationErrorInForm(fieldName, errors) {
const inputField = Array.from(this.form).find(node => { return node.name == fieldName })
if (inputField !== undefined) {
const $messageNode = this.buildValidationMessageNode(errors)
const $messageNode = this.buildValidationMessageNode(fieldName, errors)
const $inputField = $(inputField)
$inputField.addClass('is-invalid')
$messageNode.insertAfter($inputField)
} else {
const $messageNode = this.buildValidationMessageNode(errors, true)
const $messageNode = this.buildValidationMessageNode(fieldName, errors, true)
const $flashContainer = $(this.form).parent().find('#flashContainer')
$messageNode.insertAfter($flashContainer)
}
}
buildValidationMessageNode(errors, isAlert=false) {
buildValidationMessageNode(fieldName, errors, isAlert=false) {
const $messageNode = $('<div></div>')
if (isAlert) {
$messageNode.addClass('alert alert-danger').attr('role', 'alert')
$messageNode.append($('<strong></strong>').text(`${fieldName}: `))
} else {
$messageNode.addClass('invalid-feedback')
}
@ -1020,7 +1021,7 @@ class FormValidationHelper {
if (hasMultipleErrors) {
$messageNode.append($('<li></li>').text(error))
} else {
$messageNode.text(error)
$messageNode.append($('<span></span>').text(error))
}
}
} else {