Release 2.0.2 (#3856)
* allow to overwrite global spreadsheet styles * bump version * fix deprecations in vcard download * bump composer packages * added help page for all registered locales * fix menu id's, cleanup times route, fix configurable homepage redirect * format duration without leading zero in hours (unify javascript with php behavior) * fix active records in all screen sizes * improved responsiveness in XS * fixed invoice number for customer null fields * fix javascript respects multiple recent-activity dropdowns * show recent activities on small screens * fix user-profile layout column in XS * fix search is always marked as active
This commit is contained in:
@@ -368,20 +368,39 @@ final class CustomerController extends AbstractController
|
||||
$vcard = new VCard();
|
||||
|
||||
$contact = $customer->getContact() ?? $customer->getName();
|
||||
if ($contact === null || \strlen($contact) === 0) {
|
||||
$contact = 'Unknown';
|
||||
}
|
||||
|
||||
$contact = explode(' ', $contact);
|
||||
$lastname = array_pop($contact);
|
||||
$firstname = \count($contact) > 0 ? $contact[0] : $lastname;
|
||||
$firstname = \count($contact) > 0 ? $contact[0] : '';
|
||||
$vcard->addName($lastname, $firstname);
|
||||
|
||||
$note = $customer->getComment();
|
||||
if ($note !== null) {
|
||||
$note .= PHP_EOL;
|
||||
}
|
||||
|
||||
$vcard->addName($lastname, $firstname);
|
||||
$vcard->addNote($note . $customer->getAddress());
|
||||
$vcard->addAddress(null, null, null, null, null, null, Countries::getName($customer->getCountry()));
|
||||
$address = $customer->getAddress();
|
||||
if (!empty($note) || !empty($address)) {
|
||||
$vcard->addNote($note . $address);
|
||||
}
|
||||
|
||||
$vcard->addCompany($customer->getCompany() ?? $customer->getName());
|
||||
$vcard->addEmail($customer->getEmail());
|
||||
$country = $customer->getCountry();
|
||||
if ($country !== null) {
|
||||
$vcard->addAddress(null, null, null, null, null, null, Countries::getName($country));
|
||||
}
|
||||
|
||||
$company = $customer->getCompany();
|
||||
if ($company !== null) {
|
||||
$vcard->addCompany($company);
|
||||
}
|
||||
|
||||
$email = $customer->getEmail();
|
||||
if ($email !== null) {
|
||||
$vcard->addEmail($email);
|
||||
}
|
||||
|
||||
$hasPref = false;
|
||||
|
||||
|
||||
86
src/Controller/HelpController.php
Normal file
86
src/Controller/HelpController.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?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\Configuration\LocaleService;
|
||||
use App\Repository\Query\BaseQuery;
|
||||
use App\Utils\DataTable;
|
||||
use App\Utils\LocaleFormatter;
|
||||
use App\Utils\PageSetup;
|
||||
use App\Utils\Pagination;
|
||||
use Pagerfanta\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Intl\Locales;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
|
||||
#[Route(path: '/help')]
|
||||
#[IsGranted('IS_AUTHENTICATED_REMEMBERED')]
|
||||
final class HelpController extends AbstractController
|
||||
{
|
||||
#[Route(path: '/locales', defaults: [], name: 'help_locales', methods: ['GET'])]
|
||||
public function helpLocale(Request $request, LocaleService $service): Response
|
||||
{
|
||||
$table = new DataTable('help_locales', new BaseQuery());
|
||||
$table->addColumn('name', ['class' => 'alwaysVisible', 'orderBy' => false]);
|
||||
$table->addColumn('description', ['class' => 'd-none', 'orderBy' => false]);
|
||||
$table->addColumn('language', ['class' => 'd-none w-min', 'orderBy' => false]);
|
||||
$table->addColumn('date', ['class' => 'alwaysVisible w-min', 'orderBy' => false]);
|
||||
$table->addColumn('time', ['class' => 'alwaysVisible w-min text-center', 'orderBy' => false]);
|
||||
$table->addColumn('duration', ['class' => 'd-none w-min text-end', 'orderBy' => false]);
|
||||
$table->addColumn('money', ['class' => 'w-min text-end', 'orderBy' => false, 'title' => 'rate']);
|
||||
$table->addColumn('hour_24', ['class' => 'alwaysVisible w-min text-center', 'orderBy' => false]);
|
||||
$table->addColumn('rtl', ['class' => 'd-none w-min text-center', 'orderBy' => false, 'title' => 'RTL']);
|
||||
|
||||
$page = new PageSetup('help_locales');
|
||||
$page->setDataTable($table);
|
||||
$page->setActionName('help_locales');
|
||||
|
||||
$data = $this->buildLocales($request, $service);
|
||||
$pagination = new Pagination(new ArrayAdapter($data));
|
||||
$pagination->setMaxPerPage(9999);
|
||||
$table->setPagination($pagination);
|
||||
|
||||
return $this->render('help/index.html.twig', [
|
||||
'page_setup' => $page,
|
||||
'dataTable' => $table,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param LocaleService $service
|
||||
* @return array<string, array<string, string|bool|null>>
|
||||
*/
|
||||
private function buildLocales(Request $request, LocaleService $service): array
|
||||
{
|
||||
$requestLocale = $request->getLocale();
|
||||
$data = [];
|
||||
$now = $this->getDateTimeFactory()->createDateTime();
|
||||
|
||||
foreach ($service->getAllLocales() as $locale) {
|
||||
$formatter = new LocaleFormatter($service, $locale);
|
||||
$data[$locale] = [
|
||||
'language' => $locale,
|
||||
'name' => Locales::getName($locale, $locale),
|
||||
'description' => Locales::getName($locale, $requestLocale),
|
||||
'date' => $formatter->dateShort($now),
|
||||
'time' => $formatter->time($now),
|
||||
'duration' => $formatter->duration(46120),
|
||||
'money' => $formatter->money(2794.83, 'EUR'),
|
||||
'hour_24' => $service->is24Hour($locale),
|
||||
'rtl' => $service->isRightToLeft($locale),
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ namespace App\Controller;
|
||||
|
||||
use App\Configuration\LocaleService;
|
||||
use App\Entity\User;
|
||||
use App\Event\ConfigureMainMenuEvent;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
@@ -26,11 +28,9 @@ final class HomepageController extends AbstractController
|
||||
public const DEFAULT_ROUTE = 'timesheet';
|
||||
|
||||
#[Route(path: '', defaults: [], name: 'homepage', methods: ['GET'])]
|
||||
public function indexAction(Request $request, LocaleService $service): Response
|
||||
public function indexAction(Request $request, LocaleService $service, EventDispatcherInterface $eventDispatcher): Response
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->getUser();
|
||||
$userRoute = $user->getPreferenceValue('login_initial_view', self::DEFAULT_ROUTE, false);
|
||||
$userLanguage = $user->getLanguage();
|
||||
$requestLanguage = $request->getLocale();
|
||||
|
||||
@@ -48,13 +48,23 @@ final class HomepageController extends AbstractController
|
||||
$userLanguage = $service->getDefaultLocale();
|
||||
}
|
||||
|
||||
$routes = [
|
||||
[$userRoute, $userLanguage],
|
||||
[$userRoute, $requestLanguage],
|
||||
[$userRoute, User::DEFAULT_LANGUAGE],
|
||||
[self::DEFAULT_ROUTE, $userLanguage],
|
||||
[self::DEFAULT_ROUTE, $requestLanguage],
|
||||
];
|
||||
$routes = [];
|
||||
|
||||
$userRoute = $user->getPreferenceValue('login_initial_view');
|
||||
if (\is_string($userRoute)) {
|
||||
$event = new ConfigureMainMenuEvent();
|
||||
$eventDispatcher->dispatch($event);
|
||||
$menu = $event->findById($userRoute);
|
||||
if ($menu !== null && \count($menu->getRouteArgs()) === 0 && $menu->getRoute() !== null) {
|
||||
$userRoute = $menu->getRoute();
|
||||
}
|
||||
$routes[] = [$userRoute, $userLanguage];
|
||||
$routes[] = [$userRoute, $requestLanguage];
|
||||
$routes[] = [$userRoute, User::DEFAULT_LANGUAGE];
|
||||
}
|
||||
|
||||
$routes[] = [self::DEFAULT_ROUTE, $userLanguage];
|
||||
$routes[] = [self::DEFAULT_ROUTE, $requestLanguage];
|
||||
|
||||
foreach ($routes as $routeSettings) {
|
||||
$route = $routeSettings[0];
|
||||
|
||||
Reference in New Issue
Block a user