adding js for showing running transactions

This commit is contained in:
Dario Rekowski on RockPI 2020-01-15 15:36:00 +00:00
parent b88cd9ba3c
commit 5103779713
13 changed files with 237 additions and 141 deletions

View File

@ -55,7 +55,7 @@ Router::scope('/', function (RouteBuilder $routes) {
$csrf->whitelistCallback(function ($request) {
// Skip token check for API URLs.
//die($request->getParam('controller'));
if($request->getParam('controller') === 'TransactionJsonRequestHandler') {
if($request->getParam('controller') === 'JsonRequestHandler') {
return true;
}
});

View File

@ -146,9 +146,11 @@ class AppController extends Controller
if($session_id != 0) {
$userStored = $session->read('StateUser');
$transactionPendings = $session->read('Transactions.pending');
$transactionExecutings = $session->read('Transaction.executing');
if($session->read('session_id') != $session_id ||
( $userStored && !isset($userStored['id'])) ||
intval($transactionPendings) > 0) {
intval($transactionPendings) > 0 ||
intval($transactionExecutings) > 0) {
$http = new Client();
try {
$loginServer = Configure::read('LoginServer');
@ -170,8 +172,10 @@ class AppController extends Controller
}
//var_dump($json);
$transactionPendings = $json['Transaction.pending'];
$transactionExecuting = $json['Transaction.executing'];
//echo "read transaction pending: $transactionPendings<br>";
$session->write('Transactions.pending', $transactionPendings);
$session->write('Transaction.executing', $transactionExecuting);
$session->write('session_id', $session_id);
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
if($json['user']['public_hex'] != '') {

View File

@ -7,6 +7,8 @@
*/
namespace App\Controller\Component;
use App\Model\Validation\GenericValidation;
use Cake\Controller\Component;
use Cake\Http\Client;
use Cake\Core\Configure;
@ -53,6 +55,32 @@ class JsonRequestClientComponent extends Component
return ['state' => 'success', 'data' => $json];
}
public function getRunningUserTasks($email)
{
if($email == "") {
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'email is empty'];
}
if(!GenericValidation::email($email, [])) {
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'email is invalid'];
}
$http = new Client();
$transactionbody = json_encode([
'email' => $email
]);
$response = $http->post($this->getLoginServerUrl() . '/getRunningUserTasks', $transactionbody, ['type' => 'json']);
$responseStatus = $response->getStatusCode();
if($responseStatus != 200) {
return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response status code isn\'t 200', 'details' => $responseStatus];
}
$json = $response->getJson();
if($json == null) {
return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response isn\'t valid json', 'details' => $responseType];
}
return ['state' => 'success', 'data' => $json];
}
static public function getLoginServerUrl()
{
$loginServer = Configure::read('LoginServer');

View File

@ -40,7 +40,15 @@ class DashboardController extends AppController
}
$user = $session->read('StateUser');
$serverUser = $this->Auth->user('id');
if($serverUser) {
$adminErrorsTable = TableRegistry::getTableLocator()->get('AdminErrors');
$adminErrorCount = $adminErrorsTable->find('all')->count();
$this->set('adminErrorCount', $adminErrorCount);
}
$this->set('user', $user);
$this->set('serverUser', $serverUser);
$this->set('timeUsed', microtime(true) - $startTime);
}

View File

@ -132,6 +132,7 @@ class StateBalancesController extends AppController
}
uasort($transactions, array($this, 'sortTransactions'));
$this->set('transactions', $transactions);
$this->set('transactionExecutingCount', $session->read('Transaction.executing'));
$this->set('balance', $session->read('StateUser.balance'));
$this->set('timeUsed', microtime(true) - $startTime);
}

View File

