UI updates - new user menu, updated about and profile screen and more (#723)

This commit is contained in:
Kevin Papst
2019-04-25 17:50:28 +02:00
committed by GitHub
parent 28801bf1ea
commit 56fe14c451
83 changed files with 1067 additions and 1089 deletions

View File

@@ -0,0 +1,60 @@
{% extends 'base.html.twig' %}
{% import "macros/actions.html.twig" as actions %}
{% block page_title %}{{ 'about.title'|trans({}, 'about') }}{% endblock %}
{% block page_actions %}{{ actions.about('index') }}{% endblock %}
{% block main %}
<div class="row">
<div class="col-md-3">
<div class="box box-primary">
<div class="box-body">
<img src="{{ asset('apple-touch-icon.png') }}" class="profile-user-img img-responsive img-circle" alt="Kimai logo" style="border: 0;">
<h3 class="profile-username text-center">{{ constant('App\\Constants::SOFTWARE') }}</h3>
<p class="text-muted text-center">
{{ constant('App\\Constants::VERSION') }}
{{ constant('App\\Constants::STATUS') }}
({{ constant('App\\Constants::NAME') }})
</p>
<hr>
<ul class="nav nav-stacked">
<li>
<a href="{{ ''|docu_link }}" target="_blank">
<i class="menu-icon fas fa-question bg-navy"></i>
{{ 'help'|trans({}, 'about') }}
</a>
</li>
<li>
<a href="{{ constant('App\\Constants::GITHUB') }}" target="_blank">
<i class="menu-icon fab fa-github bg-gray"></i>
{{ 'support'|trans({}, 'about') }}
</a>
</li>
<li>
<a href="{{ constant('App\\Constants::HOMEPAGE') }}" target="_blank">
<i class="menu-icon fa fa-home bg-green"></i>
{{ 'website'|trans({}, 'about') }}
</a>
</li>
</ul>
<hr>
<p class="text-center">
Made with ♥ by <a href="https://www.kevinpapst.de/">Kevin Papst</a> and <a href="{{ constant('App\\Constants::GITHUB') }}graphs/contributors" target="_blank">great contributors</a>.
</p>
</div>
</div>
{% block about_box %}{% endblock %}
</div>
<div class="col-md-9">
{% block about %}{% endblock %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,39 @@
{% extends 'about/layout.html.twig' %}
{% block about %}
{% embed '@AdminLTE/Widgets/box-widget.html.twig' %}
{% block box_title %}{{ constant('App\\Constants::SOFTWARE') }} is published under{% endblock %}
{% block box_body %}
<pre>
{{ license }}
</pre>
{% endblock %}
{% block box_footer %}
<a class="btn btn-default" href="https://choosealicense.com/licenses/mit/" target="_blank">choosealicense.com</a>
<a class="btn btn-default" href="https://en.wikipedia.org/wiki/MIT_License" target="_blank">wikipedia.org</a>
{% endblock %}
{% endembed %}
{% embed '@AdminLTE/Widgets/box-widget.html.twig' %}
{% block box_title %}Special thanks ...{% endblock %}
{% block box_body %}
<p>... to the authors of the following libraries, Kimai wouldn't be possible without them:</p>
<ul>
<li>AdminLTE: <a href="https://adminlte.io" target="_blank">https://adminlte.io</a></li>
<li>Bootstrap: <a href="https://getbootstrap.com" target="_blank">https://getbootstrap.com</a></li>
<li>Bootstrap-Select: <a href="https://developer.snapappointments.com/bootstrap-select" target="_blank">https://developer.snapappointments.com/bootstrap-select</a></li>
<li>chart.js: <a href="https://www.chartjs.org" target="_blank">https://www.chartjs.org</a></li>
<li>DateRangePicker: <a href="http://www.daterangepicker.com/" target="_blank">http://www.daterangepicker.com/</a></li>
<li>Doctrine: <a href="https://www.doctrine-project.org" target="_blank">https://www.doctrine-project.org</a></li>
<li>FontAwesome: <a href="https://fontawesome.com" target="_blank">https://fontawesome.com</a></li>
<li>FullCalendar: <a href="https://fullcalendar.io" target="_blank">https://fullcalendar.io</a></li>
<li>jQuery: <a href="https://jquery.com" target="_blank">https://jquery.com</a></li>
<li>jQuery UI: <a href="https://jqueryui.com" target="_blank">http://jqueryui.com</a></li>
<li>MomentJS: <a href="https://momentjs.com" target="_blank">https://momentjs.com</a></li>
<li>PHPOffice: <a href="https://github.com/PHPOffice" target="_blank">https://github.com/PHPOffice</a></li>
<li>Symfony: <a href="https://symfony.com" target="_blank">https://symfony.com</a></li>
<li>...</li>
</ul>
{% endblock %}
{% endembed %}
{% endblock %}

View File

@@ -1,149 +1,69 @@
{% extends 'base.html.twig' %}
{% extends 'about/layout.html.twig' %}
{% import "macros/widgets.html.twig" as widgets %}
{% block page_title %}{{ 'about.title'|trans({}, 'about') }}{% endblock %}
{% block page_subtitle %}{{ 'about.subtitle'|trans({}, 'about') }}{% endblock %}
{% block main %}
{% block about_box %}
{% if is_granted('system_actions') %}
{% embed '@AdminLTE/Widgets/box-widget.html.twig' with {'boxtype': 'warning'} %}
{% block box_title %}{{ 'label.actions'|trans }}{% endblock %}
{% block box_body %}
{% if content_action is defined and content_action is not empty %}
<pre>
{{ content_action }}
</pre>
{% endif %}
{{ widgets.callout('info', 'Thank you for using Kimai ' ~ constant('App\\Constants::VERSION') ~ ' ' ~ constant('App\\Constants::STATUS') ~ ' - ' ~ constant('App\\Constants::NAME'), 'Kimai ' ~ constant('App\\Constants::VERSION'), 'fas fa-thumbs-up') }}
<div class="row">
<div class="col-md-12">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs" role="tablist">
<li role="presentation"class ="active"><a href="#systeminfo" aria-controls="systeminfo" role="tab" data-toggle="tab">{{ 'tab.system'|trans({}, 'about') }}</a></li>
<li role="presentation"><a href="#license" aria-controls="license" role="tab" data-toggle="tab">{{ 'tab.license'|trans({}, 'about') }}</a></li>
<li role="presentation"><a href="#thanks" aria-controls="thanks" role="tab" data-toggle="tab">{{ 'tab.thanks'|trans({}, 'about') }}</a></li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="systeminfo">
<div class="box-group" id="accordion">
{% if is_granted('system_actions') %}
<div class="panel box">
<div class="box-header with-border">
<h4 class="box-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseSystemAction" aria-expanded="true">
{{ 'label.actions'|trans }}
</a>
</h4>
</div>
<div id="collapseSystemAction" class="panel-collapse collapse in" aria-expanded="true">
<div class="box-body">
<p>
<a href="{{ path('system_flush_cache') }}" class="btn btn-primary" onclick="$(this).html('Clear cache <i class=\'fas fa-spinner fa-spin\'></i>')">Clear cache</a>
</p>
{% if content_action is defined and content_action is not empty %}
<pre>
{{ content_action }}
</pre>
{% endif %}
</div>
</div>
</div>
{% endif %}
<div class="panel box">
<div class="box-header with-border">
<h4 class="box-title">
<a data-toggle="collapse" role="button" data-parent="#accordion" href="#collapseEnvironment" aria-expanded="false" aria-controls="collapseEnvironment">
Environment
</a>
</h4>
</div>
<div id="collapseEnvironment" class="panel-collapse collapse" aria-expanded="false" role="tabpanel">
<div class="box-body">
<dl>
{% for name, value in dotenv %}
<dt>{{ name }}</dt>
<dd>{{ value }}</dd>
{% endfor %}
</dl>
</div>
</div>
</div>
<div class="panel box">
<div class="box-header with-border">
<h4 class="box-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapsePhp" class="collapsed" aria-expanded="false">
PHP
</a>
</h4>
</div>
<div id="collapsePhp" class="panel-collapse collapse" aria-expanded="false">
<div class="box-body">
<dl>
<dt>Version</dt><dd>{{ constant('PHP_VERSION') }}</dd>
<dt>Modules</dt><dd>{{ modules|join(', ') }}</dd>
{% for name, value in settings %}
<dt>{{ name }}</dt>
<dd>
{% if value is empty %}
<i>unknown</i>
{% else %}
{{ value }}
{% endif %}
</dd>
{% endfor %}
</dl>
</div>
</div>
</div>
<div class="panel box">
<div class="box-header with-border">
<h4 class="box-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseSystem" class="collapsed" aria-expanded="false">
Server
</a>
</h4>
</div>
<div id="collapseSystem" class="panel-collapse collapse" aria-expanded="false">
<div class="box-body">
<dl>
{% for name, value in info %}
<dt>{{ name }}</dt>
<dd>{{ value|raw }}</dd>
{% endfor %}
</dl>
</div>
</div>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="license">
<pre>{{ license }}</pre>
<p>
<a href="https://choosealicense.com/licenses/mit/" target="_blank">choosealicense.com</a>,
<a href="https://en.wikipedia.org/wiki/MIT_License" target="_blank">wikipedia.org</a>
</p>
</div>
<div role="tabpanel" class="tab-pane" id="thanks">
<p>Special thanks to the authors of the following libraries, Kimai wouldn't be possible without them:</p>
<ul>
<li>AdminLTE: <a href="https://adminlte.io" target="_blank">https://adminlte.io</a></li>
<li>Bootstrap: <a href="https://getbootstrap.com" target="_blank">https://getbootstrap.com</a></li>
<li>Bootstrap-Select: <a href="https://developer.snapappointments.com/bootstrap-select" target="_blank">https://developer.snapappointments.com/bootstrap-select</a></li>
<li>chart.js: <a href="https://www.chartjs.org" target="_blank">https://www.chartjs.org</a></li>
<li>DateRangePicker: <a href="http://www.daterangepicker.com/" target="_blank">http://www.daterangepicker.com/</a></li>
<li>Doctrine: <a href="https://www.doctrine-project.org" target="_blank">https://www.doctrine-project.org</a></li>
<li>FontAwesome: <a href="https://fontawesome.com" target="_blank">https://fontawesome.com</a></li>
<li>FullCalendar: <a href="https://fullcalendar.io" target="_blank">https://fullcalendar.io</a></li>
<li>jQuery: <a href="https://jquery.com" target="_blank">https://jquery.com</a></li>
<li>jQuery UI: <a href="https://jqueryui.com" target="_blank">http://jqueryui.com</a></li>
<li>MomentJS: <a href="https://momentjs.com" target="_blank">https://momentjs.com</a></li>
<li>Symfony: <a href="https://symfony.com" target="_blank">https://symfony.com</a></li>
<li>...</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<p>
<a href="{{ path('system_flush_cache') }}" class="btn btn-primary" onclick="$(this).html('Clear cache <i class=\'fas fa-spinner fa-spin\'></i>')">Clear cache</a>
</p>
{% endblock %}
{% endembed %}
{% endif %}
{% endblock %}
{% block about %}
{% embed '@AdminLTE/Widgets/box-widget.html.twig' %}
{% block box_title %}Environment{% endblock %}
{% block box_body %}
<dl>
{% for name, value in dotenv %}
<dt>{{ name }}</dt>
<dd>{{ value }}</dd>
{% endfor %}
</dl>
{% endblock %}
{% endembed %}
{% embed '@AdminLTE/Widgets/box-widget.html.twig' %}
{% block box_title %}PHP{% endblock %}
{% block box_body %}
<dl>
<dt>Version</dt><dd>{{ constant('PHP_VERSION') }}</dd>
<dt>Modules</dt><dd>{{ modules|join(', ') }}</dd>
{% for name, value in settings %}
<dt>{{ name }}</dt>
<dd>
{% if value is empty %}
<i>unknown</i>
{% else %}
{{ value }}
{% endif %}
</dd>
{% endfor %}
</dl>
{% endblock %}
{% endembed %}
{% embed '@AdminLTE/Widgets/box-widget.html.twig' %}
{% block box_title %}Server{% endblock %}
{% block box_body %}
<dl>
{% for name, value in info %}
<dt>{{ name }}</dt>
<dd>{{ value|raw }}</dd>
{% endfor %}
</dl>
{% endblock %}
{% endembed %}
{% endblock %}

View File

@@ -20,9 +20,9 @@
{% set columns = {
'name': 'alwaysVisible',
'customer': 'hidden-xs',
'project': '',
'project': 'hidden-xs',
'comment': 'hidden-xs',
'visible': 'hidden-xs',
'visible': '',
'actions': 'alwaysVisible',
} %}

View File

@@ -1,6 +1,6 @@
{% extends '@AdminLTE/layout/default-layout-avanzu.html.twig' %}
{% extends '@AdminLTE/layout/default-layout.html.twig' %}
{% block avanzu_after_body_start %}
{% block after_body_start %}
{% embed 'embeds/modal.html.twig' %}
{% block modal_id %}remote_form_modal{% endblock %}
{% block modal_title %}{% endblock %}
@@ -9,7 +9,7 @@
{% endembed %}
{% endblock %}
{% block avanzu_page_content_before %}
{% block page_content_before %}
{% set event = trigger(constant('App\\Event\\ThemeEvent::CONTENT_BEFORE')) %}
{{ event.content|raw }}
<div class="toolbar-pad no-print">
@@ -17,13 +17,13 @@
</div>
{% endblock %}
{% block avanzu_page_content_after %}
{% block page_content_after %}
{% block main_after %}{% endblock %}
{% set event = trigger(constant('App\\Event\\ThemeEvent::CONTENT_AFTER')) %}
{{ event.content|raw }}
{% endblock %}
{% block avanzu_page_content %}
{% block page_content %}
{% set event = trigger(constant('App\\Event\\ThemeEvent::CONTENT_START')) %}
{{ event.content|raw }}
{% block main %}{% endblock %}
@@ -31,33 +31,25 @@
{{ event.content|raw }}
{% endblock %}
{% block avanzu_document_title %}
{% block title %}{{ 'browser.title'|trans }}{% endblock %}
{% block title %}
{{ 'browser.title'|trans }}
{% endblock %}
{% block avanzu_page_title %}
{% block page_title %}{% endblock %}
{% endblock %}
{% block page_subtitle %}{% endblock %}
{% block avanzu_page_subtitle %}
{% block page_subtitle %}{% endblock %}
{% endblock %}
{% block avanzu_logo_mini %}
{% block logo_mini %}
<b>K</b>TT
{% endblock %}
{% block avanzu_logo_lg %}
{% block logo_large %}
<b>Kimai</b> - Time Tracking
{% endblock %}
{% block avanzu_footer %}
{% block footer %}
{% block footer %}
<!-- Page rendered on {{ 'now'|localizeddate('long', 'long', null, 'UTC') }} -->
{% endblock %}
{% endblock %}
{% block avanzu_navbar_messages %}
{% block navbar_messages %}
{% if app.user is not null and is_granted('IS_AUTHENTICATED_REMEMBERED') %}
{% if is_granted('view_own_timesheet') %}
<li class="visible-xs-inline-block">
@@ -85,23 +77,76 @@
{% endif %}
{% endblock %}
{% block avanzu_navbar_notifications %}
{% block navbar_notifications %}
{% if app.user is not null and is_granted('IS_AUTHENTICATED_REMEMBERED') %}
{{ render(controller('App\\Controller\\NavbarController::recentActivitiesAction')) }}
{% endif %}
{% endblock %}
{# deactivated blocks #}
{% block avanzu_navbar_tasks %}{% endblock %}
{% block avanzu_navbar_user %}{% endblock %}
{% block avanzu_sidebar_user %}{% endblock %}
{% block avanzu_sidebar_search %}{% endblock %}
{% block navbar_tasks %}{% endblock %}
{% block sidebar_user %}{% endblock %}
{% block sidebar_search %}{% endblock %}
{% block avanzu_breadcrumb %}
{{ block('page_actions') }}
{% block navbar_user %}
{% import "macros/widgets.html.twig" as widgets %}
<li class="dropdown user-menu">
<a href="#" class="dropdown-toggle ddt-large" data-toggle="dropdown">
<i class="{{ 'user'|icon }} fa-2x"></i>
</a>
<ul class="dropdown-menu">
{% if app.user is not null %}
<li>
<a href="{{ path('user_profile', {'username' : app.user.username}) }}">
<h4 class="control-sidebar-subheading">
<i class="{{ 'profile-stats'|icon }}"></i>
{{ widgets.username(app.user) }}
</h4>
</a>
</li>
<li>
<a href="{{ path('user_profile_edit', {'username' : app.user.username}) }}">
<h4 class="control-sidebar-subheading">
<i class="{{ 'profile'|icon }}"></i>
{{ 'profile.title'|trans }}
</h4>
</a>
</li>
<li>
<a href="{{ path('user_profile_preferences', {'username' : app.user.username}) }}">
<h4 class="control-sidebar-subheading">
<i class="{{ 'settings'|icon }}"></i>
{{ 'profile.preferences'|trans }}
</h4>
</a>
</li>
<li>
<a href="{{ path('fos_user_security_logout') }}">
<h4 class="control-sidebar-subheading">
<i class="{{ 'logout'|icon }}"></i>
{{ 'menu.logout'|trans }}
</h4>
</a>
</li>
{% endif %}
{% if kimai_context.show_about %}
<li class="divider"></li>
<li>
<a href="{{ path('about') }}">
<h4 class="control-sidebar-subheading">
<i class="{{ 'about'|icon }}"></i>
{{ 'about.title'|trans({}, 'about') }}
</h4>
</a>
</li>
{% endif %}
</ul>
</li>
{% endblock %}
{% block page_actions %}{% endblock %}
{% block breadcrumb %}
{% block page_actions %}{% endblock %}
{% endblock %}
{% block stylesheets %}
{# we do not call parent() as we use a custom built for the frontend assets and don't want the default <stylesheet> #}

View File

@@ -1,31 +1,5 @@
{% extends 'base.html.twig' %}
{% block page_title %}{{ 'http_error.title'|trans({}, 'exceptions') }}{% endblock %}
{% block page_subtitle %}{{ status_code }}{% endblock %}
{% extends 'error.html.twig' %}
{% block main %}
{% set errorTitleKey = "http_error_#{status_code}.description" %}
{% set errorTitleTrans = errorTitleKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% if errorTitleKey == errorTitleTrans %}
{% set errorTitleKey = 'http_error.description' %}
{% set errorTitleTrans = errorTitleKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% endif %}
{% set errorMessageKey = "http_error_#{status_code}.suggestion" %}
{% set errorMessageTrans = errorMessageKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% if errorMessageKey == errorMessageTrans %}
{% set errorMessageKey = 'http_error.suggestion' %}
{% set errorMessageTrans = errorMessageKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% endif %}
<div class="error-page">
<h2 class="headline text-yellow"> {{ status_code }}</h2>
<div class="error-content">
<h3><i class="fas fa-unlock-alt text-yellow"></i> {{ errorTitleTrans }}</h3>
<p>{{ errorMessageTrans }}</p>
</div>
</div>
{% block error_icon %}
<i class="fas fa-unlock-alt text-yellow"></i>
{% endblock %}
{% block avanzu_control_sidebar %}{% endblock %}
{% block avanzu_navbar_control_sidebar_toggle %}{% endblock %}

View File

@@ -1,31 +1 @@
{% extends 'base.html.twig' %}
{% block page_title %}{{ 'http_error.title'|trans({}, 'exceptions') }}{% endblock %}
{% block page_subtitle %}{{ status_code }}{% endblock %}
{% block main %}
{% set errorTitleKey = "http_error_#{status_code}.description" %}
{% set errorTitleTrans = errorTitleKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% if errorTitleKey == errorTitleTrans %}
{% set errorTitleKey = 'http_error.description' %}
{% set errorTitleTrans = errorTitleKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% endif %}
{% set errorMessageKey = "http_error_#{status_code}.suggestion" %}
{% set errorMessageTrans = errorMessageKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% if errorMessageKey == errorMessageTrans %}
{% set errorMessageKey = 'http_error.suggestion' %}
{% set errorMessageTrans = errorMessageKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% endif %}
<div class="error-page">
<h2 class="headline text-yellow"> {{ status_code }}</h2>
<div class="error-content">
<h3><i class="fas fa-unlock-alt text-yellow"></i> {{ errorTitleTrans }}</h3>
<p>{{ errorMessageTrans }}</p>
</div>
</div>
{% endblock %}
{% block avanzu_control_sidebar %}{% endblock %}
{% block avanzu_navbar_control_sidebar_toggle %}{% endblock %}
{% extends 'error.html.twig' %}

View File

@@ -17,8 +17,8 @@
{% endif %}
{% endblock %}
{% block modal_footer %}
<button type="submit" class="btn {% if used %}btn-outline{% else %}btn-primary{% endif %} pull-left modal-form-save" data-loading-text="{{ 'action.delete'|trans }}..." id="{{ block('modal_id') }}_save">{{ 'action.delete'|trans }}</button>
<button type="button" class="btn btn-default btn-cancel" data-dismiss="modal">{{ 'action.close'|trans }}</button>
<button type="submit" class="btn {% if used %}btn-outline{% else %}btn-primary{% endif %} modal-form-save" data-loading-text="{{ 'action.delete'|trans }}..." id="{{ block('modal_id') }}_save">{{ 'action.delete'|trans }}</button>
{% endblock %}
{% block modal_end %}{{ form_end(form) }}{% endblock %}
{% endembed %}

View File

@@ -11,8 +11,8 @@
{{ form_widget(form) }}
{% endblock %}
{% block modal_footer %}
<button type="submit" class="btn btn-primary pull-left modal-form-save" data-loading-text="{{ 'action.save'|trans }}..." id="{{ block('modal_id') }}_save">{{ 'action.save'|trans }}</button>
<button type="button" class="btn btn-default btn-cancel" data-dismiss="modal">{{ 'action.close'|trans }}</button>
<button type="submit" class="btn btn-primary modal-form-save" data-loading-text="{{ 'action.save'|trans }}..." id="{{ block('modal_id') }}_save">{{ 'action.save'|trans }}</button>
{% endblock %}
{% block modal_end %}{{ form_end(form) }}{% endblock %}
{% endembed %}

33
templates/error.html.twig Normal file
View File

@@ -0,0 +1,33 @@
{% extends 'base.html.twig' %}
{% block page_title %}{{ 'http_error.title'|trans({}, 'exceptions') }}{% endblock %}
{% block page_subtitle %}{{ status_code }}{% endblock %}
{% block main %}
{% set errorTitleKey = "http_error_#{status_code}.description" %}
{% set errorTitleTrans = errorTitleKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% if errorTitleKey == errorTitleTrans %}
{% set errorTitleKey = 'http_error.description' %}
{% set errorTitleTrans = errorTitleKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% endif %}
{% set errorMessageKey = "http_error_#{status_code}.suggestion" %}
{% set errorMessageTrans = errorMessageKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% if errorMessageKey == errorMessageTrans %}
{% set errorMessageKey = 'http_error.suggestion' %}
{% set errorMessageTrans = errorMessageKey|trans({ '%status_code%': status_code }, 'exceptions') %}
{% endif %}
<div class="error-page">
<h2 class="headline text-yellow"> {{ status_code }}</h2>
{% block error_content %}
<div class="error-content">
<h3>{% block error_icon %}{% endblock %} {{ errorTitleTrans }}</h3>
<p>{{ errorMessageTrans }}</p>
<a class="btn btn-primary" href="javascript:window.history.back();">{{ 'action.back'|trans }}</a>
</div>
{% endblock %}
</div>
{% endblock %}

View File

@@ -8,6 +8,7 @@
{% block page_actions %}
{% set actions = {
'filter': '#collapseExport',
'visibility': '#modal_export',
'off': {'id':'export-toggle-button'}
} %}
{{ widgets.page_actions(actions) }}
@@ -27,13 +28,13 @@
{{ widgets.callout('warning', 'error.no_entries_found') }}
{% else %}
{% set columns = {
'date': '',
'date': 'alwaysVisible',
'user': 'hidden-xs hidden-sm',
'customer': 'hidden-xs hidden-sm',
'project': 'hidden-xs hidden-sm',
'activity': 'hidden-xs hidden-sm',
'description': 'hidden-xs hidden-sm',
'unit_price': '',
'unit_price': 'hidden-xs',
'duration': '',
'total_rate': '',
'exported': 'alwaysVisible',
@@ -55,20 +56,20 @@
{% endif %}
<tr>
<td class="text-nowrap">{{ entry.begin|date_short }}</td>
<td class="hidden-xs hidden-sm">{{ widgets.label_user(entry.user) }}</td>
<td class="hidden-xs hidden-sm">{{ widgets.label_customer(entry.project.customer) }}</td>
<td class="hidden-xs hidden-sm">{{ widgets.label_project(entry.project) }}</td>
<td class="hidden-xs hidden-sm">{{ widgets.label_activity(entry.activity) }}</td>
<td class="hidden-xs hidden-sm timesheet-description">
<td class="{{ tables.data_table_column_class(tableName, columns, 'user') }}">{{ widgets.label_user(entry.user) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'customer') }}">{{ widgets.label_customer(entry.project.customer) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'project') }}">{{ widgets.label_project(entry.project) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'activity') }}">{{ widgets.label_activity(entry.activity) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'description') }} timesheet-description">
{{ entry.description }}
</td>
<td class="text-nowrap">
<td class="{{ tables.data_table_column_class(tableName, columns, 'unit_price') }} text-nowrap">
{{ rate|money(currency) }}
</td>
<td class="text-nowrap">
<td class="{{ tables.data_table_column_class(tableName, columns, 'duration') }} text-nowrap">
{{ duration }}
</td>
<td class="text-nowrap">
<td class="{{ tables.data_table_column_class(tableName, columns, 'total_rate') }} text-nowrap">
{{ entry.rate|money(currency) }}
</td>
<td>

View File

@@ -6,7 +6,7 @@
{% block page_title %}{{ 'invoice.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'invoice.subtitle'|trans }}{% endblock %}
{% block page_actions %}
{% set actions = {'filter': '#collapseInvoice'} %}
{% set actions = {'filter': '#collapseInvoice', 'visibility': '#modal_invoice'} %}
{% if is_granted('create_invoice_template') %}
{% set actions = actions|merge({'create': path('admin_invoice_template_create')}) %}
{% endif %}
@@ -37,10 +37,10 @@
{{ widgets.callout('success', 'invoice.preview') }}
{% set columns = {
'date': '',
'user': 'hidden-xs hidden-sm',
'activity': 'hidden-xs hidden-sm',
'unit_price': 'text-center',
'date': 'alwaysVisible',
'user': 'hidden-sm',
'description': 'hidden-xs hidden-sm',
'unit_price': 'hidden-xs text-center',
'amount': 'text-center',
'total_rate': 'text-right',
} %}
@@ -60,17 +60,17 @@
{% endif %}
<tr>
<td class="text-nowrap">{{ entry.begin|date_short }}</td>
<td class="hidden-xs hidden-sm">{{ widgets.label_user(entry.user) }}</td>
<td class="hidden-xs hidden-sm timesheet-description">
<td class="{{ tables.data_table_column_class(tableName, columns, 'user') }}">{{ widgets.label_user(entry.user) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'description') }} timesheet-description">
{% if entry.description is not empty %}
{{ entry.description|desc2html }}
{% else %}
{{ entry.activity.name }} / {{ entry.project.name }}
{% endif %}
</td>
<td class="text-center">{{ rate|money(model.calculator.currency) }}</td>
<td class="text-center text-nowrap">{{ duration }}</td>
<td class="text-right text-nowrap">{{ entry.rate|money(model.calculator.currency) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'unit_price') }} text-center">{{ rate|money(model.calculator.currency) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'amount') }} text-center text-nowrap">{{ duration }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'total_rate') }} text-right text-nowrap">{{ entry.rate|money(model.calculator.currency) }}</td>
</tr>
{% endfor %}
{{ tables.data_table_footer(entries) }}

View File

@@ -56,7 +56,7 @@
<thead>
<tr>
<th>{{ 'label.date'|trans }}</th>
<th>{{ 'label.activity'|trans }}</th>
<th>{{ 'label.description'|trans }}</th>
<th>{{ 'label.unit_price'|trans }}</th>
<th>{{ 'label.hours'|trans }}</th>
<th>{{ 'label.total_rate'|trans }}</th>

View File

@@ -244,3 +244,31 @@
{{ widgets.page_actions(event.payload.actions) }}
{% endif %}
{% endmacro %}
{% macro about(view) %}
{% import "macros/widgets.html.twig" as widgets %}
{% set actions = {'about': {'url': path('about')}} %}
{% if is_granted('system_information') %}
{% set actions = actions|merge({'debug': path('about_debug')}) %}
{% endif %}
{% set event = trigger('actions.about', {'actions': actions, 'view': view}) %}
{{ widgets.page_actions(event.payload.actions) }}
{% endmacro %}
{% macro profile(view, user) %}
{% import "macros/widgets.html.twig" as widgets %}
{% set actions = {'profile-stats': {'url': path('user_profile', {'username' : user.username})}} %}
{% if is_granted('edit', user) %}
{% set actions = actions|merge({'profile': {'url': path('user_profile_edit', {'username' : user.username})}}) %}
{% endif %}
{% if is_granted('preferences', user) %}
{% set actions = actions|merge({'settings': {'url': path('user_profile_preferences', {'username' : user.username})}}) %}
{% endif %}
{% set event = trigger('actions.profile', {'actions': actions, 'view': view}) %}
{{ widgets.page_actions(event.payload.actions) }}
{% endmacro %}

View File

@@ -21,8 +21,9 @@
<p>{{ 'modal.columns.description'|trans }}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary pull-left" onclick="$.datatable.saveVisibility('#modal_{{ name }}')">{{ 'action.save'|trans }}</button>
<button type="button" class="btn btn-warning pull-left" onclick="$.datatable.resetVisibility('#modal_{{ name }}')">{{ 'action.delete'|trans }}</button>
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'action.close'|trans }}</button>
<button type="button" class="btn btn-primary" onclick="$.datatable.saveVisibility('#modal_{{ name }}')">{{ 'action.save'|trans }}</button>
</div>
</div>
</div>

