user-profile - sidebar links and language settings (#369)

This commit is contained in:
Kevin Papst
2018-10-23 23:59:38 +02:00
committed by GitHub
parent 0165658659
commit 6633c550f5
28 changed files with 280 additions and 242 deletions

View File

@@ -23,7 +23,7 @@ admin_lte:
# https://github.com/kevinpapst/AdminLTEBundle/blob/master/Resources/docs/control_sidebar.md # https://github.com/kevinpapst/AdminLTEBundle/blob/master/Resources/docs/control_sidebar.md
control_sidebar: control_sidebar:
settings: settings:
icon: "fas fa-cogs" icon: "fas fa-user"
controller: 'App\Controller\SidebarController::settingsAction' controller: 'App\Controller\SidebarController::settingsAction'
home: home:
icon: "fas fa-question-circle" icon: "fas fa-question-circle"
@@ -31,7 +31,7 @@ admin_lte:
routes: routes:
adminlte_profile: user_profile adminlte_profile: user_profile
adminlte_welcome: dashboard adminlte_welcome: homepage
adminlte_login: fos_user_security_login adminlte_login: fos_user_security_login
adminlte_login_check: fos_user_security_check adminlte_login_check: fos_user_security_check
adminlte_registration: fos_user_registration_register adminlte_registration: fos_user_registration_register

View File

@@ -4,10 +4,3 @@ home:
_controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction _controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction
route: homepage route: homepage
permanent: true permanent: true
homepage:
path: /{_locale}
defaults:
_controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction
route: timesheet
permanent: true

View File

@@ -33,10 +33,7 @@ services:
# ================================================================================ # ================================================================================
App\EventSubscriber\RedirectToLocaleSubscriber: App\EventSubscriber\RedirectToLocaleSubscriber:
class: App\EventSubscriber\RedirectToLocaleSubscriber
arguments: ['@router', '%app_locales%', '%locale%'] arguments: ['@router', '%app_locales%', '%locale%']
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
App\Calendar\Service: App\Calendar\Service:
arguments: arguments:
@@ -81,12 +78,11 @@ services:
# FORMS # FORMS
# ================================================================================ # ================================================================================
# form type to edit user roles
App\Form\Type\UserRoleType: App\Form\Type\UserRoleType:
class: App\Form\Type\UserRoleType
arguments: ["%security.role_hierarchy.roles%"] arguments: ["%security.role_hierarchy.roles%"]
tags:
- { name: form.type } App\Form\Type\LanguageType:
arguments: ["%app_locales%"]
App\Form\Extension\DocumentationLinkExtension: App\Form\Extension\DocumentationLinkExtension:
tags: tags:

View File

@@ -30,4 +30,8 @@ class Constants
* Used in multiple views * Used in multiple views
*/ */
public const GITHUB = 'https://github.com/kevinpapst/kimai2/'; public const GITHUB = 'https://github.com/kevinpapst/kimai2/';
/**
* Used in multiple views
*/
public const HOMEPAGE = 'https://v2.kimai.org';
} }

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Controller;
use App\Entity\User;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
/**
* Homepage controller is a redirect controller with user specific logic.
*
* @Route(path="/homepage")
* @Security("is_granted('ROLE_USER')")
*/
class HomepageController extends Controller
{
/**
* @Route(path="", defaults={}, name="homepage", methods={"GET"})
*
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function indexAction(Request $request)
{
// make me configurable via UserPreference
$route = 'timesheet';
/** @var User $user */
$user = $this->getUser();
$locale = $request->getLocale();
$language = $user->getPreferenceValue('language', $locale);
return $this->redirectToRoute($route, ['_locale' => $language]);
}
}

View File