@ -244,6 +244,7 @@ class TransactionCreationsController extends AppController
$this->set('activeUser', $user);
$this->set('creationForm', $creationForm);
$this->set('transactionExecutingCount', $session->read('Transaction.executing'));
$this->set('timeUsed', microtime(true) - $startTime);
if ($this->request->is('post')) {

View File

@ -1,97 +0,0 @@
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\ORM\TableRegistry;
use Model\Transactions\Transaction;
/*!
* @author: Dario Rekowski#
*
* @date: 03.11.2019
*
* @desc: Handle requests from other server put or request transaction
*/
class TransactionJsonRequestHandlerController extends AppController {
public function initialize()
{
parent::initialize();
//$this->Auth->allow(['add', 'edit']);
$this->Auth->allow('index');
}
public function index()
{
if($this->request->is('post')) {
$jsonData = $this->request->input('json_decode');
//var_dump($jsonData);
if($jsonData == NULL || !isset($jsonData->method) || !isset($jsonData->transaction)) {
return $this->returnJson(['state' => 'error', 'msg' => 'parameter error']);
}
$method = $jsonData->method;
switch($method) {
case 'putTransaction': return $this->putTransaction($jsonData->transaction);
case 'userDelete': return $this->userDelete($jsonData->user);
}
return $this->returnJson(['state' => 'error', 'msg' => 'unknown method', 'details' => $method]);
}
return $this->returnJson(['state' => 'error', 'msg' => 'no post']);
}
private function putTransaction($transactionBase64) {
$transaction = new Transaction($transactionBase64);
if($transaction->hasErrors()) {
return $this->returnJson(['state' => 'error', 'msg' => 'error parsing transaction', 'details' => $transaction->getErrors()]);
}
if(!$transaction->validate()) {
return $this->returnJsonSaveError($transaction, ['state' => 'error', 'msg' => 'error validate transaction', 'details' => $transaction->getErrors()]);
}
if ($transaction->save()) {
// success
return $this->returnJson(['state' => 'success']);
} else {
return $this->returnJsonSaveError($transaction, [
'state' => 'error',
'msg' => 'error saving transaction in db',
'details' => json_encode($transaction->getErrors())
]);
}
return $this->returnJson(['state' => 'success']);
}
private function userDelete($userPubkeyHex) {
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
$user = $stateUserTable->find('all')->where(['public_key' => hex2bin($userPubkeyHex)]);
if(!$user || $user->count == 0) {
return $this->returnJson(['state' => 'error', 'msg' => 'user not found']);
}
}
private function returnJsonSaveError($transaction, $errorArray) {
$json = json_encode($errorArray);
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
$pub = $transaction->getFirstPublic();
$stateUserQuery = $stateUserTable
->find('all')
->where(['public_key' => $pub])
->contain(false);
if($stateUserQuery->count() == 1) {
$stateErrorsTable = TableRegistry::getTableLocator()->get('StateErrors');
$stateErrorEntity = $stateErrorsTable->newEntity();
$stateErrorEntity->state_user_id = $stateUserQuery->first()->id;
$stateErrorEntity->transaction_type_id = $transaction->getTransactionBody()->getTransactionTypeId();
$stateErrorEntity->message_json = $json;
$stateErrorsTable->save($stateErrorEntity);
}
return $this->returnJsonEncoded($json);
}
}

View File

@ -15,6 +15,7 @@ $this->assign('title', __('Willkommen') . '&nbsp;' . $user['first_name'] . '&nbs
<span class='grd-second-timer'><?= round($requestTime * 1000.0) ?> ms</span>
<?php endif; ?>
<div class="grd_container_small">
<fieldset>
<h3>Gradido ...</h3>
<?= $this->Html->link(
@ -32,4 +33,34 @@ $this->assign('title', __('Willkommen') . '&nbsp;' . $user['first_name'] . '&nbs
<h3>Account ...</h3>
<a class="grd-nav-bn" href="./account/user_delete"><?= __("löschen"); ?></a>
</fieldset>-->
<?php if($serverUser != null) : ?>
<fieldset class="grd-margin-top-10">
<h3>Server Admin Gradido ...</h3>
<?= $this->Html->link(
__('einzeln schöpfen'),
['controller' => 'TransactionCreations', 'action' => 'create'],
['class' => 'grd-nav-bn grd-nav-bn-large']
);?>
<?= $this->Html->link(
__('viele schöpfen'),
['controller' => 'TransactionCreations', 'action' => 'createMulti'],
['class' => 'grd-nav-bn grd-nav-bn-large']
);?>
</fieldset>
<?= $this->Html->link(
__('Fehler') . ' (' . $adminErrorCount . ')',
['controller' => 'AdminErrors'], ['class' => 'grd-nav-bn']);
?>
<?php endif; ?>
<?php if($user['role'] == 'admin') : ?>
<fieldset class="grd-margin-top-10">
<h3>Adminbereich</h3>
<?= $this->Html->link(
__('Benutzer suchen'),
['controller' => 'StateUsers', 'action' => 'search'],
['class' => 'grd-nav-bn grd-nav-bn-large']
); ?>
</fieldset>
<?php endif; ?>
</div>

View File

@ -66,10 +66,7 @@ if(!isset($balance)) {
?>
</li>
<?php endif; ?>
<?php if(isset($GLOBALS['ServerUser'])) : ?>
<li><?= $this->Html->link(__('Server'), ['controller' => 'Dashboard', 'action' => 'serverIndex'], ['class' => 'grd-nav-bn'])?></li>
<?php endif; ?>
<li><?= $this->Html->link(__('Startseite'), ['controller' => 'Dashboard'], ['class' => 'grd-nav-bn'])?></li>
<li><?= $this->Html->link(__('Startseite'), ['controller' => 'Dashboard', 'action' => 'index'], ['class' => 'grd-nav-bn'])?></li>
<!--<li><?= $this->Html->link(__('Kontostand'), ['controller' => 'StateBalances', 'action' => 'overview'], ['class' => 'grd-nav-bn']) ?>-->
<?php if(intval($transactionPendings) > 0) : ?>
<li>

View File

@ -18,6 +18,17 @@ $this->assign('title', __('Kontoübersicht'));
</div>
</div>
</div>
<?php if($transactionExecutingCount > 0) : ?>
<div class="row">
<div class="col-md-8 equel-grid">
<div class="grid">
<div id="transaction-execute-display" class="grid-body py-3" style="color:grey">
</div>
</div>
</div>
</div>
<?php endif; ?>
<div class="row">
<div class="col-md-10 equel-grid">
<div class="grid">
@ -94,4 +105,56 @@ $this->assign('title', __('Kontoübersicht'));
<!--<a class="border-top px-3 py-2 d-block text-gray" href="#"><small class="font-weight-medium"><i class="mdi mdi-chevron-down mr-2"></i>View All Order History</small></a>-->
</div>
</div>
</div>
</div>
<?php if($transactionExecutingCount > 0) : ?>
<script type="text/javascript">
//function getJson(basisUrl, method, successFunction, errorFunction, timeoutFunction)
g_transactionExecutionCount = <?= $transactionExecutingCount ?>;
function updateTransactionExecutingDisplay(count) {
var display = document.getElementById('transaction-execute-display');
display.innerHTML = count + " ";
if(count == 1) {
display.innerHTML += "<?= __('Laufende Transaktion') ?>";
} else {
display.innerHTML += "<?= __('Laufende Transaktionen') ?>";
}
display.innerHTML += '&nbsp;<div class="spinner-border text-light spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>';
}
function checkTransactionExecuting() {
getJson('<?= $this->Url->build(["controller" => "JsonRequestHandler"]);?>', 'getRunningUserTasks',
// success
function(json) {
if(json.state === 'success') {
var newCount = 0;
if(json.data.runningTasks["sign transaction"] != undefined) {
newCount = json.data.runningTasks["sign transaction"];
}
if(newCount != g_transactionExecutionCount) {
g_transactionExecutionCount = newCount;
location.reload();
//updateTransactionExecutingDisplay(g_transactionExecutionCount);
}
}
},
// error
function(e) {
},
// timeout
function(e) {
}
)
}
(function(document, window, domIsReady, undefined) {
domIsReady(function() {
updateTransactionExecutingDisplay(g_transactionExecutionCount);
setTimeout(checkTransactionExecuting, 100);
//setInterval(checkTransactionExecuting, 100);
});
})(document, window, domIsReady);
</script>
<?php endif; ?>

View File

@ -57,7 +57,9 @@ $this->assign('title', __('Schöpfungstransaktion'));
<button type="button" onclick="uncheckAll()">Alle abwählen</button>
<div style="margin-bottom:5px"></div>
<?= $this->Form->create($creationForm) ?>
<?php if($transactionExecutingCount > 0) : ?>
<div id="transaction-execute-display"></div>
<?php endif; ?>
<fieldset>
<?= $this->Form->control('memo'); ?>
<?= $this->Form->control('amount', ['required' => false]); ?>
@ -107,6 +109,7 @@ $this->assign('title', __('Schöpfungstransaktion'));
</div>
<?= $this->Form->end() ?>
</div>
<?= $this->Html->script('basic'); ?>
<script type="text/javascript">
function checkAll()
{
@ -128,34 +131,6 @@ $this->assign('title', __('Schöpfungstransaktion'));
}
}
// cross browser dom is ready module from:
// https://www.competa.com/blog/cross-browser-document-ready-with-vanilla-javascript/
var domIsReady = (function(domIsReady) {
var isBrowserIeOrNot = function() {
return (!document.attachEvent || typeof document.attachEvent === "undefined" ? 'not-ie' : 'ie');
}
domIsReady = function(callback) {
if(callback && typeof callback === 'function'){
if(isBrowserIeOrNot() !== 'ie') {
document.addEventListener("DOMContentLoaded", function() {
return callback();
});
} else {
document.attachEvent("onreadystatechange", function() {
if(document.readyState === "complete") {
return callback();
}
});
}
} else {
console.error('The callback is not a function!');
}
}
return domIsReady;
})(domIsReady || {});
(function(document, window, domIsReady, undefined) {
domIsReady(function() {
var userAmountInputs = document.getElementsByClassName("user_amount");
@ -177,4 +152,63 @@ var domIsReady = (function(domIsReady) {
//
</script>
</script>
<?php if($transactionExecutingCount > 0) : ?>
<script type="text/javascript">
//function getJson(basisUrl, method, successFunction, errorFunction, timeoutFunction)
g_transactionExecutionCount = <?= $transactionExecutingCount ?>;
g_updateExecutionDisplayInterval = null;
function updateTransactionExecutingDisplay(count) {
var display = document.getElementById('transaction-execute-display');
if(count > 0) {
display.innerHTML = count + " ";
if(count == 1) {
display.innerHTML += "<?= __('Laufende Transaktion') ?>";
} else {
display.innerHTML += "<?= __('Laufende Transaktionen') ?>";
}
} else {
display.innerHTML = '<?= __('Alle Transaktionen abgeschlossen!') ?> <button class="grd-form-bn grd_clickable" onclick="location.reload()">Seite neuladen</button>';
}
}
function checkTransactionExecuting() {
getJson('<?= $this->Url->build(["controller" => "JsonRequestHandler"]);?>', 'getRunningUserTasks',
// success
function(json) {
if(json.state === 'success') {
var newCount = 0;
if(json.data.runningTasks["sign transaction"] != undefined) {
newCount = json.data.runningTasks["sign transaction"];
}
if(newCount != g_transactionExecutionCount) {
g_transactionExecutionCount = newCount;
//location.reload();
updateTransactionExecutingDisplay(g_transactionExecutionCount);
}
if(newCount == 0) {
clearInterval(g_updateExecutionDisplayInterval);
}
}
},
// error
function(e) {
},
// timeout
function(e) {
}
)
}
(function(document, window, domIsReady, undefined) {
domIsReady(function() {
updateTransactionExecutingDisplay(g_transactionExecutionCount);
//setTimeout(checkTransactionExecuting, 100);
g_updateExecutionDisplayInterval = setInterval(checkTransactionExecuting, 100);
});
})(document, window, domIsReady);
</script>
<?php endif; ?>

View File

@ -1,7 +1,7 @@
<?php
namespace App\Test\TestCase\Controller;
use App\Controller\TransactionJsonRequestHandlerController;
use App\Controller\JsonRequestHandlerController;
use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase;

View File

@ -1,9 +1,3 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
// cross browser dom is ready module from:
// https://www.competa.com/blog/cross-browser-document-ready-with-vanilla-javascript/
var domIsReady = (function(domIsReady) {
@ -32,6 +26,38 @@ var domIsReady = (function(domIsReady) {
return domIsReady;
})(domIsReady || {});
// vanilla ajax request, json get
function getJson(basisUrl, method, successFunction, errorFunction, timeoutFunction) {
var xhr = new XMLHttpRequest();
xhr.onload = function(e) {
var xhr = e.target;
//console.log(xhr);
var jsonReturn = [];
if (xhr.responseType === 'json') {
jsonReturn = xhr.response;
} else {
jsonReturn = JSON.parse(xhr.responseText);
}
successFunction(jsonReturn);
}
xhr.onerror = function(e) {
errorFunction(e);
}
xhr.ontimeout = function(e) {
timeoutFunction(e);
}
var bustCache = '&' + new Date().getTime();
//oReq.open('GET', e.target.dataset.url + bustCache, true);
xhr.open('GET', basisUrl + '?method='+method + bustCache, true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.responseType = 'json';
xhr.send();
}
/*
* var el = document.querySelector('.toggle-me');