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: validations:
required: true required: true
- type: textarea - type: textarea
id: image id: environment
attributes: attributes:
label: Describe your setup (OS, Docker versions) label: Describe your setup and add your Docker compose file (redact your credentials)
description: >
- 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: > 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]
Docker compose file:
```yaml ```yaml
version: '3.5' version: '3.5'
services: services:
@@ -44,3 +35,8 @@ body:
``` ```
validations: validations:
required: true 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 * [KIMAI] KimaiThemeInitializer: initialize theme functionality
*/ */
import { Tooltip } from 'bootstrap'; import { Tooltip, Offcanvas } from 'bootstrap';
import KimaiPlugin from '../KimaiPlugin'; import KimaiPlugin from '../KimaiPlugin';
export default class KimaiThemeInitializer extends KimaiPlugin { export default class KimaiThemeInitializer extends KimaiPlugin {
@@ -21,6 +21,10 @@ export default class KimaiThemeInitializer extends KimaiPlugin {
return new Tooltip(tooltipTriggerEl); return new Tooltip(tooltipTriggerEl);
}); });
// support for offcanvas elements
const offcanvasElementList = document.querySelectorAll('.offcanvas');
[...offcanvasElementList].map(offcanvasEl => new Offcanvas(offcanvasEl));
// activate all form plugins // activate all form plugins
/** @type {KimaiForm} FORMS */ /** @type {KimaiForm} FORMS */
const FORMS = this.getContainer().getPlugin('form'); const FORMS = this.getContainer().getPlugin('form');

106
composer.lock generated
View File

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

View File

