Improved mobile view #151 (#150)

- fixed group by for mysql mode
- only user can edit own prefs
- updated installation README
- pagerfanta shows less links
- improved manual tab
- moved user profile link to pref tabs
- added menu links to top navbar
- moved page actions to breadcrumb position
- integrated daterangepicker and improved toolbar forms
- bugfix for time rounding
This commit is contained in:
Kevin Papst
2018-06-05 21:28:25 +02:00
committed by GitHub
parent db5b6f8e2e
commit 7206d064a5
41 changed files with 1027 additions and 897 deletions

View File

@@ -36,6 +36,10 @@ Lets prepare the environment by installing all dependencies:
composer install
```
The next steps depend on where you want to use Kimai, you can choose between development or production mdoe.
### Installation (development)
The default installation uses a SQLite database, so there is no need to create a database for your first tests.
The default settings will work out-of-the-box, but you might want to adjust the `.env` values to your needs.
You can configure your database through your environment (e.g. Webserver, Cloud-Provider) or in your `.env` file:
@@ -52,15 +56,7 @@ bin/console doctrine:database:create
bin/console doctrine:schema:create
```
To generate the frontend assets ([more information here](var/docs/developers.md)), execute:
```bash
yarn install
npm run prod
```
### Installation (development / demo)
Lets boostrap your environment by executing this commands (which is only available in dev environment):
Lets bootstrap your environment by executing this commands (which is only available in dev environment):
```bash
bin/console kimai:reset-dev
```
@@ -98,8 +94,19 @@ bin/console server:run
This command will start a web server for Kimai. Now you can access the application in your browser at <http://127.0.0.1:8000/>.
You can stop the built-in web server by pressing `Ctrl + C` while you're in the terminal.
To re-generate the frontend assets ([more information here](var/docs/developers.md)), execute:
```bash
yarn install
npm run prod
```
### Installation (live)
### Installation (production)
Make sure the [directories are read and writable by your webserver](https://symfony.com/doc/current/setup/file_permissions.html):
```bash
chown -R www-data var/
chmod -R 777 var/
```
The database to use is up to you, but we would not recommend using the default SQLite database for production usage.
Please create your database and configure the connection string in your environment, e.g. with the `.env` file:
@@ -109,10 +116,10 @@ DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name
APP_SECRET=insert_a_random_secret_string_for_production
```
Create the database schemas and warm up the cache:
Create the database schemas and warm up the cache (as webserver user):
```bash
bin/console doctrine:schema:create
bin/console cache:warmup --env=prod
sudo -u www-data bin/console cache:warmup --env=prod
```
Create your first user with the following command. You will be asked to enter a password afterwards.
@@ -120,6 +127,7 @@ Create your first user with the following command. You will be asked to enter a
```bash
bin/console kimai:create-user username admin@example.com ROLE_SUPER_ADMIN
```
_Tip: You can skip the "create user" step, if you are going to import data from Kimai v1._
For available roles, please refer to the [user documentation](var/docs/users.md).

View File

@@ -5,10 +5,38 @@
* file that was distributed with this source code.
*/
@import "~bootstrap-sass/assets/stylesheets/bootstrap/variables";
.error-page {
margin-bottom: 50px;
}
/* ================================ CONTENT ================================ */
.content {
padding: 15px 0;
}
.content-header {
h1 {
small {
display: none;
}
}
}
@media (min-width: $screen-sm-min) {
.content-header {
h1 {
small {
display: inline-block;
}
}
}
.content {
padding: 15px;
}
}
/* ================================ NAVBAR ================================ */
.navbar-nav>li>a.ddt-large {
@@ -16,7 +44,7 @@
padding-bottom: 9px;
}
li.messages-menu ul.menu li:hover .pull-left i {
li.messages-menu ul.menu li .pull-left i {
color: #dd4b39;
}
@@ -53,8 +81,23 @@ li.open .ticktac i.running{
/* ================================ TOOLBAR ================================ */
.control-sidebar select {
color: #000;
@media (max-width: $screen-md-min) {
.content-header > .breadcrumb {
position: absolute;
float: right;
background: transparent;
}
}
.control-sidebar {
select {
color: #000;
}
div.image {
img.img-circle {
max-width: 34px;
}
}
}
.data_table .box-header>.box-tools {
@@ -64,10 +107,12 @@ li.open .ticktac i.running{
.box-header .box-title.toolbar form {
font-size: 13px;
}
.toolbar form input,
.toolbar form select {
display: inline-block;
width: inherit;
@media (min-width: $screen-sm-min) {
.toolbar form input,
.toolbar form select {
display: inline-block;
width: inherit;
}
}
.toolbar form .form-group {
@@ -105,6 +150,16 @@ footer.main-footer {
/* ================================ INVOICES ================================ */
.invoice {
margin: 0;
}
@media (min-width: $screen-sm-min) {
.invoice {
margin: 10px 25px;
}
}
.page-header-small{
font-size: 14px;
}
@@ -127,13 +182,6 @@ table.invoice-sum th, table.invoice-sum td {
/* ================================ DATA-TABLES ================================ */
/*
TODO "display:hidden" regel für dataTable - spalten - mobile ansicht
TODO "display:hidden" regel für dataTable - header icon - mobile ansicht
*/
/*
dataTables.bootstrap.css
*/
@@ -194,7 +242,6 @@ div.dataTables_paginate ul.pagination {
}
}
table.dataTable td,
table.dataTable th {
-webkit-box-sizing: content-box;
@@ -202,7 +249,6 @@ table.dataTable th {
box-sizing: content-box;
}
table.dataTable {
clear: both;
/*margin-top: 6px !important;
@@ -331,9 +377,6 @@ div.dataTables_scrollHead table.table-bordered {
border-bottom-width: 0;
}
/*
* TableTools styles
*/

View File

@@ -4,3 +4,4 @@ $fa-font-path: "~font-awesome/fonts";
@import '~bootstrap-sass/assets/stylesheets/bootstrap';
@import '~font-awesome/scss/font-awesome';
@import '~daterangepicker/daterangepicker.css';

View File

@@ -7,6 +7,10 @@ require('jquery-ui');
require('bootstrap-sass');
require('jquery-slimscroll');
const Moment = require('moment');
global.moment = Moment;
require('daterangepicker');
// ------ for charts ------
const Chart = require('../../vendor/almasaeed2010/adminlte/plugins/chartjs/Chart.min.js');
global.Chart = Chart;

View File

@@ -36,6 +36,31 @@ $(function() {
$('.dropdown-toggle').dropdown();
$('input[data-datepicker="on"]').daterangepicker({
singleDatePicker: true,
showDropdowns: true,
locale: {
format: "YYYY-MM-DD",
firstDay: 1
}
});
$('input[data-datetimepicker="on"]').daterangepicker({
singleDatePicker: true,
timePicker: true,
timePicker24Hour: true,
showDropdowns: true,
autoUpdateInput: false,
locale: {
cancelLabel: 'Clear',
format: "YYYY-MM-DD HH:mm",
firstDay: 1
}
});
$('input[data-datetimepicker="on"]').on('apply.daterangepicker', function(ev, picker) {
$(this).val(picker.startDate.format('YYYY-MM-DD HH:mm'));
});
/*
$('input').iCheck({
checkboxClass: 'icheckbox_square-blue',

View File

@@ -7,15 +7,16 @@
"prod": "node_modules/.bin/encore production"
},
"devDependencies": {
"@symfony/webpack-encore": "git://github.com/symfony/webpack-encore.git#0.17.2",
"@symfony/webpack-encore": "^0.20.1",
"bootstrap-sass": "^3.3.7",
"daterangepicker": "^3.0.3",
"font-awesome": "^4.7.0",
"icheck": "^1.0.2",
"jquery": "^3.3.1",
"jquery-slimscroll": "^1.3.8",
"jquery-ui": "^1.12.1",
"node-sass": "^4.7.2",
"sass-loader": "^6.0.6",
"node-sass": "^4.9.0",
"sass-loader": "^7.0.2",
"webpack-notifier": "^1.5.1"
}
}

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,18 +1,18 @@
{
"build/app.css": "/build/app.css?693b17f722072629aa711aa269697f8d",
"build/app.js": "/build/app.js?a780ad21736af2959a4d",
"build/app.js": "/build/app.js?ce4b9c776d5d7f2b3282",
"build/app.css": "/build/app.css?37c3ca7efa95dd916f5e63b1e0efdee8",
"build/fonts/fontawesome-webfont.eot": "/build/fonts/fontawesome-webfont.eot?674f50d2",
"build/fonts/fontawesome-webfont.ttf?v=4.7.0": "/build/fonts/fontawesome-webfont.ttf?b06871f2",
"build/fonts/fontawesome-webfont.woff2?v=4.7.0": "/build/fonts/fontawesome-webfont.woff2?af7ae505",
"build/fonts/fontawesome-webfont.woff?v=4.7.0": "/build/fonts/fontawesome-webfont.woff?fee66e71",
"build/fonts/glyphicons-halflings-regular.eot": "/build/fonts/glyphicons-halflings-regular.eot?f4769f9b",
"build/fonts/glyphicons-halflings-regular.ttf": "/build/fonts/glyphicons-halflings-regular.ttf?e18bbf61",
"build/fonts/glyphicons-halflings-regular.woff": "/build/fonts/glyphicons-halflings-regular.woff?fa277232",
"build/fonts/glyphicons-halflings-regular.woff2": "/build/fonts/glyphicons-halflings-regular.woff2?448c34a5",
"build/images/blue.png": "/build/images/blue.png?96f8a905",
"build/images/blue@2x.png": "/build/images/blue@2x.png?2694acfd",
"build/images/boxed-bg.jpg": "/build/images/boxed-bg.jpg?7799dece",
"build/images/default_avatar.png": "/build/images/default_avatar.png?fc197350",
"build/images/blue.png": "/build/images/blue.png?96f8a905",
"build/images/glyphicons-halflings-regular.svg": "/build/images/glyphicons-halflings-regular.svg?89889688",
"build/fonts/glyphicons-halflings-regular.eot": "/build/fonts/glyphicons-halflings-regular.eot?f4769f9b",
"build/images/fontawesome-webfont.svg?v=4.7.0": "/build/images/fontawesome-webfont.svg?912ec66d",
"build/images/glyphicons-halflings-regular.svg": "/build/images/glyphicons-halflings-regular.svg?89889688"
"build/fonts/fontawesome-webfont.ttf?v=4.7.0": "/build/fonts/fontawesome-webfont.ttf?b06871f2",
"build/fonts/glyphicons-halflings-regular.woff2": "/build/fonts/glyphicons-halflings-regular.woff2?448c34a5",
"build/images/blue@2x.png": "/build/images/blue@2x.png?2694acfd",
"build/fonts/fontawesome-webfont.woff?v=4.7.0": "/build/fonts/fontawesome-webfont.woff?fee66e71",
"build/fonts/fontawesome-webfont.woff2?v=4.7.0": "/build/fonts/fontawesome-webfont.woff2?af7ae505",
"build/fonts/glyphicons-halflings-regular.woff": "/build/fonts/glyphicons-halflings-regular.woff?fa277232",
"build/fonts/glyphicons-halflings-regular.ttf": "/build/fonts/glyphicons-halflings-regular.ttf?e18bbf61",
"build/images/default_avatar.png": "/build/images/default_avatar.png?fc197350"
}

View File

@@ -32,10 +32,13 @@ class SidebarController extends AbstractController
*/
public function settingsAction()
{
return $this->render('sidebar/settings.html.twig', []);
$user = $this->getUser();
return $this->render('sidebar/settings.html.twig', [
'user' => $user,
]);
/*
$user = $this->getUser();
$form = $this->createForm(UserPreferencesForm::class, $user, [
'action' => $this->generateUrl('user_profile_preferences', ['username' => $user->getUsername()]),

View File

@@ -90,6 +90,8 @@ trait TimesheetControllerTrait
$record->setEnd($end);
}
// TODO validate that end is not before begin
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($entry);
$entityManager->flush();
@@ -132,7 +134,9 @@ trait TimesheetControllerTrait
}
}
$entityManager = $this->getDoctrine()->getManager();
// TODO validate that end is not before begin
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($entry);
$entityManager->flush();

View File

@@ -42,7 +42,11 @@ class TimesheetEditForm extends AbstractType
if ($entry->getEnd() === null || !$options['duration_only']) {
$builder->add('begin', DateTimeType::class, [
'label' => 'label.begin',
'date_widget' => 'single_text',
'widget' => 'single_text',
'html5' => false,
'format' => 'yyyy-MM-dd H:m',
'with_seconds' => false,
'attr' => ['data-datetimepicker' => 'on'],
]);
}
@@ -51,8 +55,12 @@ class TimesheetEditForm extends AbstractType
} else {
$builder->add('end', DateTimeType::class, [
'label' => 'label.end',
'date_widget' => 'single_text',
'widget' => 'single_text',
'required' => false,
'html5' => false,
'format' => 'yyyy-MM-dd H:m',
'with_seconds' => false,
'attr' => ['data-datetimepicker' => 'on'],
]);
}

View File

@@ -108,7 +108,9 @@ abstract class AbstractToolbarForm extends AbstractType
$builder->add('begin', DateType::class, [
'label' => 'label.begin',
'widget' => 'single_text',
'html5' => false,
'required' => false,
'attr' => ['data-datepicker' => 'on'],
]);
}
@@ -120,7 +122,9 @@ abstract class AbstractToolbarForm extends AbstractType
$builder->add('end', DateType::class, [
'label' => 'label.end',
'widget' => 'single_text',
'html5' => false,
'required' => false,
'attr' => ['data-datepicker' => 'on'],
]);
}

View File

@@ -13,7 +13,6 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use App\Repository\CustomerRepository;
use App\Repository\Query\CustomerQuery;
/**
* Custom form field type to select a customer.

View File

@@ -41,6 +41,7 @@ class ActivityRepository extends AbstractRepository
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('t', 'a', 'p', 'c')
->distinct()
->from(Timesheet::class, 't')
->join('t.activity', 'a')
->join('a.project', 'p')
@@ -49,7 +50,7 @@ class ActivityRepository extends AbstractRepository
->andWhere('a.visible = 1')
->andWhere('p.visible = 1')
->andWhere('c.visible = 1')
->groupBy('a.id')
->groupBy('a.id', 't.id')
->orderBy('t.end', 'DESC')
->setMaxResults(10)
;

View File

@@ -36,8 +36,9 @@ class TimesheetRepository extends AbstractRepository
*/
public function stopRecording(Timesheet $entry)
{
// seems to be necessary so Doctrine will recognize a changed timestamp
$entry->setBegin(clone $entry->getBegin());
$entry->setEnd(new DateTime());
$entityManager = $this->getEntityManager();
$entityManager->persist($entry);
$entityManager->flush();

View File

@@ -72,18 +72,30 @@ class UserVoter extends AbstractVoter
return $this->canView($subject, $user, $token);
case self::EDIT:
case self::PASSWORD:
case self::PREFERENCES:
return $this->canEdit($subject, $user, $token);
case self::DELETE:
return $this->canDelete($subject, $user, $token);
case self::CREATE: // create actually passes in the current user as $subject, not the new one
case self::ROLES:
return $this->canAdminUsers($token);
case self::PREFERENCES:
return $this->canEditPreferences($subject, $user, $token);
}
return false;
}
/**
* @param User $profile
* @param User $user
* @param TokenInterface $token
* @return bool
*/
protected function canEditPreferences(User $profile, User $user, TokenInterface $token)
{
return $profile->getId() == $user->getId();
}
/**
* @param User $profile
* @param User $user

View File

@@ -4,6 +4,7 @@
{% block page_title %}{{ 'admin_activity.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_activity.subtitle'|trans }} {{ 'subtitle.amount'|trans({'%count%': entries.count}) }}{% endblock %}
{% block page_actions %}{{ widgets.page_actions({'plus-square': path('admin_activity_create')}) }}{% endblock %}
{% block main %}
{% if entries.count == 0 %}
@@ -12,24 +13,24 @@
{{ tables.data_table_header({
'label.name': '',
'label.customer': '',
'label.customer': 'hidden-xs',
'label.project': '',
'label.comment': 'hidden-xs',
'label.visible': '',
'label.visible': 'hidden-xs',
'label.actions': '',
}, toolbarForm, {'plus-square': path('admin_activity_create')}) }}
}, toolbarForm) }}
{% for entry in entries %}
<tr>
<td>{{ entry.name }}</td>
<td>
<td class="hidden-xs">
<a href="{{ path('admin_customer_edit', {'id' : entry.project.customer.id}) }}">{{ widgets.label_customer(entry.project.customer) }}</a>
</td>
<td>
<a href="{{ path('admin_project_edit', {'id' : entry.project.id}) }}">{{ widgets.label_project(entry.project) }}</a>
</td>
<td class="hidden-xs">{{ entry.comment }}</td>
<td>{{ widgets.label_visible(entry.visible) }}</td>
<td class="hidden-xs">{{ widgets.label_visible(entry.visible) }}</td>
<td>
{% set actionButtons = {} %}
{% if is_granted('edit', entry) %}

View File

@@ -4,6 +4,7 @@
{% block page_title %}{{ 'admin_customer.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_customer.subtitle'|trans }} {{ 'subtitle.amount'|trans({'%count%': entries.count}) }}{% endblock %}
{% block page_actions %}{{ widgets.page_actions({'plus-square': path('admin_customer_create')}) }}{% endblock %}
{% block main %}
{% if entries.count == 0 %}
@@ -17,9 +18,9 @@
'label.country': 'hidden-xs',
'label.customer_number': 'hidden-xs',
'label.currency': 'hidden-xs',
'label.visible': '',
'label.visible': 'hidden-xs',
'label.actions': '',
}, toolbarForm, {'plus-square': path('admin_customer_create')}) }}
}, toolbarForm) }}
{% for entry in entries %}
<tr>
@@ -27,13 +28,14 @@
<td>
{% for project in entry.projects %}
<a href="{{ path('admin_project_edit', {'id' : project.id}) }}">{{ widgets.label_project(project) }}</a>
<br class="visible-xs-block">
{% endfor %}
</td>
<td class="hidden-xs">{{ entry.comment }}</td>
<td class="hidden-xs">{{ entry.country|country }}</td>
<td class="hidden-xs">{{ entry.number }}</td>
<td class="hidden-xs">{{ entry.currency }} {{ entry.currency|currency }}</td>
<td>{{ widgets.label_visible(entry.visible) }}</td>
<td class="hidden-xs">{{ widgets.label_visible(entry.visible) }}</td>
<td>
{% set actionButtons = {} %}
{% if is_granted('edit', entry) %}

View File

@@ -4,6 +4,7 @@
{% block page_title %}{{ 'admin_project.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_project.subtitle'|trans }} {{ 'subtitle.amount'|trans({'%count%': entries.count}) }}{% endblock %}
{% block page_actions %}{{ widgets.page_actions({'plus-square': path('admin_project_create')}) }}{% endblock %}
{% block main %}
{% if entries.count == 0 %}
@@ -15,9 +16,9 @@
'label.customer': '',
'label.comment': 'hidden-xs hidden-sm',
'label.budget': 'hidden-xs',
'label.visible': '',
'label.visible': 'hidden-xs',
'label.actions': '',
}, toolbarForm, {'plus-square': path('admin_project_create')}) }}
}, toolbarForm) }}
{% for entry in entries %}
<tr>
@@ -27,7 +28,7 @@
</td>
<td class="hidden-xs hidden-sm">{{ entry.comment }}</td>
<td class="hidden-xs">{{ entry.budget|money(entry.customer.currency) }}</td>
<td>{{ widgets.label_visible(entry.visible) }}</td>
<td class="hidden-xs">{{ widgets.label_visible(entry.visible) }}</td>
<td>
{% set actionButtons = {} %}
{% if is_granted('edit', entry) %}

View File

@@ -4,6 +4,7 @@
{% block page_title %}{{ 'admin_timesheet.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_timesheet.subtitle'|trans }}{% endblock %}
{% block page_actions %}{{ widgets.page_actions({'plus-square': path('admin_timesheet_create')}) }}{% endblock %}
{% block main %}
{% if entries.count == 0 %}
@@ -25,7 +26,7 @@
'label.actions': '',
}) %}
{{ tables.data_table_header(columns, toolbarForm, {'plus-square': path('admin_timesheet_create')}) }}
{{ tables.data_table_header(columns, toolbarForm) }}
{% for entry in entries %}
<tr>

View File

@@ -4,6 +4,7 @@
{% block page_title %}{{ 'admin_user.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_user.subtitle'|trans }} {{ 'subtitle.amount'|trans({'%count%': entries.count}) }}{% endblock %}
{% block page_actions %}{{ widgets.page_actions({'plus-square': path('admin_user_create')}) }}{% endblock %}
{% block main %}
{% if entries.count == 0 %}
@@ -19,7 +20,7 @@
'label.active': '',
'label.roles': '',
'label.actions': '',
}, toolbarForm, {'plus-square': path('admin_user_create')}) }}
}, toolbarForm) }}
{% for entry in entries %}
<tr>

View File

@@ -1,5 +1,7 @@
{% extends '@AvanzuAdminTheme/layout/default-layout.html.twig' %}
{% block avanzu_page_content_class %}{{ parent() }} {% block main_content_class %}{% endblock %}{% endblock %}
{% block avanzu_page_content_before %}
<div class="pad margin no-print">
{% block main_before %}{% endblock %}
@@ -47,6 +49,21 @@
{% block avanzu_navbar_messages %}
{% if app.user is not null and is_granted('IS_AUTHENTICATED_REMEMBERED') %}
{% if is_granted('ROLE_USER') %}
<li class="visible-xs-inline-block">
<a href="{{ path('timesheet') }}" class="ddt-large">
<i class="fa fa-clock-o fa-2x"></i>
</a>
</li>
{% endif %}
{% if is_granted('ROLE_TEAMLEAD') %}
<li class="visible-xs-inline-block">
<a href="{{ path('invoice') }}" class="ddt-large">
<i class="fa fa-print fa-2x"></i>
</a>
</li>
{% endif %}
{% block navbar_extensions %}{% endblock %}
{{ render(controller('App\\Controller\\TimesheetController::activeEntriesAction')) }}
{% endif %}
{% endblock %}
@@ -58,15 +75,20 @@
{% endblock %}
{% block avanzu_navbar_toggle %}{{ parent() }}{% endblock %}
{% block avanzu_navbar_tasks %}{{ parent() }}{% endblock %}
{% block avanzu_navbar_user %}{{ parent() }}{% endblock %}
{% block avanzu_navbar_tasks %}{#{ parent() }#}{% endblock %}
{% block avanzu_navbar_user %}{#{ parent() }#}{% endblock %}
{% block avanzu_navbar_control_sidebar_toggle %}{{ parent() }}{% endblock %}
{% block avanzu_sidebar_user %}{# right now we simply deactivate that box #}{% endblock %}
{% block avanzu_sidebar_search %}{# right now we simply deactivate that box #}{% endblock %}
{% block avanzu_sidebar_nav %}{{ parent() }}{% endblock %}
{% block avanzu_breadcrumb %}{{ parent() }}{% endblock %}
{% block avanzu_breadcrumb %}
{{ block('page_actions') }}
{% endblock %}
{% block page_actions %}{% endblock %}
{% block avanzu_control_sidebar %}{{ parent() }}{% endblock %}
{% block avanzu_javascripts %}

View File

@@ -14,18 +14,6 @@
<small>{{user.title}}</small>
</p>
</li>
{#
<!-- Menu Body -->
<li class="user-body">
<div class="col-xs-4 text-center">
</div>
<div class="col-xs-4 text-center">
</div>
<div class="col-xs-4 text-center">
</div>
</li>
#}
<!-- Menu Footer-->
<li class="user-footer">
<div class="pull-left">
<a href="{{ path('user_profile', {'username' : user.username}) }}" class="btn btn-default btn-flat">{{ 'label.user_profile'|trans }}</a>

View File

@@ -4,6 +4,8 @@
{% block page_title %}{{ 'dashboard.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'dashboard.subtitle'|trans }}{% endblock %}
{% block main_content_class %}dashboard{% endblock %}
{% block main %}
{% for settings in dashboard_widgets %}

View File

@@ -8,7 +8,7 @@
{% set class = ' timepicker' %}
{% endif %}
{% set class = class ~ ' datepicker' %}
{% set attr = attr|merge({'class' : class, 'data-datepickerenable':'on'}) %}
{% set attr = attr|merge({'class' : class}) %}
{{ block('form_widget_simple') }}
{% else %}
{% set date_pattern = '<div class="row">' ~ date_pattern ~ '</div>'|raw %}
@@ -21,6 +21,5 @@
'{{ month }}': form_widget(form.month),
'{{ day }}': form_widget(form.day),
})|raw }}
{% endif %}
{% endblock %}

View File

@@ -4,11 +4,12 @@
{% block page_title %}{{ 'invoice.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'invoice.subtitle'|trans }}{% endblock %}
{% block page_actions %}{{ widgets.page_actions({'plus-square': path('admin_invoice_template_create'), 'list': path('admin_invoice_template')}) }}{% endblock %}
{% block avanzu_page_content_class %}invoice{% endblock %}
{% block main_content_class %}invoice{% endblock %}
{% block main_before %}
{{ macro.toolbar(form, {'plus-square': path('admin_invoice_template_create'), 'list': path('admin_invoice_template')}) }}
{{ macro.toolbar(form) }}
{% endblock %}
{% block main_after %}

View File

@@ -48,6 +48,6 @@
</div>
<div class="navigation text-center no-print">
{{ pagerfanta(entries, 'twitter_bootstrap3_translated', { routeName: route }) }}
{{ pagerfanta(entries, 'twitter_bootstrap3_translated', { proximity: 1, routeName: route }) }}
</div>
{% endmacro %}

View File

@@ -1,4 +1,16 @@
{% macro page_actions(tools) %}
<div class="breadcrumb">
<div class="box-tools">
<div class="btn-group">
{% for icon,url in tools %}
<a class="btn btn-default" href="{{ url }}"><i class="fa fa-{{ icon }}"></i></a>
{% endfor %}
</div>
</div>
</div>
{% endmacro %}
{% macro page_header(title) %}
<h2 class="page-header">{{ title|trans }}</h2>
{% endmacro %}

View File

@@ -1,8 +1,8 @@
{% if entries is not empty %}
<li class="dropdown messages-menu">
<a href="#" class="dropdown-toggle ddt-large ticktac" data-toggle="dropdown">
<i class="fa fa-play-circle fa-2x"></i>
{% if entries is not empty %}<span class="label label-{% if entries|length >= kimai_context.active_warning %}danger{% else %}warning{% endif %}">{{ entries|length }}</span>{% endif %}
<span class="label label-{% if entries|length >= kimai_context.active_warning %}danger{% else %}warning{% endif %}">{{ entries|length }}</span>
</a>
<ul class="dropdown-menu">
<li class="header">
@@ -35,3 +35,10 @@
<li class="footer"><a href="{{ path('timesheet_create') }}">{{ 'timesheet.start'|trans }}</a></li>
</ul>
</li>
{% else %}
<li class="messages-menu">
<a href="{{ path('timesheet_create') }}" class="ddt-large">
<i class="fa fa-play-circle fa-2x"></i>
</a>
</li>
{% endif %}

View File

@@ -1,53 +1,19 @@
<h3 class="control-sidebar-heading">{{ 'home.title'|trans({}, 'sidebar') }}</h3>
<div class="form-group">
{{ 'home.betainfo'|trans({}, 'sidebar')|raw|nl2br }}
</div>
<h3 class="control-sidebar-heading">{{ 'help.title'|trans({}, 'sidebar') }}</h3>
<div class="form-group">
<a href="{{ path('help') }}" class="btn btn-success">{{ 'help.link'|trans({}, 'sidebar') }}</a>
</div>
<h3 class="control-sidebar-heading">{{ 'about.title'|trans({}, 'sidebar') }}</h3>
<div class="form-group">
<p>
Kimai {{ constant('App\\Constants::VERSION') }}
</p>
<p>
{{ 'made.by.license'|trans({'%kevin%': '<a href="http://www.kevinpapst.de" target="_blank">Kevin Papst</a>', '%simon%': '<a href="https://github.com/simonschaufi" target="_blank">Simon Schaufelberger</a>'}, 'sidebar')|raw }}
</p>
<p>
{{ 'github.link'|trans({'%url%': constant('App\\Constants::GITHUB')}, 'sidebar')|raw }}
</p>
</div>
{#
<ul class="control-sidebar-menu">
<li>
<a href="javascript:;">
<i class="menu-icon fa fa-birthday-cake bg-red"></i>
<a href="{{ path('help') }}">
<i class="menu-icon fa fa-book bg-yellow"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'Kevin\'s Birthday'|trans({}, 'AvanzuAdminTheme') }}</h4>
<p>{{ 'Will be 23 on April 24th'|trans({}, 'AvanzuAdminTheme') }}</p>
<h4 class="control-sidebar-subheading">{{ 'help.title'|trans({}, 'sidebar') }}</h4>
<p>{{ 'help.subtitle'|trans({}, 'sidebar') }}</p>
</div>
</a>
</li>
</ul>
<h3 class="control-sidebar-heading">{{ 'Tasks Progress'|trans({}, 'AvanzuAdminTheme') }}</h3>
<ul class="control-sidebar-menu">
<li>
<a href="javascript::;">
<h4 class="control-sidebar-subheading">
{{ 'Custom Template Design'|trans({}, 'AvanzuAdminTheme') }}
<span class="label label-danger pull-right">70%</span>
</h4>
<div class="progress progress-xxs">
<div class="progress-bar progress-bar-danger" style="width: 70%"></div>
</div>
</a>
</li>
</ul>
#}
<h3 class="control-sidebar-heading">{{ 'home.title'|trans({}, 'sidebar') }}</h3>
<div class="form-group">
{{ 'home.betainfo'|trans({'%version%': constant('App\\Constants::VERSION'), '%url%': constant('App\\Constants::GITHUB')}, 'sidebar')|raw|nl2br }}
<br>
<a href="{{ constant('App\\Constants::GITHUB') }}graphs/contributors">{{ 'made.by.license'|trans({}, 'sidebar')|raw }}</a>
</div>

View File

@@ -1,4 +1,23 @@
{% import "@AvanzuAdminTheme/layout/macros.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<ul class="control-sidebar-menu">
<li>
<a href="{{ path('user_profile', {'username' : user.username}) }}">
<div class="pull-left image">
{{ macro.avatar(user.avatar, user.username, 'img-circle') }}
</div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ widgets.username(user) }}</h4>
<p>{{ user.title }}</p>
</div>
</a>
</li>
</ul>
<h3 class="control-sidebar-heading">{{ 'preferences.title'|trans({}, 'sidebar') }}</h3>
<div class="form-group">
<label class="control-sidebar-subheading">
{{ 'preferences.label.language'|trans({}, 'sidebar') }}

View File

@@ -4,6 +4,7 @@
{% block page_title %}{{ 'timesheet.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'timesheet.subtitle'|trans }}{% endblock %}
{% block page_actions %}{{ widgets.page_actions({'plus-square': path('timesheet_create')}) }}{% endblock %}
{% block main %}
@@ -25,7 +26,7 @@
'label.actions': '',
}) %}
{{ tables.data_table_header(columns, toolbarForm, {'plus-square': path('timesheet_create')}) }}
{{ tables.data_table_header(columns, toolbarForm) }}
{% for entry in entries %}
<tr>

View File

@@ -569,7 +569,7 @@
</trans-unit>
<trans-unit id="stats.durationTotal">
<source>stats.durationTotal</source>
<target>Working hourstotal</target>
<target>Working hours total</target>
</trans-unit>
<trans-unit id="stats.amountTotal">
<source>stats.amountTotal</source>

View File

@@ -4,11 +4,11 @@
<body>
<trans-unit id="previous">
<source>previous</source>
<target>Vorherige</target>
<target></target>
</trans-unit>
<trans-unit id="next">
<source>next</source>
<target>Nächste</target>
<target></target>
</trans-unit>
</body>
</file>

View File

@@ -4,11 +4,11 @@
<body>
<trans-unit id="previous">
<source>previous</source>
<target>Previous</target>
<target></target>
</trans-unit>
<trans-unit id="next">
<source>next</source>
<target>Next</target>
<target></target>
</trans-unit>
</body>
</file>

View File

@@ -4,11 +4,11 @@
<body>
<trans-unit id="previous">
<source>previous</source>
<target>Предыдущая</target>
<target></target>
</trans-unit>
<trans-unit id="next">
<source>next</source>
<target>Следующая</target>
<target></target>
</trans-unit>
</body>
</file>

View File

@@ -8,32 +8,24 @@
</trans-unit>
<trans-unit id="home.betainfo">
<source>home.betainfo</source>
<target><![CDATA[Danke für die Nutzung der Open-Source Zeiterfassung <strong>Kimai</strong>.
<target><![CDATA[Danke für die Nutzung der Open-Source Zeiterfassung <a href="%url%" target="_blank">Kimai</a>.
Diese neue Version 2 ist aktuell noch in einer frühen Phase der Entwicklung und wurde vorab veröffentlicht, um frühzeitig Rückmeldungen ihrer Benutzer zu sammeln und deren Ideen in die weitere Planung zu integrieren.
Diese neue Version %version% ist aktuell noch in einer frühen Phase der Entwicklung und wurde vorab veröffentlicht, um frühzeitig Rückmeldungen ihrer Benutzer zu sammeln und deren Ideen in die weitere Planung zu integrieren.
Um bei der Verbesserung von <strong>Kimai</strong> zu helfen, schicken Sie mir bitte eine Nachricht auf der verlinkten Webseite. Egal ob Fragen, Fehlermeldungen oder Ideen für Erweiterungen, Ihr Feedback ist wertvoll!
]]></target>
</trans-unit>
<trans-unit id="made.by.license">
<source>made.by.license</source>
<target>Mit ♥ entwickelt von %kevin% und %simon%.</target>
</trans-unit>
<trans-unit id="github.link">
<source>github.link</source>
<target><![CDATA[Weitere Informationen finden Sie auf der <a href="%url%" target="_blank">Kimai Homepage</a>.]]></target>
<target>Mit ♥ entwickelt von tollen Mitwirkenden</target>
</trans-unit>
<trans-unit id="help.title">
<source>help.title</source>
<target>Dokumentation</target>
<target>Bedienungsanleitung</target>
</trans-unit>
<trans-unit id="help.link">
<source>help.link</source>
<target>Benutzer Handbuch</target>
</trans-unit>
<trans-unit id="about.title">
<source>about.title</source>
<target>Über Kimai</target>
<source>help.subtitle</source>
<target>Anzeigen (nur englisch)</target>
</trans-unit>
<trans-unit id="preferences.title">
<source>preferences.title</source>

View File

@@ -8,32 +8,24 @@
</trans-unit>
<trans-unit id="home.betainfo">
<source>home.betainfo</source>
<target><![CDATA[Thank you for using the open source time-tracker <strong>Kimai</strong>.
<target><![CDATA[Thank you for using the open source time-tracker <a href="%url%" target="_blank">Kimai</a>.
This new version 2 is currently in an early stage of development and has been published in advance to collect feedback from its users and integrate their ideas into further planning.
This new version %version% is currently in an early stage of development and has been published in advance to collect feedback from its users and integrate their ideas into further planning.
To help me improve <strong>Kimai</strong>, please send your message on the linked website. Whether you have questions, error messages or ideas for enhancements, your feedback is valuable!
]]></target>
</trans-unit>
<trans-unit id="made.by.license">
<source>made.by.license</source>
<target><![CDATA[Made with ♥ by %kevin% and %simon%.]]></target>
</trans-unit>
<trans-unit id="github.link">
<source>github.link</source>
<target><![CDATA[Further information can be found on the <a href="%url%" target="_blank">Kimai Homepage</a>.]]></target>
<target>Made with ♥ by great contributors</target>
</trans-unit>
<trans-unit id="help.title">
<source>help.title</source>
<target>Documentation</target>
<target>Manual</target>
</trans-unit>
<trans-unit id="help.link">
<source>help.link</source>
<target>User manual</target>
</trans-unit>
<trans-unit id="about.title">
<source>about.title</source>
<target>About Kimai</target>
<source>help.subtitle</source>
<target>Show documentation</target>
</trans-unit>
<trans-unit id="preferences.title">
<source>preferences.title</source>

View File

@@ -8,9 +8,9 @@
</trans-unit>
<trans-unit id="home.betainfo">
<source>home.betainfo</source>
<target><![CDATA[Спасибо за использование open source Программы для учета времени <strong>Kimai</strong>.
<target><![CDATA[Спасибо за использование open source Программы для учета времени <a href="%url%" target="_blank">Kimai</a>.
Данная "Версия 2" пока еще находится на ранней стадии ее разработки. Она была выпущена с целью получения ранних отзывов от пользователей и их последующего учета при дальнейшем планировании функций.
Данная "Версия %version%" пока еще находится на ранней стадии ее разработки. Она была выпущена с целью получения ранних отзывов от пользователей и их последующего учета при дальнейшем планировании функций.
Для помощи в усовершенствовании <strong>Kimai</strong>, пожалуйства, отправляйте свои сообщения на страницу под ссылкой. Приветствуются любые вопросы, идеи по разработке, в частности на тему развернутых функциий, а также сообщения об ошибках. Нам очень важна любая обратная связь от Вас!

1425
yarn.lock

File diff suppressed because it is too large Load Diff