diff --git a/app/Http/Controllers/Budget/IndexController.php b/app/Http/Controllers/Budget/IndexController.php index 78bd66d719..8db0e98e64 100644 --- a/app/Http/Controllers/Budget/IndexController.php +++ b/app/Http/Controllers/Budget/IndexController.php @@ -28,6 +28,7 @@ use Carbon\Carbon; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Support\Http\Controllers\DateCalculation; +use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Pagination\LengthAwarePaginator; @@ -63,7 +64,6 @@ class IndexController extends Controller ); } - /** * Show all budgets. * @@ -134,5 +134,29 @@ class IndexController extends Controller ); } + /** + * @param Request $request + * + * @return JsonResponse + */ + public function reorder(Request $request, BudgetRepositoryInterface $repository): JsonResponse + { + $budgetIds = $request->get('budgetIds'); + $page = (int)$request->get('page'); + $pageSize = (int)app('preferences')->get('listPageSize', 50)->data; + + $currentOrder = (($page - 1) * $pageSize) + 1; + foreach ($budgetIds as $budgetId) { + $budgetId = (int)$budgetId; + $budget = $repository->findNull($budgetId); + if (null !== $budget) { + $repository->setBudgetOrder($budget, $currentOrder); + } + $currentOrder++; + } + + return response()->json(['OK']); + } + } diff --git a/app/Models/Budget.php b/app/Models/Budget.php index 0ef5142e05..5efdbe2b58 100644 --- a/app/Models/Budget.php +++ b/app/Models/Budget.php @@ -42,6 +42,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property-read string $email * @property bool encrypted * @property Collection budgetlimits + * @property int $order */ class Budget extends Model { @@ -61,7 +62,7 @@ class Budget extends Model 'encrypted' => 'boolean', ]; /** @var array Fields that can be filled */ - protected $fillable = ['user_id', 'name', 'active']; + protected $fillable = ['user_id', 'name', 'active','order']; /** @var array Hidden from view */ protected $hidden = ['encrypted']; diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 3787219f0e..b1a18f6719 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -107,6 +107,7 @@ class BudgetRepository implements BudgetRepositoryInterface } catch (Exception $e) { Log::debug(sprintf('Could not delete budget limit: %s', $e->getMessage())); } + Budget::where('order',0)->update(['order' => 100]); // do the clean up by hand because Sqlite can be tricky with this. $budgetLimits = BudgetLimit::orderBy('created_at', 'DESC')->get(['id', 'budget_id', 'start_date', 'end_date']); @@ -289,11 +290,14 @@ class BudgetRepository implements BudgetRepositoryInterface public function getActiveBudgets(): Collection { /** @var Collection $set */ - $set = $this->user->budgets()->where('active', 1)->get(); + $set = $this->user->budgets()->where('active', 1) + ->get(); $set = $set->sortBy( function (Budget $budget) { - return strtolower($budget->name); + $str = str_pad((string)$budget->order, 4, '0', STR_PAD_LEFT) . strtolower($budget->name); + + return $str; } ); @@ -554,7 +558,9 @@ class BudgetRepository implements BudgetRepositoryInterface $set = $set->sortBy( function (Budget $budget) { - return strtolower($budget->name); + $str = str_pad((string)$budget->order, 4, '0', STR_PAD_LEFT) . strtolower($budget->name); + + return $str; } ); @@ -583,7 +589,9 @@ class BudgetRepository implements BudgetRepositoryInterface $set = $set->sortBy( function (Budget $budget) { - return strtolower($budget->name); + $str = str_pad((string)$budget->order, 4, '0', STR_PAD_LEFT) . strtolower($budget->name); + + return $str; } ); @@ -652,6 +660,18 @@ class BudgetRepository implements BudgetRepositoryInterface return $availableBudget; } + /** + * @param Budget $budget + * @param int $order + */ + public function setBudgetOrder(Budget $budget, int $order): void + { + $budget->order = $order; + $budget->save(); + } + + /** @noinspection MoreThanThreeArgumentsInspection */ + /** * @param User $user */ @@ -660,7 +680,6 @@ class BudgetRepository implements BudgetRepositoryInterface $this->user = $user; } - /** @noinspection MoreThanThreeArgumentsInspection */ /** * @param Collection $budgets * @param Collection $accounts @@ -825,6 +844,8 @@ class BudgetRepository implements BudgetRepositoryInterface } + /** @noinspection MoreThanThreeArgumentsInspection */ + /** * @param BudgetLimit $budgetLimit * @param array $data @@ -848,7 +869,6 @@ class BudgetRepository implements BudgetRepositoryInterface return $budgetLimit; } - /** @noinspection MoreThanThreeArgumentsInspection */ /** * @param Budget $budget * @param Carbon $start diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index d6df2f54c6..54433c9ace 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -156,7 +156,6 @@ interface BudgetRepositoryInterface */ public function getBudgetLimits(Budget $budget, Carbon $start = null, Carbon $end = null): Collection; - /** @noinspection MoreThanThreeArgumentsInspection */ /** * @param Collection $budgets * @param Collection $accounts @@ -167,6 +166,8 @@ interface BudgetRepositoryInterface */ public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array; + /** @noinspection MoreThanThreeArgumentsInspection */ + /** * @return Collection */ @@ -195,7 +196,6 @@ interface BudgetRepositoryInterface */ public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array; - /** @noinspection MoreThanThreeArgumentsInspection */ /** * @param TransactionCurrency $currency * @param Carbon $start @@ -206,6 +206,14 @@ interface BudgetRepositoryInterface */ public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): AvailableBudget; + /** @noinspection MoreThanThreeArgumentsInspection */ + + /** + * @param Budget $budget + * @param int $order + */ + public function setBudgetOrder(Budget $budget, int $order): void; + /** * @param User $user */ diff --git a/public/js/ff/budgets/index.js b/public/js/ff/budgets/index.js index ea31da14e3..fb962528d4 100644 --- a/public/js/ff/budgets/index.js +++ b/public/js/ff/budgets/index.js @@ -48,8 +48,101 @@ $(function () { } }); + // sortable! + if (typeof $(".sortable-table tbody").sortable !== "undefined") { + $(".sortable-table tbody").sortable( + { + helper: fixHelper, + items: 'tr:not(.ignore)', + stop: sortStop, + handle: '.handle', + start: function (event, ui) { + // Build a placeholder cell that spans all the cells in the row + var cellCount = 0; + $('td, th', ui.helper).each(function () { + // For each TD or TH try and get it's colspan attribute, and add that or 1 to the total + var colspan = 1; + var colspanAttr = $(this).attr('colspan'); + if (colspanAttr > 1) { + colspan = colspanAttr; + } + cellCount += colspan; + }); + + // Add the placeholder UI - note that this is the item's content, so TD rather than TR + ui.placeholder.html(' '); + } + } + ); + } }); +var fixHelper = function (e, tr) { + "use strict"; + var $originals = tr.children(); + var $helper = tr.clone(); + $helper.children().each(function (index) { + // Set helper cell sizes to match the original sizes + $(this).width($originals.eq(index).width()); + }); + return $helper; +}; + + +function sortStop(event, ui) { + "use strict"; + + + //var current = $(ui.item); + var list = $('.sortable-table tbody tr'); + var submit = []; + $.each(list, function (i, v) { + var row = $(v); + var id = parseInt(row.data('id')); + if (id > 0) { + submit.push(id); + } + }); + var arr = { + budgetIds: submit, + page: page, + _token: token + }; + // var thisDate = current.data('date'); + // var originalBG = current.css('backgroundColor'); + // + // + // if (current.prev().data('date') !== thisDate && current.next().data('date') !== thisDate) { + // // animate something with color: + // current.animate({backgroundColor: "#d9534f"}, 200, function () { + // $(this).animate({backgroundColor: originalBG}, 200); + // return undefined; + // }); + // + // return false; + // } + // + // // do update + // var list = $('tr[data-date="' + thisDate + '"]'); + // var submit = []; + // $.each(list, function (i, v) { + // var row = $(v); + // var id = row.data('id'); + // submit.push(id); + // }); + // + // // do extra animation when done? + $.get('budgets/reorder', arr); + // + // current.animate({backgroundColor: "#5cb85c"}, 200, function () { + // $(this).animate({backgroundColor: originalBG}, 200); + // return undefined; + // }); + // return undefined; + //alert('drop!'); +} + + function drawSpentBar() { "use strict"; if ($('.spentBar').length > 0) { diff --git a/resources/views/budgets/index.twig b/resources/views/budgets/index.twig index 73e175b45a..d5d62fde16 100644 --- a/resources/views/budgets/index.twig +++ b/resources/views/budgets/index.twig @@ -17,7 +17,8 @@ {{ 'budgeted'|_ }}: {{ budgeted|formatAmountPlain }}
- {{ trans('firefly.available_between',{start: start.formatLocalized(monthAndDayFormat), end: end.formatLocalized(monthAndDayFormat) }) }}: + {{ trans('firefly.available_between',{start: start.formatLocalized(monthAndDayFormat), end: end.formatLocalized(monthAndDayFormat) }) }} + : {{ available|formatAmountPlain }} @@ -39,7 +40,8 @@
- {{ trans('firefly.spent_between', {start: start.formatLocalized(monthAndDayFormat), end: end.formatLocalized(monthAndDayFormat)}) }}: {{ spent|formatAmount }} + {{ trans('firefly.spent_between', {start: start.formatLocalized(monthAndDayFormat), end: end.formatLocalized(monthAndDayFormat)}) }} + : {{ spent|formatAmount }}
@@ -135,12 +137,12 @@
- {{ 'createBudget'|_ }} + {{ 'createBudget'|_ }}
{{ paginator.render|raw }}
- +
@@ -151,53 +153,53 @@ - - {% for budget in paginator %} - - - + + {% if budgetInformation[budget.id]['currentLimit'] %} - {{ budget.name }} + {% set repAmount = budgetInformation[budget.id]['budgeted'] %} {% else %} - {{ budget.name }} + {% set repAmount = '0' %} {% endif %} - - {% if budgetInformation[budget.id]['currentLimit'] %} - {% set repAmount = budgetInformation[budget.id]['budgeted'] %} - {% else %} - {% set repAmount = '0' %} - {% endif %} - - - - + + + + {% endfor %}
+ {% for budget in paginator %} +
+ {% if budgetInformation[budget.id]['currentLimit'] %} + {{ budget.name }} + {% else %} + {{ budget.name }} + {% endif %} + -
-
{{ defaultCurrency.symbol|raw }}
- - -
- -
- {{ (repAmount + budgetInformation[budget.id]['spent'])|formatAmount }} - {% if repAmount + budgetInformation[budget.id]['spent'] > 0 %} - ({{ ((repAmount + budgetInformation[budget.id]['spent']) / activeDaysLeft)|formatAmount }}) - {% endif %} -
+
+
{{ defaultCurrency.symbol|raw }}
+ + +
+ +
+ {{ (repAmount + budgetInformation[budget.id]['spent'])|formatAmount }} + {% if repAmount + budgetInformation[budget.id]['spent'] > 0 %} + ({{ ((repAmount + budgetInformation[budget.id]['spent']) / activeDaysLeft)|formatAmount }}) + {% endif %} +
@@ -206,7 +208,7 @@
@@ -239,6 +241,7 @@ {% endblock %} {% block scripts %} +