@@ -89,10 +89,6 @@ class MenuBuilderSubscriber implements EventSubscriberInterface
); );
} }
$event->addItem(
new MenuItemModel('logout', 'menu.logout', 'fos_user_security_logout', [], 'fas fa-sign-out-alt')
);
$this->activateByRoute( $this->activateByRoute(
$event->getRequest()->get('_route'), $event->getRequest()->get('_route'),
$event->getItems() $event->getItems()

View File

@@ -9,8 +9,10 @@
namespace App\EventSubscriber; namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/** /**
@@ -21,7 +23,7 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
* *
* @author Oleg Voronkovich <oleg-voronkovich@yandex.ru> * @author Oleg Voronkovich <oleg-voronkovich@yandex.ru>
*/ */
class RedirectToLocaleSubscriber class RedirectToLocaleSubscriber implements EventSubscriberInterface
{ {
/** /**
* @var UrlGeneratorInterface * @var UrlGeneratorInterface
@@ -70,6 +72,16 @@ class RedirectToLocaleSubscriber
$this->locales = array_unique($this->locales); $this->locales = array_unique($this->locales);
} }
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['onKernelRequest']
];
}
/** /**
* @param GetResponseEvent $event * @param GetResponseEvent $event
*/ */

View File

@@ -13,11 +13,13 @@ use App\Entity\User;
use App\Entity\UserPreference; use App\Entity\UserPreference;
use App\Event\UserPreferenceEvent; use App\Event\UserPreferenceEvent;
use App\Form\Type\CalendarViewType; use App\Form\Type\CalendarViewType;
use App\Form\Type\LanguageType;
use App\Form\Type\SkinType; use App\Form\Type\SkinType;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\TimezoneType;
use Symfony\Component\HttpKernel\Event\KernelEvent; use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
@@ -70,6 +72,16 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
->setValue(0) ->setValue(0)
->setType(IntegerType::class) ->setType(IntegerType::class)
->addConstraint(new Range(['min' => 0])), ->addConstraint(new Range(['min' => 0])),
/*
(new UserPreference())
->setName('timezone')
->setValue(date_default_timezone_get())
->setType(TimezoneType::class),
*/
(new UserPreference())
->setName('language')
->setValue('en') // TODO fetch from services.yaml
->setType(LanguageType::class),
(new UserPreference()) (new UserPreference())
->setName(UserPreference::SKIN) ->setName(UserPreference::SKIN)
@@ -100,13 +112,6 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
->setName('calendar.initial_view') ->setName('calendar.initial_view')
->setValue(CalendarViewType::DEFAULT_VIEW) ->setValue(CalendarViewType::DEFAULT_VIEW)
->setType(CalendarViewType::class), ->setType(CalendarViewType::class),
/*
(new UserPreference())
->setName('language')
->setValue('de')
->setType(LanguageType::class),
*/
]; ];
} }

View File

