Built a new routine for intro tours.

This commit is contained in:
James Cole 2017-07-16 07:35:08 +02:00
parent 09131e8c36
commit 58bfb35fa6
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
9 changed files with 185 additions and 44 deletions

View File

@ -67,10 +67,16 @@ class Controller extends BaseController
// get shown-intro-preference: // get shown-intro-preference:
if (auth()->check()) { if (auth()->check()) {
$key = 'shown_demo_' . Route::currentRouteName(); $route = Route::currentRouteName();
$key = 'shown_demo_' . $route;
$config = config('intro.' . $route);
$shownDemo = Preferences::get($key, false)->data; $shownDemo = Preferences::get($key, false)->data;
if (is_null($config) || (is_array($config) && count($config) === 0)) {
// no demo when no data for demo.
$shownDemo = true;
}
View::share('shownDemo', $shownDemo); View::share('shownDemo', $shownDemo);
View::share('current_route_name', Route::currentRouteName()); View::share('current_route_name', $route);
} }
return $next($request); return $next($request);

View File

@ -0,0 +1,67 @@
<?php
/**
* IntroController.php
* 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.
*/
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Json;
use Preferences;
use Response;
/**
* Class IntroController
*
* @package FireflyIII\Http\Controllers\Json
*/
class IntroController
{
/**
* @param string $route
*
* @return \Illuminate\Http\JsonResponse
*/
public function getIntroSteps(string $route)
{
$elements = config(sprintf('intro.%s', $route));
$steps = [];
if (is_array($elements) && count($elements) > 0) {
foreach ($elements as $key => $options) {
$currentStep = $options;
// point to HTML element when not an intro or outro:
if (!in_array($key, ['intro', 'outro'])) {
$currentStep['element'] = '#' . $key;
}
// get the text:
$currentStep['intro'] = trans('intro.' . $route . '_' . $key);
// save in array:
$steps[] = $currentStep;
}
}
return Response::json($steps);
}
/**
* @param string $route
*
* @return \Illuminate\Http\JsonResponse
*/
public function postFinished(string $route)
{
$key = 'shown_demo_' . $route;
Preferences::set($key, true);
return Response::json(['result' => sprintf('Reported demo watched for route "%s".', $route)]);
}
}

25
config/intro.php Normal file
View File

@ -0,0 +1,25 @@
<?php
/**
* intro.php
* 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.
*/
declare(strict_types=1);
/*
* Always make sure intro is the first element (if any) and outro is the last one.
*/
return [
'index' => [
'intro' => [],
'accounts-chart' => [],
'box_out_holder' => [],
'all_transactions' => ['position' => 'left'],
'help' => ['position' => 'bottom'],
'outro' => [],
],
];

View File

@ -6,9 +6,28 @@
* See the LICENSE file for details. * See the LICENSE file for details.
*/ */
/** global: route_for_tour */ /** global: routeForTour, routeStepsUri, routeForFinishedTour */
$(function () { $(function () {
"use strict"; "use strict";
//alert('show user intro for ' + route_for_tour); //alert('show user intro for ' + route_for_tour);
}); $.getJSON(routeStepsUri).done(setupIntro)
});
function setupIntro(steps) {
var intro = introJs();
intro.setOptions({
steps: steps,
exitOnEsc: true,
exitOnOverlayClick: true,
keyboardNavigation: true,
});
intro.oncomplete(reportIntroFinished);
intro.onexit(reportIntroFinished);
intro.start();
}
function reportIntroFinished() {
$.post(routeForFinishedTour);
}

View File

@ -0,0 +1,18 @@
<?php
/**
* intro.php
* 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.
*/
return [
'index_intro' => 'Welcome to the index page of Firefly III. Please take the time to walk through this intro to get a feeling of how Firefly III works.',
'index_accounts-chart' => 'This chart shows the current balance of your asset accounts. You can select the accounts visible here in your preferences.',
'index_box_out_holder' => 'This little box and the boxes next to this one will give you a quick overview of your financial situation',
'index_all_transactions' => 'These boxes will hold your most recent transactions.',
'index_help' => 'If you ever need help with a page or a form, press this button.',
'index_outro' => 'Most pages of Firefly III will start with a little tour like this one. Please contact me when you have questions or comments. Enjoy!',
];

View File

