mirror of
https://github.com/kevinpapst/kimai2.git
synced 2025-03-24 09:04:47 +00:00
298 lines
12 KiB
Twig
298 lines
12 KiB
Twig
{% extends '@AdminLTE/layout/default-layout.html.twig' %}
|
|
|
|
{% block body_start %}
|
|
data-title="{{- get_title()|e('html_attr') -}}"
|
|
{% endblock %}
|
|
|
|
{% block after_body_start %}
|
|
{% embed 'embeds/modal.html.twig' %}
|
|
{% block modal_id %}remote_form_modal{% endblock %}
|
|
{% block modal_title %}{% endblock %}
|
|
{% block modal_body %}{% endblock %}
|
|
{% block modal_footer %}{% endblock %}
|
|
{% endembed %}
|
|
{% block page_search %}{% endblock %}
|
|
{% endblock %}
|
|
|
|
{% block page_content_start %}
|
|
{% if app.session and app.session.started and app.session.flashbag.peekAll|length > 0 %}
|
|
{% set close = adminlte_close_alert|default(true) %}
|
|
{% set domain = 'flashmessages' %}
|
|
<script type="text/javascript">
|
|
document.addEventListener('kimai.initialized', function(options) {
|
|
var ALERT = options.detail.kimai.getPlugin('alert');
|
|
{% for type, messages in app.session.flashbag.all %}
|
|
{% for message in messages %}
|
|
{% if type == 'fos_user_success' %}
|
|
{% set type = 'success' %}
|
|
{% set domain = 'FOSUserBundle' %}
|
|
{% endif %}
|
|
{% if type == 'error' %}
|
|
ALERT.error('{{ message|trans({}, domain) }}');
|
|
{% elseif type == 'warning' %}
|
|
ALERT.warning('{{ message|trans({}, domain) }}');
|
|
{% elseif type == 'success' %}
|
|
ALERT.success('{{ message|trans({}, domain) }}');
|
|
{% else %}
|
|
ALERT.info('{{ message|trans({}, domain) }}');
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
});
|
|
</script>
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
{% block page_content_before %}
|
|
{% set event = trigger(constant('App\\Event\\ThemeEvent::CONTENT_BEFORE')) %}
|
|
{{ event.content|raw }}
|
|
<div class="toolbar-pad no-print">
|
|
{% block main_before %}{% endblock %}
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block page_content_after %}
|
|
{% block main_after %}{% endblock %}
|
|
{% set event = trigger(constant('App\\Event\\ThemeEvent::CONTENT_AFTER')) %}
|
|
{{ event.content|raw }}
|
|
{% endblock %}
|
|
|
|
{% block page_content %}
|
|
{% set event = trigger(constant('App\\Event\\ThemeEvent::CONTENT_START')) %}
|
|
{{ event.content|raw }}
|
|
{% block main %}{% endblock %}
|
|
{% set event = trigger(constant('App\\Event\\ThemeEvent::CONTENT_END')) %}
|
|
{{ event.content|raw }}
|
|
{% endblock %}
|
|
|
|
{% block title %}
|
|
{{- get_title() -}}
|
|
{% endblock %}
|
|
|
|
{% block page_subtitle %}{% endblock %}
|
|
|
|
{% block logo_mini %}
|
|
{% if not kimai_context.branding.mini is empty %}
|
|
{{ kimai_context.branding.mini|raw }}
|
|
{% else %}
|
|
<b>K</b>TT
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
{% block logo_large %}
|
|
{% if not kimai_context.branding.company is empty %}
|
|
{{ kimai_context.branding.company|raw }}
|
|
{% else %}
|
|
<b>Kimai</b> - Time Tracking
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
{% block footer %}
|
|
<!-- Page rendered on {{ 'now'|date_full }} -->
|
|
{% endblock %}
|
|
|
|
{% block navbar_start %}
|
|
{% if app.user is not null and is_granted('IS_AUTHENTICATED_REMEMBERED') %}
|
|
{% if is_granted('view_own_timesheet') %}
|
|
{% if app.user.preferenceValue('login.initial_view') == 'calendar' %}
|
|
<li class="visible-xs-inline-block">
|
|
<a href="{{ path('calendar') }}" class="ddt-large">
|
|
<i class="{{ 'calendar'|icon }} fa-2x"></i>
|
|
</a>
|
|
</li>
|
|
{% else %}
|
|
<li class="visible-xs-inline-block">
|
|
<a href="{{ path('timesheet') }}" class="ddt-large">
|
|
<i class="{{ 'timesheet'|icon }} fa-2x"></i>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% if is_granted('view_invoice') %}
|
|
<li class="visible-xs-inline-block">
|
|
<a href="{{ path('invoice') }}" class="ddt-large">
|
|
<i class="{{ 'invoice'|icon }} fa-2x"></i>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if is_granted('create_export') %}
|
|
<li class="visible-xs-inline-block">
|
|
<a href="{{ path('export') }}" class="ddt-large">
|
|
<i class="{{ 'export'|icon }} fa-2x"></i>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% block navbar_extensions %}{% endblock %}
|
|
{% set active_timesheets = active_timesheets(app.user) %}
|
|
{% set soft_limit = theme_config('soft_limit') %}
|
|
<li class="dropdown messages-menu" style="{% if active_timesheets is empty %}display:none{% endif %}">
|
|
<a href="#" class="dropdown-toggle ddt-large ticktac" data-toggle="dropdown">
|
|
<i class="{{ 'start'|icon }} fa-2x"></i>
|
|
<span data-warning="{{ soft_limit }}" class="label label-{% if active_timesheets|length > soft_limit %}danger{% else %}warning{% endif %}">{% if active_timesheets|length > 0 %}{{ active_timesheets|length }}{% endif %}</span>
|
|
</a>
|
|
<ul class="dropdown-menu"
|
|
data-api="{{ path('active_timesheet') }}"
|
|
data-href="{{ path('stop_timesheet', {'id' : '000'}) }}"
|
|
data-icon="{{ 'stop-small'|icon }}">
|
|
<li class="header">
|
|
{{ 'active.entries'|trans }}
|
|
</li>
|
|
<li>
|
|
<ul class="menu">
|
|
{% for entry in active_timesheets %}
|
|
<li>
|
|
<a href="{{ path('stop_timesheet', {'id' : entry.id}) }}" class="api-link" data-event="kimai.timesheetStop kimai.timesheetUpdate" data-method="PATCH" data-msg-error="timesheet.stop.error" data-msg-success="timesheet.stop.success">
|
|
<div class="pull-left">
|
|
<i class="{{ 'stop-small'|icon }} fa-2x"></i>
|
|
</div>
|
|
<h4>
|
|
<span>{{ entry.activity.name }}</span>
|
|
<small>
|
|
<span data-title="true" data-since="{{ entry.begin.format(constant('DATE_ISO8601')) }}">{{ entry|duration }}</span>
|
|
</small>
|
|
</h4>
|
|
<p>{{ entry.project.name }} ({{ entry.project.customer.name }})</p>
|
|
</a>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</li>
|
|
{% if is_granted('create_own_timesheet') %}
|
|
<li class="footer"><a href="{{ path('timesheet_create') }}" class="modal-ajax-form">{{ 'timesheet.start'|trans }}</a></li>
|
|
{% endif %}
|
|
</ul>
|
|
</li>
|
|
{% if is_granted('create_own_timesheet') %}
|
|
<li class="messages-menu-empty" style="{% if active_timesheets is not empty %}display:none{% endif %}">
|
|
<a href="{{ path('timesheet_create') }}" class="ddt-large modal-ajax-form">
|
|
<i class="{{ 'start'|icon }} fa-2x"></i>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
|
|
{# these blocks and the hook-in logic by the AdminTheme could be re-used by Kimai or an extension at some point #}
|
|
{#
|
|
{% block navbar_messages %}{% endblock %}
|
|
{% block navbar_notifications %}{% endblock %}
|
|
{% block navbar_tasks %}{% endblock %}
|
|
{% block navbar_end %}{% endblock %}
|
|
#}
|
|
|
|
{# deactivated blocks, as Kimai does not ship the sidebar for UX reasons #}
|
|
{% block sidebar_user %}{% endblock %}
|
|
{% block sidebar_search %}{% endblock %}
|
|
|
|
{% block navbar_user %}
|
|
{% if app.user is not null and is_granted('IS_AUTHENTICATED_REMEMBERED') %}
|
|
{% include 'navbar/recent-activities.html.twig' %}
|
|
{% endif %}
|
|
{% import "macros/widgets.html.twig" as widgets %}
|
|
<li class="dropdown user-menu">
|
|
<a href="#" class="dropdown-toggle ddt-large" data-toggle="dropdown">
|
|
{{ widgets.user_avatar(app.user, false) }}
|
|
</a>
|
|
<ul class="dropdown-menu">
|
|
{% if app.user is not null %}
|
|
{% if is_granted('view', app.user) %}
|
|
<li>
|
|
<a href="{{ path('user_profile', {'username' : app.user.username}) }}">
|
|
<h4 class="control-sidebar-subheading">
|
|
<i class="{{ 'avatar'|icon }}"></i>
|
|
{{ 'my.profile'|trans }}
|
|
</h4>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if is_granted('edit', app.user) %}
|
|
<li>
|
|
<a href="{{ path('user_profile_edit', {'username' : app.user.username}) }}">
|
|
<h4 class="control-sidebar-subheading">
|
|
<i class="{{ 'profile'|icon }}"></i>
|
|
{{ 'action.edit'|trans }}
|
|
</h4>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if is_granted('preferences', app.user) %}
|
|
<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>
|
|
{% endif %}
|
|
<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 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> #}
|
|
{{ encore_entry_link_tags('app') }}
|
|
{% set event = trigger(constant('App\\Event\\ThemeEvent::STYLESHEET')) %}
|
|
{{ event.content|raw }}
|
|
{% endblock %}
|
|
|
|
{% block head %}
|
|
{{ parent() }}
|
|
{{ encore_entry_script_tags('app') }}
|
|
{% include 'partials/head.html.twig' %}
|
|
{% set event = trigger(constant('App\\Event\\ThemeEvent::HTML_HEAD')) %}
|
|
{{ event.content|raw }}
|
|
{% endblock %}
|
|
|
|
{% block javascripts %}
|
|
{# no call to parent(), as we use a custom built for the frontend assets and don't want the default <script> #}
|
|
<script type="text/javascript">
|
|
window.addEventListener('load', function() {
|
|
var loader = new KimaiWebLoader(
|
|
{
|
|
formatDuration: '{{ get_format_duration() }}',
|
|
login: '{{ path('fos_user_security_login') }}',
|
|
locale: '{{ app.request.locale }}',
|
|
first_dow_iso: {{ iso_day_by_name(app.user.firstDayOfWeek) }},
|
|
twentyFourHours: {{ 'true'|hour24('false') }},
|
|
autoComplete: {{ theme_config('autocomplete_chars') }},
|
|
defaultColor: '{{ constant('App\\Constants::DEFAULT_COLOR') }}',
|
|
updateBrowserTitle: {% if app.user.preferenceValue('theme.update_browser_title') %}true{% else %}false{% endif %}
|
|
},
|
|
{
|
|
{% for key, translation in javascript_translations() -%}
|
|
'{{ key }}': '{{ translation.0|trans({}, translation.1)|escape('js') }}',
|
|
{%- endfor %}
|
|
}
|
|
);
|
|
window.kimai = loader.getKimai();
|
|
});
|
|
</script>
|
|
{% set event = trigger(constant('App\\Event\\ThemeEvent::JAVASCRIPT')) %}
|
|
{{ event.content|raw }}
|
|
{% endblock %}
|