Edit file File name : widgets.html.twig Content :{% macro icon(icon) %} <i class="{{ icon|icon(icon) }}"></i> {% endmacro %} {%- macro page_actions(tools) -%} <div class="breadcrumb"> <div class="box-tools"> {{ _self.button_group(tools) }} </div> </div> {%- endmacro -%} {%- macro entity_actions(tools) -%} <div class="breadcrumb"> <div class="box-tools"> <div class="btn-group"> {% set actions = {} %} {%- for icon, values in tools %} {% if icon == 'back' %} {{ _self.action_button(icon, values) }} {% else %} {% set actions = actions|merge({(icon): values}) %} {% endif %} {% endfor %} {{ _self.table_actions(actions, '') }} </div> </div> </div> {%- 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) %} {% if user.avatar is not empty and kimai_config.themeAllowAvatarUrls %} {% set avatar = asset(user.avatar, 'avatars') %} {% if tooltip is same as (false) %} <img src="{{ avatar }}" class="img-circle avatar{% if class is not empty %} {{ class }}{% endif %}" alt="{{ user.displayName }}" /> {% else %} <img src="{{ avatar }}" class="img-circle avatar{% if class is not empty %} {{ class }}{% endif %}" alt="{{ user.displayName }}" data-toggle="tooltip" data-placement="top" title="{{ tooltip|default(user.displayName) }}" /> {% endif %} {% else %} {% set color = user.color|colorize(user.displayName) %} <span class="avatar {{ class }}" style="background-color: {{ color }}; color: {{ color|font_contrast }}" {%- if tooltip is not same as (false) %} data-toggle="tooltip" data-placement="top" title="{{ tooltip|default(user.displayName) }}"{% endif -%}> <span class="initials">{{ user.initials }}</span> </span> {% endif %} {% endmacro %} {# options = {'inherit': true, 'random': false} #} {% macro label_activity(activity, options) %} {% set inherit = options.inherit ?? true %} {% set random = options.random ?? false %} {% 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 and random %} {% 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, 'random': false} #} {% macro label_project(project, options) %} {% set inherit = options.inherit ?? true %} {% set random = options.random ?? false %} {% 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 and random %} {% set color = color|colorize(project.name) %} {% endif %} {{ _self.label_color_dot('project', isVisible, project.name, null, color) }} {% endmacro %} {# options = {'random': false} #} {% macro label_customer(customer, options) %} {% set random = options.random ?? false %} {% set color = customer.color %} {% if color is empty and random %} {% 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) %} {% apply spaceless %} <span class="label-{{ type }}{{ isVisible is same as (false) ? ' label-invisible' : '' }}"> <span class="name"> <i class="dot {{ 'dot'|icon }} fa-fw"{% if color is not empty %} style="color:{{ color }}"{% endif %}></i> <span class="name-inner"> {%- if url is not empty -%} <a href="{{ url }}">{{ name }}</a> {%- else -%} {{ name }} {%- endif -%} </span> </span> </span> {% endapply %} {% endmacro %} {% macro color_dot(color, tooltip) %} <span class="label-color" data-toggle="tooltip" data-placement="top" title="{{ tooltip }}"> <i class="dot {{ 'dot'|icon }} fa-fw"{% if color is not empty %} style="color:{{ color }}"{% endif %}></i> </span> {% endmacro %} {% macro badge_team_access(teams) %} {% if teams|length > 0 %} {{ _self.badge_counter(teams|length) }} {% else %} {{ _self.badge_counter(0, null, 'bg-gray') }} {% endif %} {% endmacro %} {% macro badge_counter(count, url, type) %} {% if url %} <a href="{{ url }}"><span class="badge {{ type|default('bg-blue') }}">{{ count }}</span></a> {% else %} <span class="badge {{ type|default('bg-blue') }}">{{ count }}</span> {% endif %} {% endmacro %} {% macro label(title, type, tooltip) %} <span {% if tooltip %}data-toggle="tooltip" data-placement="top" title="{{ tooltip }}" {% endif %}class="label label-{{ type|default('success') }}">{{ title }}</span> {% endmacro %} {% macro label_color(title, color) %} <span class="label" 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 alert(type, description, title, icon) %} <div class="alert alert-{{ type|default('danger') }} alert-dismissible"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> {% if title and icon %} <h4><i class="icon {{ icon|icon(icon) }}"></i> {{ title|trans }}</h4> {{ description|trans }} {% elseif icon %} <i class="icon {{ icon|icon(icon) }}"></i> {{ description|trans }} {% else %} {{ description|trans }} {% endif %} </div> {% endmacro %} {% macro callout(type, description, title, icon) %} <div class="callout callout-{{ type|default('danger') }} lead"> {% if title %}<h4>{% if icon %}<i class="{{ icon|icon(icon) }}">{% endif %}</i> {{ title|trans }}</h4>{% endif %} <p>{{ description|trans }}</p> </div> {% endmacro %} {% macro info_box_progress(title, description, amount, percentage, icon, color) %} <div class="info-box bg-{{ color }}"> <span class="info-box-icon"><i class="{{ icon|icon(icon) }}"></i></span> <div class="info-box-content"> <span class="info-box-text">{{ title|trans }}</span> <span class="info-box-number">{{ amount }}</span> <div class="progress"> <div class="progress-bar" style="width: {{ percentage }}%"></div> </div> <span class="progress-description"> {{ description }} </span> </div> <!-- /.info-box-content --> </div> {% endmacro %} {% macro button_group_dropdown(title, actions) %} <div class="btn-group"> <button type="button" class="btn btn-default">{{ title|trans }}</button> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">{{ 'label.toggle_dropdown'|trans }}</span> </button> <ul class="dropdown-menu" role="menu"> {% for url, entry in actions %} <li><a href="{{ url }}">{{ entry|trans }}</a></li> {% endfor %} </ul> </div> {% endmacro %} {% macro table_actions(actions, class) %} {% if actions|length >= 1 %} {% if class is null %} {% set class = 'btn-sm' %} {% endif %} {% set trash = null %} {% set divider = false %} <div class="btn-group dropdown"> <button type="button" class="btn btn-default {{ class }} dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="fa fa-chevron-down"></span> </button> <ul class="dropdown-menu dropdown-menu-right"> {%- apply spaceless -%} {%- for icon,values in actions %} {% if 'divider' in icon and values is null %} {% if not loop.last and divider is same as (false) %} <li class="divider"></li> {% endif %} {% set divider = true %} {% else %} {% if values is iterable %} {% if values['title'] is not defined %} {% set values = values|merge({'title': icon|trans({}, 'actions')}) %} {% endif %} {% else %} {% set values = {'url': values, 'title': icon|trans({}, 'actions')} %} {% endif %} {% if icon == 'trash' %} {% set trash = values %} {% else %} {% set divider = false %} {% if values.children is defined %} {%- for childIcon, childValues in values.children %} <li> {{ _self.action_button(childIcon, childValues, false) }} </li> {% endfor %} {% else %} <li> {{ _self.action_button(icon, values, false) }} </li> {% endif %} {% endif %} {% endif %} {% endfor -%} {%- if trash is not null %} {% if actions|length > 1 and divider is same as (false) %} <li class="divider"></li> {% endif %} <li class="delete"> {{ _self.action_button('trash', trash, false) }} </li> {% endif -%} {% endapply %} </ul> </div> {% endif %} {% endmacro %} {% macro list_group_actions(actions, highlightUrl) %} {% if actions|length > 0 %} <div class="list-group"> {% for icon, values in actions %} {% if 'divider' in icon and values is null %} </div><div class="list-group"> {# <a class="list-group-item disabled list-group-divider"></a> #} {% else %} {% if values is not iterable %} {% set values = {'url': values} %} {% endif %} {% if values['children'] is defined %} {{ _self.list_group_actions(values['children'], highlightUrl) }} {% else %} {% if values['title'] is not defined %} {% set values = values|merge({'title': icon|trans({}, 'actions')}) %} {% endif %} {% set class = 'list-group-item' %} {% if highlightUrl == values.url %} {% set class = class ~ ' active' %} {% endif %} {% set values = values|merge({'class': class}) %} {{ _self.action_button(icon, values, false) }} {% endif %} {% endif %} {% endfor %} </div> {% endif %} {% endmacro %} {% macro action_button(icon, values, type) %} {%- apply spaceless -%} {% set id = null %} {% set onclick = null %} {% set modal = null %} {% set toggle = null %} {% set url = null %} {% set target = null %} {% set title = null %} {% set disabled = false %} {% set attr = {} %} {% set label = null %} {% set translation_domain = 'messages' %} {% if type is same as (false) %} {% set class = "" %} {% elseif type is null %} {% set class = "btn btn-default btn-" ~ icon ~ " " %} {% else %} {% set class = "btn btn-" ~ type ~ " btn-" ~ icon ~ " " %} {% endif %} {% if values is not iterable %} {% deprecated 'Passing a non iterable action_button is deprecated since 1.15 and will be removed with 2.0' %} {% set url = values %} {% if 'onclick:' in url %} {% set onclick = url|replace({'onclick:': ''}) %} {% set url = '#' %} {% endif %} {% if '#collapse' in url %} {% set toggle = 'collapse' %} {% endif %} {% if '#modal' in url %} {% set modal = url %} {% set url = '#' %} {% endif %} {% else %} {% set icon = values.icon ?? icon %} {% set disabled = values.disabled ?? false %} {% set url = values.url ?? '#' %} {% set onclick = values.onclick ?? null %} {% set modal = values.modal ?? null %} {% set toggle = values.toggle ?? null %} {% set target = values.target ?? null %} {% set id = values.id ?? null %} {% set title = values.title ?? null %} {% set class = class ~ ( values.class | default("")) %} {% set attr = values.attr ?? {} %} {% set label = values.label ?? null %} {% set translation_domain = values.translation_domain ?? translation_domain %} {% endif %} {% if disabled is same as (true) %} {% set class = class ~ " disabled" %} {% endif %} <a class="{{ class | trim }}" href="{{ url }}" {%- if disabled is same as (true) %} disabled="disabled"{% endif %} {%- if id is not empty %} id="{{ id }}"{% endif %} {%- if toggle is not empty %} data-toggle="{{ toggle }}"{% endif %} {%- if modal is not empty %} data-toggle="modal" data-target="{{ modal }}"{% endif %} {%- if onclick is not empty %} onclick="{{ onclick }}"{% endif %} {%- if target is not empty %} target="{{ target }}"{% endif %} {%- if attr is not empty %} {% for name, value in attr %} {{ ' ' ~ name }}={% if '"' in value %}'{{ value|raw }}'{% else %}"{{ value|raw }}"{% endif %} {% endfor %} {% endif %} >{% if title is not null %}{{ title|trans({}, translation_domain) }}{% else %}{{ _self.icon(icon) }}{% endif %}{% if label is not null %}<span class="label bg-yellow">{{ label }}</span>{% endif %}</a> {% endapply %} {% endmacro %} {% macro button_group(actions, type) %} <div class="btn-group"> {%- apply spaceless -%} {%- for icon,values in actions %} {% if 'divider' in icon and values is null %} {# what to do here ? #} {% else %} {% if values.children is defined %} <div class="btn-group"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> {{ _self.icon(icon) }} <span class="caret"></span> <span class="sr-only">{{ 'label.toggle_dropdown'|trans }}</span> </button> <ul class="dropdown-menu dropdown-menu-right" role="menu"> {% for childIcon,childValues in values.children %} <li>{{ _self.action_button(childIcon, childValues, false) }}</li> {% endfor %} </ul> </div> {% else %} {{ _self.action_button(icon, values, type) }} {% endif %} {% endif %} {% endfor -%} {% endapply %} </div> {% endmacro %} {% macro button_action(icon, url) %} <a href="{{ url }}" class="btn btn-default btn-{{ icon }}"> {{ _self.icon(icon) }} </a> {% endmacro %} {% macro tag_list(taglist) %} {% for tag in taglist %} {{ _self.badge(tag.name, tag.color|colorize(tag.name)) }} {% endfor %} {% endmacro %} {% macro form_type_value(type, value, entity) %} {% if '\\ColorPickerType' in type %} {{ _self.color_dot(value, value) }} {% 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_full }} {% elseif '\\CountryType' in type %} {{ value|country }} {% elseif '\\CurrencyType' in type %} {{ value|currency }} {% elseif '\\LanguageType' in type %} {{ value|language }} {% 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, showTitle, collapseAt) %} {% set collapseAt = collapseAt ?? 12 %} {% if showTitle is null %} {% set showTitle = true %} {% endif %} <table class="table table-hover dataTable" role="grid"> {% if showTitle %} <thead> <tr> <th class="hw-min">{{ 'label.team'|trans }}</th> <th>{{ 'label.user'|trans }}</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 userTeamCount = members|length %} <tr{% if is_granted('edit', team) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_team_member', {'id': team.id}) }}"{% endif %}> <td> {{ _self.label_color_dot('color', true, team.name, null, team.color|colorize(team.name)) }} </td> <td class="avatars"> {% set teamHiddenId = 'team_' ~ team.id ~ '_hiddenUser' ~ random() %} {% set counter = 0 %} {% for member in members|sort((a, b) => b.teamlead <=> a.teamlead) %} {% set user = member.user %} {% if member.teamlead %} {{ _self.user_avatar(user, ('label.teamlead'|trans ~ ': ' ~ user.displayName), 'teamlead') }} {% else %} {{ _self.user_avatar(user) }} {% endif %} {% set counter = counter + 1 %} {% if userTeamCount > (collapseAt + 1) and counter == (collapseAt - 1) and loop.index != userTeamCount %} <a href="#" onclick="$(this).parent().append($('#{{ teamHiddenId }}').contents());$('#{{ teamHiddenId }}').remove();$(this).remove();return false;" class="badge">{{ 'label.plus_more'|trans({'%count%': (userTeamCount - collapseAt)}) }}</a> <span class="hidden" id="{{ teamHiddenId }}"> {% set counter = counter + 1 %} {% endif %} {% if userTeamCount > collapseAt and counter != (collapseAt - 1) and loop.index == userTeamCount %} </span> {% 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 %}warning{% 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) %}warning{% 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 %}warning{% 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 %}warning{% 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 percent(maximum, current) %} {% if maximum > 0 %} {{ (current / (maximum / 100))|number_format(2) }} % {% else %} {{ 0|number_format(2) }} % {% endif %} {% endmacro %} Save