mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop
This commit is contained in:
commit
e38b64547f
@ -1,6 +1,6 @@
|
||||
language: php
|
||||
php:
|
||||
- 7.1.18
|
||||
- 7.2
|
||||
|
||||
cache:
|
||||
directories:
|
||||
|
@ -98,6 +98,7 @@ class UpgradeDatabase extends Command
|
||||
$this->migrateAttachmentData();
|
||||
$this->migrateBillsToRules();
|
||||
$this->budgetLimitCurrency();
|
||||
$this->removeCCLiabilities();
|
||||
|
||||
$this->info('Firefly III database is up to date.');
|
||||
|
||||
@ -535,6 +536,28 @@ class UpgradeDatabase extends Command
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function removeCCLiabilities(): void
|
||||
{
|
||||
$ccType = AccountType::where('type', AccountType::CREDITCARD)->first();
|
||||
$debtType =AccountType::where('type', AccountType::DEBT)->first();
|
||||
if(null === $ccType || null === $debtType) {
|
||||
return;
|
||||
}
|
||||
/** @var Collection $accounts */
|
||||
$accounts = Account::where('account_type_id', $ccType->id)->get();
|
||||
foreach($accounts as $account) {
|
||||
$account->account_type_id = $debtType->id;
|
||||
$account->save();
|
||||
$this->line(sprintf('Converted credit card liability account "%s" (#%d) to generic debt liability.', $account->name, $account->id));
|
||||
}
|
||||
if($accounts->count() > 0) {
|
||||
$this->info('Credit card liability types are no longer supported and have been converted to generic debts. See: http://bit.ly/FF3-credit-cards');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method makes sure that the transaction journal uses the currency given in the transaction.
|
||||
*
|
||||
|
@ -108,6 +108,7 @@ class TransactionFactory
|
||||
{
|
||||
Log::debug('Start of TransactionFactory::createPair()', $data);
|
||||
// all this data is the same for both transactions:
|
||||
Log::debug('Searching for currency info.');
|
||||
$currency = $this->findCurrency($data['currency_id'], $data['currency_code']);
|
||||
$description = $journal->description === $data['description'] ? null : $data['description'];
|
||||
|
||||
@ -164,6 +165,7 @@ class TransactionFactory
|
||||
}
|
||||
|
||||
// set foreign currency
|
||||
Log::debug('Trying to find foreign currency information.');
|
||||
$foreign = $this->findCurrency($data['foreign_currency_id'], $data['foreign_currency_code']);
|
||||
$this->setForeignCurrency($source, $foreign);
|
||||
$this->setForeignCurrency($dest, $foreign);
|
||||
|
@ -36,6 +36,11 @@ use Log;
|
||||
*/
|
||||
class TransactionJournalFactory
|
||||
{
|
||||
/** @var User The user */
|
||||
private $user;
|
||||
|
||||
use JournalServiceTrait, TransactionTypeTrait;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
@ -46,10 +51,6 @@ class TransactionJournalFactory
|
||||
}
|
||||
}
|
||||
|
||||
use JournalServiceTrait, TransactionTypeTrait;
|
||||
/** @var User The user */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Store a new transaction journal.
|
||||
*
|
||||
@ -67,13 +68,15 @@ class TransactionJournalFactory
|
||||
$type = $this->findTransactionType($data['type']);
|
||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user);
|
||||
Log::debug(sprintf('Going to store a %s', $type->type));
|
||||
$description = app('steam')->cleanString($data['description']);
|
||||
$description = str_replace(["\n", "\t", "\r"], "\x20", $description);
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $data['user'],
|
||||
'transaction_type_id' => $type->id,
|
||||
'bill_id' => null,
|
||||
'transaction_currency_id' => $defaultCurrency->id,
|
||||
'description' => $data['description'],
|
||||
'description' => $description,
|
||||
'date' => $data['date']->format('Y-m-d'),
|
||||
'order' => 0,
|
||||
'tag_count' => 0,
|
||||
@ -114,7 +117,7 @@ class TransactionJournalFactory
|
||||
// store date meta fields (if present):
|
||||
$fields = ['sepa-cc', 'sepa-ct-op', 'sepa-ct-id', 'sepa-db', 'sepa-country', 'sepa-ep', 'sepa-ci', 'interest_date', 'book_date', 'process_date',
|
||||
'due_date', 'recurrence_id', 'payment_date', 'invoice_date', 'internal_reference', 'bunq_payment_id', 'importHash', 'importHashV2',
|
||||
'external_id', 'sepa-batch-id','original-source'];
|
||||
'external_id', 'sepa-batch-id', 'original-source'];
|
||||
|
||||
foreach ($fields as $field) {
|
||||
$this->storeMeta($journal, $data, $field);
|
||||
|
@ -182,13 +182,17 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
/**
|
||||
* Save attachments that get uploaded with models, through the app.
|
||||
*
|
||||
* @param Model $model
|
||||
* @param object $model
|
||||
* @param array|null $files
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Illuminate\Contracts\Encryption\EncryptException
|
||||
*/
|
||||
public function saveAttachmentsForModel(Model $model, ?array $files): bool
|
||||
public function saveAttachmentsForModel(object $model, ?array $files): bool
|
||||
{
|
||||
if(!($model instanceof Model)) {
|
||||
return false;
|
||||
}
|
||||
Log::debug(sprintf('Now in saveAttachmentsForModel for model %s', \get_class($model)));
|
||||
if (\is_array($files)) {
|
||||
Log::debug('$files is an array.');
|
||||
|
@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Helpers\Attachments;
|
||||
|
||||
use FireflyIII\Models\Attachment;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
@ -84,10 +83,10 @@ interface AttachmentHelperInterface
|
||||
/**
|
||||
* Save attachments that got uploaded.
|
||||
*
|
||||
* @param Model $model
|
||||
* @param object $model
|
||||
* @param null|array $files
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveAttachmentsForModel(Model $model, ?array $files): bool;
|
||||
public function saveAttachmentsForModel(object $model, ?array $files): bool;
|
||||
}
|
||||
|
@ -83,12 +83,10 @@ class CreateController extends Controller
|
||||
$debt = $this->repository->getAccountTypeByType(AccountType::DEBT);
|
||||
$loan = $this->repository->getAccountTypeByType(AccountType::LOAN);
|
||||
$mortgage = $this->repository->getAccountTypeByType(AccountType::MORTGAGE);
|
||||
$creditCard = $this->repository->getAccountTypeByType(AccountType::CREDITCARD);
|
||||
$liabilityTypes = [
|
||||
$debt->id => (string)trans('firefly.account_type_' . AccountType::DEBT),
|
||||
$loan->id => (string)trans('firefly.account_type_' . AccountType::LOAN),
|
||||
$mortgage->id => (string)trans('firefly.account_type_' . AccountType::MORTGAGE),
|
||||
$creditCard->id => (string)trans('firefly.account_type_' . AccountType::CREDITCARD),
|
||||
];
|
||||
asort($liabilityTypes);
|
||||
|
||||
|
@ -90,12 +90,10 @@ class EditController extends Controller
|
||||
$debt = $this->repository->getAccountTypeByType(AccountType::DEBT);
|
||||
$loan = $this->repository->getAccountTypeByType(AccountType::LOAN);
|
||||
$mortgage = $this->repository->getAccountTypeByType(AccountType::MORTGAGE);
|
||||
$creditCard = $this->repository->getAccountTypeByType(AccountType::CREDITCARD);
|
||||
$liabilityTypes = [
|
||||
$debt->id => (string)trans('firefly.account_type_' . AccountType::DEBT),
|
||||
$loan->id => (string)trans('firefly.account_type_' . AccountType::LOAN),
|
||||
$mortgage->id => (string)trans('firefly.account_type_' . AccountType::MORTGAGE),
|
||||
$creditCard->id => (string)trans('firefly.account_type_' . AccountType::CREDITCARD),
|
||||
];
|
||||
asort($liabilityTypes);
|
||||
|
||||
|
@ -47,6 +47,8 @@ class JobStatusController extends Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
// set time limit to zero to prevent timeouts.
|
||||
set_time_limit(0);
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
|
@ -36,8 +36,10 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* TODO refactor so each auto-complete thing is a function call because lots of code duplication.
|
||||
* Class AutoCompleteController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
|
||||
@ -49,18 +51,40 @@ class AutoCompleteController extends Controller
|
||||
/**
|
||||
* Returns a JSON list of all accounts.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function allAccounts(AccountRepositoryInterface $repository): JsonResponse
|
||||
public function allAccounts(Request $request, AccountRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$return = array_unique(
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-all-accounts');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
$repository->getAccountsByType(
|
||||
[AccountType::REVENUE, AccountType::EXPENSE, AccountType::BENEFICIARY, AccountType::DEFAULT, AccountType::ASSET]
|
||||
)->pluck('name')->toArray()
|
||||
)
|
||||
);
|
||||
sort($return);
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
@ -68,15 +92,86 @@ class AutoCompleteController extends Controller
|
||||
/**
|
||||
* List of all journals.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param TransactionCollectorInterface $collector
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function allTransactionJournals(TransactionCollectorInterface $collector): JsonResponse
|
||||
public function allTransactionJournals(Request $request, TransactionCollectorInterface $collector): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-all-journals');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$collector->setLimit(250)->setPage(1);
|
||||
$return = array_unique($collector->getTransactions()->pluck('description')->toArray());
|
||||
sort($return);
|
||||
$return = array_values(array_unique($collector->getTransactions()->pluck('description')->toArray()));
|
||||
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* List of revenue accounts.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function assetAccounts(Request $request, AccountRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-asset-accounts');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$set = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
$filtered = $set->filter(
|
||||
function (Account $account) {
|
||||
if (true === $account->active) {
|
||||
return $account;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
);
|
||||
$return = array_values(array_unique($filtered->pluck('name')->toArray()));
|
||||
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
@ -84,16 +179,37 @@ class AutoCompleteController extends Controller
|
||||
/**
|
||||
* Returns a JSON list of all bills.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param BillRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function bills(BillRepositoryInterface $repository): JsonResponse
|
||||
public function bills(Request $request, BillRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$return = array_unique(
|
||||
$repository->getActiveBills()->pluck('name')->toArray()
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-bills');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$return = array_unique($repository->getActiveBills()->pluck('name')->toArray());
|
||||
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
sort($return);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
@ -101,14 +217,37 @@ class AutoCompleteController extends Controller
|
||||
/**
|
||||
* List of budgets.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function budgets(BudgetRepositoryInterface $repository): JsonResponse
|
||||
public function budgets(Request $request, BudgetRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-budgets');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$return = array_unique($repository->getBudgets()->pluck('name')->toArray());
|
||||
sort($return);
|
||||
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
@ -116,14 +255,34 @@ class AutoCompleteController extends Controller
|
||||
/**
|
||||
* Returns a list of categories.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function categories(CategoryRepositoryInterface $repository): JsonResponse
|
||||
public function categories(Request $request, CategoryRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-categories');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$return = array_unique($repository->getCategories()->pluck('name')->toArray());
|
||||
sort($return);
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
@ -131,27 +290,62 @@ class AutoCompleteController extends Controller
|
||||
/**
|
||||
* List of currency names.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param CurrencyRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function currencyNames(CurrencyRepositoryInterface $repository): JsonResponse
|
||||
public function currencyNames(Request $request, CurrencyRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-currency-names');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$return = $repository->get()->pluck('name')->toArray();
|
||||
sort($return);
|
||||
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON list of all beneficiaries.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function expenseAccounts(AccountRepositoryInterface $repository): JsonResponse
|
||||
public function expenseAccounts(Request $request, AccountRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-expense-accounts');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$set = $repository->getAccountsByType([AccountType::EXPENSE, AccountType::BENEFICIARY]);
|
||||
$filtered = $set->filter(
|
||||
function (Account $account) {
|
||||
@ -166,27 +360,43 @@ class AutoCompleteController extends Controller
|
||||
|
||||
sort($return);
|
||||
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List of journals with their ID.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param TransactionCollectorInterface $collector
|
||||
* @param TransactionJournal $except
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function journalsWithId(TransactionCollectorInterface $collector, TransactionJournal $except): JsonResponse
|
||||
public function journalsWithId(Request $request, TransactionCollectorInterface $collector, TransactionJournal $except): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('recent-journals-id');
|
||||
|
||||
$cache->addProperty('ac-expense-accounts');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
|
||||
// find everything:
|
||||
$collector->setLimit(400)->setPage(1);
|
||||
$set = $collector->getTransactions()->pluck('description', 'journal_id')->toArray();
|
||||
$return = [];
|
||||
@ -200,6 +410,19 @@ class AutoCompleteController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
sort($return);
|
||||
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
@ -208,12 +431,23 @@ class AutoCompleteController extends Controller
|
||||
/**
|
||||
* List of revenue accounts.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function revenueAccounts(AccountRepositoryInterface $repository): JsonResponse
|
||||
public function revenueAccounts(Request $request, AccountRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-revenue-accounts');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$set = $repository->getAccountsByType([AccountType::REVENUE]);
|
||||
$filtered = $set->filter(
|
||||
function (Account $account) {
|
||||
@ -227,30 +461,18 @@ class AutoCompleteController extends Controller
|
||||
$return = array_unique($filtered->pluck('name')->toArray());
|
||||
sort($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* List of revenue accounts.
|
||||
*
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function assetAccounts(AccountRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$set = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
$filtered = $set->filter(
|
||||
function (Account $account) {
|
||||
if (true === $account->active) {
|
||||
return $account;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
$return = array_unique($filtered->pluck('name')->toArray());
|
||||
sort($return);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
@ -258,28 +480,63 @@ class AutoCompleteController extends Controller
|
||||
/**
|
||||
* Returns a JSON list of all beneficiaries.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param TagRepositoryInterface $tagRepository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function tags(TagRepositoryInterface $tagRepository): JsonResponse
|
||||
public function tags(Request $request, TagRepositoryInterface $tagRepository): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-revenue-accounts');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$return = array_unique($tagRepository->get()->pluck('tag')->toArray());
|
||||
sort($return);
|
||||
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* List of journals by type.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param TransactionCollectorInterface $collector
|
||||
* @param string $what
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function transactionJournals(TransactionCollectorInterface $collector, string $what): JsonResponse
|
||||
public function transactionJournals(Request $request, TransactionCollectorInterface $collector, string $what): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-revenue-accounts');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$type = config('firefly.transactionTypesByWhat.' . $what);
|
||||
$types = [$type];
|
||||
|
||||
@ -287,21 +544,60 @@ class AutoCompleteController extends Controller
|
||||
$return = array_unique($collector->getTransactions()->pluck('description')->toArray());
|
||||
sort($return);
|
||||
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* List if transaction types.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param JournalRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function transactionTypes(JournalRepositoryInterface $repository): JsonResponse
|
||||
public function transactionTypes(Request $request, JournalRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('ac-revenue-accounts');
|
||||
// very unlikely a user will actually search for this string.
|
||||
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
|
||||
$cache->addProperty($key);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());
|
||||
}
|
||||
// find everything:
|
||||
$return = array_unique($repository->getTransactionTypes()->pluck('type')->toArray());
|
||||
sort($return);
|
||||
|
||||
if ('' !== $search) {
|
||||
$return = array_values(
|
||||
array_unique(
|
||||
array_filter(
|
||||
$return, function (string $value) use ($search) {
|
||||
return !(false === stripos($value, $search));
|
||||
}, ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class Authenticate
|
||||
*/
|
||||
public function handle($request, Closure $next, ...$guards)
|
||||
{
|
||||
$this->authenticate($guards);
|
||||
$this->authenticate($request, $guards);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@ -86,7 +86,7 @@ class Authenticate
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
protected function authenticate(array $guards)
|
||||
protected function authenticate($request, array $guards)
|
||||
{
|
||||
|
||||
if (empty($guards)) {
|
||||
|
@ -57,7 +57,7 @@ class SecureHeaders
|
||||
"form-action 'self'",
|
||||
"font-src 'self'",
|
||||
"connect-src 'self'",
|
||||
"img-src 'self' data:",
|
||||
"img-src 'self' data: https://api.tiles.mapbox.com",
|
||||
];
|
||||
|
||||
$featurePolicies = [
|
||||
|
@ -92,58 +92,7 @@ class Request extends FormRequest
|
||||
*/
|
||||
public function string(string $field): string
|
||||
{
|
||||
$string = $this->get($field) ?? '';
|
||||
$search = [
|
||||
"\u{0001}", // start of heading
|
||||
"\u{0002}", // start of text
|
||||
"\u{0003}", // end of text
|
||||
"\u{0004}", // end of transmission
|
||||
"\u{0005}", // enquiry
|
||||
"\u{0006}", // ACK
|
||||
"\u{0007}", // BEL
|
||||
"\u{0008}", // backspace
|
||||
"\u{000E}", // shift out
|
||||
"\u{000F}", // shift in
|
||||
"\u{0010}", // data link escape
|
||||
"\u{0011}", // DC1
|
||||
"\u{0012}", // DC2
|
||||
"\u{0013}", // DC3
|
||||
"\u{0014}", // DC4
|
||||
"\u{0015}", // NAK
|
||||
"\u{0016}", // SYN
|
||||
"\u{0017}", // ETB
|
||||
"\u{0018}", // CAN
|
||||
"\u{0019}", // EM
|
||||
"\u{001A}", // SUB
|
||||
"\u{001B}", // escape
|
||||
"\u{001C}", // file separator
|
||||
"\u{001D}", // group separator
|
||||
"\u{001E}", // record separator
|
||||
"\u{001F}", // unit separator
|
||||
"\u{007F}", // DEL
|
||||
"\u{00A0}", // non-breaking space
|
||||
"\u{1680}", // ogham space mark
|
||||
"\u{180E}", // mongolian vowel separator
|
||||
"\u{2000}", // en quad
|
||||
"\u{2001}", // em quad
|
||||
"\u{2002}", // en space
|
||||
"\u{2003}", // em space
|
||||
"\u{2004}", // three-per-em space
|
||||
"\u{2005}", // four-per-em space
|
||||
"\u{2006}", // six-per-em space
|
||||
"\u{2007}", // figure space
|
||||
"\u{2008}", // punctuation space
|
||||
"\u{2009}", // thin space
|
||||
"\u{200A}", // hair space
|
||||
"\u{200B}", // zero width space
|
||||
"\u{202F}", // narrow no-break space
|
||||
"\u{3000}", // ideographic space
|
||||
"\u{FEFF}", // zero width no -break space
|
||||
];
|
||||
$replace = "\x20"; // plain old normal space
|
||||
$string = str_replace($search, $replace, $string);
|
||||
|
||||
return trim($string);
|
||||
return app('steam')->cleanString($this->get($field) ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,7 +79,7 @@ class ChooseAccountsHandler implements BunqJobConfigurationInterface
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$accounts = $config['accounts'] ?? [];
|
||||
$mapping = $data['account_mapping'] ?? [];
|
||||
$applyRules = 1 === (int)$data['apply_rules'];
|
||||
$applyRules = 1 === (int)($data['apply_rules'] ?? 0);
|
||||
$final = [];
|
||||
|
||||
/*
|
||||
|
@ -30,7 +30,6 @@ use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
@ -38,6 +37,7 @@ use stdClass;
|
||||
*/
|
||||
class Steam
|
||||
{
|
||||
|
||||
/**
|
||||
* @param \FireflyIII\Models\Account $account
|
||||
* @param \Carbon\Carbon $date
|
||||
@ -315,6 +315,68 @@ class Steam
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove weird chars from strings.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function cleanString(string $string): string
|
||||
{
|
||||
$search = [
|
||||
"\u{0001}", // start of heading
|
||||
"\u{0002}", // start of text
|
||||
"\u{0003}", // end of text
|
||||
"\u{0004}", // end of transmission
|
||||
"\u{0005}", // enquiry
|
||||
"\u{0006}", // ACK
|
||||
"\u{0007}", // BEL
|
||||
"\u{0008}", // backspace
|
||||
"\u{000E}", // shift out
|
||||
"\u{000F}", // shift in
|
||||
"\u{0010}", // data link escape
|
||||
"\u{0011}", // DC1
|
||||
"\u{0012}", // DC2
|
||||
"\u{0013}", // DC3
|
||||
"\u{0014}", // DC4
|
||||
"\u{0015}", // NAK
|
||||
"\u{0016}", // SYN
|
||||
"\u{0017}", // ETB
|
||||
"\u{0018}", // CAN
|
||||
"\u{0019}", // EM
|
||||
"\u{001A}", // SUB
|
||||
"\u{001B}", // escape
|
||||
"\u{001C}", // file separator
|
||||
"\u{001D}", // group separator
|
||||
"\u{001E}", // record separator
|
||||
"\u{001F}", // unit separator
|
||||
"\u{007F}", // DEL
|
||||
"\u{00A0}", // non-breaking space
|
||||
"\u{1680}", // ogham space mark
|
||||
"\u{180E}", // mongolian vowel separator
|
||||
"\u{2000}", // en quad
|
||||
"\u{2001}", // em quad
|
||||
"\u{2002}", // en space
|
||||
"\u{2003}", // em space
|
||||
"\u{2004}", // three-per-em space
|
||||
"\u{2005}", // four-per-em space
|
||||
"\u{2006}", // six-per-em space
|
||||
"\u{2007}", // figure space
|
||||
"\u{2008}", // punctuation space
|
||||
"\u{2009}", // thin space
|
||||
"\u{200A}", // hair space
|
||||
"\u{200B}", // zero width space
|
||||
"\u{202F}", // narrow no-break space
|
||||
"\u{3000}", // ideographic space
|
||||
"\u{FEFF}", // zero width no -break space
|
||||
];
|
||||
$replace = "\x20"; // plain old normal space
|
||||
$string = str_replace($search, $replace, $string);
|
||||
|
||||
return trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $isEncrypted
|
||||
* @param $value
|
||||
|
@ -46,21 +46,21 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.1.0",
|
||||
"php": ">=7.2.0",
|
||||
"ext-bcmath": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-zip": "*",
|
||||
"bacon/bacon-qr-code": "1.*",
|
||||
"bacon/bacon-qr-code": "2.*",
|
||||
"bunq/sdk_php": "dev-master#8c1faefc111d9b970168a1837ca165d854954941",
|
||||
"davejamesmiller/laravel-breadcrumbs": "5.*",
|
||||
"doctrine/dbal": "2.*",
|
||||
"fideloper/proxy": "4.*",
|
||||
"laravel/framework": "5.6.*",
|
||||
"laravel/passport": "^5.0",
|
||||
"laravelcollective/html": "5.6.*",
|
||||
"laravel/framework": "5.7.*",
|
||||
"laravel/passport": "^7.0",
|
||||
"laravelcollective/html": "5.7.*",
|
||||
"league/commonmark": "0.*",
|
||||
"league/csv": "9.*",
|
||||
"league/fractal": "^0.17.0",
|
||||
@ -74,9 +74,9 @@
|
||||
"filp/whoops": "2.*",
|
||||
"fzaninotto/faker": "1.*",
|
||||
"johnkary/phpunit-speedtrap": "^3.0",
|
||||
"mockery/mockery": "^1.0",
|
||||
"mockery/mockery": "1.*",
|
||||
"php-coveralls/php-coveralls": "^2.0",
|
||||
"phpunit/phpunit": "~7.0",
|
||||
"phpunit/phpunit": "7.*",
|
||||
"roave/security-advisories": "dev-master"
|
||||
},
|
||||
"autoload": {
|
||||
@ -112,13 +112,13 @@
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"php artisan firefly:upgrade-database",
|
||||
"php artisan firefly:verify",
|
||||
"php artisan firefly:instructions update",
|
||||
"php artisan passport:install"
|
||||
"@php artisan firefly:upgrade-database",
|
||||
"@php artisan firefly:verify",
|
||||
"@php artisan firefly:instructions update",
|
||||
"@php artisan passport:install"
|
||||
],
|
||||
"post-install-cmd": [
|
||||
"php artisan firefly:instructions install"
|
||||
"@php artisan firefly:instructions install"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
|
411
composer.lock
generated
411
composer.lock
generated
@ -4,36 +4,39 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "dcaf20ad3436c4fc4cbebeee09c9de1f",
|
||||
"content-hash": "364135d1fab7e47564deae52ea0c12c2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
"version": "1.0.3",
|
||||
"version": "2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Bacon/BaconQrCode.git",
|
||||
"reference": "5a91b62b9d37cee635bbf8d553f4546057250bee"
|
||||
"reference": "eaac909da3ccc32b748a65b127acd8918f58d9b0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/5a91b62b9d37cee635bbf8d553f4546057250bee",
|
||||
"reference": "5a91b62b9d37cee635bbf8d553f4546057250bee",
|
||||
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/eaac909da3ccc32b748a65b127acd8918f58d9b0",
|
||||
"reference": "eaac909da3ccc32b748a65b127acd8918f58d9b0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dasprid/enum": "^1.0",
|
||||
"ext-iconv": "*",
|
||||
"php": "^5.4|^7.0"
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8"
|
||||
"phly/keep-a-changelog": "^1.4",
|
||||
"phpunit/phpunit": "^6.4",
|
||||
"squizlabs/php_codesniffer": "^3.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "to generate QR code images"
|
||||
"ext-imagick": "to generate QR code images"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"BaconQrCode": "src/"
|
||||
"psr-4": {
|
||||
"BaconQrCode\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@ -50,7 +53,7 @@
|
||||
],
|
||||
"description": "BaconQrCode is a QR code generator for PHP.",
|
||||
"homepage": "https://github.com/Bacon/BaconQrCode",
|
||||
"time": "2017-10-17T09:59:25+00:00"
|
||||
"time": "2018-04-25T17:53:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bunq/sdk_php",
|
||||
@ -117,27 +120,69 @@
|
||||
"time": "2018-09-01T12:54:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "davejamesmiller/laravel-breadcrumbs",
|
||||
"version": "5.1.0",
|
||||
"name": "dasprid/enum",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/davejamesmiller/laravel-breadcrumbs.git",
|
||||
"reference": "2a02abfeca13acba6d528f4fcd385570452308f7"
|
||||
"url": "https://github.com/DASPRiD/Enum.git",
|
||||
"reference": "631ef6e638e9494b0310837fa531bedd908fc22b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/davejamesmiller/laravel-breadcrumbs/zipball/2a02abfeca13acba6d528f4fcd385570452308f7",
|
||||
"reference": "2a02abfeca13acba6d528f4fcd385570452308f7",
|
||||
"url": "https://api.github.com/repos/DASPRiD/Enum/zipball/631ef6e638e9494b0310837fa531bedd908fc22b",
|
||||
"reference": "631ef6e638e9494b0310837fa531bedd908fc22b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.4",
|
||||
"squizlabs/php_codesniffer": "^3.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DASPRiD\\Enum\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-2-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ben Scholzen 'DASPRiD'",
|
||||
"email": "mail@dasprids.de",
|
||||
"homepage": "https://dasprids.de/"
|
||||
}
|
||||
],
|
||||
"description": "PHP 7.1 enum implementation",
|
||||
"keywords": [
|
||||
"enum",
|
||||
"map"
|
||||
],
|
||||
"time": "2017-10-25T22:45:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "davejamesmiller/laravel-breadcrumbs",
|
||||
"version": "5.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/davejamesmiller/laravel-breadcrumbs.git",
|
||||
"reference": "f24853b97d9f973a9b936d2692f93b11924415e2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/davejamesmiller/laravel-breadcrumbs/zipball/f24853b97d9f973a9b936d2692f93b11924415e2",
|
||||
"reference": "f24853b97d9f973a9b936d2692f93b11924415e2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "5.6.*",
|
||||
"illuminate/view": "5.6.*",
|
||||
"illuminate/support": "5.6.*|5.7.*",
|
||||
"illuminate/view": "5.6.*|5.7.*",
|
||||
"php": ">=7.1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/framework": "5.6.*",
|
||||
"orchestra/testbench": "3.6.*",
|
||||
"laravel/framework": "5.6.*|5.7.*",
|
||||
"orchestra/testbench": "3.6.*|3.7.*",
|
||||
"php-coveralls/php-coveralls": "^1.0",
|
||||
"phpunit/phpunit": "7.*"
|
||||
},
|
||||
@ -173,7 +218,7 @@
|
||||
"keywords": [
|
||||
"laravel"
|
||||
],
|
||||
"time": "2018-05-05T19:30:03+00:00"
|
||||
"time": "2018-09-14T06:29:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "defuse/php-encryption",
|
||||
@ -1022,42 +1067,42 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v5.6.38",
|
||||
"version": "v5.7.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "38d838bab9434af79e8ab274ae63f52f7ed45d6e"
|
||||
"reference": "f6e8f6562120e0063313e81716666cfcd362569b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/38d838bab9434af79e8ab274ae63f52f7ed45d6e",
|
||||
"reference": "38d838bab9434af79e8ab274ae63f52f7ed45d6e",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/f6e8f6562120e0063313e81716666cfcd362569b",
|
||||
"reference": "f6e8f6562120e0063313e81716666cfcd362569b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/inflector": "~1.1",
|
||||
"dragonmantank/cron-expression": "~2.0",
|
||||
"erusev/parsedown": "~1.7",
|
||||
"doctrine/inflector": "^1.1",
|
||||
"dragonmantank/cron-expression": "^2.0",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"league/flysystem": "^1.0.8",
|
||||
"monolog/monolog": "~1.12",
|
||||
"nesbot/carbon": "1.25.*",
|
||||
"monolog/monolog": "^1.12",
|
||||
"nesbot/carbon": "^1.26.3",
|
||||
"php": "^7.1.3",
|
||||
"psr/container": "~1.0",
|
||||
"psr/container": "^1.0",
|
||||
"psr/simple-cache": "^1.0",
|
||||
"ramsey/uuid": "^3.7",
|
||||
"swiftmailer/swiftmailer": "~6.0",
|
||||
"symfony/console": "~4.0",
|
||||
"symfony/debug": "~4.0",
|
||||
"symfony/finder": "~4.0",
|
||||
"symfony/http-foundation": "~4.0",
|
||||
"symfony/http-kernel": "~4.0",
|
||||
"symfony/process": "~4.0",
|
||||
"symfony/routing": "~4.0",
|
||||
"symfony/var-dumper": "~4.0",
|
||||
"swiftmailer/swiftmailer": "^6.0",
|
||||
"symfony/console": "^4.1",
|
||||
"symfony/debug": "^4.1",
|
||||
"symfony/finder": "^4.1",
|
||||
"symfony/http-foundation": "^4.1",
|
||||
"symfony/http-kernel": "^4.1",
|
||||
"symfony/process": "^4.1",
|
||||
"symfony/routing": "^4.1",
|
||||
"symfony/var-dumper": "^4.1",
|
||||
"tijsverkoyen/css-to-inline-styles": "^2.2.1",
|
||||
"vlucas/phpdotenv": "~2.2"
|
||||
"vlucas/phpdotenv": "^2.2"
|
||||
},
|
||||
"conflict": {
|
||||
"tightenco/collect": "<5.5.33"
|
||||
@ -1093,43 +1138,45 @@
|
||||
"illuminate/view": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"aws/aws-sdk-php": "~3.0",
|
||||
"doctrine/dbal": "~2.6",
|
||||
"aws/aws-sdk-php": "^3.0",
|
||||
"doctrine/dbal": "^2.6",
|
||||
"filp/whoops": "^2.1.4",
|
||||
"league/flysystem-cached-adapter": "~1.0",
|
||||
"mockery/mockery": "~1.0",
|
||||
"league/flysystem-cached-adapter": "^1.0",
|
||||
"mockery/mockery": "^1.0",
|
||||
"moontoast/math": "^1.1",
|
||||
"orchestra/testbench-core": "3.6.*",
|
||||
"pda/pheanstalk": "~3.0",
|
||||
"phpunit/phpunit": "~7.0",
|
||||
"orchestra/testbench-core": "3.7.*",
|
||||
"pda/pheanstalk": "^3.0",
|
||||
"phpunit/phpunit": "^7.0",
|
||||
"predis/predis": "^1.1.1",
|
||||
"symfony/css-selector": "~4.0",
|
||||
"symfony/dom-crawler": "~4.0"
|
||||
"symfony/css-selector": "^4.1",
|
||||
"symfony/dom-crawler": "^4.1",
|
||||
"true/punycode": "^2.1"
|
||||
},
|
||||
"suggest": {
|
||||
"aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).",
|
||||
"doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.6).",
|
||||
"aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (^3.0).",
|
||||
"doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6).",
|
||||
"ext-pcntl": "Required to use all features of the queue worker.",
|
||||
"ext-posix": "Required to use all features of the queue worker.",
|
||||
"fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).",
|
||||
"guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~6.0).",
|
||||
"laravel/tinker": "Required to use the tinker console command (~1.0).",
|
||||
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).",
|
||||
"league/flysystem-cached-adapter": "Required to use the Flysystem cache (~1.0).",
|
||||
"league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).",
|
||||
"league/flysystem-sftp": "Required to use the Flysystem SFTP driver (~1.0).",
|
||||
"nexmo/client": "Required to use the Nexmo transport (~1.0).",
|
||||
"pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).",
|
||||
"predis/predis": "Required to use the redis cache and queue drivers (~1.0).",
|
||||
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~3.0).",
|
||||
"symfony/css-selector": "Required to use some of the crawler integration testing tools (~4.0).",
|
||||
"symfony/dom-crawler": "Required to use most of the crawler integration testing tools (~4.0).",
|
||||
"symfony/psr-http-message-bridge": "Required to psr7 bridging features (~1.0)."
|
||||
"fzaninotto/faker": "Required to use the eloquent factory builder (^1.4).",
|
||||
"guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (^6.0).",
|
||||
"laravel/tinker": "Required to use the tinker console command (^1.0).",
|
||||
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).",
|
||||
"league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).",
|
||||
"league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (^1.0).",
|
||||
"league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).",
|
||||
"moontoast/math": "Required to use ordered UUIDs (^1.1).",
|
||||
"nexmo/client": "Required to use the Nexmo transport (^1.0).",
|
||||
"pda/pheanstalk": "Required to use the beanstalk queue driver (^3.0).",
|
||||
"predis/predis": "Required to use the redis cache and queue drivers (^1.0).",
|
||||
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^3.0).",
|
||||
"symfony/css-selector": "Required to use some of the crawler integration testing tools (^4.1).",
|
||||
"symfony/dom-crawler": "Required to use most of the crawler integration testing tools (^4.1).",
|
||||
"symfony/psr-http-message-bridge": "Required to psr7 bridging features (^1.0)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.6-dev"
|
||||
"dev-master": "5.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -1157,20 +1204,20 @@
|
||||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"time": "2018-09-04T13:15:09+00:00"
|
||||
"time": "2018-09-18T13:34:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/passport",
|
||||
"version": "v5.0.3",
|
||||
"version": "v7.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/passport.git",
|
||||
"reference": "9dbcc3d6f8f20f1a83cbef73bbb563ce59e43ded"
|
||||
"reference": "90124969cdd4ff39d4cd5a608c23bbe16e772f7e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/passport/zipball/9dbcc3d6f8f20f1a83cbef73bbb563ce59e43ded",
|
||||
"reference": "9dbcc3d6f8f20f1a83cbef73bbb563ce59e43ded",
|
||||
"url": "https://api.github.com/repos/laravel/passport/zipball/90124969cdd4ff39d4cd5a608c23bbe16e772f7e",
|
||||
"reference": "90124969cdd4ff39d4cd5a608c23bbe16e772f7e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1184,8 +1231,8 @@
|
||||
"illuminate/encryption": "~5.6",
|
||||
"illuminate/http": "~5.6",
|
||||
"illuminate/support": "~5.6",
|
||||
"league/oauth2-server": "^6.0",
|
||||
"php": ">=7.0",
|
||||
"league/oauth2-server": "^7.0",
|
||||
"php": ">=7.1",
|
||||
"phpseclib/phpseclib": "^2.0",
|
||||
"symfony/psr-http-message-bridge": "~1.0",
|
||||
"zendframework/zend-diactoros": "~1.0"
|
||||
@ -1226,39 +1273,39 @@
|
||||
"oauth",
|
||||
"passport"
|
||||
],
|
||||
"time": "2018-03-15T12:39:02+00:00"
|
||||
"time": "2018-08-13T14:45:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravelcollective/html",
|
||||
"version": "v5.6.10",
|
||||
"version": "v5.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/LaravelCollective/html.git",
|
||||
"reference": "974605fcd22a7e4d19f0b2ef635a0d1d7400387d"
|
||||
"reference": "777b6d390811ba249255ed5750bf17a019cd88a5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/LaravelCollective/html/zipball/974605fcd22a7e4d19f0b2ef635a0d1d7400387d",
|
||||
"reference": "974605fcd22a7e4d19f0b2ef635a0d1d7400387d",
|
||||
"url": "https://api.github.com/repos/LaravelCollective/html/zipball/777b6d390811ba249255ed5750bf17a019cd88a5",
|
||||
"reference": "777b6d390811ba249255ed5750bf17a019cd88a5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/http": "5.6.*",
|
||||
"illuminate/routing": "5.6.*",
|
||||
"illuminate/session": "5.6.*",
|
||||
"illuminate/support": "5.6.*",
|
||||
"illuminate/view": "5.6.*",
|
||||
"illuminate/http": "5.7.*",
|
||||
"illuminate/routing": "5.7.*",
|
||||
"illuminate/session": "5.7.*",
|
||||
"illuminate/support": "5.7.*",
|
||||
"illuminate/view": "5.7.*",
|
||||
"php": ">=7.1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/database": "5.6.*",
|
||||
"illuminate/database": "5.7.*",
|
||||
"mockery/mockery": "~1.0",
|
||||
"phpunit/phpunit": "~7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.6-dev"
|
||||
"dev-master": "5.7-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
@ -1294,7 +1341,7 @@
|
||||
],
|
||||
"description": "HTML and Form Builders for the Laravel Framework",
|
||||
"homepage": "https://laravelcollective.com",
|
||||
"time": "2018-06-18T15:04:16+00:00"
|
||||
"time": "2018-09-05T18:32:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "lcobucci/jwt",
|
||||
@ -1356,16 +1403,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
"version": "0.17.5",
|
||||
"version": "0.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/commonmark.git",
|
||||
"reference": "82d7ab62d7f68391cb9d323f3ccce50be24a5369"
|
||||
"reference": "006af077d4b1b7eb1d9760964f9f984ba188632c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/82d7ab62d7f68391cb9d323f3ccce50be24a5369",
|
||||
"reference": "82d7ab62d7f68391cb9d323f3ccce50be24a5369",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/006af077d4b1b7eb1d9760964f9f984ba188632c",
|
||||
"reference": "006af077d4b1b7eb1d9760964f9f984ba188632c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1394,7 +1441,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.18-dev"
|
||||
"dev-master": "0.19-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -1421,7 +1468,7 @@
|
||||
"markdown",
|
||||
"parser"
|
||||
],
|
||||
"time": "2018-03-29T14:35:19+00:00"
|
||||
"time": "2018-09-18T13:13:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/csv",
|
||||
@ -1542,26 +1589,26 @@
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "1.0.46",
|
||||
"version": "1.0.47",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "f3e0d925c18b92cf3ce84ea5cc58d62a1762a2b2"
|
||||
"reference": "a11e4a75f256bdacf99d20780ce42d3b8272975c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f3e0d925c18b92cf3ce84ea5cc58d62a1762a2b2",
|
||||
"reference": "f3e0d925c18b92cf3ce84ea5cc58d62a1762a2b2",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a11e4a75f256bdacf99d20780ce42d3b8272975c",
|
||||
"reference": "a11e4a75f256bdacf99d20780ce42d3b8272975c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-fileinfo": "*",
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
"conflict": {
|
||||
"league/flysystem-sftp": "<1.0.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-fileinfo": "*",
|
||||
"phpspec/phpspec": "^3.4",
|
||||
"phpunit/phpunit": "^5.7.10"
|
||||
},
|
||||
@ -1622,7 +1669,7 @@
|
||||
"sftp",
|
||||
"storage"
|
||||
],
|
||||
"time": "2018-08-22T07:45:22+00:00"
|
||||
"time": "2018-09-14T15:30:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/fractal",
|
||||
@ -1690,34 +1737,36 @@
|
||||
},
|
||||
{
|
||||
"name": "league/oauth2-server",
|
||||
"version": "6.1.1",
|
||||
"version": "7.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/oauth2-server.git",
|
||||
"reference": "a0cabb573c7cd5ee01803daec992d6ee3677c4ae"
|
||||
"reference": "8184f771d43ea7305ddbb893d0daf6f0352ec5fd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/a0cabb573c7cd5ee01803daec992d6ee3677c4ae",
|
||||
"reference": "a0cabb573c7cd5ee01803daec992d6ee3677c4ae",
|
||||
"url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/8184f771d43ea7305ddbb893d0daf6f0352ec5fd",
|
||||
"reference": "8184f771d43ea7305ddbb893d0daf6f0352ec5fd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"defuse/php-encryption": "^2.1",
|
||||
"ext-openssl": "*",
|
||||
"lcobucci/jwt": "^3.1",
|
||||
"lcobucci/jwt": "^3.2.2",
|
||||
"league/event": "^2.1",
|
||||
"paragonie/random_compat": "^2.0",
|
||||
"php": ">=5.6.0",
|
||||
"psr/http-message": "^1.0"
|
||||
"php": ">=7.0.0",
|
||||
"psr/http-message": "^1.0.1"
|
||||
},
|
||||
"replace": {
|
||||
"league/oauth2server": "*",
|
||||
"lncd/oauth2": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.38 || ^5.7.21",
|
||||
"zendframework/zend-diactoros": "^1.0"
|
||||
"phpstan/phpstan": "^0.9.2",
|
||||
"phpstan/phpstan-phpunit": "^0.9.4",
|
||||
"phpstan/phpstan-strict-rules": "^0.9.0",
|
||||
"phpunit/phpunit": "^6.3 || ^7.0",
|
||||
"zendframework/zend-diactoros": "^1.3.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -1754,7 +1803,7 @@
|
||||
"secure",
|
||||
"server"
|
||||
],
|
||||
"time": "2017-12-23T23:33:42+00:00"
|
||||
"time": "2018-06-23T16:57:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
@ -1836,16 +1885,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "1.25.0",
|
||||
"version": "1.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4"
|
||||
"reference": "55667c1007a99e82030874b1bb14d24d07108413"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cbcf13da0b531767e39eb86e9687f5deba9857b4",
|
||||
"reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/55667c1007a99e82030874b1bb14d24d07108413",
|
||||
"reference": "55667c1007a99e82030874b1bb14d24d07108413",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1858,13 +1907,15 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.23-dev"
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Carbon\\Laravel\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Carbon\\": "src/Carbon/"
|
||||
"": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@ -1885,7 +1936,7 @@
|
||||
"datetime",
|
||||
"time"
|
||||
],
|
||||
"time": "2018-03-19T15:50:49+00:00"
|
||||
"time": "2018-08-07T08:39:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
@ -1951,33 +2002,29 @@
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v2.0.17",
|
||||
"version": "v9.99.99",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "29af24f25bab834fcbb38ad2a69fa93b867e070d"
|
||||
"reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/29af24f25bab834fcbb38ad2a69fa93b867e070d",
|
||||
"reference": "29af24f25bab834fcbb38ad2a69fa93b867e070d",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
|
||||
"reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
"php": "^7"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
"phpunit/phpunit": "4.*|5.*",
|
||||
"vimeo/psalm": "^1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/random.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
@ -1996,7 +2043,7 @@
|
||||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"time": "2018-07-04T16:31:37+00:00"
|
||||
"time": "2018-07-02T15:55:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
@ -2500,22 +2547,22 @@
|
||||
},
|
||||
{
|
||||
"name": "rcrowe/twigbridge",
|
||||
"version": "v0.9.6",
|
||||
"version": "v0.9.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rcrowe/TwigBridge.git",
|
||||
"reference": "c3579440a3ca47ca45bfb0ed854bc0ff9b086bf5"
|
||||
"reference": "d0c998ae6d39f154c4e2d01ef914e49d0b7d5d68"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/c3579440a3ca47ca45bfb0ed854bc0ff9b086bf5",
|
||||
"reference": "c3579440a3ca47ca45bfb0ed854bc0ff9b086bf5",
|
||||
"url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/d0c998ae6d39f154c4e2d01ef914e49d0b7d5d68",
|
||||
"reference": "d0c998ae6d39f154c4e2d01ef914e49d0b7d5d68",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*",
|
||||
"illuminate/view": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*",
|
||||
"php": ">=5.4.0",
|
||||
"illuminate/support": "5.5.*|5.6.*|5.7.*",
|
||||
"illuminate/view": "5.5.*|5.6.*|5.7.*",
|
||||
"php": ">=7",
|
||||
"twig/twig": "~1.30"
|
||||
},
|
||||
"require-dev": {
|
||||
@ -2568,20 +2615,20 @@
|
||||
"laravel",
|
||||
"twig"
|
||||
],
|
||||
"time": "2018-02-08T15:59:23+00:00"
|
||||
"time": "2018-08-31T13:30:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v6.1.2",
|
||||
"version": "v6.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||
"reference": "7d760881d266d63c5e7a1155cbcf2ac656a31ca8"
|
||||
"reference": "8ddcb66ac10c392d3beb54829eef8ac1438595f4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/7d760881d266d63c5e7a1155cbcf2ac656a31ca8",
|
||||
"reference": "7d760881d266d63c5e7a1155cbcf2ac656a31ca8",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8ddcb66ac10c392d3beb54829eef8ac1438595f4",
|
||||
"reference": "8ddcb66ac10c392d3beb54829eef8ac1438595f4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2627,7 +2674,7 @@
|
||||
"mail",
|
||||
"mailer"
|
||||
],
|
||||
"time": "2018-07-13T07:04:35+00:00"
|
||||
"time": "2018-09-11T07:12:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
@ -3835,16 +3882,16 @@
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zend-diactoros",
|
||||
"version": "1.8.5",
|
||||
"version": "1.8.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zendframework/zend-diactoros.git",
|
||||
"reference": "3e4edb822c942f37ade0d09579cfbab11e2fee87"
|
||||
"reference": "20da13beba0dde8fb648be3cc19765732790f46e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/3e4edb822c942f37ade0d09579cfbab11e2fee87",
|
||||
"reference": "3e4edb822c942f37ade0d09579cfbab11e2fee87",
|
||||
"url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/20da13beba0dde8fb648be3cc19765732790f46e",
|
||||
"reference": "20da13beba0dde8fb648be3cc19765732790f46e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3857,6 +3904,7 @@
|
||||
"require-dev": {
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"php-http/psr7-integration-tests": "dev-master",
|
||||
"phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7",
|
||||
"zendframework/zend-coding-standard": "~1.0"
|
||||
},
|
||||
@ -3894,22 +3942,22 @@
|
||||
"psr",
|
||||
"psr-7"
|
||||
],
|
||||
"time": "2018-08-10T14:16:32+00:00"
|
||||
"time": "2018-09-05T19:29:37+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "barryvdh/laravel-ide-helper",
|
||||
"version": "v2.5.0",
|
||||
"version": "v2.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/laravel-ide-helper.git",
|
||||
"reference": "09db8c9a76711e98c61af0795934fb15955223fb"
|
||||
"reference": "7db1843473e1562d8e0490b51db847d3a1415140"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/09db8c9a76711e98c61af0795934fb15955223fb",
|
||||
"reference": "09db8c9a76711e98c61af0795934fb15955223fb",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/7db1843473e1562d8e0490b51db847d3a1415140",
|
||||
"reference": "7db1843473e1562d8e0490b51db847d3a1415140",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3970,7 +4018,7 @@
|
||||
"phpstorm",
|
||||
"sublime"
|
||||
],
|
||||
"time": "2018-08-31T13:28:09+00:00"
|
||||
"time": "2018-09-06T18:41:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/reflection-docblock",
|
||||
@ -4380,16 +4428,16 @@
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
"version": "2.2.0",
|
||||
"version": "2.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/filp/whoops.git",
|
||||
"reference": "181c4502d8f34db7aed7bfe88d4f87875b8e947a"
|
||||
"reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/181c4502d8f34db7aed7bfe88d4f87875b8e947a",
|
||||
"reference": "181c4502d8f34db7aed7bfe88d4f87875b8e947a",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/e79cd403fb77fc8963a99ecc30e80ddd885b3311",
|
||||
"reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4408,7 +4456,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1-dev"
|
||||
"dev-master": "2.2-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -4437,7 +4485,7 @@
|
||||
"throwable",
|
||||
"whoops"
|
||||
],
|
||||
"time": "2018-03-03T17:56:25+00:00"
|
||||
"time": "2018-06-30T13:14:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fzaninotto/faker",
|
||||
@ -5230,21 +5278,24 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
||||
"reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c"
|
||||
"reference": "050bedf145a257b1ff02746c31894800e5122946"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cecbc684605bb0cc288828eb5d65d93d5c676d3c",
|
||||
"reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
|
||||
"reference": "050bedf145a257b1ff02746c31894800e5122946",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
@ -5273,7 +5324,7 @@
|
||||
"filesystem",
|
||||
"iterator"
|
||||
],
|
||||
"time": "2018-06-11T11:44:00+00:00"
|
||||
"time": "2018-09-13T20:33:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-text-template",
|
||||
@ -5416,16 +5467,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "7.3.3",
|
||||
"version": "7.3.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "1bd5629cccfb2c0a9ef5474b4ff772349e1ec898"
|
||||
"reference": "7b331efabbb628c518c408fdfcaf571156775de2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1bd5629cccfb2c0a9ef5474b4ff772349e1ec898",
|
||||
"reference": "1bd5629cccfb2c0a9ef5474b4ff772349e1ec898",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7b331efabbb628c518c408fdfcaf571156775de2",
|
||||
"reference": "7b331efabbb628c518c408fdfcaf571156775de2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -5496,7 +5547,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2018-09-01T15:49:55+00:00"
|
||||
"time": "2018-09-08T15:14:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "roave/security-advisories",
|
||||
@ -5508,6 +5559,7 @@
|
||||
"amphp/http": "<1.0.1",
|
||||
"asymmetricrypt/asymmetricrypt": ">=0,<9.9.99",
|
||||
"aws/aws-sdk-php": ">=3,<3.2.1",
|
||||
"brightlocal/phpwhois": "<=4.2.5",
|
||||
"bugsnag/bugsnag-laravel": ">=2,<2.0.2",
|
||||
"cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.0.15|>=3.1,<3.1.4|>=3.4,<3.4.14|>=3.5,<3.5.17|>=3.6,<3.6.4",
|
||||
"cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4",
|
||||
@ -5519,6 +5571,7 @@
|
||||
"contao/core-bundle": ">=4,<4.4.18|>=4.5,<4.5.8",
|
||||
"contao/listing-bundle": ">=4,<4.4.8",
|
||||
"contao/newsletter-bundle": ">=4,<4.1",
|
||||
"david-garcia/phpwhois": "<=4.3.1",
|
||||
"doctrine/annotations": ">=1,<1.2.7",
|
||||
"doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2",
|
||||
"doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1",
|
||||
@ -5533,6 +5586,7 @@
|
||||
"drupal/drupal": ">=7,<7.59|>=8,<8.4.8|>=8.5,<8.5.3",
|
||||
"erusev/parsedown": "<1.7",
|
||||
"ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.3|>=5.4,<5.4.11.3|>=2017.8,<2017.8.1.1|>=2017.12,<2017.12.2.1",
|
||||
"ezyang/htmlpurifier": "<4.1.1",
|
||||
"firebase/php-jwt": "<2",
|
||||
"friendsofsymfony/rest-bundle": ">=1.2,<1.2.2",
|
||||
"friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
|
||||
@ -5544,7 +5598,11 @@
|
||||
"illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30",
|
||||
"illuminate/database": ">=4,<4.0.99|>=4.1,<4.1.29",
|
||||
"illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15",
|
||||
"ivankristianto/phpwhois": "<=4.3",
|
||||
"james-heinrich/getid3": "<1.9.9",
|
||||
"joomla/session": "<1.3.1",
|
||||
"jsmitty12/phpwhois": "<5.1",
|
||||
"kazist/phpwhois": "<=4.2.6",
|
||||
"kreait/firebase-php": ">=3.2,<3.8.1",
|
||||
"laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30",
|
||||
"laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
|
||||
@ -5554,6 +5612,7 @@
|
||||
"monolog/monolog": ">=1.8,<1.12",
|
||||
"namshi/jose": "<2.2",
|
||||
"onelogin/php-saml": "<2.10.4",
|
||||
"openid/php-openid": "<2.3",
|
||||
"oro/crm": ">=1.7,<1.7.4",
|
||||
"oro/platform": ">=1.7,<1.7.4",
|
||||
"padraic/humbug_get_contents": "<1.1.2",
|
||||
@ -5562,21 +5621,25 @@
|
||||
"paypal/merchant-sdk-php": "<3.12",
|
||||
"phpmailer/phpmailer": ">=5,<5.2.24",
|
||||
"phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3",
|
||||
"phpwhois/phpwhois": "<=4.2.5",
|
||||
"phpxmlrpc/extras": "<0.6.1",
|
||||
"propel/propel": ">=2.0.0-alpha1,<=2.0.0-alpha7",
|
||||
"propel/propel1": ">=1,<=1.7.1",
|
||||
"pusher/pusher-php-server": "<2.2.1",
|
||||
"sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9",
|
||||
"sensiolabs/connect": "<4.2.3",
|
||||
"serluck/phpwhois": "<=4.2.6",
|
||||
"shopware/shopware": "<5.3.7",
|
||||
"silverstripe/cms": ">=3,<=3.0.11|>=3.1,<3.1.11",
|
||||
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
|
||||
"silverstripe/framework": ">=3,<3.3",
|
||||
"silverstripe/userforms": "<3",
|
||||
"simple-updates/phpwhois": "<=1",
|
||||
"simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4",
|
||||
"simplesamlphp/simplesamlphp": "<1.15.2",
|
||||
"simplesamlphp/simplesamlphp-module-infocard": "<1.0.1",
|
||||
"slim/slim": "<2.6",
|
||||
"smarty/smarty": "<3.1.33",
|
||||
"socalnick/scn-social-auth": "<1.15.2",
|
||||
"squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1",
|
||||
"stormpath/sdk": ">=0,<9.9.99",
|
||||
@ -5603,8 +5666,10 @@
|
||||
"symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
|
||||
"symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
|
||||
"thelia/backoffice-default-template": ">=2.1,<2.1.2",
|
||||
"thelia/thelia": ">=2.1,<2.1.2|>=2.1.0-beta1,<2.1.3",
|
||||
"thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2",
|
||||
"theonedemon/phpwhois": "<=4.2.5",
|
||||
"titon/framework": ">=0,<9.9.99",
|
||||
"truckersmp/phpwhois": "<=4.3.1",
|
||||
"twig/twig": "<1.20",
|
||||
"typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.30|>=8,<8.7.17|>=9,<9.3.2",
|
||||
"typo3/cms-core": ">=8,<8.7.17|>=9,<9.3.2",
|
||||
@ -5657,7 +5722,7 @@
|
||||
}
|
||||
],
|
||||
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
|
||||
"time": "2018-08-14T15:39:17+00:00"
|
||||
"time": "2018-09-17T20:20:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit-reverse-lookup",
|
||||
@ -6636,7 +6701,7 @@
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=7.1.0",
|
||||
"php": ">=7.2.0",
|
||||
"ext-bcmath": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-gd": "*",
|
||||
|
@ -31,6 +31,7 @@ return [
|
||||
'4.7.3' => 'This version of Firefly III handles bills differently. See http://bit.ly/FF3-new-bills for more information.',
|
||||
'4.7.4' => 'This version of Firefly III has a new import routine. See http://bit.ly/FF3-new-import for more information.',
|
||||
'4.7.6' => 'This will be the last version to require PHP7.1. Future versions will require PHP7.2 minimum.',
|
||||
'4.7.7' => 'This version of Firefly III requires PHP7.2.',
|
||||
],
|
||||
'install' =>
|
||||
[
|
||||
@ -40,6 +41,7 @@ return [
|
||||
'4.7.3' => 'This version of Firefly III handles bills differently. See http://bit.ly/FF3-new-bills for more information.',
|
||||
'4.7.4' => 'This version of Firefly III has a new import routine. See http://bit.ly/FF3-new-import for more information.',
|
||||
'4.7.6' => 'This will be the last version to require PHP7.1. Future versions will require PHP7.2 minimum.',
|
||||
'4.7.7' => 'This version of Firefly III requires PHP7.2.',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
@ -28,7 +28,7 @@ use Illuminate\Database\Seeder;
|
||||
*/
|
||||
class AccountTypeSeeder extends Seeder
|
||||
{
|
||||
public function run()
|
||||
public function run(): void
|
||||
{
|
||||
$types = [
|
||||
AccountType::DEFAULT,
|
||||
@ -42,8 +42,7 @@ class AccountTypeSeeder extends Seeder
|
||||
AccountType::LOAN,
|
||||
AccountType::RECONCILIATION,
|
||||
AccountType::DEBT,
|
||||
AccountType::MORTGAGE,
|
||||
AccountType::CREDITCARD,
|
||||
AccountType::MORTGAGE
|
||||
];
|
||||
foreach ($types as $type) {
|
||||
try {
|
||||
|
@ -65,6 +65,9 @@ class TransactionCurrencySeeder extends Seeder
|
||||
$currencies[] = ['code' => 'BCH', 'name' => 'Bitcoin cash', 'symbol' => '₿C', 'decimal_places' => 8];
|
||||
$currencies[] = ['code' => 'ETH', 'name' => 'Ethereum', 'symbol' => 'Ξ', 'decimal_places' => 12];
|
||||
|
||||
// PLEASE ADD NEW CURRENCIES BELOW THIS LINE
|
||||
$currencies[] = ['code' => 'ILS', 'name' => 'Israeli new shekel', 'symbol' => '₪', 'decimal_places' => 2];
|
||||
|
||||
foreach ($currencies as $currency) {
|
||||
try {
|
||||
TransactionCurrency::create($currency);
|
||||
|
12
public/css/bootstrap-tagsinput.css
vendored
12
public/css/bootstrap-tagsinput.css
vendored
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* bootstrap-tagsinput v0.8.0
|
||||
* bootstrap-tagsinput v0.9.1
|
||||
*
|
||||
*/
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
line-height: 22px;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput input {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
@ -27,44 +26,35 @@
|
||||
width: auto;
|
||||
max-width: inherit;
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput.form-control input::-moz-placeholder {
|
||||
color: #777;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput.form-control input:-ms-input-placeholder {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput.form-control input::-webkit-input-placeholder {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput input:focus {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput .tag {
|
||||
margin-right: 2px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput .tag [data-role="remove"] {
|
||||
margin-left: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput .tag [data-role="remove"]:after {
|
||||
content: "x";
|
||||
padding: 0px 2px;
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput .tag [data-role="remove"]:hover {
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput .tag [data-role="remove"]:hover:active {
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||
}
|
||||
|
74
public/css/firefly.css
vendored
74
public/css/firefly.css
vendored
@ -170,3 +170,77 @@ span.info-box-text a:hover, span.info-box-number a:hover {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.bootstrap-tagsinput {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.accordion {
|
||||
margin-bottom:-3px;
|
||||
}
|
||||
|
||||
.accordion-group {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.twitter-typeahead {
|
||||
width:100%;
|
||||
}
|
||||
span.twitter-typeahead {
|
||||
display: inline !important;width:100%;
|
||||
|
||||
}
|
||||
.tt-input {
|
||||
background-color:#fff !important;
|
||||
}
|
||||
|
||||
|
||||
.twitter-typeahead .tt-query,
|
||||
.twitter-typeahead .tt-hint {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.twitter-typeahead .tt-hint
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tt-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
float: left;
|
||||
min-width: 160px;
|
||||
padding: 5px 0;
|
||||
margin: 2px 0 0;
|
||||
list-style: none;
|
||||
font-size: 14px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #cccccc;
|
||||
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||
background-clip: padding-box;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tt-suggestion {
|
||||
display: block;
|
||||
padding: 3px 20px;
|
||||
clear: both;
|
||||
font-weight: normal;
|
||||
line-height: 1.428571429;
|
||||
color: #333333;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tt-suggestion:hover,
|
||||
.tt-suggestion:focus {
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
outline: 0;
|
||||
background-color: #428bca;
|
||||
}
|
23
public/js/ff/accounts/edit-reconciliation.js
vendored
23
public/js/ff/accounts/edit-reconciliation.js
vendored
@ -18,8 +18,6 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** global: what, Modernizr, selectsForeignCurrency, convertForeignToNative, validateCurrencyForTransfer, convertSourceToDestination, journalData, journal, accountInfo, exchangeRateInstructions, currencyInfo */
|
||||
|
||||
$(document).ready(function () {
|
||||
"use strict";
|
||||
setAutocompletes();
|
||||
@ -30,24 +28,7 @@ $(document).ready(function () {
|
||||
* Set the auto-complete JSON things.
|
||||
*/
|
||||
function setAutocompletes() {
|
||||
|
||||
$.getJSON('json/categories').done(function (data) {
|
||||
$('input[name="category"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
|
||||
$.getJSON('json/tags').done(function (data) {
|
||||
var opt = {
|
||||
typeahead: {
|
||||
source: data,
|
||||
afterSelect: function () {
|
||||
this.$element.val("");
|
||||
},
|
||||
autoSelect: false,
|
||||
}
|
||||
};
|
||||
$('input[name="tags"]').tagsinput(
|
||||
opt
|
||||
);
|
||||
});
|
||||
initCategoryAC();
|
||||
initTagsAC();
|
||||
}
|
||||
|
||||
|
165
public/js/ff/common/autocomplete.js
vendored
Normal file
165
public/js/ff/common/autocomplete.js
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* autocomplete.js
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Do tags auto complete.
|
||||
*/
|
||||
function initTagsAC() {
|
||||
console.log('initTagsAC()');
|
||||
var tagTags = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/tags',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (tagTag) {
|
||||
return {name: tagTag};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/tags?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
tagTags.initialize();
|
||||
$('input[name="tags"]').tagsinput({
|
||||
typeaheadjs: {
|
||||
hint: true,
|
||||
highlight: true,
|
||||
name: 'tags',
|
||||
displayKey: 'name',
|
||||
valueKey: 'name',
|
||||
source: tagTags.ttAdapter()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Do destination name (expense accounts) auto complete.
|
||||
*/
|
||||
function initExpenseAC() {
|
||||
initExpenseACField('destination_name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Do destination name (expense accounts) auto complete.
|
||||
*/
|
||||
function initExpenseACField(fieldName) {
|
||||
console.log('initExpenseACField("' + fieldName + '")');
|
||||
if ($('input[name="' + fieldName + '"]').length > 0) {
|
||||
var destNames = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/expense-accounts',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/expense-accounts?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
destNames.initialize();
|
||||
$('input[name="' + fieldName + '"]').typeahead({hint: true, highlight: true,}, {source: destNames, displayKey: 'name', autoSelect: false});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do source name (revenue accounts) auto complete.
|
||||
*/
|
||||
function initRevenueAC() {
|
||||
initRevenueACField('source_name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Do source name (revenue accounts) auto complete.
|
||||
*/
|
||||
function initRevenueACField(fieldName) {
|
||||
console.log('initRevenueACField("' + fieldName + '")');
|
||||
if ($('input[name="' + fieldName + '"]').length > 0) {
|
||||
var sourceNames = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/revenue-accounts',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/revenue-accounts?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
sourceNames.initialize();
|
||||
$('input[name="' + fieldName + '"]').typeahead({hint: true, highlight: true,}, {source: sourceNames, displayKey: 'name', autoSelect: false});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do categories auto complete.
|
||||
*/
|
||||
function initCategoryAC() {
|
||||
var categories = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/categories',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/categories?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
categories.initialize();
|
||||
$('input[name="category"]').typeahead({hint: true, highlight: true,}, {source: categories, displayKey: 'name', autoSelect: false});
|
||||
}
|
37
public/js/ff/recurring/create.js
vendored
37
public/js/ff/recurring/create.js
vendored
@ -137,39 +137,10 @@ function parseRepetitionSuggestions(data) {
|
||||
}
|
||||
|
||||
function initializeAutoComplete() {
|
||||
// auto complete things:
|
||||
$.getJSON('json/tags').done(function (data) {
|
||||
var opt = {
|
||||
typeahead: {
|
||||
source: data,
|
||||
afterSelect: function () {
|
||||
this.$element.val("");
|
||||
},
|
||||
autoSelect: false,
|
||||
},
|
||||
autoSelect: false,
|
||||
};
|
||||
|
||||
$('input[name="tags"]').tagsinput(
|
||||
opt
|
||||
);
|
||||
});
|
||||
|
||||
if ($('input[name="destination_name"]').length > 0) {
|
||||
$.getJSON('json/expense-accounts').done(function (data) {
|
||||
$('input[name="destination_name"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
}
|
||||
|
||||
if ($('input[name="source_name"]').length > 0) {
|
||||
$.getJSON('json/revenue-accounts').done(function (data) {
|
||||
$('input[name="source_name"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
}
|
||||
|
||||
$.getJSON('json/categories').done(function (data) {
|
||||
$('input[name="category"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
initTagsAC();
|
||||
initExpenseAC();
|
||||
initRevenueAC();
|
||||
initCategoryAC();
|
||||
}
|
||||
|
||||
/**
|
||||
|
45
public/js/ff/recurring/edit.js
vendored
45
public/js/ff/recurring/edit.js
vendored
@ -109,11 +109,11 @@ function respondToFirstDateChange() {
|
||||
|
||||
// preselected value:
|
||||
var preSelected = currentRepType;
|
||||
if(preSelected === '') {
|
||||
if (preSelected === '') {
|
||||
preSelected = select.val();
|
||||
}
|
||||
|
||||
$.getJSON(suggestUri, {date: date,pre_select: preSelected,past:true}).fail(function () {
|
||||
$.getJSON(suggestUri, {date: date, pre_select: preSelected, past: true}).fail(function () {
|
||||
console.error('Could not load repetition suggestions');
|
||||
alert('Could not load repetition suggestions');
|
||||
}).done(parseRepetitionSuggestions);
|
||||
@ -128,8 +128,8 @@ function parseRepetitionSuggestions(data) {
|
||||
if (data.hasOwnProperty(k)) {
|
||||
console.log('label: ' + data[k].label + ', selected: ' + data[k].selected);
|
||||
opt = $('<option>').val(k).attr('label', data[k].label).text(data[k].label);
|
||||
if(data[k].selected) {
|
||||
opt.attr('selected','selected');
|
||||
if (data[k].selected) {
|
||||
opt.attr('selected', 'selected');
|
||||
}
|
||||
select.append(opt);
|
||||
}
|
||||
@ -138,39 +138,10 @@ function parseRepetitionSuggestions(data) {
|
||||
}
|
||||
|
||||
function initializeAutoComplete() {
|
||||
// auto complete things:
|
||||
$.getJSON('json/tags').done(function (data) {
|
||||
var opt = {
|
||||
typeahead: {
|
||||
source: data,
|
||||
afterSelect: function () {
|
||||
this.$element.val("");
|
||||
},
|
||||
autoSelect: false,
|
||||
},
|
||||
autoSelect: false,
|
||||
};
|
||||
|
||||
$('input[name="tags"]').tagsinput(
|
||||
opt
|
||||
);
|
||||
});
|
||||
|
||||
if ($('input[name="destination_name"]').length > 0) {
|
||||
$.getJSON('json/expense-accounts').done(function (data) {
|
||||
$('input[name="destination_name"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
}
|
||||
|
||||
if ($('input[name="source_name"]').length > 0) {
|
||||
$.getJSON('json/revenue-accounts').done(function (data) {
|
||||
$('input[name="source_name"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
}
|
||||
|
||||
$.getJSON('json/categories').done(function (data) {
|
||||
$('input[name="category"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
initTagsAC();
|
||||
initExpenseAC();
|
||||
initRevenueAC();
|
||||
initCategoryAC();
|
||||
}
|
||||
|
||||
/**
|
||||
|
31
public/js/ff/rules/create-edit.js
vendored
31
public/js/ff/rules/create-edit.js
vendored
@ -360,15 +360,32 @@ function updateTriggerInput(selectList) {
|
||||
* @param URI
|
||||
*/
|
||||
function createAutoComplete(input, URI) {
|
||||
console.log('Now in createAutoComplete().')
|
||||
console.log('Now in createAutoComplete("' + URI + '").');
|
||||
input.typeahead('destroy');
|
||||
$.getJSON(URI).done(function (data) {
|
||||
console.log('Input now has auto complete from URI ' + URI);
|
||||
input.typeahead({source: data, autoSelect: false});
|
||||
}).fail(function () {
|
||||
console.log('Could not grab URI ' + URI + ' so autocomplete will not work');
|
||||
});
|
||||
|
||||
var source = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: URI,
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: URI + '?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
source.initialize();
|
||||
input.typeahead({hint: true, highlight: true,}, {source: source, displayKey: 'name', autoSelect: false});
|
||||
}
|
||||
|
||||
function testRuleTriggers() {
|
||||
|
34
public/js/ff/transactions/convert.js
vendored
Normal file
34
public/js/ff/transactions/convert.js
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* convert.js
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
$(document).ready(function () {
|
||||
"use strict";
|
||||
setAutocompletes();
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Set the auto-complete JSON things.
|
||||
*/
|
||||
function setAutocompletes() {
|
||||
initRevenueACField('source_account_revenue');
|
||||
initExpenseACField('destination_account_expense');
|
||||
}
|
||||
|
6
public/js/ff/transactions/list.js
vendored
6
public/js/ff/transactions/list.js
vendored
@ -67,7 +67,7 @@ function goToMassEdit() {
|
||||
baseHref = bases[0].href;
|
||||
}
|
||||
|
||||
window.location.href = baseHref + '/transactions/mass/edit/' + checkedArray;
|
||||
window.location.href = baseHref + 'transactions/mass/edit/' + checkedArray;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ function goToBulkEdit() {
|
||||
baseHref = bases[0].href;
|
||||
}
|
||||
|
||||
window.location.href = baseHref + '/transactions/bulk/edit/' + checkedArray;
|
||||
window.location.href = baseHref + 'transactions/bulk/edit/' + checkedArray;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ function goToMassDelete() {
|
||||
if (bases.length > 0) {
|
||||
baseHref = bases[0].href;
|
||||
}
|
||||
window.location.href = baseHref + '/transactions/mass/delete/' + checkedArray;
|
||||
window.location.href = baseHref + 'transactions/mass/delete/' + checkedArray;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
19
public/js/ff/transactions/mass/edit-bulk.js
vendored
19
public/js/ff/transactions/mass/edit-bulk.js
vendored
@ -22,21 +22,6 @@
|
||||
|
||||
$(document).ready(function () {
|
||||
"use strict";
|
||||
|
||||
$.getJSON('json/categories').done(function (data) {
|
||||
$('input[name="category"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
|
||||
$.getJSON('json/tags').done(function (data) {
|
||||
var opt = {
|
||||
source: data,
|
||||
afterSelect: function () {
|
||||
this.$element.val("");
|
||||
},
|
||||
autoSelect: false
|
||||
};
|
||||
$('input[name="tags"]').tagsinput(
|
||||
opt
|
||||
);
|
||||
});
|
||||
initTagsAC();
|
||||
initCategoryAC();
|
||||
});
|
78
public/js/ff/transactions/mass/edit.js
vendored
78
public/js/ff/transactions/mass/edit.js
vendored
@ -25,19 +25,83 @@ $(document).ready(function () {
|
||||
|
||||
// destination account names:
|
||||
if ($('input[name^="destination_name["]').length > 0) {
|
||||
$.getJSON('json/expense-accounts').done(function (data) {
|
||||
$('input[name^="destination_name["]').typeahead({source: data, autoSelect: false});
|
||||
var destNames = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/expense-accounts',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/expense-accounts?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
destNames.initialize();
|
||||
$('input[name^="destination_name["]').typeahead({hint: true, highlight: true,}, {source: destNames, displayKey: 'name', autoSelect: false});
|
||||
}
|
||||
|
||||
// source account name
|
||||
if ($('input[name^="source_name["]').length > 0) {
|
||||
$.getJSON('json/revenue-accounts').done(function (data) {
|
||||
$('input[name^="source_name["]').typeahead({source: data, autoSelect: false});
|
||||
|
||||
var sourceNames = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/revenue-accounts',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
|
||||
$.getJSON('json/categories').done(function (data) {
|
||||
$('input[name^="category["]').typeahead({source: data, autoSelect: false});
|
||||
},
|
||||
remote: {
|
||||
url: 'json/revenue-accounts?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
sourceNames.initialize();
|
||||
|
||||
$('input[name^="source_name["]').typeahead({hint: true, highlight: true,}, {source: sourceNames, displayKey: 'name', autoSelect: false});
|
||||
}
|
||||
|
||||
var categories = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/categories',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/categories?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
categories.initialize();
|
||||
|
||||
$('input[name^="category["]').typeahead({hint: true, highlight: true,}, {source: categories, displayKey: 'name', autoSelect: false});
|
||||
|
||||
});
|
41
public/js/ff/transactions/show.js
vendored
41
public/js/ff/transactions/show.js
vendored
@ -22,19 +22,37 @@
|
||||
|
||||
$(function () {
|
||||
"use strict";
|
||||
|
||||
|
||||
$.getJSON(autoCompleteUri).done(function (data) {
|
||||
var $input = $("#link_other");
|
||||
$input.typeahead({
|
||||
source: data,
|
||||
autoSelect: true
|
||||
var transactions = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: autoCompleteUri,
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
$input.change(function () {
|
||||
var current = $input.typeahead("getActive");
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: autoCompleteUri + '?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
transactions.initialize();
|
||||
var input=$("#link_other");
|
||||
input.typeahead({hint: true, highlight: true,}, {source: transactions, displayKey: 'name', autoSelect: false});
|
||||
|
||||
input.change(function () {
|
||||
var current = input.typeahead("getActive");
|
||||
if (current) {
|
||||
// Some item from your model is active!
|
||||
if (current.name.toLowerCase() === $input.val().toLowerCase()) {
|
||||
if (current.name.toLowerCase() ===
|
||||
input.val().toLowerCase()) {
|
||||
// This means the exact match is found. Use toLowerCase() if you want case insensitive match.
|
||||
$('input[name="link_journal_id"]').val(current.id);
|
||||
} else {
|
||||
@ -44,7 +62,4 @@ $(function () {
|
||||
$('input[name="link_journal_id"]').val(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
40
public/js/ff/transactions/single/common.js
vendored
40
public/js/ff/transactions/single/common.js
vendored
@ -47,39 +47,17 @@ function runModernizer() {
|
||||
*/
|
||||
function setCommonAutocomplete() {
|
||||
console.log('In setCommonAutoComplete()');
|
||||
$.getJSON('json/tags').done(function (data) {
|
||||
var opt = {
|
||||
typeahead: {
|
||||
source: data,
|
||||
afterSelect: function () {
|
||||
this.$element.val("");
|
||||
},
|
||||
autoSelect: false,
|
||||
},
|
||||
autoSelect: false,
|
||||
};
|
||||
|
||||
$('input[name="tags"]').tagsinput(
|
||||
opt
|
||||
);
|
||||
});
|
||||
// do tags auto complete:
|
||||
initTagsAC();
|
||||
// do destination name (expense accounts):
|
||||
initExpenseAC();
|
||||
|
||||
// do source name (revenue accounts):
|
||||
initRevenueAC();
|
||||
|
||||
if ($('input[name="destination_name"]').length > 0) {
|
||||
$.getJSON('json/expense-accounts').done(function (data) {
|
||||
$('input[name="destination_name"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
}
|
||||
|
||||
if ($('input[name="source_name"]').length > 0) {
|
||||
$.getJSON('json/revenue-accounts').done(function (data) {
|
||||
$('input[name="source_name"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
}
|
||||
|
||||
$.getJSON('json/categories').done(function (data) {
|
||||
$('input[name="category"]').typeahead({source: data, autoSelect: false});
|
||||
});
|
||||
// do categories auto complete:
|
||||
initCategoryAC();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,7 +86,7 @@ function selectsForeignCurrency() {
|
||||
|
||||
// both holders are shown to the user:
|
||||
$('#exchange_rate_instruction_holder').show();
|
||||
if(what !== 'transfer') {
|
||||
if (what !== 'transfer') {
|
||||
console.log('Show native amount holder.');
|
||||
$('#native_amount_holder').show();
|
||||
}
|
||||
|
28
public/js/ff/transactions/single/create.js
vendored
28
public/js/ff/transactions/single/create.js
vendored
@ -60,7 +60,7 @@ $(document).ready(function () {
|
||||
|
||||
|
||||
// overrule click on currency:
|
||||
if(useAccountCurrency === false) {
|
||||
if (useAccountCurrency === false) {
|
||||
$('.currency-option[data-id="' + overruleCurrency + '"]').click();
|
||||
$('[data-toggle="dropdown"]').parent().removeClass('open');
|
||||
}
|
||||
@ -136,9 +136,31 @@ function getExchangeInstructions() {
|
||||
*
|
||||
*/
|
||||
function updateDescription() {
|
||||
$.getJSON('json/transaction-journals/' + what).done(function (data) {
|
||||
$('input[name="description"]').typeahead('destroy').typeahead({source: data, autoSelect: false});
|
||||
|
||||
// do description auto complete:
|
||||
var journalNames = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/transaction-journals/' + what,
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/transaction-journals/' + what + '?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
journalNames.initialize();
|
||||
$('input[name="description"]').typeahead('destroy').typeahead({hint: true, highlight: true,}, {source: journalNames, displayKey: 'name', autoSelect: false});
|
||||
$('#ffInput_description').focus();
|
||||
}
|
||||
|
||||
|
26
public/js/ff/transactions/single/edit.js
vendored
26
public/js/ff/transactions/single/edit.js
vendored
@ -148,9 +148,31 @@ function getAccountId() {
|
||||
* Set the auto-complete JSON things.
|
||||
*/
|
||||
function setAutocompletes() {
|
||||
$.getJSON('json/transaction-journals/' + what).done(function (data) {
|
||||
$('input[name="description"]').typeahead({source: data, autoSelect: false});
|
||||
|
||||
// do description auto complete:
|
||||
var journalNames = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/transaction-journals/' + what,
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/transaction-journals/' + what + '?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
journalNames.initialize();
|
||||
$('input[name="description"]').typeahead({hint: true, highlight: true,}, {source: journalNames, displayKey: 'name', autoSelect: false});
|
||||
}
|
||||
|
||||
/**
|
||||
|
189
public/js/ff/transactions/split/edit.js
vendored
189
public/js/ff/transactions/split/edit.js
vendored
@ -21,53 +21,152 @@
|
||||
|
||||
/** global: originalSum,originalForeignSum, accounting, what, Modernizr, currencySymbol, foreignCurrencySymbol */
|
||||
|
||||
var destAccounts = {};
|
||||
var srcAccounts = {};
|
||||
var categories = {};
|
||||
var descriptions = {};
|
||||
var destNames;
|
||||
var sourceNames;
|
||||
var categories;
|
||||
var journalNames;
|
||||
|
||||
$(document).ready(function () {
|
||||
"use strict";
|
||||
$('.btn-do-split').click(cloneDivRow);
|
||||
$('.remove-current-split').click(removeDivRow);
|
||||
|
||||
$.getJSON('json/expense-accounts').done(function (data) {
|
||||
destAccounts = data;
|
||||
$('input[name$="destination_name]"]').typeahead({source: destAccounts, autoSelect: false});
|
||||
// auto complete destination name (expense accounts):
|
||||
destNames = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/expense-accounts',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
|
||||
$.getJSON('json/revenue-accounts').done(function (data) {
|
||||
srcAccounts = data;
|
||||
$('input[name$="source_name]"]').typeahead({source: srcAccounts, autoSelect: false});
|
||||
});
|
||||
|
||||
$.getJSON('json/categories').done(function (data) {
|
||||
categories = data;
|
||||
$('input[name$="category_name]"]').typeahead({source: categories, autoSelect: false});
|
||||
});
|
||||
|
||||
$.getJSON('json/transaction-journals/' + what).done(function (data) {
|
||||
descriptions = data;
|
||||
$('input[name="journal_description"]').typeahead({source: descriptions, autoSelect: false});
|
||||
$('input[name$="transaction_description]"]').typeahead({source: descriptions, autoSelect: false});
|
||||
});
|
||||
|
||||
$.getJSON('json/tags').done(function (data) {
|
||||
|
||||
var opt = {
|
||||
typeahead: {
|
||||
source: data,
|
||||
afterSelect: function () {
|
||||
this.$element.val("");
|
||||
},
|
||||
autoSelect: false
|
||||
}
|
||||
};
|
||||
$('input[name="tags"]').tagsinput(
|
||||
opt
|
||||
);
|
||||
},
|
||||
remote: {
|
||||
url: 'json/expense-accounts?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
destNames.initialize();
|
||||
$('input[name$="destination_name]"]').typeahead({hint: true, highlight: true,}, {source: destNames, displayKey: 'name', autoSelect: false});
|
||||
|
||||
// auto complete source name (revenue accounts):
|
||||
sourceNames = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/revenue-accounts',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/revenue-accounts?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
sourceNames.initialize();
|
||||
$('input[name$="source_name]"]').typeahead({hint: true, highlight: true,}, {source: sourceNames, displayKey: 'name', autoSelect: false});
|
||||
|
||||
// auto complete category fields:
|
||||
categories = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/categories',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/categories?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
categories.initialize();
|
||||
$('input[name$="category_name]"]').typeahead({hint: true, highlight: true,}, {source: categories, displayKey: 'name', autoSelect: false});
|
||||
|
||||
// get transaction journal name things:
|
||||
journalNames = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/transaction-journals/' + what,
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/transaction-journals/' + what + '?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
journalNames.initialize();
|
||||
|
||||
$('input[name="journal_description"]').typeahead({hint: true, highlight: true,}, {source: journalNames, displayKey: 'name', autoSelect: false});
|
||||
$('input[name$="transaction_description]"]').typeahead({hint: true, highlight: true,}, {source: journalNames, displayKey: 'name', autoSelect: false});
|
||||
|
||||
// get tags:
|
||||
console.log('initTagsAC()');
|
||||
var tagTags = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
prefetch: {
|
||||
url: 'json/tags',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (tagTag) {
|
||||
return {name: tagTag};
|
||||
});
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
url: 'json/tags?search=%QUERY',
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
tagTags.initialize();
|
||||
$('input[name="tags"]').tagsinput({
|
||||
typeaheadjs: {
|
||||
hint: true,
|
||||
highlight: true,
|
||||
name: 'tags',
|
||||
displayKey: 'name',
|
||||
valueKey: 'name',
|
||||
source: tagTags.ttAdapter()
|
||||
}
|
||||
});
|
||||
|
||||
$('input[name$="][amount]"]').on('change', calculateBothSums);
|
||||
$('input[name$="][foreign_amount]"]').on('change', calculateBothSums);
|
||||
@ -128,18 +227,18 @@ function cloneDivRow() {
|
||||
|
||||
source.find('input[name$="][amount]"]').val("").on('change', calculateBothSums);
|
||||
source.find('input[name$="][foreign_amount]"]').val("").on('change', calculateBothSums);
|
||||
if (destAccounts.length > 0) {
|
||||
source.find('input[name$="destination_name]"]').typeahead({source: destAccounts, autoSelect: false});
|
||||
if (destNames) {
|
||||
source.find('input[name$="destination_name]"]').typeahead({hint: true, highlight: true,}, {source: destNames, displayKey: 'name', autoSelect: false});
|
||||
}
|
||||
|
||||
if (srcAccounts.length > 0) {
|
||||
source.find('input[name$="source_name]"]').typeahead({source: srcAccounts, autoSelect: false});
|
||||
if (sourceNames) {
|
||||
source.find('input[name$="source_name]"]').typeahead({hint: true, highlight: true,}, {source: sourceNames, displayKey: 'name', autoSelect: false});
|
||||
}
|
||||
if (categories.length > 0) {
|
||||
source.find('input[name$="category_name]"]').typeahead({source: categories, autoSelect: false});
|
||||
if (categories) {
|
||||
source.find('input[name$="category_name]"]').typeahead({hint: true, highlight: true,}, {source: categories, displayKey: 'name', autoSelect: false});
|
||||
}
|
||||
if (descriptions.length > 0) {
|
||||
source.find('input[name$="transaction_description]"]').typeahead({source: descriptions, autoSelect: false});
|
||||
if (journalNames) {
|
||||
source.find('input[name$="transaction_description]"]').typeahead({hint: true, highlight: true,}, {source: journalNames, displayKey: 'name', autoSelect: false});
|
||||
}
|
||||
|
||||
$('div.split_row_holder').append(source);
|
||||
|
4
public/js/lib/bootstrap-tagsinput.min.js
vendored
4
public/js/lib/bootstrap-tagsinput.min.js
vendored
File diff suppressed because one or more lines are too long
1
public/js/lib/typeahead/.htaccess
Normal file
1
public/js/lib/typeahead/.htaccess
Normal file
@ -0,0 +1 @@
|
||||
Options -Indexes
|
918
public/js/lib/typeahead/bloodhound.js
vendored
Normal file
918
public/js/lib/typeahead/bloodhound.js
vendored
Normal file
@ -0,0 +1,918 @@
|
||||
/*!
|
||||
* typeahead.js 0.11.1
|
||||
* https://github.com/twitter/typeahead.js
|
||||
* Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
|
||||
*/
|
||||
|
||||
(function(root, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define("bloodhound", [ "jquery" ], function(a0) {
|
||||
return root["Bloodhound"] = factory(a0);
|
||||
});
|
||||
} else if (typeof exports === "object") {
|
||||
module.exports = factory(require("jquery"));
|
||||
} else {
|
||||
root["Bloodhound"] = factory(jQuery);
|
||||
}
|
||||
})(this, function($) {
|
||||
var _ = function() {
|
||||
"use strict";
|
||||
return {
|
||||
isMsie: function() {
|
||||
return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
|
||||
},
|
||||
isBlankString: function(str) {
|
||||
return !str || /^\s*$/.test(str);
|
||||
},
|
||||
escapeRegExChars: function(str) {
|
||||
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||
},
|
||||
isString: function(obj) {
|
||||
return typeof obj === "string";
|
||||
},
|
||||
isNumber: function(obj) {
|
||||
return typeof obj === "number";
|
||||
},
|
||||
isArray: $.isArray,
|
||||
isFunction: $.isFunction,
|
||||
isObject: $.isPlainObject,
|
||||
isUndefined: function(obj) {
|
||||
return typeof obj === "undefined";
|
||||
},
|
||||
isElement: function(obj) {
|
||||
return !!(obj && obj.nodeType === 1);
|
||||
},
|
||||
isJQuery: function(obj) {
|
||||
return obj instanceof $;
|
||||
},
|
||||
toStr: function toStr(s) {
|
||||
return _.isUndefined(s) || s === null ? "" : s + "";
|
||||
},
|
||||
bind: $.proxy,
|
||||
each: function(collection, cb) {
|
||||
$.each(collection, reverseArgs);
|
||||
function reverseArgs(index, value) {
|
||||
return cb(value, index);
|
||||
}
|
||||
},
|
||||
map: $.map,
|
||||
filter: $.grep,
|
||||
every: function(obj, test) {
|
||||
var result = true;
|
||||
if (!obj) {
|
||||
return result;
|
||||
}
|
||||
$.each(obj, function(key, val) {
|
||||
if (!(result = test.call(null, val, key, obj))) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return !!result;
|
||||
},
|
||||
some: function(obj, test) {
|
||||
var result = false;
|
||||
if (!obj) {
|
||||
return result;
|
||||
}
|
||||
$.each(obj, function(key, val) {
|
||||
if (result = test.call(null, val, key, obj)) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return !!result;
|
||||
},
|
||||
mixin: $.extend,
|
||||
identity: function(x) {
|
||||
return x;
|
||||
},
|
||||
clone: function(obj) {
|
||||
return $.extend(true, {}, obj);
|
||||
},
|
||||
getIdGenerator: function() {
|
||||
var counter = 0;
|
||||
return function() {
|
||||
return counter++;
|
||||
};
|
||||
},
|
||||
templatify: function templatify(obj) {
|
||||
return $.isFunction(obj) ? obj : template;
|
||||
function template() {
|
||||
return String(obj);
|
||||
}
|
||||
},
|
||||
defer: function(fn) {
|
||||
setTimeout(fn, 0);
|
||||
},
|
||||
debounce: function(func, wait, immediate) {
|
||||
var timeout, result;
|
||||
return function() {
|
||||
var context = this, args = arguments, later, callNow;
|
||||
later = function() {
|
||||
timeout = null;
|
||||
if (!immediate) {
|
||||
result = func.apply(context, args);
|
||||
}
|
||||
};
|
||||
callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
if (callNow) {
|
||||
result = func.apply(context, args);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
},
|
||||
throttle: function(func, wait) {
|
||||
var context, args, timeout, result, previous, later;
|
||||
previous = 0;
|
||||
later = function() {
|
||||
previous = new Date();
|
||||
timeout = null;
|
||||
result = func.apply(context, args);
|
||||
};
|
||||
return function() {
|
||||
var now = new Date(), remaining = wait - (now - previous);
|
||||
context = this;
|
||||
args = arguments;
|
||||
if (remaining <= 0) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
previous = now;
|
||||
result = func.apply(context, args);
|
||||
} else if (!timeout) {
|
||||
timeout = setTimeout(later, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
},
|
||||
stringify: function(val) {
|
||||
return _.isString(val) ? val : JSON.stringify(val);
|
||||
},
|
||||
noop: function() {}
|
||||
};
|
||||
}();
|
||||
var VERSION = "0.11.1";
|
||||
var tokenizers = function() {
|
||||
"use strict";
|
||||
return {
|
||||
nonword: nonword,
|
||||
whitespace: whitespace,
|
||||
obj: {
|
||||
nonword: getObjTokenizer(nonword),
|
||||
whitespace: getObjTokenizer(whitespace)
|
||||
}
|
||||
};
|
||||
function whitespace(str) {
|
||||
str = _.toStr(str);
|
||||
return str ? str.split(/\s+/) : [];
|
||||
}
|
||||
function nonword(str) {
|
||||
str = _.toStr(str);
|
||||
return str ? str.split(/\W+/) : [];
|
||||
}
|
||||
function getObjTokenizer(tokenizer) {
|
||||
return function setKey(keys) {
|
||||
keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0);
|
||||
return function tokenize(o) {
|
||||
var tokens = [];
|
||||
_.each(keys, function(k) {
|
||||
tokens = tokens.concat(tokenizer(_.toStr(o[k])));
|
||||
});
|
||||
return tokens;
|
||||
};
|
||||
};
|
||||
}
|
||||
}();
|
||||
var LruCache = function() {
|
||||
"use strict";
|
||||
function LruCache(maxSize) {
|
||||
this.maxSize = _.isNumber(maxSize) ? maxSize : 100;
|
||||
this.reset();
|
||||
if (this.maxSize <= 0) {
|
||||
this.set = this.get = $.noop;
|
||||
}
|
||||
}
|
||||
_.mixin(LruCache.prototype, {
|
||||
set: function set(key, val) {
|
||||
var tailItem = this.list.tail, node;
|
||||
if (this.size >= this.maxSize) {
|
||||
this.list.remove(tailItem);
|
||||
delete this.hash[tailItem.key];
|
||||
this.size--;
|
||||
}
|
||||
if (node = this.hash[key]) {
|
||||
node.val = val;
|
||||
this.list.moveToFront(node);
|
||||
} else {
|
||||
node = new Node(key, val);
|
||||
this.list.add(node);
|
||||
this.hash[key] = node;
|
||||
this.size++;
|
||||
}
|
||||
},
|
||||
get: function get(key) {
|
||||
var node = this.hash[key];
|
||||
if (node) {
|
||||
this.list.moveToFront(node);
|
||||
return node.val;
|
||||
}
|
||||
},
|
||||
reset: function reset() {
|
||||
this.size = 0;
|
||||
this.hash = {};
|
||||
this.list = new List();
|
||||
}
|
||||
});
|
||||
function List() {
|
||||
this.head = this.tail = null;
|
||||
}
|
||||
_.mixin(List.prototype, {
|
||||
add: function add(node) {
|
||||
if (this.head) {
|
||||
node.next = this.head;
|
||||
this.head.prev = node;
|
||||
}
|
||||
this.head = node;
|
||||
this.tail = this.tail || node;
|
||||
},
|
||||
remove: function remove(node) {
|
||||
node.prev ? node.prev.next = node.next : this.head = node.next;
|
||||
node.next ? node.next.prev = node.prev : this.tail = node.prev;
|
||||
},
|
||||
moveToFront: function(node) {
|
||||
this.remove(node);
|
||||
this.add(node);
|
||||
}
|
||||
});
|
||||
function Node(key, val) {
|
||||
this.key = key;
|
||||
this.val = val;
|
||||
this.prev = this.next = null;
|
||||
}
|
||||
return LruCache;
|
||||
}();
|
||||
var PersistentStorage = function() {
|
||||
"use strict";
|
||||
var LOCAL_STORAGE;
|
||||
try {
|
||||
LOCAL_STORAGE = window.localStorage;
|
||||
LOCAL_STORAGE.setItem("~~~", "!");
|
||||
LOCAL_STORAGE.removeItem("~~~");
|
||||
} catch (err) {
|
||||
LOCAL_STORAGE = null;
|
||||
}
|
||||
function PersistentStorage(namespace, override) {
|
||||
this.prefix = [ "__", namespace, "__" ].join("");
|
||||
this.ttlKey = "__ttl__";
|
||||
this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix));
|
||||
this.ls = override || LOCAL_STORAGE;
|
||||
!this.ls && this._noop();
|
||||
}
|
||||
_.mixin(PersistentStorage.prototype, {
|
||||
_prefix: function(key) {
|
||||
return this.prefix + key;
|
||||
},
|
||||
_ttlKey: function(key) {
|
||||
return this._prefix(key) + this.ttlKey;
|
||||
},
|
||||
_noop: function() {
|
||||
this.get = this.set = this.remove = this.clear = this.isExpired = _.noop;
|
||||
},
|
||||
_safeSet: function(key, val) {
|
||||
try {
|
||||
this.ls.setItem(key, val);
|
||||
} catch (err) {
|
||||
if (err.name === "QuotaExceededError") {
|
||||
this.clear();
|
||||
this._noop();
|
||||
}
|
||||
}
|
||||
},
|
||||
get: function(key) {
|
||||
if (this.isExpired(key)) {
|
||||
this.remove(key);
|
||||
}
|
||||
return decode(this.ls.getItem(this._prefix(key)));
|
||||
},
|
||||
set: function(key, val, ttl) {
|
||||
if (_.isNumber(ttl)) {
|
||||
this._safeSet(this._ttlKey(key), encode(now() + ttl));
|
||||
} else {
|
||||
this.ls.removeItem(this._ttlKey(key));
|
||||
}
|
||||
return this._safeSet(this._prefix(key), encode(val));
|
||||
},
|
||||
remove: function(key) {
|
||||
this.ls.removeItem(this._ttlKey(key));
|
||||
this.ls.removeItem(this._prefix(key));
|
||||
return this;
|
||||
},
|
||||
clear: function() {
|
||||
var i, keys = gatherMatchingKeys(this.keyMatcher);
|
||||
for (i = keys.length; i--; ) {
|
||||
this.remove(keys[i]);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
isExpired: function(key) {
|
||||
var ttl = decode(this.ls.getItem(this._ttlKey(key)));
|
||||
return _.isNumber(ttl) && now() > ttl ? true : false;
|
||||
}
|
||||
});
|
||||
return PersistentStorage;
|
||||
function now() {
|
||||
return new Date().getTime();
|
||||
}
|
||||
function encode(val) {
|
||||
return JSON.stringify(_.isUndefined(val) ? null : val);
|
||||
}
|
||||
function decode(val) {
|
||||
return $.parseJSON(val);
|
||||
}
|
||||
function gatherMatchingKeys(keyMatcher) {
|
||||
var i, key, keys = [], len = LOCAL_STORAGE.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((key = LOCAL_STORAGE.key(i)).match(keyMatcher)) {
|
||||
keys.push(key.replace(keyMatcher, ""));
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
}();
|
||||
var Transport = function() {
|
||||
"use strict";
|
||||
var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10);
|
||||
function Transport(o) {
|
||||
o = o || {};
|
||||
this.cancelled = false;
|
||||
this.lastReq = null;
|
||||
this._send = o.transport;
|
||||
this._get = o.limiter ? o.limiter(this._get) : this._get;
|
||||
this._cache = o.cache === false ? new LruCache(0) : sharedCache;
|
||||
}
|
||||
Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
|
||||
maxPendingRequests = num;
|
||||
};
|
||||
Transport.resetCache = function resetCache() {
|
||||
sharedCache.reset();
|
||||
};
|
||||
_.mixin(Transport.prototype, {
|
||||
_fingerprint: function fingerprint(o) {
|
||||
o = o || {};
|
||||
return o.url + o.type + $.param(o.data || {});
|
||||
},
|
||||
_get: function(o, cb) {
|
||||
var that = this, fingerprint, jqXhr;
|
||||
fingerprint = this._fingerprint(o);
|
||||
if (this.cancelled || fingerprint !== this.lastReq) {
|
||||
return;
|
||||
}
|
||||
if (jqXhr = pendingRequests[fingerprint]) {
|
||||
jqXhr.done(done).fail(fail);
|
||||
} else if (pendingRequestsCount < maxPendingRequests) {
|
||||
pendingRequestsCount++;
|
||||
pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always);
|
||||
} else {
|
||||
this.onDeckRequestArgs = [].slice.call(arguments, 0);
|
||||
}
|
||||
function done(resp) {
|
||||
cb(null, resp);
|
||||
that._cache.set(fingerprint, resp);
|
||||
}
|
||||
function fail() {
|
||||
cb(true);
|
||||
}
|
||||
function always() {
|
||||
pendingRequestsCount--;
|
||||
delete pendingRequests[fingerprint];
|
||||
if (that.onDeckRequestArgs) {
|
||||
that._get.apply(that, that.onDeckRequestArgs);
|
||||
that.onDeckRequestArgs = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
get: function(o, cb) {
|
||||
var resp, fingerprint;
|
||||
cb = cb || $.noop;
|
||||
o = _.isString(o) ? {
|
||||
url: o
|
||||
} : o || {};
|
||||
fingerprint = this._fingerprint(o);
|
||||
this.cancelled = false;
|
||||
this.lastReq = fingerprint;
|
||||
if (resp = this._cache.get(fingerprint)) {
|
||||
cb(null, resp);
|
||||
} else {
|
||||
this._get(o, cb);
|
||||
}
|
||||
},
|
||||
cancel: function() {
|
||||
this.cancelled = true;
|
||||
}
|
||||
});
|
||||
return Transport;
|
||||
}();
|
||||
var SearchIndex = window.SearchIndex = function() {
|
||||
"use strict";
|
||||
var CHILDREN = "c", IDS = "i";
|
||||
function SearchIndex(o) {
|
||||
o = o || {};
|
||||
if (!o.datumTokenizer || !o.queryTokenizer) {
|
||||
$.error("datumTokenizer and queryTokenizer are both required");
|
||||
}
|
||||
this.identify = o.identify || _.stringify;
|
||||
this.datumTokenizer = o.datumTokenizer;
|
||||
this.queryTokenizer = o.queryTokenizer;
|
||||
this.reset();
|
||||
}
|
||||
_.mixin(SearchIndex.prototype, {
|
||||
bootstrap: function bootstrap(o) {
|
||||
this.datums = o.datums;
|
||||
this.trie = o.trie;
|
||||
},
|
||||
add: function(data) {
|
||||
var that = this;
|
||||
data = _.isArray(data) ? data : [ data ];
|
||||
_.each(data, function(datum) {
|
||||
var id, tokens;
|
||||
that.datums[id = that.identify(datum)] = datum;
|
||||
tokens = normalizeTokens(that.datumTokenizer(datum));
|
||||
_.each(tokens, function(token) {
|
||||
var node, chars, ch;
|
||||
node = that.trie;
|
||||
chars = token.split("");
|
||||
while (ch = chars.shift()) {
|
||||
node = node[CHILDREN][ch] || (node[CHILDREN][ch] = newNode());
|
||||
node[IDS].push(id);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
get: function get(ids) {
|
||||
var that = this;
|
||||
return _.map(ids, function(id) {
|
||||
return that.datums[id];
|
||||
});
|
||||
},
|
||||
search: function search(query) {
|
||||
var that = this, tokens, matches;
|
||||
tokens = normalizeTokens(this.queryTokenizer(query));
|
||||
_.each(tokens, function(token) {
|
||||
var node, chars, ch, ids;
|
||||
if (matches && matches.length === 0) {
|
||||
return false;
|
||||
}
|
||||
node = that.trie;
|
||||
chars = token.split("");
|
||||
while (node && (ch = chars.shift())) {
|
||||
node = node[CHILDREN][ch];
|
||||
}
|
||||
if (node && chars.length === 0) {
|
||||
ids = node[IDS].slice(0);
|
||||
matches = matches ? getIntersection(matches, ids) : ids;
|
||||
} else {
|
||||
matches = [];
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return matches ? _.map(unique(matches), function(id) {
|
||||
return that.datums[id];
|
||||
}) : [];
|
||||
},
|
||||
all: function all() {
|
||||
var values = [];
|
||||
for (var key in this.datums) {
|
||||
values.push(this.datums[key]);
|
||||
}
|
||||
return values;
|
||||
},
|
||||
reset: function reset() {
|
||||
this.datums = {};
|
||||
this.trie = newNode();
|
||||
},
|
||||
serialize: function serialize() {
|
||||
return {
|
||||
datums: this.datums,
|
||||
trie: this.trie
|
||||
};
|
||||
}
|
||||
});
|
||||
return SearchIndex;
|
||||
function normalizeTokens(tokens) {
|
||||
tokens = _.filter(tokens, function(token) {
|
||||
return !!token;
|
||||
});
|
||||
tokens = _.map(tokens, function(token) {
|
||||
return token.toLowerCase();
|
||||
});
|
||||
return tokens;
|
||||
}
|
||||
function newNode() {
|
||||
var node = {};
|
||||
node[IDS] = [];
|
||||
node[CHILDREN] = {};
|
||||
return node;
|
||||
}
|
||||
function unique(array) {
|
||||
var seen = {}, uniques = [];
|
||||
for (var i = 0, len = array.length; i < len; i++) {
|
||||
if (!seen[array[i]]) {
|
||||
seen[array[i]] = true;
|
||||
uniques.push(array[i]);
|
||||
}
|
||||
}
|
||||
return uniques;
|
||||
}
|
||||
function getIntersection(arrayA, arrayB) {
|
||||
var ai = 0, bi = 0, intersection = [];
|
||||
arrayA = arrayA.sort();
|
||||
arrayB = arrayB.sort();
|
||||
var lenArrayA = arrayA.length, lenArrayB = arrayB.length;
|
||||
while (ai < lenArrayA && bi < lenArrayB) {
|
||||
if (arrayA[ai] < arrayB[bi]) {
|
||||
ai++;
|
||||
} else if (arrayA[ai] > arrayB[bi]) {
|
||||
bi++;
|
||||
} else {
|
||||
intersection.push(arrayA[ai]);
|
||||
ai++;
|
||||
bi++;
|
||||
}
|
||||
}
|
||||
return intersection;
|
||||
}
|
||||
}();
|
||||
var Prefetch = function() {
|
||||
"use strict";
|
||||
var keys;
|
||||
keys = {
|
||||
data: "data",
|
||||
protocol: "protocol",
|
||||
thumbprint: "thumbprint"
|
||||
};
|
||||
function Prefetch(o) {
|
||||
this.url = o.url;
|
||||
this.ttl = o.ttl;
|
||||
this.cache = o.cache;
|
||||
this.prepare = o.prepare;
|
||||
this.transform = o.transform;
|
||||
this.transport = o.transport;
|
||||
this.thumbprint = o.thumbprint;
|
||||
this.storage = new PersistentStorage(o.cacheKey);
|
||||
}
|
||||
_.mixin(Prefetch.prototype, {
|
||||
_settings: function settings() {
|
||||
return {
|
||||
url: this.url,
|
||||
type: "GET",
|
||||
dataType: "json"
|
||||
};
|
||||
},
|
||||
store: function store(data) {
|
||||
if (!this.cache) {
|
||||
return;
|
||||
}
|
||||
this.storage.set(keys.data, data, this.ttl);
|
||||
this.storage.set(keys.protocol, location.protocol, this.ttl);
|
||||
this.storage.set(keys.thumbprint, this.thumbprint, this.ttl);
|
||||
},
|
||||
fromCache: function fromCache() {
|
||||
var stored = {}, isExpired;
|
||||
if (!this.cache) {
|
||||
return null;
|
||||
}
|
||||
stored.data = this.storage.get(keys.data);
|
||||
stored.protocol = this.storage.get(keys.protocol);
|
||||
stored.thumbprint = this.storage.get(keys.thumbprint);
|
||||
isExpired = stored.thumbprint !== this.thumbprint || stored.protocol !== location.protocol;
|
||||
return stored.data && !isExpired ? stored.data : null;
|
||||
},
|
||||
fromNetwork: function(cb) {
|
||||
var that = this, settings;
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
settings = this.prepare(this._settings());
|
||||
this.transport(settings).fail(onError).done(onResponse);
|
||||
function onError() {
|
||||
cb(true);
|
||||
}
|
||||
function onResponse(resp) {
|
||||
cb(null, that.transform(resp));
|
||||
}
|
||||
},
|
||||
clear: function clear() {
|
||||
this.storage.clear();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
return Prefetch;
|
||||
}();
|
||||
var Remote = function() {
|
||||
"use strict";
|
||||
function Remote(o) {
|
||||
this.url = o.url;
|
||||
this.prepare = o.prepare;
|
||||
this.transform = o.transform;
|
||||
this.transport = new Transport({
|
||||
cache: o.cache,
|
||||
limiter: o.limiter,
|
||||
transport: o.transport
|
||||
});
|
||||
}
|
||||
_.mixin(Remote.prototype, {
|
||||
_settings: function settings() {
|
||||
return {
|
||||
url: this.url,
|
||||
type: "GET",
|
||||
dataType: "json"
|
||||
};
|
||||
},
|
||||
get: function get(query, cb) {
|
||||
var that = this, settings;
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
query = query || "";
|
||||
settings = this.prepare(query, this._settings());
|
||||
return this.transport.get(settings, onResponse);
|
||||
function onResponse(err, resp) {
|
||||
err ? cb([]) : cb(that.transform(resp));
|
||||
}
|
||||
},
|
||||
cancelLastRequest: function cancelLastRequest() {
|
||||
this.transport.cancel();
|
||||
}
|
||||
});
|
||||
return Remote;
|
||||
}();
|
||||
var oParser = function() {
|
||||
"use strict";
|
||||
return function parse(o) {
|
||||
var defaults, sorter;
|
||||
defaults = {
|
||||
initialize: true,
|
||||
identify: _.stringify,
|
||||
datumTokenizer: null,
|
||||
queryTokenizer: null,
|
||||
sufficient: 5,
|
||||
sorter: null,
|
||||
local: [],
|
||||
prefetch: null,
|
||||
remote: null
|
||||
};
|
||||
o = _.mixin(defaults, o || {});
|
||||
!o.datumTokenizer && $.error("datumTokenizer is required");
|
||||
!o.queryTokenizer && $.error("queryTokenizer is required");
|
||||
sorter = o.sorter;
|
||||
o.sorter = sorter ? function(x) {
|
||||
return x.sort(sorter);
|
||||
} : _.identity;
|
||||
o.local = _.isFunction(o.local) ? o.local() : o.local;
|
||||
o.prefetch = parsePrefetch(o.prefetch);
|
||||
o.remote = parseRemote(o.remote);
|
||||
return o;
|
||||
};
|
||||
function parsePrefetch(o) {
|
||||
var defaults;
|
||||
if (!o) {
|
||||
return null;
|
||||
}
|
||||
defaults = {
|
||||
url: null,
|
||||
ttl: 24 * 60 * 60 * 1e3,
|
||||
cache: true,
|
||||
cacheKey: null,
|
||||
thumbprint: "",
|
||||
prepare: _.identity,
|
||||
transform: _.identity,
|
||||
transport: null
|
||||
};
|
||||
o = _.isString(o) ? {
|
||||
url: o
|
||||
} : o;
|
||||
o = _.mixin(defaults, o);
|
||||
!o.url && $.error("prefetch requires url to be set");
|
||||
o.transform = o.filter || o.transform;
|
||||
o.cacheKey = o.cacheKey || o.url;
|
||||
o.thumbprint = VERSION + o.thumbprint;
|
||||
o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;
|
||||
return o;
|
||||
}
|
||||
function parseRemote(o) {
|
||||
var defaults;
|
||||
if (!o) {
|
||||
return;
|
||||
}
|
||||
defaults = {
|
||||
url: null,
|
||||
cache: true,
|
||||
prepare: null,
|
||||
replace: null,
|
||||
wildcard: null,
|
||||
limiter: null,
|
||||
rateLimitBy: "debounce",
|
||||
rateLimitWait: 300,
|
||||
transform: _.identity,
|
||||
transport: null
|
||||
};
|
||||
o = _.isString(o) ? {
|
||||
url: o
|
||||
} : o;
|
||||
o = _.mixin(defaults, o);
|
||||
!o.url && $.error("remote requires url to be set");
|
||||
o.transform = o.filter || o.transform;
|
||||
o.prepare = toRemotePrepare(o);
|
||||
o.limiter = toLimiter(o);
|
||||
o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;
|
||||
delete o.replace;
|
||||
delete o.wildcard;
|
||||
delete o.rateLimitBy;
|
||||
delete o.rateLimitWait;
|
||||
return o;
|
||||
}
|
||||
function toRemotePrepare(o) {
|
||||
var prepare, replace, wildcard;
|
||||
prepare = o.prepare;
|
||||
replace = o.replace;
|
||||
wildcard = o.wildcard;
|
||||
if (prepare) {
|
||||
return prepare;
|
||||
}
|
||||
if (replace) {
|
||||
prepare = prepareByReplace;
|
||||
} else if (o.wildcard) {
|
||||
prepare = prepareByWildcard;
|
||||
} else {
|
||||
prepare = idenityPrepare;
|
||||
}
|
||||
return prepare;
|
||||
function prepareByReplace(query, settings) {
|
||||
settings.url = replace(settings.url, query);
|
||||
return settings;
|
||||
}
|
||||
function prepareByWildcard(query, settings) {
|
||||
settings.url = settings.url.replace(wildcard, encodeURIComponent(query));
|
||||
return settings;
|
||||
}
|
||||
function idenityPrepare(query, settings) {
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
function toLimiter(o) {
|
||||
var limiter, method, wait;
|
||||
limiter = o.limiter;
|
||||
method = o.rateLimitBy;
|
||||
wait = o.rateLimitWait;
|
||||
if (!limiter) {
|
||||
limiter = /^throttle$/i.test(method) ? throttle(wait) : debounce(wait);
|
||||
}
|
||||
return limiter;
|
||||
function debounce(wait) {
|
||||
return function debounce(fn) {
|
||||
return _.debounce(fn, wait);
|
||||
};
|
||||
}
|
||||
function throttle(wait) {
|
||||
return function throttle(fn) {
|
||||
return _.throttle(fn, wait);
|
||||
};
|
||||
}
|
||||
}
|
||||
function callbackToDeferred(fn) {
|
||||
return function wrapper(o) {
|
||||
var deferred = $.Deferred();
|
||||
fn(o, onSuccess, onError);
|
||||
return deferred;
|
||||
function onSuccess(resp) {
|
||||
_.defer(function() {
|
||||
deferred.resolve(resp);
|
||||
});
|
||||
}
|
||||
function onError(err) {
|
||||
_.defer(function() {
|
||||
deferred.reject(err);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}();
|
||||
var Bloodhound = function() {
|
||||
"use strict";
|
||||
var old;
|
||||
old = window && window.Bloodhound;
|
||||
function Bloodhound(o) {
|
||||
o = oParser(o);
|
||||
this.sorter = o.sorter;
|
||||
this.identify = o.identify;
|
||||
this.sufficient = o.sufficient;
|
||||
this.local = o.local;
|
||||
this.remote = o.remote ? new Remote(o.remote) : null;
|
||||
this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null;
|
||||
this.index = new SearchIndex({
|
||||
identify: this.identify,
|
||||
datumTokenizer: o.datumTokenizer,
|
||||
queryTokenizer: o.queryTokenizer
|
||||
});
|
||||
o.initialize !== false && this.initialize();
|
||||
}
|
||||
Bloodhound.noConflict = function noConflict() {
|
||||
window && (window.Bloodhound = old);
|
||||
return Bloodhound;
|
||||
};
|
||||
Bloodhound.tokenizers = tokenizers;
|
||||
_.mixin(Bloodhound.prototype, {
|
||||
__ttAdapter: function ttAdapter() {
|
||||
var that = this;
|
||||
return this.remote ? withAsync : withoutAsync;
|
||||
function withAsync(query, sync, async) {
|
||||
return that.search(query, sync, async);
|
||||
}
|
||||
function withoutAsync(query, sync) {
|
||||
return that.search(query, sync);
|
||||
}
|
||||
},
|
||||
_loadPrefetch: function loadPrefetch() {
|
||||
var that = this, deferred, serialized;
|
||||
deferred = $.Deferred();
|
||||
if (!this.prefetch) {
|
||||
deferred.resolve();
|
||||
} else if (serialized = this.prefetch.fromCache()) {
|
||||
this.index.bootstrap(serialized);
|
||||
deferred.resolve();
|
||||
} else {
|
||||
this.prefetch.fromNetwork(done);
|
||||
}
|
||||
return deferred.promise();
|
||||
function done(err, data) {
|
||||
if (err) {
|
||||
return deferred.reject();
|
||||
}
|
||||
that.add(data);
|
||||
that.prefetch.store(that.index.serialize());
|
||||
deferred.resolve();
|
||||
}
|
||||
},
|
||||
_initialize: function initialize() {
|
||||
var that = this, deferred;
|
||||
this.clear();
|
||||
(this.initPromise = this._loadPrefetch()).done(addLocalToIndex);
|
||||
return this.initPromise;
|
||||
function addLocalToIndex() {
|
||||
that.add(that.local);
|
||||
}
|
||||
},
|
||||
initialize: function initialize(force) {
|
||||
return !this.initPromise || force ? this._initialize() : this.initPromise;
|
||||
},
|
||||
add: function add(data) {
|
||||
this.index.add(data);
|
||||
return this;
|
||||
},
|
||||
get: function get(ids) {
|
||||
ids = _.isArray(ids) ? ids : [].slice.call(arguments);
|
||||
return this.index.get(ids);
|
||||
},
|
||||
search: function search(query, sync, async) {
|
||||
var that = this, local;
|
||||
local = this.sorter(this.index.search(query));
|
||||
sync(this.remote ? local.slice() : local);
|
||||
if (this.remote && local.length < this.sufficient) {
|
||||
this.remote.get(query, processRemote);
|
||||
} else if (this.remote) {
|
||||
this.remote.cancelLastRequest();
|
||||
}
|
||||
return this;
|
||||
function processRemote(remote) {
|
||||
var nonDuplicates = [];
|
||||
_.each(remote, function(r) {
|
||||
!_.some(local, function(l) {
|
||||
return that.identify(r) === that.identify(l);
|
||||
}) && nonDuplicates.push(r);
|
||||
});
|
||||
async && async(nonDuplicates);
|
||||
}
|
||||
},
|
||||
all: function all() {
|
||||
return this.index.all();
|
||||
},
|
||||
clear: function clear() {
|
||||
this.index.reset();
|
||||
return this;
|
||||
},
|
||||
clearPrefetchCache: function clearPrefetchCache() {
|
||||
this.prefetch && this.prefetch.clear();
|
||||
return this;
|
||||
},
|
||||
clearRemoteCache: function clearRemoteCache() {
|
||||
Transport.resetCache();
|
||||
return this;
|
||||
},
|
||||
ttAdapter: function ttAdapter() {
|
||||
return this.__ttAdapter();
|
||||
}
|
||||
});
|
||||
return Bloodhound;
|
||||
}();
|
||||
return Bloodhound;
|
||||
});
|
7
public/js/lib/typeahead/bloodhound.min.js
vendored
Normal file
7
public/js/lib/typeahead/bloodhound.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2451
public/js/lib/typeahead/typeahead.bundle.js
vendored
Normal file
2451
public/js/lib/typeahead/typeahead.bundle.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
public/js/lib/typeahead/typeahead.bundle.min.js
vendored
Normal file
8
public/js/lib/typeahead/typeahead.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1538
public/js/lib/typeahead/typeahead.jquery.js
vendored
Normal file
1538
public/js/lib/typeahead/typeahead.jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
public/js/lib/typeahead/typeahead.jquery.min.js
vendored
Normal file
7
public/js/lib/typeahead/typeahead.jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -96,7 +96,8 @@
|
||||
<script type="text/javascript">
|
||||
var what = "{{ what }}";
|
||||
</script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
|
||||
|
@ -7,9 +7,18 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
|
||||
<base href="{{ route('index') }}/">
|
||||
<link rel="stylesheet" href="css/app.css?v={{ FF_VERSION }}" type="text/css" media="all"/>
|
||||
|
||||
{# libraries #}
|
||||
<link href="lib/bs/css/bootstrap.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
|
||||
<link href="lib/fa/css/font-awesome.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
|
||||
|
||||
{# the theme #}
|
||||
<link href="lib/adminlte/css/AdminLTE.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
|
||||
<link href="lib/adminlte/css/skins/skin-blue-light.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
|
||||
|
||||
{# Firefly III customisations #}
|
||||
<link href="css/firefly.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
|
||||
|
||||
{% include('partials.favicons') %}
|
||||
</head>
|
||||
<body class="ff-error-page">
|
||||
|
@ -194,7 +194,8 @@
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="lib/fc/fullcalendar.min.js?v={{ FF_VERSION }}"></script>
|
||||
|
@ -215,7 +215,8 @@
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="lib/fc/fullcalendar.min.js?v={{ FF_VERSION }}"></script>
|
||||
|
@ -145,7 +145,7 @@
|
||||
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript">
|
||||
var triggerCount = {{ triggerCount }};
|
||||
var actionCount = {{ actionCount }};
|
||||
|
@ -128,7 +128,7 @@
|
||||
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript">
|
||||
var triggerCount = {{ triggerCount }};
|
||||
var actionCount = {{ actionCount }};
|
||||
|
@ -128,7 +128,8 @@
|
||||
<script type="text/javascript">
|
||||
var what = "";
|
||||
</script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/transactions/mass/edit-bulk.js?v={{ FF_VERSION }}"></script>
|
||||
{% endblock %}
|
||||
|
@ -215,10 +215,7 @@
|
||||
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
<link href="css/bootstrap-tagsinput.css?v={{ FF_VERSION }}" type="text/css" rel="stylesheet" media="all">
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/transactions/convert.js?v={{ FF_VERSION }}"></script>
|
||||
{% endblock %}
|
||||
|
@ -136,6 +136,7 @@
|
||||
<script type="text/javascript">
|
||||
var what = "";
|
||||
</script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/transactions/mass/edit.js?v={{ FF_VERSION }}"></script>
|
||||
{% endblock %}
|
||||
|
@ -463,6 +463,6 @@
|
||||
<script type="text/javascript">
|
||||
var autoCompleteUri = "{{ route('json.journals-with-id',[journal.id]) }}";
|
||||
</script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/transactions/show.js?v={{ FF_VERSION }}"></script>
|
||||
{% endblock %}
|
||||
|
@ -240,8 +240,11 @@
|
||||
var overruleCurrency = {{ preFilled.amount_currency_id_amount|default(0) }};
|
||||
|
||||
</script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
|
||||
|
||||
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="jscript/accounts?ext=.js&v={{ FF_VERSION }}"></script>
|
||||
|
@ -248,7 +248,8 @@
|
||||
<script type="text/javascript">
|
||||
var what = "{{ what }}";
|
||||
</script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
|
||||
|
@ -328,7 +328,8 @@
|
||||
var originalForeignSum = {{ preFilled.journal_foreign_amount }};
|
||||
var what = "{{ preFilled.what }}";
|
||||
</script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
|
||||
|
@ -75,7 +75,7 @@
|
||||
|
||||
<div class="buttons">
|
||||
<!-- Authorize Button -->
|
||||
<form method="post" action="/oauth/authorize">
|
||||
<form method="post" action="{{ route('index') }}/oauth/authorize">
|
||||
{{ csrf_field() }}
|
||||
|
||||
<input type="hidden" name="state" value="{{ request.state }}">
|
||||
@ -84,7 +84,7 @@
|
||||
</form>
|
||||
|
||||
<!-- Cancel Button -->
|
||||
<form method="post" action="/oauth/authorize">
|
||||
<form method="post" action="{{ route('index') }}/oauth/authorize">
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('DELETE') }}
|
||||
|
||||
|
@ -73,7 +73,6 @@ class CreateControllerTest extends TestCase
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Credit card'])->andReturn(AccountType::find(13))->once();
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('accounts.create', ['asset']));
|
||||
|
@ -86,7 +86,6 @@ class EditControllerTest extends TestCase
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Credit card'])->andReturn(AccountType::find(13))->once();
|
||||
|
||||
|
||||
$this->be($this->user());
|
||||
@ -131,7 +130,6 @@ class EditControllerTest extends TestCase
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Credit card'])->andReturn(AccountType::find(13))->once();
|
||||
|
||||
|
||||
$this->be($this->user());
|
||||
@ -178,7 +176,6 @@ class EditControllerTest extends TestCase
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
|
||||
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Credit card'])->andReturn(AccountType::find(13))->once();
|
||||
|
||||
$this->be($this->user());
|
||||
$account = $this->user()->accounts()->where('account_type_id', 3)->whereNull('deleted_at')->first();
|
||||
|
@ -81,7 +81,7 @@ class UserEventHandlerTest extends TestCase
|
||||
{
|
||||
$repository = $this->mock(UserRepositoryInterface::class);
|
||||
$user = $this->user();
|
||||
$event = new Login($user, true);
|
||||
$event = new Login(null, $user, true);
|
||||
$listener = new UserEventHandler();
|
||||
|
||||
// mock stuff
|
||||
@ -99,7 +99,7 @@ class UserEventHandlerTest extends TestCase
|
||||
{
|
||||
$repository = $this->mock(UserRepositoryInterface::class);
|
||||
$user = $this->emptyUser();
|
||||
$event = new Login($user, true);
|
||||
$event = new Login(null, $user, true);
|
||||
$listener = new UserEventHandler();
|
||||
|
||||
// mock stuff
|
||||
@ -121,7 +121,7 @@ class UserEventHandlerTest extends TestCase
|
||||
{
|
||||
$repository = $this->mock(UserRepositoryInterface::class);
|
||||
$user = $this->emptyUser();
|
||||
$event = new Login($user, true);
|
||||
$event = new Login(null, $user, true);
|
||||
$listener = new UserEventHandler();
|
||||
|
||||
// mock stuff
|
||||
@ -141,7 +141,7 @@ class UserEventHandlerTest extends TestCase
|
||||
{
|
||||
$repository = $this->mock(UserRepositoryInterface::class);
|
||||
$user = $this->user();
|
||||
$event = new Login($user, true);
|
||||
$event = new Login(null, $user, true);
|
||||
$listener = new UserEventHandler();
|
||||
|
||||
// mock stuff
|
||||
@ -159,7 +159,7 @@ class UserEventHandlerTest extends TestCase
|
||||
{
|
||||
$repository = $this->mock(UserRepositoryInterface::class);
|
||||
$user = $this->emptyUser();
|
||||
$event = new Login($user, true);
|
||||
$event = new Login(null, $user, true);
|
||||
$listener = new UserEventHandler();
|
||||
|
||||
// mock stuff
|
||||
|
Loading…
Reference in New Issue
Block a user