@@ -2051,11 +2051,6 @@ parameters:
count: 1 count: 1
path: src/Export/Base/HtmlRenderer.php 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\\.$#" message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Customer\\|null\\.$#"
count: 5 count: 5
@@ -2116,11 +2111,6 @@ parameters:
count: 1 count: 1
path: src/Export/Base/PDFRenderer.php 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\\.$#" message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Customer\\|null\\.$#"
count: 5 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": { "app": {
"js": [ "js": [
"/build/runtime.f0079159.js", "/build/runtime.f0079159.js",
"/build/app.9acfcfc8.js" "/build/app.63b27bee.js"
], ],
"css": [ "css": [
"/build/app.fc41168c.css" "/build/app.fc41168c.css"
@@ -45,7 +45,7 @@
"calendar": { "calendar": {
"js": [ "js": [
"/build/runtime.f0079159.js", "/build/runtime.f0079159.js",
"/build/calendar.3f4f78fe.js" "/build/calendar.a1cbcd7b.js"
], ],
"css": [ "css": [
"/build/calendar.bb473428.css" "/build/calendar.bb473428.css"
@@ -63,7 +63,7 @@
}, },
"integrity": { "integrity": {
"/build/runtime.f0079159.js": "sha384-H22sAW1aTvyIPqvHOvGXWSWTxf0y6mptp+MsVmyXCfjx/WJjBbhX9gbUZ+qIuihV", "/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/app.fc41168c.css": "sha384-3Td9W7KogJoBiywzWOgpkPPNHEIT8/a/SkMZM5NgIRmuChj/3PeOKkOHVJQlhP2E",
"/build/export-pdf.d367a32e.js": "sha384-Z5baqnzjI636nYFs4g63ViIKBZKRW4Jhv/7PQmTEQlqhfA7eK0vUMUtiyy0R5A9u", "/build/export-pdf.d367a32e.js": "sha384-Z5baqnzjI636nYFs4g63ViIKBZKRW4Jhv/7PQmTEQlqhfA7eK0vUMUtiyy0R5A9u",
"/build/export-pdf.d8a6c23b.css": "sha384-ztepocHE4rnGE9eKZ4kL6jTKaePUyiwiB9TjJjstjpf/ckcKg1HedrEOOk/8ElJg", "/build/export-pdf.d8a6c23b.css": "sha384-ztepocHE4rnGE9eKZ4kL6jTKaePUyiwiB9TjJjstjpf/ckcKg1HedrEOOk/8ElJg",
@@ -72,7 +72,7 @@
"/build/invoice-pdf.ce9aace0.js": "sha384-mtZkXrpsXFMX2YvmmTlCm91QgsTlZLzLJnDAFcTuBDtDZ7TNkqLYkfCeLzFLVfwb", "/build/invoice-pdf.ce9aace0.js": "sha384-mtZkXrpsXFMX2YvmmTlCm91QgsTlZLzLJnDAFcTuBDtDZ7TNkqLYkfCeLzFLVfwb",
"/build/invoice-pdf.2b749265.css": "sha384-DXXgkz2WWnrWnfBnXX5fmfPQSPb98upMnWxYKwTGYS04EhrPIWfDCutB2unIrWh7", "/build/invoice-pdf.2b749265.css": "sha384-DXXgkz2WWnrWnfBnXX5fmfPQSPb98upMnWxYKwTGYS04EhrPIWfDCutB2unIrWh7",
"/build/chart.f5becfac.js": "sha384-GSqETm8wULiVXyizvwRompfwu63r/C0Qd/AvrHDE4cqAKiIGCssb3QyBtGu1WN+W", "/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/calendar.bb473428.css": "sha384-900W9o8666Qpw21rLP7hn5Ql8tWd40k0IcE3QpFm7E7V6bKva7xQgGlyzVuuh4GK",
"/build/dashboard.6774a712.js": "sha384-lBwkNqUPv+IBbznagiFakY2BOIueq/Bg89wHO2XeM9YAZ51rPkrvdMd+XmFupHsM", "/build/dashboard.6774a712.js": "sha384-lBwkNqUPv+IBbznagiFakY2BOIueq/Bg89wHO2XeM9YAZ51rPkrvdMd+XmFupHsM",
"/build/dashboard.18f5a8b7.css": "sha384-PBD8ftb2yBoSjRe2sN5Xb4dEz045kOEUfcIufdSis+tWoWdAx5j4Yic+F/6CYbrP" "/build/dashboard.18f5a8b7.css": "sha384-PBD8ftb2yBoSjRe2sN5Xb4dEz045kOEUfcIufdSis+tWoWdAx5j4Yic+F/6CYbrP"

View File

@@ -1,6 +1,6 @@
{ {
"build/app.css": "/build/app.fc41168c.css", "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.css": "/build/export-pdf.d8a6c23b.css",
"build/export-pdf.js": "/build/export-pdf.d367a32e.js", "build/export-pdf.js": "/build/export-pdf.d367a32e.js",
"build/invoice.css": "/build/invoice.5bea118e.css", "build/invoice.css": "/build/invoice.5bea118e.css",
@@ -9,7 +9,7 @@
"build/invoice-pdf.js": "/build/invoice-pdf.ce9aace0.js", "build/invoice-pdf.js": "/build/invoice-pdf.ce9aace0.js",
"build/chart.js": "/build/chart.f5becfac.js", "build/chart.js": "/build/chart.f5becfac.js",
"build/calendar.css": "/build/calendar.bb473428.css", "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.css": "/build/dashboard.18f5a8b7.css",
"build/dashboard.js": "/build/dashboard.6774a712.js", "build/dashboard.js": "/build/dashboard.6774a712.js",
"build/runtime.js": "/build/runtime.f0079159.js" "build/runtime.js": "/build/runtime.f0079159.js"

View File

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

View File

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

View File

@@ -19,6 +19,7 @@ class ThemeEvent extends Event
public const HTML_HEAD = 'app.theme.html_head'; public const HTML_HEAD = 'app.theme.html_head';
public const CONTENT_BEFORE = 'app.theme.content_before'; public const CONTENT_BEFORE = 'app.theme.content_before';
public const CONTENT_START = 'app.theme.content_start'; 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_END = 'app.theme.content_end';
public const CONTENT_AFTER = 'app.theme.content_after'; public const CONTENT_AFTER = 'app.theme.content_after';

View File

@@ -33,6 +33,9 @@ final class UserFormsSubscriber extends AbstractActionsSubscriber
if ($this->isGranted('edit', $user)) { if ($this->isGranted('edit', $user)) {
$event->addAction('edit', ['url' => $this->path('user_profile_edit', ['username' => $user->getUserIdentifier()]), 'title' => 'profile-stats', 'translation_domain' => 'actions']); $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)) { if ($this->isGranted('password', $user)) {
$event->addAction('password', ['url' => $this->path('user_profile_password', ['username' => $user->getUserIdentifier()]), 'title' => 'profile.password']); $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); $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')) { 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', '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']); $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\JavascriptFormatConverter;
use App\Utils\LocaleFormatter; use App\Utils\LocaleFormatter;
use DateTime; use DateTime;
use DateTimeInterface;
use Symfony\Bundle\SecurityBundle\Security; use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Contracts\Translation\LocaleAwareInterface; use Symfony\Contracts\Translation\LocaleAwareInterface;
use Twig\Extension\AbstractExtension; use Twig\Extension\AbstractExtension;
@@ -132,7 +133,7 @@ final class LocaleFormatExtensions extends AbstractExtension implements LocaleAw
return (string) $this->getFormatter()->dateShort($date); 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); return (string) $this->getFormatter()->dateTime($date);
} }

View File

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

View File

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

View File

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

View File

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

View File

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