View File

@@ -19,10 +19,10 @@
{% else %}
{% set columns = {
'name': 'alwaysVisible',
'customer': '',
'customer': 'hidden-xs',
'comment': 'hidden-xs hidden-sm',
'budget': 'hidden-xs',
'visible': 'hidden-xs',
'visible': '',
'actions': 'alwaysVisible',
} %}

View File

@@ -1,45 +0,0 @@
{% import "macros/widgets.html.twig" as widgets %}
{% set version = constant('App\\Constants::VERSION') ~ ' ' ~ constant('App\\Constants::STATUS') %}
<h3 class="control-sidebar-heading">Kimai v2 - {{ version }}</h3>
<div class="form-group">
{{ 'home.betainfo'|trans({'%version%': version}, 'sidebar')|raw|nl2br }}
</div>
<ul class="control-sidebar-menu">
<li>
<a href="{{ constant('App\\Constants::GITHUB') }}" target="_blank">
<i class="menu-icon fab fa-github bg-gray"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">GitHub</h4>
<p>{{ 'home.github'|trans({}, 'sidebar')|raw }}</p>
</div>
</a>
</li>
<li>
<a href="{{ constant('App\\Constants::HOMEPAGE') }}" target="_blank">
<i class="menu-icon fa fa-home bg-green"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'home.website'|trans({}, 'sidebar') }}</h4>
<p>www.kimai.org</p>
</div>
</a>
</li>
{% if is_granted('system_information') %}
<li>
<a href="{{ path('about') }}">
<i class="menu-icon far fa-copyright bg-aqua"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'about.title'|trans({}, 'about') }}</h4>
<p>{{ 'about.subtitle'|trans({}, 'about') }}</p>
</div>
</a>
</li>
{% endif %}
</ul>
<p><br>Made with ♥ by <a href="https://www.kevinpapst.de/">Kevin Papst</a> and <a href="{{ constant('App\\Constants::GITHUB') }}graphs/contributors" target="_blank">great contributors</a>.</p>

