Release 2.3.0 (#4412)

- move user-preferences to edit submenu
- unify user preferences with other forms
- use light fieldset for all user-edit-forms
- support offcanvas elements
- allow to dynamically inject toolbar buttons (via plugins)
- use interface for formatting dates
- improve docker issue template
- bump version and composer packages
This commit is contained in:
Kevin Papst
2023-11-08 22:30:22 +01:00
committed by GitHub
parent 7034066de9
commit 6a828cc9bd
22 changed files with 111 additions and 120 deletions

View File

@@ -18,25 +18,16 @@ body:
validations:
required: true
- type: textarea
id: image
id: environment
attributes:
label: Describe your setup (OS, Docker versions)
label: Describe your setup and add your Docker compose file (redact your credentials)
description: >
Your working environment:
- OS: [e.g. Linux, Windows, Mac]
- Docker version: [e.g. 19.03.2]
- Docker compose version: [e.g. 1.21.0]
validations:
required: true
- type: textarea
id: command
attributes:
label: Command used to run the container
description: e.g. docker run -v ....
- type: textarea
id: compose
attributes:
label: Docker compose file (redact your credentials)
description: >
Docker compose file:
```yaml
version: '3.5'
services:
@@ -44,3 +35,8 @@ body:
```
validations:
required: true
- type: input
id: command
attributes:
label: Command used to run the container
description: e.g. docker run -v ....

View File

@@ -9,7 +9,7 @@
* [KIMAI] KimaiThemeInitializer: initialize theme functionality
*/
import { Tooltip } from 'bootstrap';
import { Tooltip, Offcanvas } from 'bootstrap';
import KimaiPlugin from '../KimaiPlugin';
export default class KimaiThemeInitializer extends KimaiPlugin {
@@ -21,6 +21,10 @@ export default class KimaiThemeInitializer extends KimaiPlugin {
return new Tooltip(tooltipTriggerEl);
});
// support for offcanvas elements
const offcanvasElementList = document.querySelectorAll('.offcanvas');
[...offcanvasElementList].map(offcanvasEl => new Offcanvas(offcanvasEl));
// activate all form plugins
/** @type {KimaiForm} FORMS */
const FORMS = this.getContainer().getPlugin('form');

106
composer.lock generated
View File

@@ -3003,16 +3003,16 @@
},
{
"name": "mpdf/mpdf",
"version": "v8.2.0",
"version": "v8.2.2",
"source": {
"type": "git",
"url": "https://github.com/mpdf/mpdf.git",
"reference": "170a236a588d177c2aa7447ce490a030ca68e6f4"
"reference": "596a87b876d7793be7be060a8ac13424de120dd5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mpdf/mpdf/zipball/170a236a588d177c2aa7447ce490a030ca68e6f4",
"reference": "170a236a588d177c2aa7447ce490a030ca68e6f4",
"url": "https://api.github.com/repos/mpdf/mpdf/zipball/596a87b876d7793be7be060a8ac13424de120dd5",
"reference": "596a87b876d7793be7be060a8ac13424de120dd5",
"shasum": ""
},
"require": {
@@ -3022,7 +3022,7 @@
"mpdf/psr-log-aware-trait": "^2.0 || ^3.0",
"myclabs/deep-copy": "^1.7",
"paragonie/random_compat": "^1.4|^2.0|^9.99.99",
"php": "^5.6 || ^7.0 || ~8.0.0 || ~8.1.0 || ~8.2.0",
"php": "^5.6 || ^7.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
"psr/http-message": "^1.0 || ^2.0",
"psr/log": "^1.0 || ^2.0 || ^3.0",
"setasign/fpdi": "^2.1"
@@ -3080,7 +3080,7 @@
"type": "custom"
}
],
"time": "2023-09-01T11:44:52+00:00"
"time": "2023-11-07T13:52:14+00:00"
},
{
"name": "mpdf/psr-http-message-shim",
@@ -4616,20 +4616,20 @@
},
{
"name": "scheb/2fa-backup-code",
"version": "v6.9.0",
"version": "v6.10.0",
"source": {
"type": "git",
"url": "https://github.com/scheb/2fa-backup-code.git",
"reference": "b01965cd221cda280526e48e7f56966154b9ba2f"
"reference": "d258a5af83b32f88484cd345b4784004766b2fe3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/scheb/2fa-backup-code/zipball/b01965cd221cda280526e48e7f56966154b9ba2f",
"reference": "b01965cd221cda280526e48e7f56966154b9ba2f",
"url": "https://api.github.com/repos/scheb/2fa-backup-code/zipball/d258a5af83b32f88484cd345b4784004766b2fe3",
"reference": "d258a5af83b32f88484cd345b4784004766b2fe3",
"shasum": ""
},
"require": {
"php": "~8.0.0 || ~8.1.0 || ~8.2.0",
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
"scheb/2fa-bundle": "self.version"
},
"type": "library",
@@ -4659,27 +4659,27 @@
"two-step"
],
"support": {
"source": "https://github.com/scheb/2fa-backup-code/tree/v6.9.0"
"source": "https://github.com/scheb/2fa-backup-code/tree/v6.10.0"
},
"time": "2022-12-10T15:20:09+00:00"
"time": "2023-11-04T12:54:57+00:00"
},
{
"name": "scheb/2fa-bundle",
"version": "v6.9.0",
"version": "v6.10.0",
"source": {
"type": "git",
"url": "https://github.com/scheb/2fa-bundle.git",
"reference": "98fee6bf6ce17514d8f3772d4c7f86e6f7595a85"
"reference": "493a8712be5461ca90f4ac0eb819cfcf6cf8d009"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/scheb/2fa-bundle/zipball/98fee6bf6ce17514d8f3772d4c7f86e6f7595a85",
"reference": "98fee6bf6ce17514d8f3772d4c7f86e6f7595a85",
"url": "https://api.github.com/repos/scheb/2fa-bundle/zipball/493a8712be5461ca90f4ac0eb819cfcf6cf8d009",
"reference": "493a8712be5461ca90f4ac0eb819cfcf6cf8d009",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "~8.0.0 || ~8.1.0 || ~8.2.0",
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
"symfony/config": "^5.4 || ^6.0",
"symfony/dependency-injection": "^5.4 || ^6.0",
"symfony/event-dispatcher": "^5.4 || ^6.0",
@@ -4726,27 +4726,27 @@
"two-step"
],
"support": {
"source": "https://github.com/scheb/2fa-bundle/tree/v6.9.0"
"source": "https://github.com/scheb/2fa-bundle/tree/v6.10.0"
},
"time": "2023-08-05T11:13:58+00:00"
"time": "2023-11-04T12:54:57+00:00"
},
{
"name": "scheb/2fa-totp",
"version": "v6.9.0",
"version": "v6.10.0",
"source": {
"type": "git",
"url": "https://github.com/scheb/2fa-totp.git",
"reference": "a0d07cb4a52b0e4ecf6453ac99b35358ebe505a9"
"reference": "ce5f9ab528d00671e6580ef37a4cb49c5e373bdb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/scheb/2fa-totp/zipball/a0d07cb4a52b0e4ecf6453ac99b35358ebe505a9",
"reference": "a0d07cb4a52b0e4ecf6453ac99b35358ebe505a9",
"url": "https://api.github.com/repos/scheb/2fa-totp/zipball/ce5f9ab528d00671e6580ef37a4cb49c5e373bdb",
"reference": "ce5f9ab528d00671e6580ef37a4cb49c5e373bdb",
"shasum": ""
},
"require": {
"paragonie/constant_time_encoding": "^2.4",
"php": "~8.0.0 || ~8.1.0 || ~8.2.0",
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
"scheb/2fa-bundle": "self.version",
"spomky-labs/otphp": "^10.0 || ^11.0"
},
@@ -4777,9 +4777,9 @@
"two-step"
],
"support": {
"source": "https://github.com/scheb/2fa-totp/tree/v6.9.0"
"source": "https://github.com/scheb/2fa-totp/tree/v6.10.0"
},
"time": "2022-12-10T15:20:09+00:00"
"time": "2023-11-04T12:54:57+00:00"
},
{
"name": "setasign/fpdi",
@@ -7222,30 +7222,30 @@
},
{
"name": "symfony/monolog-bundle",
"version": "v3.8.0",
"version": "v3.10.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/monolog-bundle.git",
"reference": "a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d"
"reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d",
"reference": "a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d",
"url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181",
"reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181",
"shasum": ""
},
"require": {
"monolog/monolog": "^1.22 || ^2.0 || ^3.0",
"php": ">=7.1.3",
"symfony/config": "~4.4 || ^5.0 || ^6.0",
"symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0",
"symfony/http-kernel": "~4.4 || ^5.0 || ^6.0",
"symfony/monolog-bridge": "~4.4 || ^5.0 || ^6.0"
"monolog/monolog": "^1.25.1 || ^2.0 || ^3.0",
"php": ">=7.2.5",
"symfony/config": "^5.4 || ^6.0 || ^7.0",
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
"symfony/http-kernel": "^5.4 || ^6.0 || ^7.0",
"symfony/monolog-bridge": "^5.4 || ^6.0 || ^7.0"
},
"require-dev": {
"symfony/console": "~4.4 || ^5.0 || ^6.0",
"symfony/phpunit-bridge": "^5.2 || ^6.0",
"symfony/yaml": "~4.4 || ^5.0 || ^6.0"
"symfony/console": "^5.4 || ^6.0 || ^7.0",
"symfony/phpunit-bridge": "^6.3 || ^7.0",
"symfony/yaml": "^5.4 || ^6.0 || ^7.0"
},
"type": "symfony-bundle",
"extra": {
@@ -7283,7 +7283,7 @@
],
"support": {
"issues": "https://github.com/symfony/monolog-bundle/issues",
"source": "https://github.com/symfony/monolog-bundle/tree/v3.8.0"
"source": "https://github.com/symfony/monolog-bundle/tree/v3.10.0"
},
"funding": [
{
@@ -7299,7 +7299,7 @@
"type": "tidelift"
}
],
"time": "2022-05-10T14:24:36+00:00"
"time": "2023-11-06T17:08:13+00:00"
},
{
"name": "symfony/options-resolver",
@@ -10826,16 +10826,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.37.1",
"version": "v3.38.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "c3fe76976081ab871aa654e872da588077e19679"
"reference": "7e6070026e76aa09d77a47519625c86593fb8e31"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/c3fe76976081ab871aa654e872da588077e19679",
"reference": "c3fe76976081ab871aa654e872da588077e19679",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7e6070026e76aa09d77a47519625c86593fb8e31",
"reference": "7e6070026e76aa09d77a47519625c86593fb8e31",
"shasum": ""
},
"require": {
@@ -10907,7 +10907,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.37.1"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.38.0"
},
"funding": [
{
@@ -10915,7 +10915,7 @@
"type": "github"
}
],
"time": "2023-10-29T20:51:23+00:00"
"time": "2023-11-07T08:44:54+00:00"
},
{
"name": "masterminds/html5",
@@ -11153,16 +11153,16 @@
},
{
"name": "phpstan/phpstan",
"version": "1.10.40",
"version": "1.10.41",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "93c84b5bf7669920d823631e39904d69b9c7dc5d"
"reference": "c6174523c2a69231df55bdc65b61655e72876d76"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/93c84b5bf7669920d823631e39904d69b9c7dc5d",
"reference": "93c84b5bf7669920d823631e39904d69b9c7dc5d",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/c6174523c2a69231df55bdc65b61655e72876d76",
"reference": "c6174523c2a69231df55bdc65b61655e72876d76",
"shasum": ""
},
"require": {
@@ -11211,7 +11211,7 @@
"type": "tidelift"
}
],
"time": "2023-10-30T14:48:31+00:00"
"time": "2023-11-05T12:57:57+00:00"
},
{
"name": "phpstan/phpstan-doctrine",

View File

@@ -2051,11 +2051,6 @@ parameters:
count: 1
path: src/Export/Base/HtmlRenderer.php
-
message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Activity\\|null\\.$#"
count: 1
path: src/Export/Base/HtmlRenderer.php
-
message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Customer\\|null\\.$#"
count: 5
@@ -2116,11 +2111,6 @@ parameters:
count: 1
path: src/Export/Base/PDFRenderer.php
-
message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Activity\\|null\\.$#"
count: 1
path: src/Export/Base/PDFRenderer.php
-
message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Customer\\|null\\.$#"
count: 5

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -3,7 +3,7 @@
"app": {
"js": [
"/build/runtime.f0079159.js",
"/build/app.9acfcfc8.js"
"/build/app.63b27bee.js"
],
"css": [
"/build/app.fc41168c.css"
@@ -45,7 +45,7 @@
"calendar": {
"js": [
"/build/runtime.f0079159.js",
"/build/calendar.3f4f78fe.js"
"/build/calendar.a1cbcd7b.js"
],
"css": [
"/build/calendar.bb473428.css"
@@ -63,7 +63,7 @@
},
"integrity": {
"/build/runtime.f0079159.js": "sha384-H22sAW1aTvyIPqvHOvGXWSWTxf0y6mptp+MsVmyXCfjx/WJjBbhX9gbUZ+qIuihV",
"/build/app.9acfcfc8.js": "sha384-tzbF0uEmHghIo+D5IuKarLYkwB3AyrLMTEFqR5mqaXCP5VSOWx3t+ZfD81kd80T+",
"/build/app.63b27bee.js": "sha384-1CV+he7m+KfetJpq/DmRwKfUhKH4L7MImv7rRUz/mr/KNR3VkT0fQJHF7ViPTVYE",
"/build/app.fc41168c.css": "sha384-3Td9W7KogJoBiywzWOgpkPPNHEIT8/a/SkMZM5NgIRmuChj/3PeOKkOHVJQlhP2E",
"/build/export-pdf.d367a32e.js": "sha384-Z5baqnzjI636nYFs4g63ViIKBZKRW4Jhv/7PQmTEQlqhfA7eK0vUMUtiyy0R5A9u",
"/build/export-pdf.d8a6c23b.css": "sha384-ztepocHE4rnGE9eKZ4kL6jTKaePUyiwiB9TjJjstjpf/ckcKg1HedrEOOk/8ElJg",
@@ -72,7 +72,7 @@
"/build/invoice-pdf.ce9aace0.js": "sha384-mtZkXrpsXFMX2YvmmTlCm91QgsTlZLzLJnDAFcTuBDtDZ7TNkqLYkfCeLzFLVfwb",
"/build/invoice-pdf.2b749265.css": "sha384-DXXgkz2WWnrWnfBnXX5fmfPQSPb98upMnWxYKwTGYS04EhrPIWfDCutB2unIrWh7",
"/build/chart.f5becfac.js": "sha384-GSqETm8wULiVXyizvwRompfwu63r/C0Qd/AvrHDE4cqAKiIGCssb3QyBtGu1WN+W",
"/build/calendar.3f4f78fe.js": "sha384-RD8enOf0Foe7IhSOGnv2DCes4QUCvLjlONH0HFq3RK9l/ozrFZakTX6SWwKOoEda",
"/build/calendar.a1cbcd7b.js": "sha384-rDvqiEk91ZGY5lHb7vYIUWM2M550H6JAOLt1c3KO5H+toq7Ico7d/KoEDeG52cVW",
"/build/calendar.bb473428.css": "sha384-900W9o8666Qpw21rLP7hn5Ql8tWd40k0IcE3QpFm7E7V6bKva7xQgGlyzVuuh4GK",
"/build/dashboard.6774a712.js": "sha384-lBwkNqUPv+IBbznagiFakY2BOIueq/Bg89wHO2XeM9YAZ51rPkrvdMd+XmFupHsM",
"/build/dashboard.18f5a8b7.css": "sha384-PBD8ftb2yBoSjRe2sN5Xb4dEz045kOEUfcIufdSis+tWoWdAx5j4Yic+F/6CYbrP"

View File

@@ -1,6 +1,6 @@
{
"build/app.css": "/build/app.fc41168c.css",
"build/app.js": "/build/app.9acfcfc8.js",
"build/app.js": "/build/app.63b27bee.js",
"build/export-pdf.css": "/build/export-pdf.d8a6c23b.css",
"build/export-pdf.js": "/build/export-pdf.d367a32e.js",
"build/invoice.css": "/build/invoice.5bea118e.css",
@@ -9,7 +9,7 @@
"build/invoice-pdf.js": "/build/invoice-pdf.ce9aace0.js",
"build/chart.js": "/build/chart.f5becfac.js",
"build/calendar.css": "/build/calendar.bb473428.css",
"build/calendar.js": "/build/calendar.3f4f78fe.js",
"build/calendar.js": "/build/calendar.a1cbcd7b.js",
"build/dashboard.css": "/build/dashboard.18f5a8b7.css",
"build/dashboard.js": "/build/dashboard.6774a712.js",
"build/runtime.js": "/build/runtime.f0079159.js"

View File

@@ -17,11 +17,11 @@ class Constants
/**
* The current release version
*/
public const VERSION = '2.2.1';
public const VERSION = '2.3.0';
/**
* The current release: major * 10000 + minor * 100 + patch
*/
public const VERSION_ID = 20201;
public const VERSION_ID = 20300;
/**
* The software name
*/

View File

@@ -288,7 +288,7 @@ final class ProfileController extends AbstractController
}
return $this->render('user/preferences.html.twig', [
'tab' => 'preferences',
'tab' => 'settings',
'user' => $profile,
'form' => $form->createView(),
'sections' => $sections

View File

@@ -19,6 +19,7 @@ class ThemeEvent extends Event
public const HTML_HEAD = 'app.theme.html_head';
public const CONTENT_BEFORE = 'app.theme.content_before';
public const CONTENT_START = 'app.theme.content_start';
public const TOOLBAR = 'app.theme.toolbar';
public const CONTENT_END = 'app.theme.content_end';
public const CONTENT_AFTER = 'app.theme.content_after';

View File

@@ -33,6 +33,9 @@ final class UserFormsSubscriber extends AbstractActionsSubscriber
if ($this->isGranted('edit', $user)) {
$event->addAction('edit', ['url' => $this->path('user_profile_edit', ['username' => $user->getUserIdentifier()]), 'title' => 'profile-stats', 'translation_domain' => 'actions']);
}
if ($this->isGranted('preferences', $user)) {
$event->addConfig($this->path('user_profile_preferences', ['username' => $user->getUserIdentifier()]));
}
if ($this->isGranted('password', $user)) {
$event->addAction('password', ['url' => $this->path('user_profile_password', ['username' => $user->getUserIdentifier()]), 'title' => 'profile.password']);
}

View File

@@ -47,10 +47,6 @@ final class UserSubscriber extends AbstractActionsSubscriber
$event->addActionToSubmenu('edit', $id, $action);
}
if ($this->isGranted('preferences', $user)) {
$event->addConfig($this->path('user_profile_preferences', ['username' => $user->getUserIdentifier()]));
}
if (($event->getUser()->getId() === $user->getId() && $this->isGranted('report:user')) || $this->isGranted('report:other')) {
$event->addActionToSubmenu('report', 'weekly', ['url' => $this->path('report_user_week', ['user' => $user->getId()]), 'translation_domain' => 'reporting', 'title' => 'report_user_week']);
$event->addActionToSubmenu('report', 'monthly', ['url' => $this->path('report_user_month', ['user' => $user->getId()]), 'translation_domain' => 'reporting', 'title' => 'report_user_month']);

View File

@@ -17,6 +17,7 @@ use App\Utils\FormFormatConverter;
use App\Utils\JavascriptFormatConverter;
use App\Utils\LocaleFormatter;
use DateTime;
use DateTimeInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Contracts\Translation\LocaleAwareInterface;
use Twig\Extension\AbstractExtension;
@@ -132,7 +133,7 @@ final class LocaleFormatExtensions extends AbstractExtension implements LocaleAw
return (string) $this->getFormatter()->dateShort($date);
}
public function dateTime(DateTime|string|null $date): string
public function dateTime(DateTimeInterface|string|null $date): string
{
return (string) $this->getFormatter()->dateTime($date);
}

View File

@@ -11,7 +11,7 @@ namespace App\Utils;
use App\Configuration\LocaleService;
use App\Entity\Timesheet;
use DateTime;
use DateTimeInterface;
use Exception;
use IntlDateFormatter;
use NumberFormatter;
@@ -195,7 +195,7 @@ final class LocaleFormatter
return (string) $formatted;
}
public function dateTime(DateTime|string|null $date): ?string
public function dateTime(DateTimeInterface|string|null $date): ?string
{
if ($date === null || $date === '') {
return null;

View File

@@ -100,6 +100,10 @@
{% if is_granted('view_own_timesheet') %}
{% include 'partials/recent-activities.html.twig' %}
{% endif %}
{% block navbar_extensions_after %}
{% set event = trigger(constant('App\\Event\\ThemeEvent::TOOLBAR')) %}
{{ event.content|raw }}
{% endblock %}
{% endif %}
{% endblock %}

View File

@@ -6,7 +6,7 @@
{{ form_row(form._token) }}
<fieldset class="form-fieldset">
<fieldset class="form-fieldset form-fieldset-light">
<legend>{{ 'work_times_should'|trans }}</legend>
<div class="form-text mb-3 help-text">{{ 'work_times_should.help'|trans }}</div>
{{ form_row(form.workHoursMonday) }}
@@ -18,7 +18,7 @@
{{ form_row(form.workHoursSunday) }}
</fieldset>
<fieldset class="form-fieldset">
<fieldset class="form-fieldset form-fieldset-light">
{{- form_rest(form) -}}
</fieldset>

View File

@@ -2,18 +2,19 @@
{% block profile_content %}
{% import "user/actions.html.twig" as actions %}
{% set event = actions(app.user, 'user_forms', tab, {'user': user}) %}
<div class="card">
<div class="card-header">
{% block form_header %}
<ul class="nav nav-pills card-header-pills" data-bs-toggle="tabs">
{% import "user/actions.html.twig" as actions %}
{% set event = actions(app.user, 'user_forms', tab, {'user': user}) %}
{% for name, settings in event.actions %}
<li class="nav-item" role="presentation">
<a href="{{ settings.url }}" class="nav-link{% if tab == name %} active{% endif %}" role="tab">{{ settings.title|trans({}, settings.translation_domain ?? 'messages') }}</a>
</li>
{% endfor %}
</ul>
{% endblock %}
</div>
{% block form_body %}
{{ form_start(form) }}

View File

@@ -1,10 +1,9 @@
{% extends 'user/layout.html.twig' %}
{% from "macros/widgets.html.twig" import form_errors %}
{% extends 'user/form.html.twig' %}
{% block profile_content %}
{% block form_content %}
{% form_theme form 'form/horizontal.html.twig' %}
{{ form_start(form) }}
{{ form_errors(form) }}
{% for section in sections %}
{% set show = false %}
@@ -15,17 +14,13 @@
{% endfor %}
{% if show %}
{% embed '@theme/embeds/card.html.twig' %}
{% block box_body %}
<fieldset class="form-fieldset form-fieldset-light mb-3">
{% for pref in form.children.preferences|filter(pref => pref.vars.data.section == section)|sort((a, b) => a.vars.data.order <=> b.vars.data.order) %}
{{ form_widget(pref) }}
{% endfor %}
{% endblock %}
{% endembed %}
</fieldset>
{% endif %}
{% endfor %}
<input type="submit" value="{{ 'action.save'|trans }}" class="btn btn-primary" />
{{ form_end(form) }}
{% endblock %}