@@ -19,16 +19,36 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
*/ */
class LanguageType extends AbstractType class LanguageType extends AbstractType
{ {
/**
* @var string[]
*/
private $locales = [];
/**
* @param array|string $locales
*/
public function __construct($locales)
{
if (!is_array($locales)) {
$locales = explode('|', $locales);
}
$this->locales = $locales;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$choices = [];
foreach ($this->locales as $key) {
$name = ucfirst(Intl::getLocaleBundle()->getLocaleName($key, $key));
$choices[$name] = $key;
}
$resolver->setDefaults([ $resolver->setDefaults([
'choices' => [ 'choices' => $choices
Intl::getLocaleBundle()->getLocaleName('de', 'de') => 'de',
Intl::getLocaleBundle()->getLocaleName('en', 'en') => 'en',
]
]); ]);
} }

View File

@@ -84,6 +84,7 @@ class Extensions extends \Twig_Extension
'trash' => 'far fa-trash-alt', 'trash' => 'far fa-trash-alt',
'user' => 'fas fa-user', 'user' => 'fas fa-user',
'visibility' => 'far fa-eye', 'visibility' => 'far fa-eye',
'settings' => 'fas fa-wrench',
]; ];
/** /**

View File

@@ -1,3 +1,6 @@
{% macro icon(icon) %}
<i class="{{ icon|icon(icon) }}"></i>
{% endmacro %}
{% macro page_actions(tools) %} {% macro page_actions(tools) %}
<div class="breadcrumb"> <div class="breadcrumb">

View File

@@ -1,20 +1,33 @@
{% import "macros/widgets.html.twig" as widgets %}
{% set version = constant('App\\Constants::VERSION') ~ ' ' ~ constant('App\\Constants::STATUS') %} {% set version = constant('App\\Constants::VERSION') ~ ' ' ~ constant('App\\Constants::STATUS') %}
<h3 class="control-sidebar-heading">Kimai v2 - {{ version }}</h3>
<div class="form-group">
{{ 'home.betainfo'|trans({'%version%': version}, 'sidebar')|raw|nl2br }}
</div>
<ul class="control-sidebar-menu"> <ul class="control-sidebar-menu">
<li> <li>
<a href="{{ path('help') }}"> <a href="{{ constant('App\\Constants::GITHUB') }}" target="_blank">
<i class="menu-icon {{ 'manual'|icon }} bg-yellow"></i> <i class="menu-icon fab fa-github bg-gray"></i>
<div class="menu-info"> <div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'help.title'|trans({}, 'sidebar') }}</h4> <h4 class="control-sidebar-subheading">GitHub</h4>
<p>{{ 'help.subtitle'|trans({}, 'sidebar') }}</p> <p>{{ 'home.github'|trans({}, 'sidebar')|raw }}</p>
</div>
</a>
</li>
<li>
<a href="{{ constant('App\\Constants::HOMEPAGE') }}" target="_blank">
<i class="menu-icon fa fa-home bg-green"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'home.website'|trans({}, 'sidebar') }}</h4>
<p>www.kimai.org</p>
</div> </div>
</a> </a>
</li> </li>
</ul> </ul>
<h3 class="control-sidebar-heading">{{ 'home.title'|trans({'%version%': version}, 'sidebar') }}</h3> <p><br>Made with ♥ by <a href="https://www.kevinpapst.de/">Kevin Papst</a> and <a href="{{ constant('App\\Constants::GITHUB') }}graphs/contributors" target="_blank">great contributors</a>.</p>
<div class="form-group">
{{ 'home.betainfo'|trans({'%version%': 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

@@ -16,15 +16,45 @@
</li> </li>
</ul> </ul>
<h3 class="control-sidebar-heading">{{ 'preferences.title'|trans({}, 'sidebar') }}</h3> <ul class="control-sidebar-menu">
<li>
<div class="form-group"> <a href="{{ path('user_profile_edit', {'username' : user.username}) }}">
<label class="control-sidebar-subheading"> <div class="pull-left image">
{{ 'preferences.label.language'|trans({}, 'sidebar') }} <i class="{{ 'user'|icon }} text-gray"></i>
<select class="pull-right" onchange="window.location.href = this.options[this.selectedIndex].value;">
{% for locale in locales() %}
<option value="{{ path(originalRequest.get('_route', 'homepage'), originalRequest.get('_route_params', [])|merge({ _locale: locale.code })) }}" {% if app.request.locale == locale.code %}selected="selected"{% endif %}>{{ locale.name|capitalize }}</option>
{% endfor %}
</select>
</label>
</div> </div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'profile.title'|trans }}</h4>
</div>
</a>
</li>
<li>
<a href="{{ path('user_profile_preferences', {'username' : user.username}) }}">
<div class="pull-left image">
<i class="{{ 'settings'|icon }} text-gray"></i>
</div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'profile.preferences'|trans }}</h4>
</div>
</a>
</li>
<li>
<a href="{{ path('help') }}">
<div class="pull-left image">
<i class="{{ 'help'|icon }} text-gray"></i>
</div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'help.title'|trans }}</h4>
</div>
</a>
</li>
<li>
<a href="{{ path('fos_user_security_logout') }}">
<div class="pull-left image">
<i class="{{ 'logout'|icon }} text-gray"></i>
</div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'menu.logout'|trans }}</h4>
</div>
</a>
</li>
</ul>

View File

@@ -18,6 +18,11 @@ use App\Tests\DataFixtures\TimesheetFixtures;
*/ */
class ActivityControllerTest extends ControllerBaseTest class ActivityControllerTest extends ControllerBaseTest
{ {
public function testIsSecure()
{
$this->assertUrlIsSecured('/activities/recent');
}
public function testRecentActivitiesAction() public function testRecentActivitiesAction()
{ {
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER); $client = $this->getClientForAuthenticatedUser(User::ROLE_USER);

View File

@@ -0,0 +1,53 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Controller;
use App\Entity\User;
use App\Entity\UserPreference;
use App\Form\Type\LanguageType;
/**
* @coversDefaultClass \App\Controller\HomepageController
* @group integration
*/
class HomepageControllerTest extends ControllerBaseTest
{
public function testIsSecure()
{
$this->assertUrlIsSecured('/homepage');
}
public function testIndexAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$this->request($client, '/homepage');
$this->assertIsRedirect($client, '/en/timesheet/');
}
public function testIndexActionWithChangedLanguage()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
$user = $this->getUserByRole($em, User::ROLE_USER);
$pref = (new UserPreference())
->setName('language')
->setValue('ar')
->setType(LanguageType::class);
$user->addPreference($pref);
$em->persist($pref);
$this->request($client, '/homepage');
$this->assertIsRedirect($client, '/ar/timesheet/');
}
}

View File

@@ -230,6 +230,8 @@ class ProfileControllerTest extends ControllerBaseTest
'user_preferences_form' => [ 'user_preferences_form' => [
'preferences' => [ 'preferences' => [
['name' => UserPreference::HOURLY_RATE, 'value' => 37], ['name' => UserPreference::HOURLY_RATE, 'value' => 37],
// ['name' => 'timezone', 'value' => 'America/Creston'],
['name' => 'language', 'value' => 'ar'],
['name' => UserPreference::SKIN, 'value' => 'blue'], ['name' => UserPreference::SKIN, 'value' => 'blue'],
['name' => 'theme.fixed_layout', 'value' => false], ['name' => 'theme.fixed_layout', 'value' => false],
['name' => 'theme.boxed_layout', 'value' => true], ['name' => 'theme.boxed_layout', 'value' => true],
@@ -250,6 +252,8 @@ class ProfileControllerTest extends ControllerBaseTest
$user = $this->getUserByRole($em, User::ROLE_USER); $user = $this->getUserByRole($em, User::ROLE_USER);
$this->assertEquals(37, $user->getPreferenceValue(UserPreference::HOURLY_RATE)); $this->assertEquals(37, $user->getPreferenceValue(UserPreference::HOURLY_RATE));
//$this->assertEquals('', $user->getPreferenceValue('America/Creston'));
$this->assertEquals('ar', $user->getPreferenceValue('language'));
$this->assertEquals('blue', $user->getPreferenceValue(UserPreference::SKIN)); $this->assertEquals('blue', $user->getPreferenceValue(UserPreference::SKIN));
$this->assertEquals(false, $user->getPreferenceValue('theme.fixed_layout')); $this->assertEquals(false, $user->getPreferenceValue('theme.fixed_layout'));
$this->assertEquals(true, $user->getPreferenceValue('theme.boxed_layout')); $this->assertEquals(true, $user->getPreferenceValue('theme.boxed_layout'));

View File

@@ -31,6 +31,9 @@ class SidebarControllerTest extends ControllerBaseTest
$this->assertContains('<ul class="control-sidebar-menu">', $content); $this->assertContains('<ul class="control-sidebar-menu">', $content);
$this->assertContains('<a href="/en/profile/' . $user->getUsername() . '">', $content); $this->assertContains('<a href="/en/profile/' . $user->getUsername() . '">', $content);
$this->assertContains('<select class="pull-right" onchange="window.location.href = this.options[this.selectedIndex].value;">', $content); $this->assertContains('<a href="/en/profile/' . $user->getUsername() . '/edit">', $content);
$this->assertContains('<a href="/en/profile/' . $user->getUsername() . '/prefs">', $content);
$this->assertContains('<a href="/en/help/">', $content);
$this->assertContains('<a href="/en/logout">', $content);
} }
} }

View File

@@ -232,8 +232,12 @@ class TimesheetControllerTest extends ControllerBaseTest
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin()); $this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
$this->assertInstanceOf(\DateTime::class, $timesheet->getEnd()); $this->assertInstanceOf(\DateTime::class, $timesheet->getEnd());
$this->assertEquals(50, $timesheet->getRate()); $this->assertEquals(50, $timesheet->getRate());
$this->assertEquals('2018-08-02T20:00:00+00:00', $timesheet->getBegin()->format(\DateTime::ATOM));
$this->assertEquals('2018-08-02T20:30:00+00:00', $timesheet->getEnd()->format(\DateTime::ATOM)); $expected = new \DateTime('2018-08-02T20:00:00');
$this->assertEquals($expected->format(\DateTime::ATOM), $timesheet->getBegin()->format(\DateTime::ATOM));
$expected = new \DateTime('2018-08-02T20:30:00');
$this->assertEquals($expected->format(\DateTime::ATOM), $timesheet->getEnd()->format(\DateTime::ATOM));
} }
public function testCreateActionWithBeginAndEndValues() public function testCreateActionWithBeginAndEndValues()
@@ -260,8 +264,12 @@ class TimesheetControllerTest extends ControllerBaseTest
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin()); $this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
$this->assertInstanceOf(\DateTime::class, $timesheet->getEnd()); $this->assertInstanceOf(\DateTime::class, $timesheet->getEnd());
$this->assertEquals(800, $timesheet->getRate()); $this->assertEquals(800, $timesheet->getRate());
$this->assertEquals('2018-08-02T10:00:00+00:00', $timesheet->getBegin()->format(\DateTime::ATOM));
$this->assertEquals('2018-08-02T18:00:00+00:00', $timesheet->getEnd()->format(\DateTime::ATOM)); $expected = new \DateTime('2018-08-02T10:00:00');
$this->assertEquals($expected->format(\DateTime::ATOM), $timesheet->getBegin()->format(\DateTime::ATOM));
$expected = new \DateTime('2018-08-02T18:00:00');
$this->assertEquals($expected->format(\DateTime::ATOM), $timesheet->getEnd()->format(\DateTime::ATOM));
} }
public function testEditAction() public function testEditAction()

