Release 2.0.2 (#3856)

* allow to overwrite global spreadsheet styles
* bump version
* fix deprecations in vcard download
* bump composer packages
* added help page for all registered locales
* fix menu id's, cleanup times route, fix configurable homepage redirect
* format duration without leading zero in hours (unify javascript with php behavior)
* fix active records in all screen sizes
* improved responsiveness in XS
* fixed invoice number for customer null fields
* fix javascript respects multiple recent-activity dropdowns
* show recent activities on small screens
* fix user-profile layout column in XS
* fix search is always marked as active
This commit is contained in:
Kevin Papst
2023-02-21 19:21:49 +01:00
committed by GitHub
parent e474087257
commit 25469113fd
61 changed files with 821 additions and 580 deletions

View File

@@ -0,0 +1,24 @@
{% extends 'datatable.html.twig' %}
{% import "macros/widgets.html.twig" as widgets %}
{% block datatable_column_value %}
{% if column == 'name' %}
{{ entry.name }}
{% elseif column == 'description' %}
{{ entry.description }}
{% elseif column == 'language' %}
{{ entry.language }}
{% elseif column == 'date' %}
{{ entry.date }}
{% elseif column == 'time' %}
{{ entry.time }}
{% elseif column == 'duration' %}
{{ entry.duration }}
{% elseif column == 'money' %}
{{ entry.money }}
{% elseif column == 'hour_24' %}
{{ widgets.label_boolean(entry.hour_24) }}
{% elseif column == 'rtl' %}
{{ widgets.label_boolean(entry.rtl) }}
{% endif %}
{% endblock %}

View File

@@ -6,13 +6,18 @@
{% if tabler_bundle.isDarkMode() or tabler_bundle.isNavbarOverlapping() %}
{% set class = "btn-dark" %}
{% endif %}
<div class="nav-item dropdown d-none d-md-flex me-3 notifications-menu" data-reload="{{ path('favorites_timesheets') }}">
<div class="nav-item dropdown d-flex me-sm-3 me-1 notifications-menu" data-reload="{{ path('favorites_timesheets') }}">
<a href="#" class="btn btn-icon {{ class}} px-0" data-bs-toggle="dropdown" tabindex="-1" aria-label="{{ 'recent.activities'|trans }}">
{{ icon('repeat') }}
</a>
<div class="dropdown-menu dropdown-menu-end dropdown-menu-card">
<div class="card">
<div class="card-header">{{ 'recent.activities'|trans }}</div>
<div class="card-header">
{{ 'recent.activities'|trans }}
<div class="card-actions">
<button type="button" class="btn-close{% if tabler_bundle.isDarkMode() %} btn-close-white{% endif %}" data-bs-dismiss="modal" aria-label="{{ 'action.close'|trans }}"></button>
</div>
</div>
<div class="list-group list-group-flush list-group-hoverable menu">
{% for favorite in favorites %}
{% set entry = favorite.getTimesheet() %}

View File

@@ -4,23 +4,23 @@
{# fake entry, because at least one html template node is needed #}
{% set active_timesheets = [{'id': '000', 'begin': null, 'activity': {'name': ''}, 'project': {'name': '', 'customer': {'name': ''}}}] %}
{% endif %}
<div class="nav-item d-flex me-3">
<div class="nav-item d-flex me-sm-3 me-1">
<div class="btn-list">
{% set class = "btn-outline-white" %}
{% if tabler_bundle.isDarkMode() or tabler_bundle.isNavbarOverlapping() %}
{% set class = "btn-dark" %}
{% endif %}
{% set entry = active_timesheets[0] %}
<div class="messages-menu" data-api="{{ path('active_timesheet') }}" data-href="{{ path('stop_timesheet', {'id' : '000'}) }}" style="{% if not hasActiveRecords %}display:none{% endif %}">
<a data-replacer="url" class="api-link ticktac-running ticktac-stop btn {{ class }}" href="{{ path('stop_timesheet', {'id' : entry.id}) }}" data-event="kimai.timesheetStop kimai.timesheetUpdate" data-method="PATCH" data-msg-error="timesheet.stop.error" data-msg-success="timesheet.stop.success"{% if hasActiveRecords %} accesskey="s"{% endif %}>
<i class="icon text-red {{ 'stop-small'|icon(true) }}"></i>
<span data-replacer="duration" data-title="true" data-since="{{ entry.begin is null ? '' : entry.begin|date_format(constant('DATE_ISO8601')) }}">{{ entry is iterable ? 0|duration : entry|duration }}</span>
<div class="ticktac-menu" data-api="{{ path('active_timesheet') }}" data-href="{{ path('stop_timesheet', {'id' : '000'}) }}" style="{% if not hasActiveRecords %}display:none{% endif %}">
<a data-replacer="url" class="api-link ticktac-running ticktac-stop btn {{ class }} btn-icon px-sm-2" href="{{ path('stop_timesheet', {'id' : entry.id}) }}" data-event="kimai.timesheetStop kimai.timesheetUpdate" data-method="PATCH" data-msg-error="timesheet.stop.error" data-msg-success="timesheet.stop.success"{% if hasActiveRecords %} accesskey="s"{% endif %}>
<i class="text-red {{ 'stop-small'|icon(false) }} me-0 me-sm-1"></i>
<span class="d-none d-sm-block" data-replacer="duration" data-title="true" data-since="{{ entry.begin is null ? '' : entry.begin|date_format(constant('DATE_ISO8601')) }}">{{ entry is iterable ? 0|duration : entry|duration }}</span>
</a>
</div>
<div class="messages-menu-empty" style="{% if hasActiveRecords %}display:none{% endif %}">
<a href="{{ path('timesheet_create') }}" class="modal-ajax-form ticktac-start btn {{ class }}" accesskey="n">
<i class="icon text-green {{ 'start'|icon(true) }}"></i>
<span>{{ 0|duration }}</span>
<div class="ticktac-menu-empty" style="{% if hasActiveRecords %}display:none{% endif %}">
<a href="{{ path('timesheet_create') }}" class="modal-ajax-form ticktac-start btn {{ class }} btn-icon px-sm-2" accesskey="n">
<i class="text-green {{ 'start'|icon(false) }} me-0 me-sm-1"></i>
<span class="d-none d-sm-block">{{ 0|duration }}</span>
</a>
</div>
</div>

View File

@@ -11,11 +11,11 @@
{% block profile_intro %}
<div class="card mb-3">
<div class="card-body box-user-profile">
<div class="row g-2 align-items-center">
<div class="row row-sm-2 align-items-center">
<div class="col-auto" data-toggle="tooltip" title="{{ 'id'|trans }}: {{ user.id }}">
{{ widgets.user_avatar(user, false, 'avatar-lg') }}
</div>
<div class="col">
<div class="col" style="min-width: 100px">
<h4 class="card-title m-0">{{ widgets.username(user) }}</h4>
{% if user.title is not empty %}
<div class="text-muted">
@@ -23,7 +23,7 @@
</div>
{% endif %}
</div>
<div class="col-auto" id="profile-buttons">
<div class="col-auto text-end mt-2 mt-sm-1" id="profile-buttons">
{% from '@theme/components/buttons.html.twig' import link_button %}
{% if app.user == user %}
{{ link_button('notifications'|trans, 'javascript:notificationStatus()', 'fas fa-bell', 'default') }}