View File

@@ -1,68 +0,0 @@
{% import "@AdminLTE/Macros/default.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
{% set linkUserProfile = path('user_profile', {'username' : user.username}) %}
{% if not is_granted('view_own_profile') %}
{% set linkUserProfile = '#' %}
{% endif %}
<ul class="control-sidebar-menu">
<li>
<a href="{{ linkUserProfile }}">
<div class="pull-left image">
{{ macro.avatar(user.avatar, user.username, 'img-circle') }}
</div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ widgets.username(user) }}</h4>
<p>{{ user.title }}</p>
</div>
</a>
</li>
</ul>
<ul class="control-sidebar-menu">
{% if is_granted('edit_own_profile') %}
<li>
<a href="{{ path('user_profile_edit', {'username' : user.username}) }}">
<div class="pull-left image">
<i class="{{ 'user'|icon }} text-gray"></i>
</div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'profile.title'|trans }}</h4>
</div>
</a>
</li>
{% endif %}
{% if is_granted('preferences_own_profile') %}
<li>
<a href="{{ path('user_profile_preferences', {'username' : user.username}) }}">
<div class="pull-left image">
<i class="{{ 'settings'|icon }} text-gray"></i>
</div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'profile.preferences'|trans }}</h4>
</div>
</a>
</li>
{% endif %}
<li>
<a href="{{ ''|docu_link }}" target="_blank">
<div class="pull-left image">
<i class="{{ 'help'|icon }} text-gray"></i>
</div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'home.help'|trans({}, 'sidebar') }}</h4>
</div>
</a>
</li>
<li>
<a href="{{ path('fos_user_security_logout') }}">
<div class="pull-left image">
<i class="{{ 'logout'|icon }} text-gray"></i>
</div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'menu.logout'|trans }}</h4>
</div>
</a>
</li>
</ul>

