Release 2.5.0 (#4454)
- added command to list users - corrected wrong german translation - work contract validations - prevent error with missing params - use collapsible, minor UI improvement - added classes to target menu buttons in custom rules - disable webpack notifier, incompatible with mac arm - use explicit menu service to generate menu - bump to fontawesome 6 and replace restart icon - change repeat icon for recent activities - moved user bookmarks (favorites) to top nav - fix totp seconds window (leeway) - new migration to fix remaining user preferences with dots in name - remove duplicate named column in user screen - unify and added translations - added missing filter and tags to InvoiceSecurity
This commit is contained in:
@@ -100,6 +100,7 @@
|
||||
{% if is_granted('view_own_timesheet') %}
|
||||
{% include 'partials/recent-activities.html.twig' %}
|
||||
{% endif %}
|
||||
{% include 'partials/user-shortcuts.html.twig' %}
|
||||
{% block navbar_extensions_after %}
|
||||
{% set event = trigger(constant('App\\Event\\ThemeEvent::TOOLBAR')) %}
|
||||
{{ event.content|raw }}
|
||||
|
||||
@@ -87,56 +87,8 @@
|
||||
{% endembed %}
|
||||
{% endif %}
|
||||
|
||||
{% if withWorkHourConfiguration %}
|
||||
{% set expectedWeekTimes = user.workHoursMonday + user.workHoursTuesday + user.workHoursWednesday + user.workHoursThursday + user.workHoursFriday + user.workHoursSaturday + user.workHoursSunday %}
|
||||
|
||||
{% embed '@theme/embeds/card.html.twig' with {'collapsed': box_configuration.collapsed} %}
|
||||
{% from "macros/status.html.twig" import status_duration %}
|
||||
{% block box_title %}
|
||||
{{ 'work_times_should'|trans }}
|
||||
{{ status_duration(expectedWeekTimes|duration) }}
|
||||
{% endblock %}
|
||||
{% block box_body %}
|
||||
<div class="datagrid">
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'agendaWeek'|trans }}</div>
|
||||
<div class="datagrid-content">{{ expectedWeekTimes|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Monday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursMonday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Tuesday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursTuesday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Wednesday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursWednesday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Thursday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursThursday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Friday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursFriday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Saturday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursSaturday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Sunday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursSunday|duration }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endembed %}
|
||||
{% endif %}
|
||||
|
||||
{% if year is defined %}
|
||||
{% embed '@theme/embeds/card.html.twig' with {'collapsed': box_configuration.collapsed, 'id': 'working_time_detail_box', 'fullsize': true} %}
|
||||
{% embed '@theme/embeds/collapsible.html.twig' with {open: not box_configuration.collapsed, id: 'working_time_detail_box', border: false, item: {options: {bodyExtraClass: 'border-top'}, bodyClasses: 'p-0 table-responsive'}} %}
|
||||
{% set yearShould = 0 %}
|
||||
{% set yearIs = 0 %}
|
||||
{% set approved = 0 %}
|
||||
@@ -154,17 +106,14 @@
|
||||
{% endfor %}
|
||||
{% from "macros/widgets.html.twig" import work_times_result, table_actions, card_tool_button, username %}
|
||||
{% from "macros/status.html.twig" import status_count %}
|
||||
{% block box_title %}
|
||||
{% block title %}
|
||||
{{ 'work_times'|trans }}
|
||||
{% if withWorkHourConfiguration %}
|
||||
|
||||
{{ status_count(approved ~ '/' ~ year.months|length) }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block box_body_classes %}card-table table-responsive{% endblock %}
|
||||
{% block box_tools %}
|
||||
{# {{ card_tool_button('visibility', {'onclick': "toggleDays(); return false;", 'id': 'toggleDaysIcon'}) }} #}
|
||||
{% endblock %}
|
||||
{% block box_body %}
|
||||
{% block body %}
|
||||
<table id="working_times_details" class="table table-vcenter table-hover dataTable">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -276,6 +225,51 @@
|
||||
{% endembed %}
|
||||
{% endif %}
|
||||
|
||||
{% if withWorkHourConfiguration %}
|
||||
{% set expectedWeekTimes = user.workHoursMonday + user.workHoursTuesday + user.workHoursWednesday + user.workHoursThursday + user.workHoursFriday + user.workHoursSaturday + user.workHoursSunday %}
|
||||
|
||||
{% embed '@theme/embeds/collapsible.html.twig' with {open: not box_configuration.collapsed, id: 'work_contract_should_preview', border: false, item: {options: {bodyExtraClass: 'border-top'}}} %}
|
||||
{% from "macros/status.html.twig" import status_duration %}
|
||||
{% block title %}
|
||||
{{ 'work_times_should'|trans }}
|
||||
|
||||
{{ status_duration(expectedWeekTimes|duration) }}
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<div class="datagrid">
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Monday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursMonday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Tuesday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursTuesday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Wednesday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursWednesday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Thursday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursThursday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Friday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursFriday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Saturday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursSaturday|duration }}</div>
|
||||
</div>
|
||||
<div class="datagrid-item">
|
||||
<div class="datagrid-title">{{ 'Sunday'|trans({}, 'system-configuration') }}</div>
|
||||
<div class="datagrid-content">{{ user.workHoursSunday|duration }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endembed %}
|
||||
{% endif %}
|
||||
|
||||
{% for controller in boxes %}
|
||||
{{ render(controller(controller, {'year': year, 'boxConfiguration': box_configuration})) }}
|
||||
{% endfor %}
|
||||
|
||||
@@ -277,7 +277,7 @@
|
||||
|
||||
{% macro action_button(icon, values, type) %}
|
||||
{% import '@theme/components/button.html.twig' as macro %}
|
||||
{% set values = values|merge({'tooltip_attr': 'data-toggle'}) %}
|
||||
{% set values = (values ?? {})|merge({'tooltip_attr': 'data-toggle'}) %}
|
||||
{{ macro.button(icon, values, type) }}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
{% if is_granted('start_own_timesheet') %}
|
||||
{% set class = "btn-outline-white" %}
|
||||
{% if tabler_bundle.isDarkMode() or tabler_bundle.isNavbarOverlapping() %}
|
||||
{% set class = "btn-dark" %}
|
||||
{% endif %}
|
||||
<div class="nav-item d-flex me-sm-3 me-1">
|
||||
<a href="{{ path('favorites_timesheets') }}" class="btn btn-icon {{ class}} px-0 remote-modal-load" data-modal-title="{{ 'recent.activities'|trans }}" tabindex="-1" aria-label="{{ 'recent.activities'|trans }}">
|
||||
{{ icon('repeat') }}
|
||||
<div class="nav-item d-flex me-1 recent-activities">
|
||||
<a href="{{ path('favorites_timesheets') }}" class="nav-link px-0 remote-modal-load recent-activities-btn" data-modal-title="{{ 'recent.activities'|trans }}" tabindex="-1" aria-label="{{ 'recent.activities'|trans }}">
|
||||
{{ icon('repeat', true) }}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{# 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-sm-3 me-1">
|
||||
<div class="nav-item d-flex me-1 ticktac">
|
||||
<div class="btn-list">
|
||||
{% set class = "btn-outline-white" %}
|
||||
{% if tabler_bundle.isDarkMode() or tabler_bundle.isNavbarOverlapping() %}
|
||||
|
||||
36
templates/partials/user-shortcuts.html.twig
Normal file
36
templates/partials/user-shortcuts.html.twig
Normal file
@@ -0,0 +1,36 @@
|
||||
{% set user_shortcuts = user_shortcuts(app.user) %}
|
||||
{% if user_shortcuts|length > 0 %}
|
||||
<div class="nav-item dropdown d-flex me-1 user-shortcuts">
|
||||
<a class="nav-link px-0 user-shortcuts-toggle" href="javascript:void(0);" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="true">
|
||||
{{ icon('far fa-bookmark', true) }}
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow dropdown-menu-card" data-bs-popper="static">
|
||||
<div class="card">
|
||||
<div class="card-header text-nowrap">{{ 'favorite_routes'|trans }}</div>
|
||||
<div class="card-body user-shortcuts-list scrollable-container p-0 pb-2">
|
||||
<div class="row overflow-visible g-0">
|
||||
{% for menu in user_shortcuts %}
|
||||
{% if not loop.first and loop.index0 % 2 == 0 %}
|
||||
</div>
|
||||
<div class="row overflow-visible g-0">
|
||||
{% endif %}
|
||||
<div class="text-center pt-3 px-3 col">
|
||||
<a href="{{ path(menu.route) }}" class="text-decoration-none">
|
||||
<span class="user-shortcuts-icon rounded-circle mb-2">
|
||||
<i class="{{ menu.icon|icon }} fs-2"></i>
|
||||
</span>
|
||||
</a>
|
||||
<a href="{{ path(menu.route) }}" class="nav-link">
|
||||
{{- menu.label|trans -}}
|
||||
</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if user_shortcuts|length > 1 and user_shortcuts|length % 2 == 1 %}
|
||||
<div class="pt-3 px-3 col"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user