View File

@@ -180,7 +180,7 @@ class ExtensionsTest extends TestCase
$icons = [ $icons = [
'user', 'customer', 'project', 'activity', 'admin', 'invoice', 'timesheet', 'dashboard', 'logout', 'trash', 'user', 'customer', 'project', 'activity', 'admin', 'invoice', 'timesheet', 'dashboard', 'logout', 'trash',
'delete', 'repeat', 'edit', 'manual', 'help', 'start', 'start-small', 'stop', 'stop-small', 'filter', 'delete', 'repeat', 'edit', 'manual', 'help', 'start', 'start-small', 'stop', 'stop-small', 'filter',
'create', 'list', 'print', 'visibility', 'calendar', 'money', 'duration', 'download', 'copy' 'create', 'list', 'print', 'visibility', 'calendar', 'money', 'duration', 'download', 'copy', 'settings'
]; ];
// test pre-defined icons // test pre-defined icons

View File

@@ -820,7 +820,7 @@
<trans-unit id="recent.activities"> <trans-unit id="recent.activities">
<source>recent.activities</source> <source>recent.activities</source>
<target> <target>
Возобновить последнюю деятельность|Возобновить одну их %count% последних деятельностей. Возобновить последнюю деятельность|Возобновить одну их %count% последних деятельностей.|Возобновить одну их %count% последних деятельностей.
</target> </target>
</trans-unit> </trans-unit>
<trans-unit id="recent.activities.format"> <trans-unit id="recent.activities.format">