View File

@@ -0,0 +1,16 @@
{% extends 'user/layout.html.twig' %}
{% import "macros/actions.html.twig" as actions %}
{% block main %}
{% embed '@AdminLTE/Widgets/box-widget.html.twig' %}
{% block box_title %}{{ ('profile.' ~ tab)|trans }}{% endblock %}
{% block box_body %}
{{ form_start(form) }}
{{ form_widget(form) }}
<input type="submit" value="{{ 'action.save'|trans }}" class="btn btn-primary" />
{{ form_end(form) }}
{% endblock %}
{% endembed %}
{% endblock %}

View File

@@ -28,7 +28,7 @@
'username': 'hidden-xs',
'email': 'hidden-xs hidden-sm',
'title': 'hidden-xs',
'roles': '',
'roles': 'hidden-xs',
'active': '',
'actions': 'alwaysVisible',
} %}

View File

@@ -0,0 +1,151 @@
{% extends 'base.html.twig' %}
{% import "macros/actions.html.twig" as actions %}
{% block page_title %}{{ 'profile.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'profile.subtitle'|trans }}{% endblock %}
{% block page_actions %}{{ actions.profile(tab, user) }}{% endblock %}
{% block main %}
{% import _self as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="row">
<div class="col-md-9">
{% block profile_content %}{% endblock %}
</div>
<div class="col-md-3">
{{ macro.profile_box(user, stats) }}
{{ macro.profile_infos(user, stats) }}
</div>
</div>
{% endblock %}
{% macro profile_infos(user, stats) %}
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'profile.about_me'|trans }}</h3>
</div>
<div class="box-body">
<ul class="nav nav-stacked">
{# colors = purple, blue, aqua, red, green #}
<li><a href="#">{{ 'label.id'|trans }} <span class="pull-right badge bg-aqua">{{ user.id }}</span></a></li>
<li><a href="#">{{ 'label.username'|trans }} <span class="pull-right badge bg-blue">{{ user.username }}</span></a></li>
<li><a href="#">{{ 'profile.first_entry'|trans }} <span class="pull-right badge bg-purple">{{ stats.firstEntry|date_short }}</span></a></li>
{% if is_granted('view_rate_own_timesheet') %}
<li><a href="#">{{ 'label.hourlyRate'|trans }} <span class="pull-right badge bg-blue">{{ user.preferenceValue('hourly_rate') }}</span></a></li>
{% endif %}
</ul>
</div>
</div>
{% endmacro %}
{% macro profile_box(user, stats) %}
{% import "@AdminLTE/Macros/default.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="box box-primary">
<div class="box-body box-profile">
{{ macro.avatar(user.avatar, user.username, 'profile-user-img img-responsive img-circle') }}
<h3 class="profile-username text-center">{{ widgets.username(user) }}</h3>
<p class="text-muted text-center">{{ user.title }}</p>
<ul class="list-group list-group-unbordered">
<li class="list-group-item">
<b>{{ 'stats.durationMonth'|trans }}</b> <a class="pull-right">{{ stats.durationThisMonth|duration }}</a>
</li>
{% if is_granted('view_rate_own_timesheet') %}
<li class="list-group-item">
<b>{{ 'stats.amountMonth'|trans }}</b> <a class="pull-right">{{ stats.amountThisMonth|money }}</a>
</li>
{% endif %}
<li class="list-group-item">
<b>{{ 'stats.durationTotal'|trans }}</b> <a class="pull-right">{{ stats.durationTotal|duration }}</a>
</li>
{% if is_granted('view_rate_own_timesheet') %}
<li class="list-group-item">
<b>{{ 'stats.amountTotal'|trans }}</b> <a class="pull-right">{{ stats.amountTotal|money }}</a>
</li>
{% endif %}
</ul>
</div>
</div>
{% endmacro %}
{# -------------------------------- UNUSED FOR NOW -------------------------------- #}
{% macro profile_list_unused(user, items, color) %}
{% import "@AdminLTE/Macros/default.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="box box-widget widget-user-2">
<!-- Add the bg color to the header using any of the bg-* classes -->
<div class="widget-user-header bg-{{ color|default(kimai_context.box_color) }}">
<div class="widget-user-image">
{{ macro.avatar(user.avatar, user.username) }}
</div>
<!-- /.widget-user-image -->
<h3 class="widget-user-username">{{ widgets.username(user) }}</h3>
<h5 class="widget-user-desc">{{ user.title }}</h5>
</div>
<div class="box-footer no-padding">
<ul class="nav nav-stacked">
{% for entry in items %}
<li><a href="{{ entry.url }}">{{ entry.title|trans }} <span class="pull-right badge bg-{{ entry.color }}">{{ entry.value }}</span></a></li>
{% endfor %}
</ul>
</div>
</div>
{% endmacro %}
{# -------------------------------- UNUSED FOR NOW -------------------------------- #}
{% macro profile_box_unused(user, stats, color) %}
{% import "@AdminLTE/Macros/default.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="box box-widget widget-user">
<div class="widget-user-header bg-{{ color|default(kimai_context.box_color) }}">
<h3 class="widget-user-username">{{ widgets.username(user) }}</h3>
<h5 class="widget-user-desc">{{ user.title }}</h5>
</div>
<div class="widget-user-image">
{{ macro.avatar(user.avatar, user.username) }}
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-6 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.durationTotal|duration }}</h5>
<span class="description-text">{{ 'stats.durationTotal'|trans }}</span>
</div>
</div>
<div class="col-sm-6 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.amountTotal|money }}</h5>
<span class="description-text">{{ 'stats.amountTotal'|trans }}</span>
</div>
</div>
<div class="col-sm-6 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.durationThisMonth|duration }}</h5>
<span class="description-text">{{ 'stats.durationMonth'|trans }}</span>
</div>
</div>
<div class="col-sm-6 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.amountThisMonth|money }}</h5>
<span class="description-text">{{ 'stats.amountMonth'|trans }}</span>
</div>
</div>
</div>
</div>
</div>
{% endmacro %}

View File

@@ -1,117 +1,24 @@
{% extends 'base.html.twig' %}
{% block page_title %}{{ 'profile.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'profile.subtitle'|trans }}{% endblock %}
{% extends 'user/layout.html.twig' %}
{% import "macros/actions.html.twig" as actions %}
{% block main %}
{% import _self as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="row">
<div class="col-md-3">
{{ macro.profile_box(user, stats) }}
{{ macro.profile_infos(user, stats, local_time) }}
</div>
<div class="col-md-9">
<div class="col-md-12">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li {% if tab == "charts" %}class="active"{% endif %}><a href="#charts" data-toggle="tab" aria-expanded="true">{{ 'profile.tab_monthly'|trans }}</a></li>
{% for formName, form in forms %}
<li {% if tab == formName %}class="active"{% endif %}><a href="#{{ formName }}" data-toggle="tab" aria-expanded="false">{{ ('profile.' ~ formName)|trans }}</a></li>
{% endfor %}
</ul>
<div class="tab-content">
<div class="tab-pane {% if tab == "charts" %}active{% endif %}" id="charts">
{% if years is empty %}
{{ widgets.callout('warning', 'error.no_entries_found') }}
{% endif %}
<script type="text/javascript">
var userProfileChartOptions = {
maintainAspectRatio : true,
responsive : true,
legend : false,
barPercentage : 0.5,
categoryPercentage : 0.9,
scales: {
xAxes: [{
gridLines: {
display: false
}
}],
yAxes: [{
gridLines: {
display: true,
color: 'rgba(0,0,0,.05)',
lineWidth: 1
}
}]
}
};
var userProfileChartLabels = [
{% for i in 1..12 %}
'{{ ('month.' ~i)|trans }}'
{% if not loop.last %},{% endif %}
{% endfor %}
];
</script>
{% for year,yearStat in years %}
<h2>{{ year }}</h2>
<div class="chart">
<canvas id="userProfileChart{{ year }}" style="height: 200px;"></canvas>
</div>
<script type="text/javascript">
$(document).ready(function () {
var userProfileChartData{{ year }} = {
labels: userProfileChartLabels,
datasets: [
{
label: '{{ year }}',
backgroundColor : '#00a65a',
borderColor : '#00a65a',
data: [
{% for month in yearStat.months %}
{{ (month.totalDuration / 3600)|round }}
{% if not loop.last %},{% endif %}
{% endfor %}
]
}
]
};
var userProfileChartCanvas{{ year }} = $("#userProfileChart{{ year }}").get(0).getContext("2d");
{% if tab == 'charts' %}
var userProfileChart{{ year }} = new Chart(
userProfileChartCanvas{{ year }}, {
type: 'bar',
data: userProfileChartData{{ year }},
options: userProfileChartOptions
}
);
{% endif %}
$('a[href="#charts"]').on('shown.bs.tab', function(event){
var userProfileChart{{ year }} = new Chart(
userProfileChartCanvas{{ year }}, {
type: 'bar',
data: userProfileChartData{{ year }},
options: userProfileChartOptions
}
);
});
});
</script>
{% endfor %}
</div>
{% for formName, form in forms %}
<div class="tab-pane {% if tab == formName %}active{% endif %}" id="{{ formName }}">
{{ form_start(form) }}
{{ form_widget(form) }}
<input type="submit" value="{{ 'action.save'|trans }}" class="btn btn-primary" />
{{ form_widget(form) }}
<input type="submit" value="{{ 'action.save'|trans }}" class="btn btn-primary" />
{{ form_end(form) }}
</div>
{% endfor %}
@@ -120,131 +27,3 @@
</div>
</div>
{% endblock %}
{% macro profile_infos(user, stats, local_time) %}
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'profile.about_me'|trans }}</h3>
</div>
<div class="box-body">
<ul class="nav nav-stacked">
{# colors = purple, blue, aqua, red, green #}
<li><a href="#">{{ 'label.id'|trans }} <span class="pull-right badge bg-aqua">{{ user.id }}</span></a></li>
<li><a href="#">{{ 'label.username'|trans }} <span class="pull-right badge bg-blue">{{ user.username }}</span></a></li>
<li><a href="#">{{ 'profile.first_entry'|trans }} <span class="pull-right badge bg-purple">{{ stats.firstEntry|date_short }}</span></a></li>
{% if is_granted('view_rate_own_timesheet') %}
<li><a href="#">{{ 'label.hourlyRate'|trans }} <span class="pull-right badge bg-blue">{{ user.preferenceValue('hourly_rate') }}</span></a></li>
{% endif %}
<li><a href="#">{{ 'label.now'|trans }} <span class="pull-right badge bg-blue">{{ local_time|date_short }} {{ local_time|time }}</span></a></li>
</ul>
</div>
</div>
{% endmacro %}
{% macro profile_box(user, stats) %}
{% import "@AdminLTE/Macros/default.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="box box-primary">
<div class="box-body box-profile">
{{ macro.avatar(user.avatar, user.username, 'profile-user-img img-responsive img-circle') }}
<h3 class="profile-username text-center">{{ widgets.username(user) }}</h3>
<p class="text-muted text-center">{{ user.title }}</p>
<ul class="list-group list-group-unbordered">
<li class="list-group-item">
<b>{{ 'stats.durationMonth'|trans }}</b> <a class="pull-right">{{ stats.durationThisMonth|duration }}</a>
</li>
{% if is_granted('view_rate_own_timesheet') %}
<li class="list-group-item">
<b>{{ 'stats.amountMonth'|trans }}</b> <a class="pull-right">{{ stats.amountThisMonth|money }}</a>
</li>
{% endif %}
<li class="list-group-item">
<b>{{ 'stats.durationTotal'|trans }}</b> <a class="pull-right">{{ stats.durationTotal|duration }}</a>
</li>
{% if is_granted('view_rate_own_timesheet') %}
<li class="list-group-item">
<b>{{ 'stats.amountTotal'|trans }}</b> <a class="pull-right">{{ stats.amountTotal|money }}</a>
</li>
{% endif %}
</ul>
</div>
</div>
{% endmacro %}
{# -------------------------------- UNUSED FOR NOW -------------------------------- #}
{% macro profile_list_unused(user, items, color) %}
{% import "@AdminLTE/Macros/default.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="box box-widget widget-user-2">
<!-- Add the bg color to the header using any of the bg-* classes -->
<div class="widget-user-header bg-{{ color|default(kimai_context.box_color) }}">
<div class="widget-user-image">
{{ macro.avatar(user.avatar, user.username) }}
</div>
<!-- /.widget-user-image -->
<h3 class="widget-user-username">{{ widgets.username(user) }}</h3>
<h5 class="widget-user-desc">{{ user.title }}</h5>
</div>
<div class="box-footer no-padding">
<ul class="nav nav-stacked">
{% for entry in items %}
<li><a href="{{ entry.url }}">{{ entry.title|trans }} <span class="pull-right badge bg-{{ entry.color }}">{{ entry.value }}</span></a></li>
{% endfor %}
</ul>
</div>
</div>
{% endmacro %}
{# -------------------------------- UNUSED FOR NOW -------------------------------- #}
{% macro profile_box_unused(user, stats, color) %}
{% import "@AdminLTE/Macros/default.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="box box-widget widget-user">
<div class="widget-user-header bg-{{ color|default(kimai_context.box_color) }}">
<h3 class="widget-user-username">{{ widgets.username(user) }}</h3>
<h5 class="widget-user-desc">{{ user.title }}</h5>
</div>
<div class="widget-user-image">
{{ macro.avatar(user.avatar, user.username) }}
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-3 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.durationTotal|duration }}</h5>
<span class="description-text">{{ 'stats.durationTotal'|trans }}</span>
</div>
</div>
<div class="col-sm-3 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.amountTotal|money }}</h5>
<span class="description-text">{{ 'stats.amountTotal'|trans }}</span>
</div>
</div>
<div class="col-sm-3 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.durationThisMonth|duration }}</h5>
<span class="description-text">{{ 'stats.durationMonth'|trans }}</span>
</div>
</div>
<div class="col-sm-3 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.amountThisMonth|money }}</h5>
<span class="description-text">{{ 'stats.amountMonth'|trans }}</span>
</div>
</div>
</div>
</div>
</div>
{% endmacro %}

View File

@@ -0,0 +1,97 @@
{% extends 'user/layout.html.twig' %}
{% import "macros/actions.html.twig" as actions %}
{% import "macros/widgets.html.twig" as widgets %}
{% block profile_content %}
{% if years is empty %}
{{ widgets.callout('warning', 'error.no_entries_found') }}
{% endif %}
<script type="text/javascript">
var userProfileChartOptions = {
maintainAspectRatio : true,
responsive : true,
legend : false,
barPercentage : 0.5,
categoryPercentage : 0.9,
scales: {
xAxes: [{
gridLines: {
display: false
}
}],
yAxes: [{
gridLines: {
display: true,
color: 'rgba(0,0,0,.05)',
lineWidth: 1
}
}]
}
};
var userProfileChartLabels = [
{% for i in 1..12 %}
'{{ ('month.' ~i)|trans }}'
{% if not loop.last %},{% endif %}
{% endfor %}
];
</script>
{% for year,yearStat in years %}
{% embed '@AdminLTE/Widgets/box-widget.html.twig' %}
{% block box_title %}{{ year }}{% endblock %}
{% block box_body %}
<div class="chart">
<canvas id="userProfileChart{{ year }}" style="height: 200px;"></canvas>
</div>
<script type="text/javascript">
$(document).ready(function () {
var userProfileChartData{{ year }} = {
labels: userProfileChartLabels,
datasets: [
{
label: '{{ year }}',
backgroundColor : '#00a65a',
borderColor : '#00a65a',
data: [
{% for month in yearStat.months %}
{{ (month.totalDuration / 3600)|round }}
{% if not loop.last %},{% endif %}
{% endfor %}
]
}
]
};
var userProfileChartCanvas{{ year }} = $("#userProfileChart{{ year }}").get(0).getContext("2d");
{% if tab == 'charts' %}
var userProfileChart{{ year }} = new Chart(
userProfileChartCanvas{{ year }}, {
type: 'bar',
data: userProfileChartData{{ year }},
options: userProfileChartOptions
}
);
{% endif %}
$('a[href="#charts"]').on('shown.bs.tab', function(event){
var userProfileChart{{ year }} = new Chart(
userProfileChartCanvas{{ year }}, {
type: 'bar',
data: userProfileChartData{{ year }},
options: userProfileChartOptions
}
);
});
});
</script>
{% endblock %}
{% endembed %}
{% endfor %}
{% endblock %}