0
0
Fork 0
mirror of https://github.com/kevinpapst/kimai2.git synced 2025-01-10 19:47:35 +00:00
kevinpapst_kimai2/templates/macros/widgets.html.twig
2024-11-21 22:44:49 +01:00

564 lines
21 KiB
Twig

{%- macro search_filter(route, options) -%}
{% set opts = {'performSearch': 1} %}
{% if options.begin is defined and options.end is defined %}
{% set opts = opts|merge({'daterange': (options.begin|report_date ~ ' - ' ~ options.end|report_date)}) %}
{% endif %}
{% if options.customer is defined %}
{% set opts = opts|merge({'customers[]': options.customer}) %}
{% endif %}
{% if options.project is defined %}
{% set opts = opts|merge({'projects[]': options.project}) %}
{% endif %}
{% if options.activity is defined %}
{% set opts = opts|merge({'activities[]': options.activity}) %}
{% endif %}
{% if options.user is defined %}
{% set opts = opts|merge({'users[]': options.user}) %}
{% endif %}
{% if options.preview is defined %}
{% set opts = opts|merge({'preview': options.preview}) %}
{% endif %}
{{- path(route, opts) -}}
{% endmacro %}
{%- macro page_actions(actions) -%}
{% set btnClasses = 'btn-primary' %}
{% set helpClasses = '' %}
{% if tabler_bundle.isNavbarOverlapping() %}
{% set helpClasses = 'btn-dark' %}
{% elseif not tabler_bundle.isDarkMode() %}
{% set btnClasses = 'btn-white' %}
{% endif %}
{% set later = {} %}
{% set help = null %}
<div class="page-actions">
<div class="pa-desktop d-none d-sm-inline-flex btn-list">
{{ _self.actions(actions, {large: true, button_class: btnClasses}) }}
{% if help is not null %}
{% set help = help|merge({class: helpClasses ~ ' action-help ' ~ (help.class|default(''))}) %}
{{ _self.action_button('help', help) }}
{% endif %}
</div>
<div class="pa-mobile d-inline-flex d-sm-none btn-list">
{% set btnClass = 'btn btn-icon ' %}
{% if tabler_bundle.isNavbarOverlapping() %}
{% set btnClass = 'btn btn-icon btn-dark' %}
{% elseif not tabler_bundle.isDarkMode() %}
{% set btnClass = 'btn btn-icon btn-white' %}
{% endif %}
{{ _self.table_actions(actions, btnClass) }}
</div>
</div>
{%- endmacro -%}
{%- macro actions(actions, options) -%}
{% set large = options.large ?? true %}
{% set btnClasses = options.button_class ?? 'btn-primary' %}
{%- for icon, values in actions %}
{% if 'help' in icon %}
{% set help = values %}
{% elseif 'divider' in icon and values is null %}
{# what to do here ? #}
{% else %}
{% if values.children is defined and values.children|length > 0 %}
<div class="dropdown">
<button type="button" class="btn {{ btnClasses }} dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ icon(icon, true) }}{% if large %} {{ values.title is defined ? values.title|trans : icon|trans }}{% endif %}
</button>
<div class="dropdown-menu">
{%- for icon, values in values.children %}
{% set values = values|merge({class: 'dropdown-item action-' ~ icon ~ ' ' ~ (values.class|default(''))}) %}
{{ _self.action_button(false, values, false) }}
{% endfor %}
</div>
</div>
{% else %}
{% set values = values|merge({combined: large, class: btnClasses ~ ' action-' ~ icon ~ ' ' ~ (values.class|default(''))}) %}
{{ _self.action_button(icon, values) }}
{% endif %}
{% endif %}
{% endfor -%}
{%- endmacro -%}
{% macro page_header(title) %}
<h2 class="page-header">{{ title|trans }}</h2>
{% endmacro %}
{% macro label_boolean(visible) %}
{% if visible %}
{{ _self.label('yes'|trans, 'success') }}
{% else %}
{{ _self.label('no'|trans, 'default') }}
{% endif %}
{% endmacro %}
{% macro label_visible(visible) %}
{{ _self.label_boolean(visible) }}
{% endmacro %}
{% macro label_role(role) %}
{% set color = 'primary' %}
{% if role == 'ROLE_SUPER_ADMIN' %}
{% set color = 'danger' %}
{% elseif role == 'ROLE_ADMIN' %}
{% set color = 'warning' %}
{% elseif role == 'ROLE_TEAMLEAD' %}
{% set color = 'success' %}
{% elseif role == 'ROLE_USER' %}
{% set color = 'gray' %}
{% endif %}
{{ _self.label(role|trans, color) }}
{% endmacro %}
{% macro username(user) %}
{{- user.displayName -}}
{% endmacro %}
{% macro label_user(user) %}
{{ _self.label_color(user.displayName, user.color|colorize(user.displayName)) }}
{% endmacro %}
{% macro label_team(team) %}
{{ _self.label_color(team.name, team.color|colorize(team.name)) }}
{% endmacro %}
{% macro user_avatar(user, tooltip, class, badge) %}
{% set avatar = null %}
{% if user.avatar is not empty and kimai_config.themeAllowAvatarUrls %}
{% set avatar = asset(user.avatar, 'avatars') %}
{% endif %}
{% if not user.enabled %}
{% set badge = 'danger' %}
{% endif %}
{% set color = user.color|colorize(user.displayName) %}
<span class="avatar {{ class }}"
{%- if tooltip is not same as (false) %} data-toggle="tooltip" data-placement="top" title="{{ tooltip|default(user.displayName) }}"{% endif -%}
{% if avatar is not null %}
style="background-image: url({{ avatar }})">&nbsp;
{% else %}
style="background-color: {{ color }}; color: {{ color|font_contrast }}">{{ user.initials }}
{% endif %}
{%- if badge is not null -%}<span class="badge bg-{{ badge }}"></span>{%-endif -%}
</span>
{% endmacro %}
{% macro avatar(initials, color, tooltip, class) %}
{% set color = color|colorize(initials) %}
<span class="avatar {{ class ?? '' }}" style="background-color: {{ color }}; color: {{ color|font_contrast }}"
{%- if tooltip is not same as null %} data-toggle="tooltip" data-placement="top" title="{{ tooltip }}"{% endif -%}>{{ initials }}</span>
{% endmacro %}
{% macro avatar_deleted(tooltip) %}
{% set initials = tooltip ?? '??' %}
{% set tooltip = 'deleted'|trans %}
{% set color = null|colorize(initials) %}
<span class="avatar {{ class ?? '' }}" style="background-color: {{ color }}; color: {{ color|font_contrast }}"
{%- if tooltip is not same as null %} data-toggle="tooltip" data-placement="top" title="{{ tooltip }}"{% endif -%}>{{ initials }}</span>
{% endmacro %}
{#
options = {'inherit': true}
#}
{% macro label_activity(activity, options) %}
{% set inherit = options.inherit ?? true %}
{% set isVisible = activity.visible %}
{% set color = activity.color %}
{% if color is empty and inherit and activity.project is not null %}
{% set color = activity.project.color ?? activity.project.customer.color %}
{% endif %}
{% if color is empty %}
{% set color = color|colorize(activity.name) %}
{% endif %}
{% if isVisible and not activity.project is null %}
{% set isVisible = activity.project.visible %}
{% if isVisible and not activity.project.customer is null %}
{% set isVisible = activity.project.customer.visible %}
{% endif %}
{% endif %}
{{ _self.label_color_dot('activity', isVisible, activity.name, null, color) }}
{% endmacro %}
{#
options = {'inherit': true}
#}
{% macro label_project(project, options) %}
{% set inherit = options.inherit ?? true %}
{% set isVisible = false %}
{% if project.visible and project.customer.visible %}
{% set isVisible = true %}
{% endif %}
{% set color = project.color %}
{% if color is empty and inherit %}
{% set color = project.customer.color %}
{% endif %}
{% if color is empty %}
{% set color = color|colorize(project.name) %}
{% endif %}
{{ _self.label_color_dot('project', isVisible, project.name, null, color) }}
{% endmacro %}
{% macro label_customer(customer) %}
{% set color = customer.color %}
{% if color is empty %}
{% set color = color|colorize(customer.name) %}
{% endif %}
{{ _self.label_color_dot('customer', customer.visible, customer.name, null, color) }}
{% endmacro %}
{# Use for list views and the main column (if the entity has something like a name) #}
{% macro label_name(label, color, isVisible) %}
{{ _self.label_color_dot('color', isVisible, label, null, color) }}
{% endmacro %}
{# Use in datatables to show linked entity names #}
{% macro label_dot(label, color, isVisible) %}
{{ _self.label_color_dot('color', isVisible, label, null, color|colorize(label)) }}
{% endmacro %}
{# for @internal use only #}
{% macro label_color_dot(type, isVisible, name, url, color) %}
{%- if url is not empty -%}<a href="{{ url }}">{% endif %}
<span class="pe-1 label-{{ type }}{{ isVisible is same as (false) ? ' label-invisible' : '' }}">
<span class="badge me-1" {% if color is not empty %} style="background-color:{{ color }}"{% endif %}></span>
{{- name -}}
</span>
{%- if url is not empty -%}</a>{% endif %}
{% endmacro %}
{% macro badge_team_access(teams) %}
{% if teams|length > 0 %}
{{ _self.badge_counter(teams|length) }}
{% else %}
{{ _self.badge_counter(0, null, 'gray') }}
{% endif %}
{% endmacro %}
{% macro badge_counter(count, url, type) %}
{% if url is not null %}
<a href="{{ url }}">{{ _self.badge_type(count, type|default('blue')) }}</a>
{% else %}
{{ _self.badge_type(count, type|default('blue')) }}
{% endif %}
{% endmacro %}
{% macro label(title, type, tooltip) %}
<span {% if tooltip %}data-toggle="tooltip" data-placement="top" title="{{ tooltip }}" {% endif %}class="badge bg-{{ type|default('success') }} text-{{ type|default('success') }}-fg">{{ title }}</span>
{% endmacro %}
{% macro label_color(title, color) %}
<span class="badge" style="background-color: {{ color|default_color }};color: {{ color|default_color|font_contrast }}">{{ title }}</span>
{% endmacro %}
{% macro badge(title, color) %}
<span class="badge"{% if color is not null %} style="background-color:{{ color }}; color:{{ color|font_contrast }}"{% endif %}>{{ title }}</span>
{% endmacro %}
{% macro badge_type(title, type) %}
{% set class = (type is not empty ? 'bg-' ~ type ~ ' text-' ~ type ~ '-fg' : '') %}
<span class="badge {{ class }}">{{ title }}</span>
{% endmacro %}
{% macro form_errors(form) %}
{% if form.vars.errors|length > 0 %}
{% set message = '' %}
{% for error in form.vars.errors %}
{% set message = message ~ error.message %}
{% if not loop.last %}
{% set message = message ~ '<br>' %}
{% endif %}
{% endfor %}
{% if message != '' %}
{{ _self.alert('danger', message) }}
{% endif %}
{% endif %}
{% endmacro %}
{% macro alert(type, description, title, icon, dismissible) %}
{% from '@theme/components/alert.html.twig' import alert %}
{{ alert({type: type, description: description|trans, title: title|trans, icon: icon, dismissible: dismissible, important: true}) }}
{% endmacro %}
{% macro callout(type, description, title, icon) %}
{% from '@theme/components/alert.html.twig' import alert %}
{{ alert({type: type|default('danger'), description: description|trans, title: title|trans, icon: icon, dismissible: false, important: true}) }}
{% endmacro %}
{% macro table_actions(actions, class) %}
{% if actions|length >= 1 %}
{% import '@theme/components/actions.html.twig' as macro %}
{{ macro.actions(actions, {'class': class|default('btn-sm'), translationDomain: 'actions'}) }}
{% endif %}
{% endmacro %}
{% macro card_tool_visibility(tableName) %}
{{ _self.card_tool_button('visibility', {'modal': ('#modal_' ~ tableName)}) }}
{% endmacro %}
{% macro card_tool_button(icon, values) %}
{% import '@theme/components/buttons.html.twig' as macro %}
{% set values = values|merge({'tooltip_attr': 'data-toggle'}) %}
{{ macro.action_cardtoolbutton(icon, values) }}
{% endmacro %}
{% macro card_tool_create(create_url) %}
{{ _self.card_tool_button('create', {'url': create_url, 'class': 'modal-ajax-form open-edit', 'title': 'create'|trans}) }}
{% endmacro %}
{% macro action_button(icon, values, type) %}
{% import '@theme/components/button.html.twig' as macro %}
{% set values = (values ?? {})|merge({'tooltip_attr': 'data-toggle'}) %}
{{ macro.button(icon, values, type) }}
{% endmacro %}
{% macro tag_list(taglist) %}
<div class="tags-list">
{% for tag in taglist %}
<span class="tag">
<span class="legend" style="background-color: {{ tag.color|colorize(tag.name) }}"></span>
{{ tag.name }}
</span>
{% endfor %}
</div>
{% endmacro %}
{% macro meta_field_value(entity, field) %}
{% set metaField = entity.metaField(field.name) %}
{% if not metaField is null %}
{% set metaField = metaField.merge(field) %}
{{ _self.form_type_value(metaField.type, metaField.value, entity) }}
{% endif %}
{% endmacro %}
{% macro form_type_value(type, value, entity) %}
{% if 'ColorPickerType' in type or 'ColorChoiceType' in type %}
{% if value is not empty %}
<span class="label-color" data-toggle="tooltip" data-placement="top" title="{{ value }}">
<i class="dot {{ 'dot'|icon(true) }} fa-fw" style="color:{{ value }}"></i>
</span>
{% endif %}
{% elseif 'DurationType' in type %}
{{ value|duration }}
{% elseif 'YesNoType' in type or 'CheckBoxType' in type %}
{{ _self.label_boolean(value) }}
{% elseif 'DatePickerType' in type %}
{{ value|date_short }}
{% elseif 'DateTimePickerType' in type %}
{{ value|date_time }}
{% elseif 'CountryType' in type %}
{{ value|country_name }}
{% elseif 'CurrencyType' in type %}
{{ value|currency_name }}
{% elseif 'LanguageType' in type %}
{{ value|locale_name }}
{% elseif 'TagsType' in type %}
{% for tag in value|split(',') %}
{% if tag is not empty %}
{{ _self.badge(tag, null|colorize(tag)) }}
{% endif %}
{% endfor %}
{% elseif 'MoneyType' in type %}
{% set classname = class_name(entity) %}
{% if entity is null %}
{{ value }}
{% elseif classname == 'App\\Entity\\Timesheet' %}
{{ value|money(entity.project.customer.currency) }}
{% elseif classname == 'App\\Entity\\Customer' %}
{{ value|money(entity.currency) }}
{% elseif classname == 'App\\Entity\\Project' %}
{{ value|money(entity.customer.currency) }}
{% elseif classname == 'App\\Entity\\Activity' and entity.project is not null %}
{{ value|money(entity.project.customer.currency) }}
{% else %}
{{ value }}
{% endif %}
{% elseif 'TextareaType' in type %}
{{ value|nl2br }}
{% elseif 'EmailType' in type %}
<a href="mailto:{{ value }}">{{ value }}</a>
{% elseif 'UrlType' in type %}
<a href="{{ value }}" target="_blank">{{ value }}</a>
{% else %}
{{ value }}
{% endif %}
{% endmacro %}
{% macro team_list(teams, options) %}
{% set showTitle = options['title'] ?? true %}
{% set collapseAt = options['collapse'] ?? 12 %}
{% set nameClass = options['name_class'] ?? '' %}
{% set viewTeam = is_granted('view_team') %}
<table class="table table-hover dataTable" role="grid">
{% if showTitle %}
<thead>
<tr>
<th class="hw-min">{{ 'team'|trans }}</th>
<th class="d-none d-sm-table-cell">{{ 'team.member'|trans({}, 'teams') }}</th>
</tr>
</thead>
{% endif %}
<tbody>
{% for team in teams|sort((a, b) => a.name <=> b.name) %}
{% set members = team.members|filter(m => m.user.enabled) %}
{% set class = 'avatar-rounded' %}
<tr{% if viewTeam and is_granted('edit', team) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_team_member', {'id': team.id}) }}"{% endif %}>
<td class="{{ nameClass }}">
{{ _self.label_color_dot('color', true, team.name, null, team.color|colorize(team.name)) }}
</td>
<td class="d-none d-sm-table-cell avatars avatar-list avatar-list-stacked">
{% for member in members|sort((a, b) => b.teamlead <=> a.teamlead) %}
{% set user = member.user %}
{% if member.teamlead %}
{{ _self.user_avatar(user, ('teamlead'|trans ~ ': ' ~ user.displayName), (class ~ ' teamlead'), 'info') }}
{% else %}
{{ _self.user_avatar(user, null, class) }}
{% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endmacro %}
{% macro nothing_found(events) %}
{{ _self.callout('warning', 'error.no_entries_found') }}
{% if events is not empty %}
<script type="text/javascript">
document.addEventListener('kimai.initialized', function() {
KimaiReloadPageWidget.create('{{ events }}');
});
</script>
{% endif %}
{% endmacro %}
{#
To be used like this:
<tr class="{{ class_customer_row(customer, now) }}">
#}
{% macro class_customer_row(customer, now) %}
{%- if not customer.visible %}bg-orange-lt{% endif -%}
{% endmacro %}
{#
To be used like this:
<tr class="{{ class_tag_row(tag) }}">
#}
{% macro class_tag_row(tag) %}
{%- if not tag.visible %}bg-orange-lt{% endif -%}
{% endmacro %}
{#
To be used like this:
<tr {{ customer_row_attr(customer, now) }}>
#}
{% macro customer_row_attr(customer, now) %}
{%- set class = _self.class_customer_row(customer, now) %}
{% set dataHref = '' %}
{% if is_granted('view', customer) %}
{% set class = class ~ ' alternative-link open-edit' %}
{% set dataHref = path('customer_details', {'id': customer.id}) %}
{% endif -%}
class="{{ class }}" data-href="{{ dataHref }}"
{% endmacro %}
{#
To be used like this:
<tr class="{{ class_project_row(project, now) }}">
#}
{% macro class_project_row(project, now) %}
{%- if not project.visible or (project.end is not null and project.end < now) %}bg-orange-lt{% endif -%}
{% endmacro %}
{#
To be used like this:
<tr {{ project_row_attr(project, now) }}>
#}
{% macro project_row_attr(project, now) %}
{%- set class = _self.class_project_row(project, now) %}
{% set dataHref = '' %}
{% if is_granted('view', project) %}
{% set class = class ~ ' alternative-link open-edit' %}
{% set dataHref = path('project_details', {'id': project.id}) %}
{% endif -%}
class="{{ class }}" data-href="{{ dataHref }}"
{% endmacro %}
{#
To be used like this:
<tr {{ class_activity_row(activity, now) }}>
#}
{% macro class_activity_row(activity, now) %}
{%- if not activity.visible %}bg-orange-lt{% endif -%}
{% endmacro %}
{#
To be used like this:
<tr {{ activity_row_attr(activity, now) }}>
#}
{% macro activity_row_attr(activity, now) %}
{%- set class = _self.class_activity_row(activity, now) %}
{% set dataHref = '' %}
{% if is_granted('view', activity) %}
{% set class = class ~ ' alternative-link open-edit' %}
{% set dataHref = path('activity_details', {'id': activity.id}) %}
{% endif -%}
class="{{ class }}" data-href="{{ dataHref }}"
{% endmacro %}
{#
To be used like this:
<tr class="{{ class_user_row(user, now) }}">
#}
{% macro class_user_row(user) %}
{%- if not user.enabled %}bg-orange-lt{% endif -%}
{% endmacro %}
{#
To be used like this:
<tr {{ user_row_attr(user) }}>
#}
{% macro user_row_attr(user) %}
{%- set class = _self.class_user_row(user) %}
{% set dataHref = '' %}
{% if is_granted('view', user) %}
{% set class = class ~ ' alternative-link open-edit' %}
{% set dataHref = path('user_profile', {'username': user.username}) %}
{% endif -%}
class="{{ class }}" data-href="{{ dataHref }}"
{% endmacro %}
{# To be used mainly in <tr class="{{ class_user_row(user, now) }}"> #}
{% macro short_stats_row(stats) %}
<div class="row">
{% set colLength = 12 / stats|length %}
{% for title, value in stats %}
<div class="col-sm-{{ colLength }} border-right">
<div class="description-block">
<h5 class="description-header">{{ value }}</h5>
<span class="description-text">{{ title }}</span>
</div>
</div>
{% endfor %}
</div>
{% endmacro %}
{% macro page_reloader(events, full_reload) %}
<script type="text/javascript">
document.addEventListener('kimai.initialized', function() {
KimaiReloadPageWidget.create('{{ events }}', {% if full_reload is same as true %}true{% else %}false{% endif %});
});
</script>
{% endmacro %}
{% macro work_times_result(should, actual, decimal) %}
{% set result = actual - should %}
{% if result == 0 %}
<span class="work_time_exact">{{ result|duration(decimal) }}</span>
{% elseif should == 0 and actual > 0 %}
<span class="work_time_positive text-green">+{{ actual|duration(decimal) }}</span>
{% elseif result < 0 %}
<span class="work_time_negative text-red">{{ result|duration(decimal) }}</span>
{% else %}
<span class="work_time_positive text-green">+{{ result|duration(decimal) }}</span>
{% endif %}
{% endmacro %}