From 6d15c503c34142b95a33461a64c86608b20f75fb Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 10 Aug 2017 20:41:33 +0200 Subject: [PATCH] Fix #515 --- app/Http/Controllers/JavascriptController.php | 112 ++++++++++++++++-- public/js/ff/firefly.js | 18 +-- public/js/lib/daterangepicker.js | 33 ++++-- resources/views/javascript/variables.twig | 29 +++++ 4 files changed, 163 insertions(+), 29 deletions(-) diff --git a/app/Http/Controllers/JavascriptController.php b/app/Http/Controllers/JavascriptController.php index 8fe17dcc50..23d4111303 100644 --- a/app/Http/Controllers/JavascriptController.php +++ b/app/Http/Controllers/JavascriptController.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Controllers; use Amount; +use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; @@ -19,9 +20,9 @@ use FireflyIII\Models\TransactionCurrency; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use Illuminate\Http\Request; +use Log; use Navigation; use Preferences; -use Session; /** * Class JavascriptController @@ -95,12 +96,16 @@ class JavascriptController extends Controller $localeconv['frac_digits'] = $defaultCurrency->decimal_places; $pref = Preferences::get('language', config('firefly.default_language', 'en_US')); $lang = $pref->data; - $data = [ - 'currencyCode' => Amount::getCurrencyCode(), - 'currencySymbol' => Amount::getCurrencySymbol(), - 'accounting' => $accounting, - 'localeconv' => $localeconv, - 'language' => $lang, + $dateRange = $this->getDateRangeConfig(); + + $data = [ + 'currencyCode' => Amount::getCurrencyCode(), + 'currencySymbol' => Amount::getCurrencySymbol(), + 'accounting' => $accounting, + 'localeconv' => $localeconv, + 'language' => $lang, + 'dateRangeTitle' => $dateRange['title'], + 'dateRangeConfig' => $dateRange['configuration'], ]; $request->session()->keep(['two-factor-secret']); @@ -108,4 +113,97 @@ class JavascriptController extends Controller ->view('javascript.variables', $data, 200) ->header('Content-Type', 'text/javascript'); } + + /** + * @return array + */ + private function getDateRangeConfig(): array + { + $viewRange = Preferences::get('viewRange', '1M')->data; + $start = session('start'); + $end = session('end'); + $first = session('first'); + $title = sprintf('%s - %s', $start->formatLocalized($this->monthAndDayFormat), $end->formatLocalized($this->monthAndDayFormat)); + $isCustom = session('is_custom_range'); + $ranges = [ + // first range is the current range: + $title => [$start, $end], + ]; + Log::debug(sprintf('viewRange is %s', $viewRange)); + + // get the format for the ranges: + $format = $this->getFormatByRange($viewRange); + + // when current range is a custom range, add the current period as the next range. + if ($isCustom) { + Log::debug('Custom is true.'); + $index = $start->formatLocalized($format); + $customPeriodStart = Navigation::startOfPeriod($start, $viewRange); + $customPeriodEnd = Navigation::endOfPeriod($customPeriodStart, $viewRange); + $ranges[$index] = [$customPeriodStart, $customPeriodEnd]; + } + // then add previous range and next range + $previousDate = Navigation::subtractPeriod($start, $viewRange); + $index = $previousDate->formatLocalized($format); + $previousStart = Navigation::startOfPeriod($previousDate, $viewRange); + $previousEnd = Navigation::endOfPeriod($previousStart, $viewRange); + $ranges[$index] = [$previousStart, $previousEnd]; + + $nextDate = Navigation::addPeriod($start, $viewRange, 0); + $index = $nextDate->formatLocalized($format); + $nextStart = Navigation::startOfPeriod($nextDate, $viewRange); + $nextEnd = Navigation::endOfPeriod($nextStart, $viewRange); + $ranges[$index] = [$nextStart, $nextEnd]; + + // everything + $index = strval(trans('firefly.everything')); + $ranges[$index] = [$first, new Carbon]; + + $return = [ + 'title' => $title, + 'configuration' => [ + 'apply' => strval(trans('firefly.apply')), + 'cancel' => strval(trans('firefly.cancel')), + 'from' => strval(trans('firefly.from')), + 'to' => strval(trans('firefly.to')), + 'customRange' => strval(trans('firefly.customRange')), + 'start' => $start->format('Y-m-d'), + 'end' => $end->format('Y-m-d'), + 'ranges' => $ranges, + ], + ]; + + + return $return; + + } + + private function getFormatByRange(string $viewRange): string + { + switch ($viewRange) { + default: + throw new FireflyException(sprintf('The date picker does not yet support "%s".', $viewRange)); // @codeCoverageIgnore + case '1D': + case 'custom': + $format = (string)trans('config.month_and_day'); + break; + case '3M': + $format = (string)trans('config.quarter_in_year'); + break; + case '6M': + $format = (string)trans('config.half_year'); + break; + case '1Y': + $format = (string)trans('config.year'); + break; + case '1M': + $format = (string)trans('config.month'); + break; + case '1W': + $format = (string)trans('config.week_in_year'); + break; + } + + return $format; + } } diff --git a/public/js/ff/firefly.js b/public/js/ff/firefly.js index 9e30b171ef..6a1cef1308 100644 --- a/public/js/ff/firefly.js +++ b/public/js/ff/firefly.js @@ -7,7 +7,7 @@ * * See the LICENSE file for details. */ -/** global: moment, accountingConfig, accounting, currencySymbol, mon_decimal_point, frac_digits, showFullList, showOnlyTop, mon_thousands_sep */ +/** global: moment, dateRangeMeta,dateRangeConfig, accountingConfig, accounting, currencySymbol, mon_decimal_point, frac_digits, showFullList, showOnlyTop, mon_thousands_sep */ $(function () { @@ -30,17 +30,17 @@ $(function () { $('.currency-option').on('click', currencySelect); // build the data range: - $('#daterange').text(dateRangeConfig.linkTitle).daterangepicker( + $('#daterange').text(dateRangeMeta.title).daterangepicker( { - ranges: ranges, + ranges: dateRangeConfig.ranges, opens: 'left', locale: { - applyLabel: dateRangeConfig.applyLabel, - cancelLabel: dateRangeConfig.cancelLabel, - fromLabel: dateRangeConfig.fromLabel, - toLabel: dateRangeConfig.toLabel, + applyLabel: dateRangeMeta.labels.apply, + cancelLabel: dateRangeMeta.labels.cancel, + fromLabel: dateRangeMeta.labels.from, + toLabel: dateRangeMeta.labels.to, weekLabel: 'W', - customRangeLabel: dateRangeConfig.customRangeLabel, + customRangeLabel: dateRangeMeta.labels.customRange, daysOfWeek: moment.weekdaysMin(), monthNames: moment.monthsShort(), firstDay: moment.localeData()._week.dow @@ -52,7 +52,7 @@ $(function () { function (start, end, label) { // send post. - $.post(dateRangeConfig.URL, { + $.post(dateRangeMeta.uri, { start: start.format('YYYY-MM-DD'), end: end.format('YYYY-MM-DD'), label: label diff --git a/public/js/lib/daterangepicker.js b/public/js/lib/daterangepicker.js index d0c4c7cb1c..dee8d697f0 100755 --- a/public/js/lib/daterangepicker.js +++ b/public/js/lib/daterangepicker.js @@ -1,14 +1,16 @@ -/* - * daterangepicker.js - * Copyright (c) 2017 thegrumpydictator@gmail.com - * This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License. - * - * See the LICENSE file for details. - */ollow the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js +/** +* @version: 2.1.25 +* @author: Dan Grossman http://www.dangrossman.info/ +* @copyright: Copyright (c) 2012-2017 Dan Grossman. All rights reserved. +* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php +* @website: http://www.daterangepicker.com/ +*/ +// Follow the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Make globaly available as well define(['moment', 'jquery'], function (moment, jquery) { + if (!jquery.fn) jquery.fn = {}; // webpack server rendering return (root.daterangepicker = factory(moment, jquery)); }); } else if (typeof module === 'object' && module.exports) { @@ -19,7 +21,8 @@ jQuery = require('jquery'); if (!jQuery.fn) jQuery.fn = {}; } - module.exports = factory(require('moment'), jQuery); + var moment = (typeof window != 'undefined' && typeof window.moment != 'undefined') ? window.moment : require('moment'); + module.exports = factory(moment, jQuery); } else { // Browser globals root.daterangepicker = factory(root.moment, root.jQuery); @@ -159,9 +162,13 @@ if (typeof options.locale.weekLabel === 'string') this.locale.weekLabel = options.locale.weekLabel; - if (typeof options.locale.customRangeLabel === 'string') - this.locale.customRangeLabel = options.locale.customRangeLabel; - + if (typeof options.locale.customRangeLabel === 'string'){ + //Support unicode chars in the custom range name. + var elem = document.createElement('textarea'); + elem.innerHTML = options.locale.customRangeLabel; + var rangeHtml = elem.value; + this.locale.customRangeLabel = rangeHtml; + } } this.container.addClass(this.locale.direction); @@ -872,7 +879,7 @@ //Preserve the time already selected var timeSelector = this.container.find('.calendar.right .calendar-time div'); - if (!this.endDate && timeSelector.html() != '') { + if (timeSelector.html() != '') { selected.hour(timeSelector.find('.hourselect option:selected').val() || selected.hour()); selected.minute(timeSelector.find('.minuteselect option:selected').val() || selected.minute()); @@ -1266,7 +1273,7 @@ var rightCalendar = this.rightCalendar; var startDate = this.startDate; if (!this.endDate) { - this.container.find('.calendar td').each(function(index, el) { + this.container.find('.calendar tbody td').each(function(index, el) { //skip week numbers, only look at dates if ($(el).hasClass('week')) return; diff --git a/resources/views/javascript/variables.twig b/resources/views/javascript/variables.twig index 19371d350d..8e476e590b 100644 --- a/resources/views/javascript/variables.twig +++ b/resources/views/javascript/variables.twig @@ -1,3 +1,32 @@ + +// date ranges +var ranges = {} +{% for title, range in dateRangeConfig.ranges %} + ranges["{{ title }}"] = [moment("{{ range[0].format('Y-m-d') }}"), moment("{{ range[1].format('Y-m-d') }}")]; +{% endfor %} + +// date range meta configuration +var dateRangeMeta = { + title: "{{ dateRangeTitle }}", + uri: "{{ route('daterange') }}", + labels: { + apply: "{{ 'apply'|_ }}", + cancel: "{{ 'cancel'|_ }}", + from: "{{ 'from'|_ }}", + to: "{{ 'to'|_ }}", + customRange: "{{ 'customRange'|_ }}" + } +}; + +// date range actual configuration: +var dateRangeConfig = { + startDate: moment("{{ dateRangeConfig.start }}"), + endDate: moment("{{ dateRangeConfig.end }}"), + ranges: ranges + +}; + + var language = "{{ language|escape }}"; var currencyCode = '{{ currencyCode|escape('js') }}'; var currencySymbol = '{{ currencySymbol|escape('js') }}';