Update rule controller to have some auto complete functionality.

This commit is contained in:
James Cole 2017-01-20 19:50:22 +01:00
parent 8635fe7ebb
commit 50e39a4a75
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
8 changed files with 179 additions and 34 deletions

View File

@ -21,6 +21,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Account\AccountTaskerInterface; use FireflyIII\Repositories\Account\AccountTaskerInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI; use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface; use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -61,6 +62,27 @@ class JsonController extends Controller
return Response::json(['html' => $view]); return Response::json(['html' => $view]);
} }
/**
* Returns a JSON list of all accounts.
*
* @param AccountRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*
*/
public function allAccounts(AccountRepositoryInterface $repository)
{
$return = array_unique(
$repository->getAccountsByType(
[AccountType::REVENUE, AccountType::EXPENSE, AccountType::BENEFICIARY, AccountType::DEFAULT, AccountType::ASSET]
)->pluck('name')->toArray()
);
sort($return);
return Response::json($return);
}
/** /**
* @param BillRepositoryInterface $repository * @param BillRepositoryInterface $repository
* *
@ -166,11 +188,8 @@ class JsonController extends Controller
*/ */
public function categories(CRI $repository) public function categories(CRI $repository)
{ {
$list = $repository->getCategories(); $return = array_unique($repository->getCategories()->pluck('name')->toArray());
$return = []; sort($return);
foreach ($list as $entry) {
$return[] = $entry->name;
}
return Response::json($return); return Response::json($return);
} }
@ -195,14 +214,10 @@ class JsonController extends Controller
*/ */
public function expenseAccounts(AccountRepositoryInterface $repository) public function expenseAccounts(AccountRepositoryInterface $repository)
{ {
$list = $repository->getAccountsByType([AccountType::EXPENSE, AccountType::BENEFICIARY]); $return = array_unique($repository->getAccountsByType([AccountType::EXPENSE, AccountType::BENEFICIARY])->pluck('name')->toArray());
$return = []; sort($return);
foreach ($list as $entry) {
$return[] = $entry->name;
}
return Response::json($return); return Response::json($return);
} }
/** /**
@ -213,14 +228,10 @@ class JsonController extends Controller
*/ */
public function revenueAccounts(AccountRepositoryInterface $repository) public function revenueAccounts(AccountRepositoryInterface $repository)
{ {
$list = $repository->getAccountsByType([AccountType::REVENUE]); $return = array_unique($repository->getAccountsByType([AccountType::REVENUE])->pluck('name')->toArray());
$return = []; sort($return);
foreach ($list as $entry) {
$return[] = $entry->name;
}
return Response::json($return); return Response::json($return);
} }
/** /**
@ -232,11 +243,8 @@ class JsonController extends Controller
*/ */
public function tags(TagRepositoryInterface $tagRepository) public function tags(TagRepositoryInterface $tagRepository)
{ {
$list = $tagRepository->get(); $return = array_unique($tagRepository->get()->pluck('tag')->toArray());
$return = []; sort($return);
foreach ($list as $entry) {
$return[] = $entry->tag;
}
return Response::json($return); return Response::json($return);
@ -270,6 +278,22 @@ class JsonController extends Controller
return Response::json(['steps' => $steps, 'template' => $template]); return Response::json(['steps' => $steps, 'template' => $template]);
} }
/**
* @param JournalCollectorInterface $collector
*
* @return \Illuminate\Http\JsonResponse
*/
public function allTransactionJournals(JournalCollectorInterface $collector)
{
$collector->setLimit(100)->setPage(1);
$return = array_unique($collector->getJournals()->pluck('description')->toArray());
sort($return);
return Response::json($return);
}
/** /**
* @param JournalCollectorInterface $collector * @param JournalCollectorInterface $collector
* @param string $what * @param string $what
@ -278,25 +302,29 @@ class JsonController extends Controller
*/ */
public function transactionJournals(JournalCollectorInterface $collector, string $what) public function transactionJournals(JournalCollectorInterface $collector, string $what)
{ {
$descriptions = [];
$type = config('firefly.transactionTypesByWhat.' . $what); $type = config('firefly.transactionTypesByWhat.' . $what);
$types = [$type]; $types = [$type];
// use journal collector instead:
$collector->setTypes($types)->setLimit(100)->setPage(1); $collector->setTypes($types)->setLimit(100)->setPage(1);
$journals = $collector->getJournals(); $return = array_unique($collector->getJournals()->pluck('description')->toArray());
foreach ($journals as $j) { sort($return);
$descriptions[] = $j->description;
}
$descriptions = array_unique($descriptions); return Response::json($return);
sort($descriptions);
return Response::json($descriptions);
} }
/**
*
*/
public function transactionTypes(JournalRepositoryInterface $repository)
{
$return = array_unique($repository->getTransactionTypes()->pluck('type')->toArray());
sort($return);
return Response::json($return);
}
/** /**
* @param Request $request * @param Request $request
* *

View File

@ -137,6 +137,14 @@ class JournalRepository implements JournalRepositoryInterface
return $entry; return $entry;
} }
/**
* @return Collection
*/
public function getTransactionTypes(): Collection
{
return TransactionType::orderBy('type', 'ASC')->get();
}
/** /**
* @param array $data * @param array $data
* *

View File

@ -16,6 +16,7 @@ namespace FireflyIII\Repositories\Journal;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType; use FireflyIII\Models\TransactionType;
use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag; use Illuminate\Support\MessageBag;
/** /**
@ -36,6 +37,11 @@ interface JournalRepositoryInterface
*/ */
public function convert(TransactionJournal $journal, TransactionType $type, Account $source, Account $destination): MessageBag; public function convert(TransactionJournal $journal, TransactionType $type, Account $source, Account $destination): MessageBag;
/**
* @return Collection
*/
public function getTransactionTypes(): Collection;
/** /**
* Deletes a journal. * Deletes a journal.
* *

View File

@ -11,25 +11,47 @@
var triggerCount = 0; var triggerCount = 0;
var actionCount = 0; var actionCount = 0;
/**
* This method triggers when a new trigger must be added to the form.
*/
function addNewTrigger() { function addNewTrigger() {
"use strict"; "use strict";
triggerCount++; triggerCount++;
// get the HTML for the new trigger
$.getJSON('json/trigger', {count: triggerCount}).done(function (data) { $.getJSON('json/trigger', {count: triggerCount}).done(function (data) {
// append it:
$('tbody.rule-trigger-tbody').append(data.html); $('tbody.rule-trigger-tbody').append(data.html);
// update all "remove trigger"-buttons so they will respond correctly
// and remove the trigger.
$('.remove-trigger').unbind('click').click(function (e) { $('.remove-trigger').unbind('click').click(function (e) {
removeTrigger(e); removeTrigger(e);
return false; return false;
}); });
// update all "select trigger type" dropdown buttons so they will respond correctly
$('select[name^="rule-trigger["]').unbind('change').change(function (e) {
var target = $(e.target);
updateTriggerAutoComplete(target)
});
// update all "select trigger type" dropdowns
// so the accompanying text-box has the correct autocomplete.
onAddNewTrigger();
}).fail(function () { }).fail(function () {
alert('Cannot get a new trigger.'); alert('Cannot get a new trigger.');
}); });
} }
/**
* Method triggers when a new action must be added to the form..
*/
function addNewAction() { function addNewAction() {
"use strict"; "use strict";
actionCount++; actionCount++;
@ -49,6 +71,11 @@ function addNewAction() {
}); });
} }
/**
* Method fires when a trigger must be removed from the form.
*
* @param e
*/
function removeTrigger(e) { function removeTrigger(e) {
"use strict"; "use strict";
var target = $(e.target); var target = $(e.target);
@ -64,6 +91,11 @@ function removeTrigger(e) {
} }
} }
/**
* Method fires when an action must be removed from the form.
*
* @param e
*/
function removeAction(e) { function removeAction(e) {
"use strict"; "use strict";
var target = $(e.target); var target = $(e.target);
@ -79,6 +111,72 @@ function removeAction(e) {
} }
} }
/**
* Method fires when a new trigger is added. It will update ALL trigger value input fields.
*/
function onAddNewTrigger() {
"use strict";
console.log('updateTriggerAutoComplete');
$.each($('.rule-trigger-holder'), function (i, v) {
var holder = $(v);
var select = holder.find('select');
console.log('Now at input #' + i);
updateTriggerAutoComplete(select);
});
}
/**
* Creates a nice auto complete trigger depending on the type of the select list value thing.
*
* @param selectList
*/
function updateTriggerAutoComplete(selectList) {
// the actual row this select list is in:
var parent = selectList.parent().parent();
// the text input we're looking for:
var input = parent.find('input[name^="rule-trigger-value["]');
switch (selectList.val()) {
default:
input.typeahead('destroy');
console.log('Cannot or will not add autocomplete to "' + selectList.val() + '"');
break;
case 'from_account_starts':
case 'from_account_ends':
case 'from_account_is':
case 'from_account_contains':
case 'to_account_starts':
case 'to_account_ends':
case 'to_account_is':
case 'to_account_contains':
createAutoComplete(input, 'json/all-accounts');
break;
case 'transaction_type':
createAutoComplete(input, 'json/transaction-types');
break;
case 'description_starts':
case 'description_ends':
case 'description_contains':
case 'description_is':
createAutoComplete(input, 'json/transaction-journals/all');
break;
}
}
/**
* Create actual autocomplete
* @param input
* @param URI
*/
function createAutoComplete(input, URI) {
console.log('Will create auto-complete for "' + URI + '".');
input.typeahead('destroy');
$.getJSON(URI).done(function (data) {
input.typeahead({source: data});
console.log('Created new auto-complete!');
});
}
function testRuleTriggers() { function testRuleTriggers() {
"use strict"; "use strict";

View File

@ -20,7 +20,6 @@ $(function () {
addNewAction(); addNewAction();
} }
$('.add_rule_trigger').click(function () { $('.add_rule_trigger').click(function () {
addNewTrigger(); addNewTrigger();

View File

@ -1,4 +1,4 @@
<tr data-count="{{ count }}"> <tr data-count="{{ count }}" class="rule-trigger-holder">
<td style="width:40px;"> <td style="width:40px;">
<a href="#" class="btn btn-danger btn-sm remove-trigger"><i class="fa fa-trash"></i></a> <a href="#" class="btn btn-danger btn-sm remove-trigger"><i class="fa fa-trash"></i></a>
</td> </td>

View File

@ -127,6 +127,7 @@
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js"></script>
<script type="text/javascript" src="js/ff/rules/create-edit.js"></script> <script type="text/javascript" src="js/ff/rules/create-edit.js"></script>
<script type="text/javascript"> <script type="text/javascript">
var triggerCount = {{ triggerCount }}; var triggerCount = {{ triggerCount }};
@ -134,3 +135,5 @@
</script> </script>
<script type="text/javascript" src="js/ff/rules/create.js"></script> <script type="text/javascript" src="js/ff/rules/create.js"></script>
{% endblock %} {% endblock %}
{% block styles %}
{% endblock %}

View File

@ -380,6 +380,7 @@ Route::group(
Route::group( Route::group(
['middleware' => 'user-full-auth', 'prefix' => 'json', 'as' => 'json.'], function () { ['middleware' => 'user-full-auth', 'prefix' => 'json', 'as' => 'json.'], function () {
Route::get('expense-accounts', ['uses' => 'JsonController@expenseAccounts', 'as' => 'expense-accounts']); Route::get('expense-accounts', ['uses' => 'JsonController@expenseAccounts', 'as' => 'expense-accounts']);
Route::get('all-accounts', ['uses' => 'JsonController@allAccounts', 'as' => 'all-accounts']);
Route::get('revenue-accounts', ['uses' => 'JsonController@revenueAccounts', 'as' => 'revenue-accounts']); Route::get('revenue-accounts', ['uses' => 'JsonController@revenueAccounts', 'as' => 'revenue-accounts']);
Route::get('categories', ['uses' => 'JsonController@categories', 'as' => 'categories']); Route::get('categories', ['uses' => 'JsonController@categories', 'as' => 'categories']);
Route::get('tags', ['uses' => 'JsonController@tags', 'as' => 'tags']); Route::get('tags', ['uses' => 'JsonController@tags', 'as' => 'tags']);
@ -388,7 +389,9 @@ Route::group(
Route::get('box/out', ['uses' => 'JsonController@boxOut', 'as' => 'box.out']); Route::get('box/out', ['uses' => 'JsonController@boxOut', 'as' => 'box.out']);
Route::get('box/bills-unpaid', ['uses' => 'JsonController@boxBillsUnpaid', 'as' => 'box.paid']); Route::get('box/bills-unpaid', ['uses' => 'JsonController@boxBillsUnpaid', 'as' => 'box.paid']);
Route::get('box/bills-paid', ['uses' => 'JsonController@boxBillsPaid', 'as' => 'box.unpaid']); Route::get('box/bills-paid', ['uses' => 'JsonController@boxBillsPaid', 'as' => 'box.unpaid']);
Route::get('transaction-journals/all', ['uses' => 'JsonController@allTransactionJournals', 'as' => 'all-transaction-journals']);
Route::get('transaction-journals/{what}', ['uses' => 'JsonController@transactionJournals', 'as' => 'transaction-journals']); Route::get('transaction-journals/{what}', ['uses' => 'JsonController@transactionJournals', 'as' => 'transaction-journals']);
Route::get('transaction-types', ['uses' => 'JsonController@transactionTypes', 'as' => 'transaction-types']);
Route::get('trigger', ['uses' => 'JsonController@trigger', 'as' => 'trigger']); Route::get('trigger', ['uses' => 'JsonController@trigger', 'as' => 'trigger']);
Route::get('action', ['uses' => 'JsonController@action', 'as' => 'action']); Route::get('action', ['uses' => 'JsonController@action', 'as' => 'action']);