View File

@@ -2,37 +2,13 @@
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2018-09-28T20:00:00Z" source-language="en" target-language="ar" datatype="plaintext" original="none"> <file date="2018-09-28T20:00:00Z" source-language="en" target-language="ar" datatype="plaintext" original="none">
<body> <body>
<trans-unit id="home.title">
<source>home.title</source>
<target>Kimai v2 - %version%</target>
</trans-unit>
<trans-unit id="home.betainfo"> <trans-unit id="home.betainfo">
<source>home.betainfo</source> <source>home.betainfo</source>
<target><![CDATA[شكرًا لك على استخدام أداة تتبع الوقت مفتوحة المصدر <a href="%url%" target="_blank">Kimai</a>. <target><![CDATA[شكرًا لك على استخدام أداة تتبع الوقت مفتوحة المصدر Kimai.
هذا الإصدار الجديد حاليًا في مرحلة مبكرة من التطوير وقد تم نشره مسبقًا لجمع التعليقات من مستخدميه ودمج أفكارهم في التخطيط الإضافي. هذا الإصدار الجديد حاليًا في مرحلة مبكرة من التطوير وقد تم نشره مسبقًا لجمع التعليقات من مستخدميه ودمج أفكارهم في التخطيط الإضافي.
لمساعدتي في تحسين <strong>Kimai</strong>, الرجاء إرسال رسالتك على موقع الويب المرتبط. سواء كان لديك أسئلة أو للتبليغ عن خطأ أو عطل أو أفكار للتحسينات ، فإن تعليقاتك ذات قيمة! لمساعدتي في تحسين Kimai, الرجاء إرسال رسالتك على موقع الويب المرتبط. سواء كان لديك أسئلة أو للتبليغ عن خطأ أو عطل أو أفكار للتحسينات ، فإن تعليقاتك ذات قيمة!
]]></target> ]]></target>
</trans-unit> </trans-unit>
<trans-unit id="made.by.license">
<source>made.by.license</source>
<target>برمج ب ♥ من قبل مساهمين متطوعين</target>
</trans-unit>
<trans-unit id="help.title">
<source>help.title</source>
<target>كتيب</target>
</trans-unit>
<trans-unit id="help.link">
<source>help.subtitle</source>
<target>عرض الوثائق</target>
</trans-unit>
<trans-unit id="preferences.title">
<source>preferences.title</source>
<target>تفضيلاتك</target>
</trans-unit>
<trans-unit id="preferences.label.language">
<source>preferences.label.language</source>
<target>لغة</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@@ -2,38 +2,22 @@
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2017-01-12T20:00:00Z" source-language="en" target-language="de" datatype="plaintext" original="sidebar.en.xliff"> <file date="2017-01-12T20:00:00Z" source-language="en" target-language="de" datatype="plaintext" original="sidebar.en.xliff">
<body> <body>
<trans-unit id="home.title">
<source>home.title</source>
<target>Kimai v2 - %version%</target>
</trans-unit>
<trans-unit id="home.betainfo"> <trans-unit id="home.betainfo">
<source>home.betainfo</source> <source>home.betainfo</source>
<target><![CDATA[Danke für die Nutzung der Open-Source Zeiterfassung <a href="%url%" target="_blank">Kimai</a>. <target><![CDATA[Danke für die Nutzung der Open-Source Zeiterfassung Kimai.
Diese neue 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. Diese neue 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! Um bei der Verbesserung von Kimai 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> ]]></target>
</trans-unit> </trans-unit>
<trans-unit id="made.by.license"> <trans-unit id="home.github">
<source>made.by.license</source> <source>home.github</source>
<target>Mit ♥ entwickelt von tollen Mitwirkenden</target> <target>Kimai - Projekt Webseite</target>
</trans-unit> </trans-unit>
<trans-unit id="help.title"> <trans-unit id="home.website">
<source>help.title</source> <source>home.website</source>
<target>Bedienungsanleitung</target> <target>Homepage</target>
</trans-unit>
<trans-unit id="help.link">
<source>help.subtitle</source>
<target>Anzeigen (nur englisch)</target>
</trans-unit>
<trans-unit id="preferences.title">
<source>preferences.title</source>
<target>Deine Einstellungen</target>
</trans-unit>
<trans-unit id="preferences.label.language">
<source>preferences.label.language</source>
<target>Sprache</target>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@@ -2,38 +2,22 @@
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2017-01-12T20:00:00Z" source-language="en" target-language="en" datatype="plaintext" original="none"> <file date="2017-01-12T20:00:00Z" source-language="en" target-language="en" datatype="plaintext" original="none">
<body> <body>
<trans-unit id="home.title">
<source>home.title</source>
<target>Kimai v2 - %version%</target>
</trans-unit>
<trans-unit id="home.betainfo"> <trans-unit id="home.betainfo">
<source>home.betainfo</source> <source>home.betainfo</source>
<target><![CDATA[Thank you for using the open source time-tracker <a href="%url%" target="_blank">Kimai</a>. <target><![CDATA[Thank you for using the open source time-tracker Kimai.
This new 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. This new 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! To help me improve Kimai, please send your message on the linked website. Whether you have questions, error messages or ideas for enhancements, your feedback is valuable!
]]></target> ]]></target>
</trans-unit> </trans-unit>
<trans-unit id="made.by.license"> <trans-unit id="home.github">
<source>made.by.license</source> <source>home.github</source>
<target>Made with ♥ by great contributors</target> <target>Kimai - Project website</target>
</trans-unit> </trans-unit>
<trans-unit id="help.title"> <trans-unit id="home.website">
<source>help.title</source> <source>home.website</source>
<target>Manual</target> <target>Homepage</target>
</trans-unit>
<trans-unit id="help.link">
<source>help.subtitle</source>
<target>Show documentation</target>
</trans-unit>
<trans-unit id="preferences.title">
<source>preferences.title</source>
<target>Your preferences</target>
</trans-unit>
<trans-unit id="preferences.label.language">
<source>preferences.label.language</source>
<target>Language</target>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@@ -2,39 +2,15 @@
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2017-01-12T20:00:00Z" source-language="en" target-language="es" datatype="plaintext" original="none"> <file date="2017-01-12T20:00:00Z" source-language="en" target-language="es" datatype="plaintext" original="none">
<body> <body>
<trans-unit id="home.title">
<source>home.title</source>
<target>Kimai v2 - %version%</target>
</trans-unit>
<trans-unit id="home.betainfo"> <trans-unit id="home.betainfo">
<source>home.betainfo</source> <source>home.betainfo</source>
<target><![CDATA[Gracias por usar el control de tiempo ppen source <a href="%url%" target="_blank">Kimai</a>. <target><![CDATA[Gracias por usar el control de tiempo ppen source Kimai.
Esta nueva versión se encuentra en una etapa inicial de desarrollo y ha sido publicada con la intención de recolectar feedback de los usuarios para incluir sus ideas en planes futuros.. Esta nueva versión se encuentra en una etapa inicial de desarrollo y ha sido publicada con la intención de recolectar feedback de los usuarios para incluir sus ideas en planes futuros..
Para ayudar a mejorar <strong>Kimai</strong>, por favor enviar sus comentarios al sitio. Sus comentarios, ideas para mejorar o reportes de errores son valiosos y agradezco el tiempo para enviárnoslos! Para ayudar a mejorar Kimai, por favor enviar sus comentarios al sitio. Sus comentarios, ideas para mejorar o reportes de errores son valiosos y agradezco el tiempo para enviárnoslos!
]]></target> ]]></target>
</trans-unit> </trans-unit>
<trans-unit id="made.by.license">
<source>made.by.license</source>
<target>Hecho con ♥ por un grandioso equipo de contribuidores</target>
</trans-unit>
<trans-unit id="help.title">
<source>help.title</source>
<target>Manual</target>
</trans-unit>
<trans-unit id="help.link">
<source>help.subtitle</source>
<target>Ver documentación</target>
</trans-unit>
<trans-unit id="preferences.title">
<source>preferences.title</source>
<target>Preferencias</target>
</trans-unit>
<trans-unit id="preferences.label.language">
<source>preferences.label.language</source>
<target>Idioma</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@@ -2,39 +2,15 @@
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2017-01-12T20:00:00Z" source-language="en" target-language="fr" datatype="plaintext" original="sidebar.en.xliff"> <file date="2017-01-12T20:00:00Z" source-language="en" target-language="fr" datatype="plaintext" original="sidebar.en.xliff">
<body> <body>
<trans-unit id="home.title">
<source>home.title</source>
<target>Kimai v2 - %version%</target>
</trans-unit>
<trans-unit id="home.betainfo"> <trans-unit id="home.betainfo">
<source>home.betainfo</source> <source>home.betainfo</source>
<target><![CDATA[Merci d'utiliser ce logiciel libre de suivi de temps <a href="%url%" target="_blank">Kimai</a>. <target><![CDATA[Merci d'utiliser ce logiciel libre de suivi de temps Kimai.
Cette nouvelle version est actuellement à un stade précoce de développement et a été publié à l'avance afin de recueillir les commentaires de ses utilisateurs et d'intégrer leurs idées dans la planification à venir. Cette nouvelle version est actuellement à un stade précoce de développement et a été publié à l'avance afin de recueillir les commentaires de ses utilisateurs et d'intégrer leurs idées dans la planification à venir.
Pour m'aider à améliorer<strong>Kimai</strong>, merci de poster votre message sur le site lié. Que vous ayez des questions, des messages ou des idées d'améliorations, vos retours sont précieux ! Pour m'aider à améliorer Kimai, merci de poster votre message sur le site lié. Que vous ayez des questions, des messages ou des idées d'améliorations, vos retours sont précieux !
]]></target> ]]></target>
</trans-unit> </trans-unit>
<trans-unit id="made.by.license">
<source>made.by.license</source>
<target>Réalisé avec ♥ par des contributeurs sympas</target>
</trans-unit>
<trans-unit id="help.title">
<source>help.title</source>
<target>Documentation</target>
</trans-unit>
<trans-unit id="help.link">
<source>help.subtitle</source>
<target>Consulter la documentation</target>
</trans-unit>
<trans-unit id="preferences.title">
<source>preferences.title</source>
<target>Vos préférences</target>
</trans-unit>
<trans-unit id="preferences.label.language">
<source>preferences.label.language</source>
<target>Langage</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@@ -2,39 +2,15 @@
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2017-01-12T20:00:00Z" source-language="en" target-language="it" datatype="plaintext" original="sidebar.en.xliff"> <file date="2017-01-12T20:00:00Z" source-language="en" target-language="it" datatype="plaintext" original="sidebar.en.xliff">
<body> <body>
<trans-unit id="home.title">
<source>home.title</source>
<target>Kimai v2 - %version%</target>
</trans-unit>
<trans-unit id="home.betainfo"> <trans-unit id="home.betainfo">
<source>home.betainfo</source> <source>home.betainfo</source>
<target><![CDATA[Thank you for using the open source time-tracker <a href="%url%" target="_blank">Kimai</a>. <target><![CDATA[Thank you for using the open source time-tracker Kimai.
This new 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. This new 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! To help me improve Kimai, please send your message on the linked website. Whether you have questions, error messages or ideas for enhancements, your feedback is valuable!
]]></target> ]]></target>
</trans-unit> </trans-unit>
<trans-unit id="made.by.license">
<source>made.by.license</source>
<target>Realizzato con ♥ da persone speciali</target>
</trans-unit>
<trans-unit id="help.title">
<source>help.title</source>
<target>Manuale</target>
</trans-unit>
<trans-unit id="help.link">
<source>help.subtitle</source>
<target>Mostra documentazione</target>
</trans-unit>
<trans-unit id="preferences.title">
<source>preferences.title</source>
<target>Le tue preferenze</target>
</trans-unit>
<trans-unit id="preferences.label.language">
<source>preferences.label.language</source>
<target>Lingua</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@@ -2,39 +2,15 @@
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2017-01-12T20:00:00Z" source-language="en" target-language="de" datatype="plaintext" original="sidebar.en.xliff"> <file date="2017-01-12T20:00:00Z" source-language="en" target-language="de" datatype="plaintext" original="sidebar.en.xliff">
<body> <body>
<trans-unit id="home.title">
<source>home.title</source>
<target>Kimai v2 - %version%</target>
</trans-unit>
<trans-unit id="home.betainfo"> <trans-unit id="home.betainfo">
<source>home.betainfo</source> <source>home.betainfo</source>
<target><![CDATA[Спасибо за использование open source Программы для учета времени <a href="%url%" target="_blank">Kimai</a>. <target><![CDATA[Спасибо за использование open source Программы для учета времени Kimai.
Данная "Версия %version%" пока еще находится на ранней стадии своей разработки. Она была выпущена с целью получения предварительных отзывов от пользователей и их последующего учета при дальнейшем планировании функций. Данная Версия пока еще находится на ранней стадии своей разработки. Она была выпущена с целью получения предварительных отзывов от пользователей и их последующего учета при дальнейшем планировании функций.
Для помощи в усовершенствовании <strong>Kimai</strong>, пожалуйства, отправляйте свои сообщения на страницу под ссылкой. Приветствуются любые вопросы, идеи по разработке, в частности на тему дополнительных функций, а также сообщения об ошибках. Нам очень важна Ваша обратная связь! Для помощи в усовершенствовании Kimai, пожалуйства, отправляйте свои сообщения на страницу под ссылкой. Приветствуются любые вопросы, идеи по разработке, в частности на тему дополнительных функций, а также сообщения об ошибках. Нам очень важна Ваша обратная связь!
]]></target> ]]></target>
</trans-unit> </trans-unit>
<trans-unit id="made.by.license">
<source>made.by.license</source>
<target>Разработано с ♥ благодаря замечательным авторам</target>
</trans-unit>
<trans-unit id="help.title">
<source>help.title</source>
<target>Руководство пользователя</target>
</trans-unit>
<trans-unit id="help.link">
<source>help.subtitle</source>
<target>Отображения (только на английском)</target>
</trans-unit>
<trans-unit id="preferences.title">
<source>preferences.title</source>
<target>Твои настройки</target>
</trans-unit>
<trans-unit id="preferences.label.language">
<source>preferences.label.language</source>
<target>Язык</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@@ -4,8 +4,8 @@ Before importing your data from a Kimai v1 installation, please read the followi
- Data from the existing v1 installation is only read and will never be changed - Data from the existing v1 installation is only read and will never be changed
- Data can only be imported from a Kimai installation with at least `v1.0.1` and database revision `1388` (check your `configuration` table) - Data can only be imported from a Kimai installation with at least `v1.0.1` and database revision `1388` (check your `configuration` table)
- Kimai v1 has support for activities without project assignment yet, which Kimai v2 doesn't support - Kimai v1 has support for activities without project assignment, a feature which Kimai v2 doesn't support (yet)
- global activities will be created for every project that has a linked activity in any of the imported timesheet records - global activities will be transformed and created for each project which has a timesheet record linking to that activity
- User-specific rates are not yet supported in Kimai 2 - User-specific rates are not yet supported in Kimai 2
- fixed-rates and hourly-rates for projects and activities are imported - fixed-rates and hourly-rates for projects and activities are imported
- fixed-rates and hourly-rates and total rate for timesheet entries are imported - fixed-rates and hourly-rates and total rate for timesheet entries are imported