entity action buttons re-designed (#746)

This commit is contained in:
Kevin Papst
2019-05-03 21:10:16 +02:00
committed by GitHub
parent 455d772095
commit e92c2d168e
22 changed files with 408 additions and 184 deletions

View File

@@ -58,7 +58,7 @@ $(function() {
// edit timesheet - date with time // edit timesheet - date with time
this.activateDateTimePicker('.content-wrapper'); this.activateDateTimePicker('.content-wrapper');
// some actions can be performed in a modal for a better UX // some actions can be performed in a modal for a better UX
this.activateAjaxFormInModal('a.modal-ajax-form'); this.activateAjaxFormInModal('.modal-ajax-form');
// activate select boxes that load dynamic data via API // activate select boxes that load dynamic data via API
this.activateApiSelects('select[data-related-select]'); this.activateApiSelects('select[data-related-select]');
}, },
@@ -312,15 +312,38 @@ $(function() {
}, },
activateAjaxFormInModal: function(selector) { activateAjaxFormInModal: function(selector) {
$('body').on('click', selector, function(event) { $('body').on('click', selector, function(event) {
// just in case an inner element is editable, than this should not be triggered
if (event.target.parentNode.isContentEditable || event.target.isContentEditable) {
return;
}
// handles the "click" on table rows to open an entry for editing: when a button within a row is clicked,
// we don't want the table row event to be processed - so we intercept it
var target = event.target;
if (event.currentTarget.tagName === 'TR') {
while (target.tagName !== 'BODY') {
if (target.tagName === 'A' || target.tagName === 'BUTTON') {
return;
}
target = target.parentNode;
}
}
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
// any element can open the modal - for none <a> elements use "data-href" instead of "href" attribute
var href = $(this).attr('data-href');
if (!href) {
href = $(this).attr('href');
}
$.ajax({ $.ajax({
url: $(this).attr('href'), url: href,
success: function(html) { success: function(html) {
$.kimai.ajaxFormInModal(html); $.kimai.ajaxFormInModal(html);
}, },
error: function(xhr, err) { error: function(xhr, err) {
window.location = $(this).attr('href'); window.location = href;
} }
}); });
}); });

View File

@@ -266,11 +266,23 @@ div.dataTables_scrollHead table.table-bordered {
} }
table.dataTable { table.dataTable {
/* action column */
.actions {
width: 90px;
li.delete a {
color: #dd4b39;
}
}
/* summary row, like the timesheet table provides */ /* summary row, like the timesheet table provides */
tr.summary td { tr {
&.summary td {
font-weight: bold; font-weight: bold;
border-bottom: 1px solid #ccc; border-bottom: 1px solid #ccc;
} }
&.open-edit {
cursor: pointer;
}
}
td { td {
/* /*
Make sure that the action buttons do not line-break if another column takes all available space Make sure that the action buttons do not line-break if another column takes all available space

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{ {
"build/app.js": "./app.js?[contenthash]", "build/app.js": "./app.js?[contenthash]",
"build/app.css": "./app.css?230233ad08d74f0006abee781c0fa499", "build/app.css": "./app.css?03894379d3cc9cde71d1ce7c0fe24573",
"build/fonts/fa-solid-900.woff2": "./fonts/fa-solid-900.woff2?e8a92a29", "build/fonts/fa-solid-900.woff2": "./fonts/fa-solid-900.woff2?e8a92a29",
"build/images/fa-solid-900.svg": "./images/fa-solid-900.svg?666a82cb", "build/images/fa-solid-900.svg": "./images/fa-solid-900.svg?666a82cb",
"build/images/glyphicons-halflings-regular.svg": "./images/glyphicons-halflings-regular.svg?89889688", "build/images/glyphicons-halflings-regular.svg": "./images/glyphicons-halflings-regular.svg?89889688",

View File

@@ -9,15 +9,8 @@
namespace App\Twig; namespace App\Twig;
use App\Constants;
use App\Entity\Timesheet;
use App\Utils\Duration;
use App\Utils\LocaleSettings;
use NumberFormatter;
use Symfony\Component\Intl\Intl;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Extension\AbstractExtension; use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction; use Twig\TwigFunction;
class TitleExtension extends AbstractExtension class TitleExtension extends AbstractExtension

View File

@@ -10,7 +10,7 @@
'project': 'hidden-xs', 'project': 'hidden-xs',
'comment': 'hidden-xs', 'comment': 'hidden-xs',
'visible': '', 'visible': '',
'actions': 'alwaysVisible', 'actions': 'actions alwaysVisible',
} %} } %}
{% set tableName = 'activity_admin' %} {% set tableName = 'activity_admin' %}
@@ -33,7 +33,7 @@
{{ tables.data_table_header(tableName, columns) }} {{ tables.data_table_header(tableName, columns) }}
{% for entry in entries %} {% for entry in entries %}
<tr> <tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_activity_edit', {'id': entry.id}) }}"{% endif %}>
<td>{{ entry.name }}</td> <td>{{ entry.name }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'customer') }}"> <td class="{{ tables.data_table_column_class(tableName, columns, 'customer') }}">
{% if entry.project and entry.project.customer %} {% if entry.project and entry.project.customer %}
@@ -51,7 +51,7 @@
</td> </td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'visible') }}">{{ widgets.label_visible(entry.visible) }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'visible') }}">{{ widgets.label_visible(entry.visible) }}</td>
<td> <td class="actions">
{{ actions.activity(entry, 'index') }} {{ actions.activity(entry, 'index') }}
</td> </td>
</tr> </tr>

View File

@@ -11,7 +11,7 @@
'number': 'hidden-xs', 'number': 'hidden-xs',
'currency': 'hidden-xs', 'currency': 'hidden-xs',
'visible': 'hidden-xs', 'visible': 'hidden-xs',
'actions': 'alwaysVisible', 'actions': 'actions alwaysVisible',
} %} } %}
{% set tableName = 'customer_admin' %} {% set tableName = 'customer_admin' %}
@@ -33,14 +33,14 @@
{{ tables.data_table_header(tableName, columns) }} {{ tables.data_table_header(tableName, columns) }}
{% for entry in entries %} {% for entry in entries %}
<tr> <tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_customer_edit', {'id': entry.id}) }}"{% endif %}>
<td>{{ entry.name }} {% if entry.company is not empty %}({{ entry.company }}){% endif %}</td> <td>{{ entry.name }} {% if entry.company is not empty %}({{ entry.company }}){% endif %}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'country') }}">{{ entry.country|country }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'country') }}">{{ entry.country|country }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'number') }}">{{ entry.number }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'number') }}">{{ entry.number }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'currency') }}">{{ entry.currency }} {{ entry.currency|currency }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'currency') }}">{{ entry.currency }} {{ entry.currency|currency }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'visible') }}">{{ widgets.label_visible(entry.visible) }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'visible') }}">{{ widgets.label_visible(entry.visible) }}</td>
<td> <td class="actions">
{{ actions.customer(entry, 'index') }} {{ actions.customer(entry, 'index') }}
</td> </td>
</tr> </tr>

View File

@@ -1,10 +1,10 @@
{% extends 'base.html.twig' %} {% extends app.request.xmlHttpRequest ? 'form.html.twig' : 'base.html.twig' %}
{% block page_title %}{{ 'admin_invoice_template.title'|trans }}{% endblock %} {% block page_title %}{{ 'admin_invoice_template.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_invoice_template.subtitle'|trans }}{% endblock %} {% block page_subtitle %}{{ 'admin_invoice_template.subtitle'|trans }}{% endblock %}
{% block main %} {% block main %}
{{ include('default/_form.html.twig', { {{ include(app.request.xmlHttpRequest ? 'default/_form_modal.html.twig' : 'default/_form.html.twig', {
'title': template.name|default('create'|trans), 'title': template.name|default('create'|trans),
'form': form, 'form': form,
'back': path('admin_invoice_template') 'back': path('admin_invoice_template')

View File

@@ -5,6 +5,7 @@
{% block page_title %}{{ 'admin_invoice_template.title'|trans }}{% endblock %} {% block page_title %}{{ 'admin_invoice_template.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_invoice_template.subtitle'|trans }}{% endblock %} {% block page_subtitle %}{{ 'admin_invoice_template.subtitle'|trans }}{% endblock %}
{% block page_actions %} {% block page_actions %}
{# TODO move me to actions macro #}
{% set actions = {} %} {% set actions = {} %}
{% if is_granted('create_invoice_template') %} {% if is_granted('create_invoice_template') %}
{% set actions = actions|merge({'create': path('admin_invoice_template_create')}) %} {% set actions = actions|merge({'create': path('admin_invoice_template_create')}) %}
@@ -12,6 +13,7 @@
{% if is_granted('view_invoice') %} {% if is_granted('view_invoice') %}
{% set actions = actions|merge({'invoice': path('invoice')}) %} {% set actions = actions|merge({'invoice': path('invoice')}) %}
{% endif %} {% endif %}
{% set event = trigger('actions.invoice_templates', {'actions': actions, 'view': 'index'}) %}
{{ widgets.page_actions(actions) }} {{ widgets.page_actions(actions) }}
{% endblock %} {% endblock %}
@@ -20,32 +22,38 @@
{{ widgets.callout('warning', 'error.no_entries_found') }} {{ widgets.callout('warning', 'error.no_entries_found') }}
{% endif %} {% endif %}
{{ tables.data_table_header('invoice_template', { {% set columns = {
'name': 'alwaysVisible', 'name': 'alwaysVisible',
'title': '', 'title': 'hidden-xs',
'due_days': 'hidden-xs', 'due_days': 'hidden-xs hidden-sm',
'vat': 'hidden-xs', 'vat': 'hidden-xs hidden-sm',
'actions': 'alwaysVisible', 'actions': 'actions alwaysVisible',
}) }} } %}
{% set tableName = 'invoice_template' %}
{{ tables.data_table_header(tableName, columns) }}
{% for entry in entries %} {% for entry in entries %}
<tr> <tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_invoice_template_edit', {'id' : entry.id, 'page': page}) }}"{% endif %}>
<td>{{ entry.name }}</td> <td>{{ entry.name }}</td>
<td>{{ entry.title }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'title') }}">{{ entry.title }}</td>
<td class="hidden-xs hidden-sm">{{ entry.dueDays }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'due_days') }}">{{ entry.dueDays }}</td>
<td class="hidden-xs hidden-sm">{{ entry.vat }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'vat') }}">{{ entry.vat }}</td>
<td> <td class="actions">
{% set actionButtons = {} %} {# TODO move me to actions macro #}
{% set actions = {} %}
{% if is_granted('edit', entry) %} {% if is_granted('edit', entry) %}
{% set actionButtons = {'edit': path('admin_invoice_template_edit', {'id' : entry.id, 'page': page})} %} {% set actions = {'edit': {'url': path('admin_invoice_template_edit', {'id' : entry.id, 'page': page}), 'class': 'modal-ajax-form'}} %}
{% endif %} {% endif %}
{% if is_granted('create_invoice_template') %} {% if is_granted('create_invoice_template') %}
{% set actionButtons = actionButtons|merge({'copy': path('admin_invoice_template_copy', {'id' : entry.id, 'page': page})}) %} {% set actions = actions|merge({'copy': path('admin_invoice_template_copy', {'id' : entry.id, 'page': page})}) %}
{% endif %} {% endif %}
{% if is_granted('delete', entry) %} {% if is_granted('delete', entry) %}
{% set actionButtons = actionButtons|merge({'trash': path('admin_invoice_template_delete', {'id' : entry.id, 'page': page})}) %} {% set actions = actions|merge({'trash': path('admin_invoice_template_delete', {'id' : entry.id, 'page': page})}) %}
{% endif %} {% endif %}
{{ widgets.button_group(actionButtons) }} {% set event = trigger('actions.invoice_templates', {'actions': actions, 'view': 'index', 'template': entry}) %}
{{ widgets.table_actions(actions) }}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -17,7 +17,11 @@
{% if activity.id is not empty %} {% if activity.id is not empty %}
{% if is_granted('edit', activity) %} {% if is_granted('edit', activity) %}
{% set actions = actions|merge({'edit': path('admin_activity_edit', {'id': activity.id})}) %} {% set class = '' %}
{% if view != 'edit' %}
{% set class = 'modal-ajax-form' %}
{% endif %}
{% set actions = actions|merge({'edit': {'url': path('admin_activity_edit', {'id': activity.id}), 'class': class}}) %}
{% endif %} {% endif %}
{% if view == 'index' and is_granted('delete', activity) %} {% if view == 'index' and is_granted('delete', activity) %}
{% set actions = actions|merge({'trash': {'url': path('admin_activity_delete', {'id': activity.id}), 'class': 'modal-ajax-form'}}) %} {% set actions = actions|merge({'trash': {'url': path('admin_activity_delete', {'id': activity.id}), 'class': 'modal-ajax-form'}}) %}
@@ -30,7 +34,49 @@
{% set event = trigger('actions.activity', {'actions': actions, 'view': view, 'activity': activity}) %} {% set event = trigger('actions.activity', {'actions': actions, 'view': view, 'activity': activity}) %}
{% if view == 'index' %} {% if view == 'index' %}
{{ widgets.button_group(event.payload.actions) }} {{ widgets.table_actions(event.payload.actions) }}
{% else %}
{{ widgets.page_actions(event.payload.actions) }}
{% endif %}
{% endmacro %}
{% macro users(view) %}
{% import "macros/widgets.html.twig" as widgets %}
{% set actions = {'filter': '#collapseUserAdmin', 'visibility': '#modal_user_admin'} %}
{% if is_granted('create_user') %}
{% set actions = actions|merge({'create': path('admin_user_create')}) %}
{% endif %}
{% set event = trigger('actions.users', {'actions': actions, 'view': view}) %}
{{ widgets.page_actions(event.payload.actions) }}
{% endmacro %}
{% macro user(user, view) %}
{% import "macros/widgets.html.twig" as widgets %}
{% set actions = {} %}
{% if user.id is not empty %}
{% if is_granted('view', user) %}
{% set actions = {'profile-stats': {'url': path('user_profile', {'username' : user.username})}} %}
{% endif %}
{% if is_granted('edit', user) %}
{% set actions = actions|merge({'edit': path('user_profile_edit', {'username' : user.username})}) %}
{% endif %}
{% if is_granted('preferences', user) %}
{% set actions = actions|merge({'settings': {'url': path('user_profile_preferences', {'username' : user.username})}}) %}
{% endif %}
{% if is_granted('view_other_timesheet') %}
{% set actions = actions|merge({'timesheet': path('admin_timesheet', {'user' : user.id})}) %}
{% endif %}
{% if view == 'index' and is_granted('delete', user) %}
{% set actions = actions|merge({'trash': {'url': path('admin_user_delete', {'id': user.id}), 'class': 'modal-ajax-form'}}) %}
{% endif %}
{% endif %}
{% set event = trigger('actions.user', {'actions': actions, 'view': view, 'user': user}) %}
{% if view == 'index' %}
{{ widgets.table_actions(event.payload.actions) }}
{% else %} {% else %}
{{ widgets.page_actions(event.payload.actions) }} {{ widgets.page_actions(event.payload.actions) }}
{% endif %} {% endif %}
@@ -54,7 +100,11 @@
{% if project.id is not empty %} {% if project.id is not empty %}
{% if is_granted('edit', project) %} {% if is_granted('edit', project) %}
{% set actions = actions|merge({'edit': path('admin_project_edit', {'id': project.id})}) %} {% set class = '' %}
{% if view != 'edit' %}
{% set class = 'modal-ajax-form' %}
{% endif %}
{% set actions = actions|merge({'edit': {'url': path('admin_project_edit', {'id': project.id}), 'class': class}}) %}
{% endif %} {% endif %}
{% if is_granted('view_activity') %} {% if is_granted('view_activity') %}
{% set actions = actions|merge({'activity': path('admin_activity', {'customer': project.customer.id, 'project': project.id})}) %} {% set actions = actions|merge({'activity': path('admin_activity', {'customer': project.customer.id, 'project': project.id})}) %}
@@ -70,7 +120,7 @@
{% set event = trigger('actions.project', {'actions': actions, 'view': view, 'project': project}) %} {% set event = trigger('actions.project', {'actions': actions, 'view': view, 'project': project}) %}
{% if view == 'index' %} {% if view == 'index' %}
{{ widgets.button_group(event.payload.actions) }} {{ widgets.table_actions(event.payload.actions) }}
{% else %} {% else %}
{{ widgets.page_actions(event.payload.actions) }} {{ widgets.page_actions(event.payload.actions) }}
{% endif %} {% endif %}
@@ -94,7 +144,11 @@
{% if customer.id is not empty %} {% if customer.id is not empty %}
{% if is_granted('edit', customer) %} {% if is_granted('edit', customer) %}
{% set actions = actions|merge({'edit': path('admin_customer_edit', {'id': customer.id})}) %} {% set class = '' %}
{% if view != 'edit' %}
{% set class = 'modal-ajax-form' %}
{% endif %}
{% set actions = actions|merge({'edit': {'url': path('admin_customer_edit', {'id': customer.id}), 'class': class}}) %}
{% endif %} {% endif %}
{% if is_granted('view_project') %} {% if is_granted('view_project') %}
{% set actions = actions|merge({'project': path('admin_project', {'customer': customer.id})}) %} {% set actions = actions|merge({'project': path('admin_project', {'customer': customer.id})}) %}
@@ -110,7 +164,7 @@
{% set event = trigger('actions.customer', {'actions': actions, 'view': view, 'customer': customer}) %} {% set event = trigger('actions.customer', {'actions': actions, 'view': view, 'customer': customer}) %}
{% if view == 'index' %} {% if view == 'index' %}
{{ widgets.button_group(event.payload.actions) }} {{ widgets.table_actions(event.payload.actions) }}
{% else %} {% else %}
{{ widgets.page_actions(event.payload.actions) }} {{ widgets.page_actions(event.payload.actions) }}
{% endif %} {% endif %}
@@ -134,6 +188,7 @@
{% endmacro %} {% endmacro %}
{% macro timesheet(timesheet, view) %} {% macro timesheet(timesheet, view) %}
{%- filter spaceless -%}
{% import "macros/widgets.html.twig" as widgets %} {% import "macros/widgets.html.twig" as widgets %}
{% set actions = {} %} {% set actions = {} %}
@@ -167,10 +222,11 @@
{% set event = trigger('actions.timesheet', {'actions': actions, 'view': view, 'timesheet': timesheet}) %} {% set event = trigger('actions.timesheet', {'actions': actions, 'view': view, 'timesheet': timesheet}) %}
{% if view == 'index' %} {% if view == 'index' %}
{{ widgets.button_group(event.payload.actions) }} {{ widgets.table_actions(event.payload.actions) }}
{% else %} {% else %}
{{ widgets.page_actions(event.payload.actions) }} {{ widgets.page_actions(event.payload.actions) }}
{% endif %} {% endif %}
{%- endfilter -%}
{% endmacro %} {% endmacro %}
{% macro timesheets_team(view) %} {% macro timesheets_team(view) %}
@@ -194,10 +250,6 @@
{% set actions = {} %} {% set actions = {} %}
{% if timesheet.id is not empty %} {% if timesheet.id is not empty %}
{% if not timesheet.end and is_granted('stop', timesheet) %}
{% set actions = actions|merge({'stop': path('admin_timesheet_stop', {'id' : timesheet.id})}) %}
{% endif %}
{% if is_granted('edit', timesheet) %} {% if is_granted('edit', timesheet) %}
{% set class = '' %} {% set class = '' %}
{% if view != 'edit' %} {% if view != 'edit' %}
@@ -206,6 +258,10 @@
{% set actions = actions|merge({'edit': {'url': path('admin_timesheet_edit', {'id': timesheet.id}), 'class': class}}) %} {% set actions = actions|merge({'edit': {'url': path('admin_timesheet_edit', {'id': timesheet.id}), 'class': class}}) %}
{% endif %} {% endif %}
{% if not timesheet.end and is_granted('stop', timesheet) %}
{% set actions = actions|merge({'stop': path('admin_timesheet_stop', {'id' : timesheet.id})}) %}
{% endif %}
{% if view == 'index' and is_granted('delete', timesheet) %} {% if view == 'index' and is_granted('delete', timesheet) %}
{% set actions = actions|merge({'trash': {'url': path('admin_timesheet_delete', {'id' : timesheet.id}), 'class': 'modal-ajax-form'}}) %} {% set actions = actions|merge({'trash': {'url': path('admin_timesheet_delete', {'id' : timesheet.id}), 'class': 'modal-ajax-form'}}) %}
{% endif %} {% endif %}
@@ -217,7 +273,7 @@
{% set event = trigger('actions.timesheet_team', {'actions': actions, 'view': view, 'timesheet': timesheet}) %} {% set event = trigger('actions.timesheet_team', {'actions': actions, 'view': view, 'timesheet': timesheet}) %}
{% if view == 'index' %} {% if view == 'index' %}
{{ widgets.button_group(event.payload.actions) }} {{ widgets.table_actions(event.payload.actions) }}
{% else %} {% else %}
{{ widgets.page_actions(event.payload.actions) }} {{ widgets.page_actions(event.payload.actions) }}
{% endif %} {% endif %}
@@ -239,7 +295,7 @@
{% set event = trigger('actions.plugin', {'actions': actions, 'view': view}) %} {% set event = trigger('actions.plugin', {'actions': actions, 'view': view}) %}
{% if view == 'index' %} {% if view == 'index' %}
{{ widgets.button_group(event.payload.actions) }} {{ widgets.table_actions(event.payload.actions) }}
{% else %} {% else %}
{{ widgets.page_actions(event.payload.actions) }} {{ widgets.page_actions(event.payload.actions) }}
{% endif %} {% endif %}
@@ -256,19 +312,3 @@
{% set event = trigger('actions.about', {'actions': actions, 'view': view}) %} {% set event = trigger('actions.about', {'actions': actions, 'view': view}) %}
{{ widgets.page_actions(event.payload.actions) }} {{ widgets.page_actions(event.payload.actions) }}
{% endmacro %} {% endmacro %}
{% macro profile(view, user) %}
{% import "macros/widgets.html.twig" as widgets %}
{% set actions = {'profile-stats': {'url': path('user_profile', {'username' : user.username})}} %}
{% if is_granted('edit', user) %}
{% set actions = actions|merge({'profile': {'url': path('user_profile_edit', {'username' : user.username})}}) %}
{% endif %}
{% if is_granted('preferences', user) %}
{% set actions = actions|merge({'settings': {'url': path('user_profile_preferences', {'username' : user.username})}}) %}
{% endif %}
{% set event = trigger('actions.profile', {'actions': actions, 'view': view}) %}
{{ widgets.page_actions(event.payload.actions) }}
{% endmacro %}

View File

@@ -86,7 +86,7 @@
<thead> <thead>
<tr> <tr>
{%- for title, class in columns -%} {%- for title, class in columns -%}
<th data-field="{{ title }}" class="{{ macro.data_table_column_class(name, columns, title) }}">{{ ('label.' ~ title)|trans }}</th> <th data-field="{{ title }}" class="{{ macro.data_table_column_class(name, columns, title) }}">{% if title is not empty and title != 'actions' %}{{ ('label.' ~ title)|trans }}{% endif %}</th>
{%- endfor -%} {%- endfor -%}
</tr> </tr>
</thead> </thead>

View File

@@ -140,18 +140,52 @@
</div> </div>
{% endmacro %} {% endmacro %}
{% macro button_group(actions) %} {% macro table_actions(actions) %}
{% import _self as macro %} {%- import _self as macro -%}
{% if actions|length >= 1 %}
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{ 'label.actions'|trans }}
<span class="fa fa-caret-down"></span></button>
<ul class="dropdown-menu dropdown-menu-right">
{%- filter spaceless -%}
{%- for icon,values in actions %} {%- for icon,values in actions %}
{% spaceless %} {% set class = '' %}
{% if icon == 'trash' %}
{% set class = 'delete' %}
<li class="divider"></li>
{% endif %}
<li class="{{ class }}">
{% if values is iterable %}
{{ macro.action_button(icon, values|merge({'title': icon|trans({}, 'actions')}), false) }}
{% else %}
{{ macro.action_button(icon, {'url': values, 'title': icon|trans({}, 'actions')}, false) }}
{% endif %}
</li>
{% endfor -%}
{% endfilter %}
</ul>
</div>
{% endif %}
{% endmacro %}
{% macro action_button(icon, values, type) %}
{%- import _self as macro -%}
{%- filter spaceless -%}
{% set id = null %} {% set id = null %}
{% set onclick = null %} {% set onclick = null %}
{% set modal = null %} {% set modal = null %}
{% set toggle = null %} {% set toggle = null %}
{% set url = null %} {% set url = null %}
{% set target = null %} {% set target = null %}
{% set title = null %}
{% set disabled = false %}
{% if type is same as (false) %}
{% set class = "" %}
{% elseif type is null %}
{% set class = "btn btn-default btn-" ~ icon ~ " " %} {% set class = "btn btn-default btn-" ~ icon ~ " " %}
{% else %}
{% set class = "btn btn-" ~ type ~ " btn-" ~ icon ~ " " %}
{% endif %}
{% if not values is iterable %} {% if not values is iterable %}
{% set url = values %} {% set url = values %}
@@ -167,16 +201,25 @@
{% set url = '#' %} {% set url = '#' %}
{% endif %} {% endif %}
{% else %} {% else %}
{% set disabled = values.disabled ?? false %}
{% set url = values.url ?? '#' %} {% set url = values.url ?? '#' %}
{% set onclick = values.onclick ?? null %} {% set onclick = values.onclick ?? null %}
{% set modal = values.modal ?? null %} {% set modal = values.modal ?? null %}
{% set toggle = values.toggle ?? null %} {% set toggle = values.toggle ?? null %}
{% set target = values.target ?? null %} {% set target = values.target ?? null %}
{% set id = values.id ?? null %} {% set id = values.id ?? null %}
{% set title = values.title ?? null %}
{% set class = class ~ ( values.class | default("")) %} {% set class = class ~ ( values.class | default("")) %}
{% endif %} {% endif %}
{% endspaceless %}
{% if disabled is same as (true) %}
{% set class = class ~ " disabled" %}
{% endif %}
<a class="{{ class | trim }}" href="{{ url }}" <a class="{{ class | trim }}" href="{{ url }}"
{%- if disabled is same as (true) -%}
disabled="disabled"
{%- endif -%}
{%- if id is not empty -%} {%- if id is not empty -%}
id="{{ id }}" id="{{ id }}"
{%- endif -%} {%- endif -%}
@@ -192,8 +235,18 @@
{%- if target is not empty -%} {%- if target is not empty -%}
target="{{ target }}" target="{{ target }}"
{%- endif -%} {%- endif -%}
>{{ macro.icon(icon) }}</a> >{% if title is not null %}{{ title }}{% else %}{{ macro.icon(icon) }}{% endif %}</a>
{% endfilter %}
{% endmacro %}
{% macro button_group(actions, type) %}
{%- import _self as macro -%}
<div class="btn-group">
{%- filter spaceless -%}
{%- for icon,values in actions %}
{{ macro.action_button(icon, values, type) }}
{% endfor -%} {% endfor -%}
{% endfilter %}
</div> </div>
{% endmacro %} {% endmacro %}

View File

@@ -23,7 +23,7 @@
<th>{{ 'label.version'|trans({}, 'plugins') }}</th> <th>{{ 'label.version'|trans({}, 'plugins') }}</th>
<th class="hidden-xs">{{ 'label.description'|trans }}</th> <th class="hidden-xs">{{ 'label.description'|trans }}</th>
<th class="hidden-xs hidden-sm">{{ 'label.required_version'|trans({}, 'plugins') }}</th> <th class="hidden-xs hidden-sm">{{ 'label.required_version'|trans({}, 'plugins') }}</th>
<th>{{ 'label.actions'|trans }}</th> <th class="actions"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@@ -10,7 +10,7 @@
'comment': 'hidden-xs hidden-sm', 'comment': 'hidden-xs hidden-sm',
'budget': 'hidden-xs', 'budget': 'hidden-xs',
'visible': '', 'visible': '',
'actions': 'alwaysVisible', 'actions': 'actions alwaysVisible',
} %} } %}
{% set tableName = 'project_admin' %} {% set tableName = 'project_admin' %}
@@ -32,7 +32,7 @@
{{ tables.data_table_header(tableName, columns) }} {{ tables.data_table_header(tableName, columns) }}
{% for entry in entries %} {% for entry in entries %}
<tr> <tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_project_edit', {'id': entry.id}) }}"{% endif %}>
<td>{{ entry.name }}</td> <td>{{ entry.name }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'customer') }}"> <td class="{{ tables.data_table_column_class(tableName, columns, 'customer') }}">
<a href="{{ path('admin_customer_edit', {'id' : entry.customer.id}) }}">{{ widgets.label_customer(entry.customer) }}</a> <a href="{{ path('admin_customer_edit', {'id' : entry.customer.id}) }}">{{ widgets.label_customer(entry.customer) }}</a>
@@ -40,7 +40,7 @@
<td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'budget') }}">{{ entry.budget|money(entry.customer.currency) }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'budget') }}">{{ entry.budget|money(entry.customer.currency) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'visible') }}">{{ widgets.label_visible(entry.visible) }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'visible') }}">{{ widgets.label_visible(entry.visible) }}</td>
<td> <td class="actions">
{{ actions.project(entry, 'index') }} {{ actions.project(entry, 'index') }}
</td> </td>
</tr> </tr>

View File

@@ -5,7 +5,9 @@
{% import "macros/actions.html.twig" as actions %} {% import "macros/actions.html.twig" as actions %}
{% set duration_only = is_duration_only() %} {% set duration_only = is_duration_only() %}
{% set columns = {'date': ''} %} {% set columns = {
'date': 'alwaysVisible',
} %}
{% if not duration_only %} {% if not duration_only %}
{% set columns = columns|merge({'starttime': 'hidden-xs', 'endtime': 'hidden-xs'}) %} {% set columns = columns|merge({'starttime': 'hidden-xs', 'endtime': 'hidden-xs'}) %}
@@ -14,12 +16,12 @@
{% set columns = columns|merge({ {% set columns = columns|merge({
'duration': '', 'duration': '',
'rate': '', 'rate': '',
'customer': 'hidden-xs hidden-sm', 'customer': 'hidden-xs hidden-sm hidden-md',
'project': 'hidden-xs hidden-sm', 'project': 'hidden-xs hidden-sm hidden-md',
'activity': 'hidden-xs hidden-sm', 'activity': 'hidden-xs hidden-sm',
'username': 'hidden-xs', 'username': 'hidden-xs',
'description': 'hidden-xs hidden-sm', 'description': 'hidden-xs hidden-sm',
'actions': 'alwaysVisible', 'actions': 'actions alwaysVisible',
}) %} }) %}
{% set tableName = 'timesheet_admin' %} {% set tableName = 'timesheet_admin' %}
@@ -41,7 +43,7 @@
{{ tables.data_table_header(tableName, columns) }} {{ tables.data_table_header(tableName, columns) }}
{% for entry in entries %} {% for entry in entries %}
<tr> <tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_timesheet_edit', {'id': entry.id}) }}"{% endif %}>
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'date') }}">{{ entry.begin|date_short }}</td> <td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'date') }}">{{ entry.begin|date_short }}</td>
{% if not duration_only %} {% if not duration_only %}
@@ -79,7 +81,7 @@
{{ widgets.label_user(entry.user) }} {{ widgets.label_user(entry.user) }}
</td> </td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'description') }}">{{ entry.description|nl2br }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'description') }}">{{ entry.description|nl2br }}</td>
<td> <td class="actions">
{{ actions.timesheet_team(entry, 'index') }} {{ actions.timesheet_team(entry, 'index') }}
</td> </td>
</tr> </tr>

View File

@@ -3,24 +3,30 @@
{% import "macros/datatables.html.twig" as tables %} {% import "macros/datatables.html.twig" as tables %}
{% import "macros/toolbar.html.twig" as toolbar %} {% import "macros/toolbar.html.twig" as toolbar %}
{% import "macros/actions.html.twig" as actions %} {% import "macros/actions.html.twig" as actions %}
{% import _self as timesheet %}
{% set tableName = 'timesheet' %} {% set tableName = 'timesheet' %}
{% set duration_only = is_duration_only() %} {% set duration_only = is_duration_only() %}
{% set canSeeRate = is_granted('view_rate_own_timesheet') %} {% set canSeeRate = is_granted('view_rate_own_timesheet') %}
{% set columns = {'date': 'alwaysVisible'} %} {% set columns = {
'date': 'alwaysVisible',
} %}
{% if not duration_only %} {% if not duration_only %}
{% set columns = columns|merge({'starttime': '', 'endtime': 'hidden-xs'}) %} {% set columns = columns|merge({
'starttime': '',
'endtime': 'hidden-xs'
}) %}
{% endif %} {% endif %}
{% set columns = columns|merge({'duration': ''}) %} {% set columns = columns|merge({'duration': ''}) %}
{% if canSeeRate %} {% if canSeeRate %}
{% set columns = columns|merge({'rate': 'hidden-xs'}) %} {% set columns = columns|merge({'rate': 'hidden-xs'}) %}
{% endif %} {% endif %}
{% set columns = columns|merge({ {% set columns = columns|merge({
'customer': 'hidden-xs hidden-sm', 'customer': 'hidden-xs hidden-sm hidden-md',
'project': 'hidden-xs hidden-sm', 'project': 'hidden-xs hidden-sm hidden-md',
'activity': 'hidden-xs hidden-sm', 'activity': 'hidden-xs hidden-sm',
'description': 'hidden-xs hidden-sm', 'description': 'hidden-xs hidden-sm',
'actions': 'alwaysVisible', 'actions': 'actions alwaysVisible',
}) %} }) %}
{% block page_title %}{{ 'timesheet.title'|trans }}{% endblock %} {% block page_title %}{{ 'timesheet.title'|trans }}{% endblock %}
@@ -33,7 +39,6 @@
{% endblock %} {% endblock %}
{% block main %} {% block main %}
{% import _self as timesheet %}
{% if entries.count == 0 %} {% if entries.count == 0 %}
{{ widgets.callout('warning', 'error.no_entries_found') }} {{ widgets.callout('warning', 'error.no_entries_found') }}
{% else %} {% else %}
@@ -43,17 +48,17 @@
{% set dayDuration = 0 %} {% set dayDuration = 0 %}
{% set dayRate = {} %} {% set dayRate = {} %}
{% for entry in entries %} {% for entry in entries %}
{% set customerCurrency = entry.project.customer.currency %} {%- set customerCurrency = entry.project.customer.currency -%}
{% if day is same as(null) %} {%- if day is same as(null) -%}
{% set day = entry.begin|date_short %} {% set day = entry.begin|date_short %}
{% endif %} {% endif %}
{% if showSummary and day is not same as(entry.begin|date_short) %} {%- if showSummary and day is not same as(entry.begin|date_short) -%}
{{ timesheet.summary(day, dayDuration, dayRate, columns, canSeeRate) }} {{ timesheet.summary(day, dayDuration, dayRate, columns, canSeeRate, duration_only, tableName) }}
{% set day = entry.begin|date_short %} {% set day = entry.begin|date_short %}
{% set dayDuration = 0 %} {% set dayDuration = 0 %}
{% set dayRate = {} %} {% set dayRate = {} %}
{% endif %} {%- endif -%}
<tr> <tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('timesheet_edit', {'id': entry.id}) }}"{% endif %}>
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'date') }}">{{ entry.begin|date_short }}</td> <td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'date') }}">{{ entry.begin|date_short }}</td>
{% if not duration_only %} {% if not duration_only %}
@@ -82,21 +87,21 @@
<td class="{{ tables.data_table_column_class(tableName, columns, 'project') }}">{{ widgets.label_project(entry.project) }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'project') }}">{{ widgets.label_project(entry.project) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'activity') }}">{{ widgets.label_activity(entry.activity) }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'activity') }}">{{ widgets.label_activity(entry.activity) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'description') }} timesheet-description">{{ entry.description|desc2html }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'description') }} timesheet-description">{{ entry.description|desc2html }}</td>
<td> <td class="actions">
{{ actions.timesheet(entry, 'index') }} {{- actions.timesheet(entry, 'index') -}}
</td> </td>
</tr> </tr>
{% if entry.end %} {%- if entry.end -%}
{% if dayRate[customerCurrency] is not defined %} {% if dayRate[customerCurrency] is not defined %}
{% set dayRate = dayRate|merge({(customerCurrency): 0}) %} {% set dayRate = dayRate|merge({(customerCurrency): 0}) %}
{% endif %} {% endif %}
{% set dayRate = dayRate|merge({(customerCurrency): dayRate[customerCurrency] + entry.rate}) %} {% set dayRate = dayRate|merge({(customerCurrency): dayRate[customerCurrency] + entry.rate}) %}
{% endif %} {%- endif -%}
{% set dayDuration = dayDuration + entry.duration %} {%- set dayDuration = dayDuration + entry.duration -%}
{% endfor %} {% endfor %}
{% if showSummary %} {% if showSummary %}
{{ timesheet.summary(day, dayDuration, dayRate, columns, canSeeRate) }} {{ timesheet.summary(day, dayDuration, dayRate, columns, canSeeRate, duration_only, tableName) }}
{% endif %} {% endif %}
{{ tables.data_table_footer(entries, 'timesheet_paginated') }} {{ tables.data_table_footer(entries, 'timesheet_paginated') }}
@@ -118,14 +123,17 @@
</script> </script>
{% endblock %} {% endblock %}
{% macro summary(day, duration, dayRates, columns, canSeeRate) %} {% macro summary(day, duration, dayRates, columns, canSeeRate, duration_only, tableName) %}
{% import "macros/datatables.html.twig" as tables %}
<tr class="summary info"> <tr class="summary info">
<td class="text-nowrap">{{ day }}</td> <td class="text-nowrap">{{ day }}</td>
<td></td> {% if not duration_only %}
<td></td> <td class="{{ tables.data_table_column_class(tableName, columns, 'starttime') }}"></td>
<td class="text-nowrap">{{ duration|duration }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'endtime') }}"></td>
{% endif %}
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'duration') }}">{{ duration|duration }}</td>
{% if canSeeRate %} {% if canSeeRate %}
<td class="text-nowrap"> <td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'rate') }}">
{% for currency, rate in dayRates %} {% for currency, rate in dayRates %}
{{ rate|money(currency) }} {{ rate|money(currency) }}
{% if not loop.last %} {% if not loop.last %}
@@ -133,9 +141,11 @@
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</td> </td>
<td colspan="{{ (columns|length) - 5 }}"></td>
{% else %}
<td colspan="{{ (columns|length) - 4 }}"></td>
{% endif %} {% endif %}
<td class="{{ tables.data_table_column_class(tableName, columns, 'customer') }}"></td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'project') }}"></td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'activity') }}"></td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'description') }}"></td>
<td class="actions"></td>
</tr> </tr>
{% endmacro %} {% endmacro %}

View File

@@ -2,6 +2,7 @@
{% import "macros/datatables.html.twig" as tables %} {% import "macros/datatables.html.twig" as tables %}
{% import "macros/widgets.html.twig" as widgets %} {% import "macros/widgets.html.twig" as widgets %}
{% import "macros/toolbar.html.twig" as toolbar %} {% import "macros/toolbar.html.twig" as toolbar %}
{% import "macros/actions.html.twig" as actions %}
{% set columns = { {% set columns = {
'alias': 'alwaysVisible', 'alias': 'alwaysVisible',
@@ -10,20 +11,14 @@
'title': 'hidden-xs', 'title': 'hidden-xs',
'roles': 'hidden-xs', 'roles': 'hidden-xs',
'active': '', 'active': '',
'actions': 'alwaysVisible', 'actions': 'actions alwaysVisible',
} %} } %}
{% set tableName = 'user_admin' %} {% set tableName = 'user_admin' %}
{% block page_title %}{{ 'admin_user.title'|trans }}{% endblock %} {% block page_title %}{{ 'admin_user.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_user.subtitle'|trans }}{% endblock %} {% block page_subtitle %}{{ 'admin_user.subtitle'|trans }}{% endblock %}
{% block page_actions %} {% block page_actions %}{{ actions.users('index') }}{% endblock %}
{% set actions = {'filter': '#collapseUserAdmin', 'visibility': '#modal_user_admin'} %}
{% if is_granted('create_user') %}
{% set actions = actions|merge({'create': path('admin_user_create')}) %}
{% endif %}
{{ widgets.page_actions(actions) }}
{% endblock %}
{% block main_before %} {% block main_before %}
{{ toolbar.toolbar(toolbarForm, 'collapseUserAdmin', showFilter) }} {{ toolbar.toolbar(toolbarForm, 'collapseUserAdmin', showFilter) }}
@@ -38,7 +33,7 @@
{{ tables.data_table_header(tableName, columns) }} {{ tables.data_table_header(tableName, columns) }}
{% for entry in entries %} {% for entry in entries %}
<tr> <tr{% if is_granted('edit', entry) %} class="open-edit" onclick="location.href='{{ path('user_profile_edit', {'username': entry.username}) }}'"{% endif %}>
<td>{{ widgets.username(entry) }}</td> <td>{{ widgets.username(entry) }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'username') }}">{{ entry.username }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'username') }}">{{ entry.username }}</td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'email') }}">{{ entry.email }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'email') }}">{{ entry.email }}</td>
@@ -49,18 +44,8 @@
{% endfor %} {% endfor %}
</td> </td>
<td class="{{ tables.data_table_column_class(tableName, columns, 'active') }}">{{ widgets.label_visible(entry.enabled) }}</td> <td class="{{ tables.data_table_column_class(tableName, columns, 'active') }}">{{ widgets.label_visible(entry.enabled) }}</td>
<td> <td class="actions">
{% set actionButtons = {} %} {{ actions.user(entry, 'index') }}
{% if is_granted('edit', entry) %}
{% set actionButtons = actionButtons|merge({'edit': path('user_profile', {'username' : entry.username})}) %}
{% endif %}
{% if is_granted('view_other_timesheet') %}
{% set actionButtons = actionButtons|merge({'timesheet': path('admin_timesheet', {'user' : entry.id})}) %}
{% endif %}
{% if is_granted('delete', entry) %}
{% set actionButtons = actionButtons|merge({'trash': {'url': path('admin_user_delete', {'id': entry.id}), 'class': 'modal-ajax-form'}}) %}
{% endif %}
{{ widgets.button_group(actionButtons) }}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -3,7 +3,7 @@
{% block page_title %}{{ 'profile.title'|trans }}{% endblock %} {% block page_title %}{{ 'profile.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'profile.subtitle'|trans }}{% endblock %} {% block page_subtitle %}{{ 'profile.subtitle'|trans }}{% endblock %}
{% block page_actions %}{{ actions.profile(tab, user) }}{% endblock %} {% block page_actions %}{{ actions.user(user, tab) }}{% endblock %}
{% block main %} {% block main %}
{% import _self as macro %} {% import _self as macro %}

View File

@@ -1,10 +1,6 @@
{% extends 'user/layout.html.twig' %} {% extends 'user/layout.html.twig' %}
{% import "macros/actions.html.twig" as actions %}
{% block main %} {% block main %}
{% import _self as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="nav-tabs-custom"> <div class="nav-tabs-custom">

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" target-language="de" datatype="plaintext" original="actions.en.xliff">
<body>
<trans-unit id="stop">
<source>stop</source>
<target>Beenden</target>
</trans-unit>
<trans-unit id="edit">
<source>edit</source>
<target>Bearbeiten</target>
</trans-unit>
<trans-unit id="trash">
<source>trash</source>
<target>Löschen</target>
</trans-unit>
<trans-unit id="repeat">
<source>repeat</source>
<target>Neu starten</target>
</trans-unit>
<trans-unit id="profile-stats">
<source>profile-stats</source>
<target>Statistiken</target>
</trans-unit>
<trans-unit id="settings">
<source>settings</source>
<target>Einstellungen</target>
</trans-unit>
<trans-unit id="timesheet">
<source>timesheet</source>
<target>Stundenzettel</target>
</trans-unit>
<trans-unit id="project">
<source>project</source>
<target>Projekte</target>
</trans-unit>
<trans-unit id="activity">
<source>activity</source>
<target>Tätigkeiten</target>
</trans-unit>
<trans-unit id="copy">
<source>copy</source>
<target>Kopie erstellen</target>
</trans-unit>
<trans-unit id="home">
<source>home</source>
<target>Homepage</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" target-language="en" datatype="plaintext" original="none">
<body>
<trans-unit id="stop">
<source>stop</source>
<target>Stop</target>
</trans-unit>
<trans-unit id="edit">
<source>edit</source>
<target>Edit</target>
</trans-unit>
<trans-unit id="trash">
<source>trash</source>
<target>Delete</target>
</trans-unit>
<trans-unit id="repeat">
<source>repeat</source>
<target>Start again</target>
</trans-unit>
<trans-unit id="profile-stats">
<source>profile-stats</source>
<target>Statistics</target>
</trans-unit>
<trans-unit id="settings">
<source>settings</source>
<target>Settings</target>
</trans-unit>
<trans-unit id="timesheet">
<source>timesheet</source>
<target>Timesheet</target>
</trans-unit>
<trans-unit id="project">
<source>project</source>
<target>Projects</target>
</trans-unit>
<trans-unit id="activity">
<source>activity</source>
<target>Activities</target>
</trans-unit>
<trans-unit id="copy">
<source>copy</source>
<target>Create copy</target>
</trans-unit>
<trans-unit id="home">
<source>home</source>
<target>Homepage</target>
</trans-unit>
</body>
</file>
</xliff>