@ -56,48 +56,50 @@
{% endif %} {% endif %}
{# TRANSACTIONS #} {# TRANSACTIONS #}
{% for data in transactions %} <div id="all_transactions">
<div class="box"> {% for data in transactions %}
<div class="box-header with-border"> <div class="box">
<h3 class="box-title"><a href="{{ route('accounts.show', data[1].id) }}">{{ data[1].name }}</a></h3> <div class="box-header with-border">
<h3 class="box-title"><a href="{{ route('accounts.show', data[1].id) }}">{{ data[1].name }}</a></h3>
<div class="box-tools pull-right"> <div class="box-tools pull-right">
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i></button> <button class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i></button>
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li><a href="{{ route('transactions.create','withdrawal') }}?account_id={{ data[1].id }}"><i <li><a href="{{ route('transactions.create','withdrawal') }}?account_id={{ data[1].id }}"><i
class="fa fa-long-arrow-left fa-fw"></i> {{ 'newWithdrawal'|_ }}</a></li> class="fa fa-long-arrow-left fa-fw"></i> {{ 'newWithdrawal'|_ }}</a></li>
<li><a href="{{ route('transactions.create','deposit') }}?account_id={{ data[1].id }}"><i <li><a href="{{ route('transactions.create','deposit') }}?account_id={{ data[1].id }}"><i
class="fa fa-long-arrow-right fa-fw"></i> {{ 'newDeposit'|_ }}</a></li> class="fa fa-long-arrow-right fa-fw"></i> {{ 'newDeposit'|_ }}</a></li>
<li><a href="{{ route('transactions.create','transfer') }}?account_from_id={{ data[1].id }}"><i <li><a href="{{ route('transactions.create','transfer') }}?account_from_id={{ data[1].id }}"><i
class="fa fa-fw fa-exchange"></i> {{ 'newTransfer'|_ }}</a></li> class="fa fa-fw fa-exchange"></i> {{ 'newTransfer'|_ }}</a></li>
</ul> </ul>
</div>
</div> </div>
</div> </div>
{% if data[0].count > 0 %}
<div class="box-body no-padding">
{% include 'list.journals-tiny' with {'transactions': data[0],'account': data[1]} %}
</div>
{% else %}
<div class="box-body">
<p>
<em>
{{ trans('firefly.no_transactions_account', {name: data[1].name}) }}
</em>
</p>
</div>
{% endif %}
<div class="box-footer clearfix">
<a class="btn btn-sm btn-default btn-flat pull-right"
href="{{ route('accounts.show',data[1].id) }}">{{ (data[1]|balance)|formatAmountPlain }}</a>
</div>
</div> </div>
{% endfor %}
{% if data[0].count > 0 %} </div>
<div class="box-body no-padding">
{% include 'list.journals-tiny' with {'transactions': data[0],'account': data[1]} %}
</div>
{% else %}
<div class="box-body">
<p>
<em>
{{ trans('firefly.no_transactions_account', {name: data[1].name}) }}
</em>
</p>
</div>
{% endif %}
<div class="box-footer clearfix">
<a class="btn btn-sm btn-default btn-flat pull-right"
href="{{ route('accounts.show',data[1].id) }}">{{ (data[1]|balance)|formatAmountPlain }}</a>
</div>
</div>
{% endfor %}
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -131,8 +133,6 @@
{% block scripts %} {% block scripts %}
<script type="text/javascript"> <script type="text/javascript">
var billCount = {{ billCount }}; var billCount = {{ billCount }};
// uri's of charts:
var accountFrontpageUri = '{{ route('chart.account.frontpage') }}'; var accountFrontpageUri = '{{ route('chart.account.frontpage') }}';
var accountRevenueUri = '{{ route('chart.account.revenue') }}'; var accountRevenueUri = '{{ route('chart.account.revenue') }}';
var accountExpenseUri = '{{ route('chart.account.expense') }}'; var accountExpenseUri = '{{ route('chart.account.expense') }}';

View File

@ -183,7 +183,9 @@
<script type="text/javascript" src="js/ff/help.js"></script> <script type="text/javascript" src="js/ff/help.js"></script>
{% if not shownDemo %} {% if not shownDemo %}
<script type="text/javascript"> <script type="text/javascript">
var route_for_tour = "{{ current_route_name }}"; var routeForTour = "{{ current_route_name }}";
var routeStepsUri = "{{ route('json.intro', [current_route_name]) }}";
var routeForFinishedTour = "{{ route('json.intro.finished', [current_route_name]) }}";
</script> </script>
<script type="text/javascript" src="lib/intro/intro.min.js"></script> <script type="text/javascript" src="lib/intro/intro.min.js"></script>
<script type="text/javascript" src="js/ff/intro/intro.js"></script> <script type="text/javascript" src="js/ff/intro/intro.js"></script>

View File

@ -8,7 +8,7 @@
<!-- Info boxes --> <!-- Info boxes -->
<div class="row hidden-sm hidden-xs"> <div class="row hidden-sm hidden-xs">
<div class="{{ boxClasses }}"> <div class="{{ boxClasses }}" id="box_out_holder">
<div class="info-box"> <div class="info-box">
<span class="info-box-icon bg-red"> <span class="info-box-icon bg-red">
<i class="fa fa-upload fa-fw"></i> <i class="fa fa-upload fa-fw"></i>

View File

@ -449,6 +449,10 @@ Route::group(
// currency conversion: // currency conversion:
Route::get('rate/{fromCurrencyCode}/{toCurrencyCode}/{date}', ['uses' => 'Json\ExchangeController@getRate', 'as' => 'rate']); Route::get('rate/{fromCurrencyCode}/{toCurrencyCode}/{date}', ['uses' => 'Json\ExchangeController@getRate', 'as' => 'rate']);
// intro things:
Route::get('intro/{route}', ['uses' => 'Json\IntroController@getIntroSteps', 'as' => 'intro']);
Route::post('intro/finished/{route}', ['uses' => 'Json\IntroController@postFinished', 'as' => 'intro.finished']);
} }
); );