Compare commits

...

1521 Commits

Author SHA1 Message Date
Kevin Papst
ef170a8ca7 prepare webhook support 2025-12-25 09:51:36 +01:00
Kevin Papst
806bb97e60 query modified_after in UTC (#5743) 2025-12-24 16:33:28 +01:00
Kevin Papst
3fcaf55d02 merge default currency settings (#5739) 2025-12-22 17:55:48 +01:00
Kevin Papst
f0e2337d67 fix dark theme was bright depending on OS settings 2025-12-22 14:24:20 +01:00
Weblate (bot)
00d801616a Translated using Weblate (#5705)
Co-authored-by: 4ipset <228gus228uu@gmail.com>
Co-authored-by: Anthony Cyndora <anthony270777@gmail.com>
Co-authored-by: C. H. <them4z@gmail.com>
Co-authored-by: Christopher Picón <ntrpc.tech@users.noreply.hosted.weblate.org>
Co-authored-by: Dane Lazov <dane.lazov@gmail.com>
Co-authored-by: Lasse Edsvik <lasse@lasseedsvik.se>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Mohammed “Medait” AIT ALI <medait.31@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Serhii Horichenko <serhii@horichenko.com>
Co-authored-by: Wilker Santana da Silva <wilker@posteo.com.br>
2025-12-21 17:11:42 +01:00
Kevin Papst
afb5a0bba4 Release 2.45 (#5721)
Co-authored-by: Henning Klein <info@henningklein.de>
2025-12-21 16:42:34 +01:00
Kevin Papst
8c1ed68817 improved dark mode, automatic theme switch (#5720) 2025-12-19 23:51:27 +01:00
Kevin Papst
b61420d633 prevent lock file changes 2025-12-18 23:07:00 +01:00
Kevin Papst
595b5f4b25 Configurable rate rounding (#5734)
* added invoice hydration of the issuer object
* added "rate calculator" mode
* new config to select rounding mode
* replace static calls with dependency injection
2025-12-16 16:47:46 +01:00
Weblate (bot)
07ac6c308f Translated using Weblate (#5704)
Co-authored-by: Serhii Horichenko <serhii@horichenko.com>
Co-authored-by: mostafa <m2-vision@users.noreply.hosted.weblate.org>
2025-11-19 15:21:30 +01:00
Kevin Papst
a6766373b4 fix modal reload 2025-11-19 15:17:24 +01:00
Kevin Papst
a15c1e56cb Release 2.44 (#5699) 2025-11-19 14:28:54 +01:00
Kevin Papst
8a42c9640f Release 2.43 (#5694) 2025-11-14 17:41:33 +01:00
Kevin Papst
8e6764b67a Release 2.42 (#5686) 2025-11-12 16:15:04 +01:00
Weblate (bot)
ea29799b89 Translated using Weblate (#5690)
Co-authored-by: Lasse Edsvik <lasse@lasseedsvik.se>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Santiago Atienza Ferro <satienza@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2025-11-12 15:40:55 +01:00
Weblate (bot)
a3ef1fd1cd Translated using Weblate (#5649)
Co-authored-by: Adrián Gelmotto Ruiz <adriangelmotto@gmail.com>
Co-authored-by: Arif Budiman <arifpedia@gmail.com>
Co-authored-by: Bamowen <mathieu.monsauret@gmail.com>
Co-authored-by: Carlos Carreras <mytriponlinux@gmail.com>
Co-authored-by: Dao Duy Tin <duytin095@gmail.com>
Co-authored-by: GD <guillaume.debat65@gmail.com>
Co-authored-by: Henry Higgins <leserboka@outlook.com>
Co-authored-by: Jonas Tisell <jonas.tisell@live.no>
Co-authored-by: Lasse Edsvik <lasse@lasseedsvik.se>
Co-authored-by: Lenny Angst <lenny@familie-angst.ch>
Co-authored-by: Levente Déri <derilevi@gmail.com>
Co-authored-by: LordTenebrous <danielmorenoperez836@gmail.com>
Co-authored-by: Lourenço Martins <hlourencoam93@gmail.com>
Co-authored-by: Marco Moreno <hibarioath@proton.me>
Co-authored-by: Martin Maslyankov <m.maslyankov@me.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Michedepain <benoitravel63000@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nadie <ef.dal.1200@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Parms <shoppingpar+weblate@simplelogin.com>
Co-authored-by: Preben Rather Sørensen <preben@rather.dk>
Co-authored-by: Py- Droid <droidpy587@gmail.com>
Co-authored-by: Rafa Herzog <49111482+necronyxon@users.noreply.github.com>
Co-authored-by: RoboDoc <theonlyrobodoc@gmail.com>
Co-authored-by: Serhii Horichenko <serhii@horichenko.com>
Co-authored-by: Tuna <ahmettunadem@gmail.com>
Co-authored-by: Turkish Language Team 🇹🇷 <turkishmark@yandex.com>
Co-authored-by: Wolf <wolski.marex@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: michte <michteting@proton.me>
Co-authored-by: mostafa <m2-vision@users.noreply.hosted.weblate.org>
Co-authored-by: no <kotvpaltoof@yandex.com>
Co-authored-by: vanapro1 <law820314@gmail.com>
Co-authored-by: zhao rongkuan (kuank) <zhaorongkuan2011@gmail.com>
Co-authored-by: Максим Горпиніч <gorpinicmaksim0@gmail.com>
Co-authored-by: Максим Горпиніч <maksimgorpinic4@gmail.com>
2025-11-09 22:48:25 +01:00
Kevin Papst
1a38c7d7a3 Release 2.41 (#5653) 2025-11-08 23:03:44 +01:00
Kevin Papst
636a51e721 group invoices by project and activity (#5675) 2025-11-02 12:34:41 +01:00
Kevin Papst
cc64acf0f8 Meta-fields for InvoiceTemplate, structured Customer address (#5519) 2025-11-02 11:24:17 +01:00
Kevin Papst
76821c24ed bump workflow version 2025-10-06 12:37:30 +02:00
Weblate (bot)
190b1dd4f3 Translated using Weblate (#5634)
Co-authored-by: Lasse Edsvik <lasse@lasseedsvik.se>
Co-authored-by: Lenny Angst <lenny@familie-angst.ch>
Co-authored-by: Py- Droid <droidpy587@gmail.com>
Co-authored-by: Ryohei Morimoto <caulked.thorax_3l@icloud.com>
Co-authored-by: WastedInside <arvidsloc@gmail.com>
Co-authored-by: oneshotkot <oneshotkot@gmail.com>
Co-authored-by: zhao rongkuan (kuank) <zhaorongkuan2011@gmail.com>
Co-authored-by: Максим Горпиніч <gorpinicmaksim0@gmail.com>
2025-09-26 12:12:48 +02:00
Kevin Papst
7937fa281a Release 2.40.0 (#5621) 2025-09-26 10:49:06 +02:00
Kevin Papst
6d78c6ba36 Configurable PDF exports (#5641) 2025-09-23 18:32:31 +02:00
Weblate (bot)
5d3e46cce2 Translated using Weblate (#5623)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Martin Maslyankov <m.maslyankov@me.com>
Co-authored-by: Wei-Cheng Yeh (IID) <iid@ccns.ncku.edu.tw>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
2025-08-31 12:56:12 +02:00
Kevin Papst
1c3aac78f6 remove debug 2025-08-30 18:27:21 +02:00
Kevin Papst
b1fb300a71 missing assets 2025-08-30 17:08:03 +02:00
Kevin Papst
a4d658b821 Release 2.39 (#5604)
* prepare audit via annotation
* default calendar slot label distance of 1h
+ replace freestyle config with dropdown
* added missing return definition in callbacks
* refactor view name handling
* dispatch calendar view changes and push them into the URL to be able to reload the poage
* bump packages
* fix timezone issue in calendar sum calculation
* fixes #5618 resetRates()
* show expected daily hours in working-contract screen
2025-08-30 11:41:17 +02:00
Weblate (bot)
4920ea5075 Translated using Weblate (#5611)
Co-authored-by: Frank JIn <chinafrank0129@outlook.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Kolappan N <kolappan@users.noreply.hosted.weblate.org>
Co-authored-by: Marc Sánchez Díaz <msanchez@aporta.biz>
Co-authored-by: Martin Maslyankov <m.maslyankov@me.com>
Co-authored-by: Wolf <wolski.marex@gmail.com>
Co-authored-by: asefeee <3470154407@qq.com>
Co-authored-by: lolly76 <thelolly76@gmail.com>
2025-08-29 14:57:25 +02:00
Kevin Papst
03dbbdc5ba added bulgarian locale (#5619) 2025-08-28 20:10:49 +02:00
Weblate (bot)
023048e7c0 Translated using Weblate (#5605)
Co-authored-by: Martin Maslyankov <m.maslyankov@me.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Mathias Peene <mathiaspeene@proton.me>
Co-authored-by: Sofia <sofimanci2112@gmail.com>
Co-authored-by: vanapro1 <law820314@gmail.com>
Co-authored-by: Максим Горпиніч <gorpinicmaksim5@gmail.com>
2025-08-15 13:44:53 +02:00
Kevin Papst
24778d3ffb replace PHPUnit annotations with attributes (#5608) 2025-08-11 18:57:42 +02:00
Kevin Papst
04331420ae Release 2.38.0 (#5563) 2025-08-08 23:25:42 +02:00
Weblate (bot)
f3890691ce Translated using Weblate (#5565)
Co-authored-by: Alioc <hit.177411245@gmail.com>
Co-authored-by: Fanny Van Prade <SmawyTranslate@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Lenny Angst <lenny@familie-angst.ch>
Co-authored-by: LordTenebrous <danielmorenoperez836@gmail.com>
Co-authored-by: Luke Gilmore <muntz18788@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Michedepain <benoitravel63000@gmail.com>
Co-authored-by: Nguyễn Quang Minh (NQM) <nguyenquangminh391@gmail.com>
Co-authored-by: Preben Rather Sørensen <preben@rather.dk>
Co-authored-by: Ricky Tigg <ricky.tigg@gmail.com>
Co-authored-by: Sasi Ba <sasiba8328@fuasha.com>
Co-authored-by: Sofia <sofimanci2112@gmail.com>
Co-authored-by: Vallo Rähn <rahn.vallo@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Yurt Page <yurtpage@gmail.com>
Co-authored-by: michte <michteting@proton.me>
Co-authored-by: qwertdery <qwertdery4@gmail.com>
Co-authored-by: tygyh <jonis9898@hotmail.com>
Co-authored-by: Максим Горпиніч <gorpinicmaksim5@gmail.com>
2025-08-08 17:00:46 +02:00
Kevin Papst
dfec807166 Release 2.37 (#5546) 2025-07-04 16:43:38 +02:00
Weblate (bot)
06b3060fe1 Translated using Weblate (#5543)
Co-authored-by: Hazret <tncytrk@live.com>
Co-authored-by: Péter Rezsuta <rezsutapeter@gmail.com>
Co-authored-by: RoboDoc <theonlyrobodoc@gmail.com>
Co-authored-by: Silvan <silvans2005@gmail.com>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
2025-07-04 16:12:40 +02:00
Kevin Papst
b6a8ae783f added test 2025-07-04 11:59:26 +02:00
Weblate (bot)
3d8fa3af44 Translated using Weblate (#5535)
Co-authored-by: Lourenço Martins <hlourencoam93@gmail.com>
Co-authored-by: Álvaro Alonso Ramírez <aalonsoramirez@gmail.com>
2025-06-16 18:25:33 +02:00
Kevin Papst
59dc82351e Release 2.36.1 (#5540)
* fix weekly hours for new entries with non-global activities
* bump packages
* prevent creating invoices with 0 entries
2025-06-16 17:53:27 +02:00
Weblate (bot)
da10099248 Translated using Weblate (#5524)
Co-authored-by: Izackalaf <izackalaf@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Monika Bikki <bikki.monika@euroone.hu>
Co-authored-by: Rafa Herzog <49111482+necronyxon@users.noreply.github.com>
Co-authored-by: RoboDoc <theonlyrobodoc@gmail.com>
Co-authored-by: Максим Горпиніч <maksimgorpinic4@gmail.com>
2025-06-11 14:26:18 +02:00
Kevin Papst
05aaa1950a configurable csv/xlsx export templates (#5531) 2025-06-11 13:06:33 +02:00
Kevin Papst
46129c7ab9 improved LDAP logging (#5517) 2025-06-07 11:48:09 +02:00
Kevin Papst
c8b4e4eabb Improve weekly hours form (#5528) 2025-06-06 15:20:00 +02:00
Kevin Papst
2f2ebd6293 Release 2.36.0 (#5514) 2025-06-02 16:07:48 +02:00
Weblate (bot)
594385f741 Translated using Weblate (#5510)
Co-authored-by: Robert Drygała <robert.drygala@gmail.com>
Co-authored-by: Tuna <ahmettunadem@gmail.com>
2025-06-02 14:35:55 +02:00
Kevin Papst
12190141d7 Release 2.35.1 (#5509)
do not trigger changes on empty time fields or empty duration
2025-05-31 15:29:43 +02:00
Kevin Papst
0420eb27c7 random improvements (#5506)
* fix order of destroying form elements
* API documentation - fixes #1949
* make command path independent
* use PhpSubprocess to execute migrations
* allow to configure optional SAML attributes
* fix deprecation
* unify wording of exported state - fixes #5392
2025-05-28 13:34:01 +02:00
Kevin Papst
81107377f4 Relax time input format requirements (#5504)
* remove locale support from time-input, only allow 12 and 24 hour format
* added blur listeners to parse all kinds of time inputs
* fix duration inputs like ":9" for 9 minutes
2025-05-28 09:36:29 +02:00
Kevin Papst
e9c172daea improve API endpoint names (#5502) 2025-05-27 13:23:08 +02:00
Kevin Papst
f42d42f512 fix searchterm parsing (#5501) 2025-05-27 13:20:27 +02:00
Weblate (bot)
b38c6fbb0e Translated using Weblate (#5498)
Co-authored-by: Maksim_220 Кабанов <law820314@gmail.com>
2025-05-27 13:15:55 +02:00
Kevin Papst
e2a1146670 Use arrow keys to change duration (#5495) 2025-05-27 13:07:29 +02:00
Kevin Papst
e69ac6968b Improved Locales (#5497)
- Switch Chinese time format to 24-hours - fixes #5496
- Use always 4 chars for year
- Use one `HH` instead of `H`, so we don't have to convert during runtime
- Update all locales
- Allow seeing time and date format in help UI
- Fix RTL in UI
- Show stats about found formats in Locales command
2025-05-26 20:59:39 +02:00
Weblate (bot)
87168de4f1 Translated using Weblate (#5484)
Co-authored-by: Piotr Laszczkowski <swistach@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2025-05-24 22:59:07 +02:00
Kevin Papst
7b158d57b5 API improvements (#5494)
* hide logo in docs UI
* always return a user in api base controller
* added example for duration fields
2025-05-24 22:09:48 +02:00
Kevin Papst
1e0fbf0b73 Release 2.35 (#5470)
* open up API for plugins by removing internal
* use constants in entity column definition
* simplified entity management API
* bump packages
* allow installing assets and run database migrations independently
* bump to apidoc-bundle 5
* do not duplicate http method in API operationId
* new security entries in Open API definition
* changed API UI provider for Swagger to Stoplight, improved endpoint titles, hide internal endpoints
* deactivate swagger json endpoint
2025-05-24 14:28:39 +02:00
Weblate (bot)
6e26a37c4d Translated using Weblate (#5471)
Co-authored-by: LordTenebrous <lordtenebrous@users.noreply.hosted.weblate.org>
Co-authored-by: Mandeep <mandeeps708@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Piotr Laszczkowski <swistach@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Максим Горпиніч <maksimgorpinic4@gmail.com>
2025-05-18 14:57:19 +02:00
Weblate (bot)
fac5a910d8 Translated using Weblate (#5462)
Co-authored-by: Harshit Sethi <hstsethi@outlook.com>
Co-authored-by: Henry Higgins <leserboka@outlook.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2025-05-09 14:30:29 +02:00
Kevin Papst
dfd97fd6f3 Release 2.34 (#5465)
* fix timing issue in timesheet edit form with deactivated rounding
* bump packages
* only show update messages for newer plugin versions
* replace deprecated method
* remove internal from API
* remove technical terms from translation
* prevent calls to internal symfony methods
* helper method to flag entry as modified
* support meta-fields in weekly-hourse view
* fix running timesheets were deleted in weekly-hourse
2025-05-09 14:22:47 +02:00
Kevin Papst
452a8d9390 improved search with negation (#5453) 2025-05-05 18:18:00 +02:00
Weblate (bot)
2a9de506a1 Translated using Weblate (#5451)
Co-authored-by: GiannosOB <giannos2105@gmail.com>
Co-authored-by: John Titor <utkin2007@gmail.com>
Co-authored-by: Lucas <merlin.lucas99@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Sotski Eugene <jekakmail@gmail.com>
Co-authored-by: Максим Горпиніч <maksimgorpinic2005a@gmail.com>
2025-05-03 11:40:11 +02:00
Kevin Papst
e663cc2b02 Release 2.33.0 (#5438) 2025-04-22 20:43:22 +02:00
Weblate (bot)
a70c803158 Translated using Weblate (#5440)
Co-authored-by: C. H <them4z@gmail.com>
Co-authored-by: GiannosOB <giannos2105@gmail.com>
Co-authored-by: Kuwush <79j0hancarl@gmail.com>
Co-authored-by: Raphael-11 <raef.laffi@medtech.tn>
Co-authored-by: fran secs <fransecs@gmail.com>
2025-04-22 10:36:44 +02:00
Weblate (bot)
9ca69e1114 Translated using Weblate (#5414)
Co-authored-by: Fajar Shiddiq <justgamers0102@gmail.com>
Co-authored-by: Hien <hienly@yandex.com>
Co-authored-by: Marc Sánchez Díaz <msanchez@aporta.biz>
Co-authored-by: Marc-Daniel DALEBA <marcodxv10@gmail.com>
Co-authored-by: Tachibana Saza <tachibanasaza@proton.me>
Co-authored-by: gacarel <gacarel657@bariswc.com>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
2025-04-06 11:36:12 +02:00
Kevin Papst
2e6b700b43 Release 2.32 (#5411)
* bump packages
* dynamic invoice options
* make sure that invoice previews can be detected
* support for mpdf associated files
* do not include any future times in work contract calculation
* re-add username column in Excel spreadsheet
* deactivate internal rate editing
* show if plugin update exists
* shorten name to Kimai only, without Time-Tracking
* remove check for existing id in work contract
* fix metafield already defined in search
* helper methods to unlock months
* new translation
* send event on unlock month
2025-04-06 09:53:48 +02:00
Kevin Papst
2a75cd6230 random improvements (#5382)
* remove permission check, as own timesheets should always be visible
* new methods to create datetime
* allow access to user roles in javascript
* support class for dropdown actions
* allow to edit internal rate
* support human readable duration in export via user configuration
* allow to order timesheet listing by user, exported and billable field
* bump codecov action
2025-03-13 18:00:50 +01:00
Weblate (bot)
934fdeb107 Translated using Weblate (#5383)
Co-authored-by: Dawid Kiełkowski <dawid55a@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Xyruz <alphxyruz@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: hugompd <hugompd@gmail.com>
Co-authored-by: Максим Горпиніч <maksimgorpinic2005a@gmail.com>
2025-03-12 18:26:08 +01:00
Kevin Papst
14cdcd3f63 Release 2.31 (#5372)
* simplify translation
* bump version
* deprecate translations
* pass date-range as argument to export and timesheet filter URL from monthly overview report
* added class for use in responsive screens
* show technical role name
* simplify multi-update title
* more statistic models
* bump composer packages
2025-02-27 17:41:25 +01:00
Weblate (bot)
674bf3a6b5 Translated using Weblate (#5371)
Co-authored-by: Vág Csaba <vagcsaba@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
2025-02-27 17:22:17 +01:00
Kevin Papst
cce49cc409 Translation cleanup (#5370)
* use correct translation key
* de-duplicate translation
2025-02-21 20:50:49 +01:00
Weblate (bot)
04cb403ea9 Translated using Weblate (#5369)
Co-authored-by: Jussi Juven <jussi.juven@disec.fi>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Максим Горпиніч <maksimgorpinic2005a@gmail.com>
2025-02-21 20:50:23 +01:00
Kevin Papst
afaa845a9a fix export dates are not localized (#5368) 2025-02-20 15:07:28 +01:00
Weblate (bot)
928b5208e9 Translated using Weblate (#5362)
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Максим Горпиніч <maksimgorpinic2005a@gmail.com>
2025-02-20 15:04:53 +01:00
Kevin Papst
8a8d0503f7 prepare break time field (#5366) 2025-02-20 14:46:20 +01:00
Kevin Papst
b341358d0a Release 2.30 (#5345)
- added missing InvoiceTemplate company, title) field validator
- graceful fallback for missing working-contract mode
- improve email test command (use configured MAIL_FROM)
- additional form types for simple usage in SystemConfiguration and UserPreferences
- allow to extend the working time query via event
2025-02-17 08:32:22 +01:00
Weblate (bot)
d30166e691 Translated using Weblate (#5344)
Co-authored-by: 3limssmile <33elimssmile@gmail.com>
Co-authored-by: Alfredo Sola <alfredo@sola.es>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Serhii Horichenko <serhii@horichenko.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: vaykly <vaykly@icloud.com>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
2025-02-17 08:31:54 +01:00
Kevin Papst
b42c77a2a1 Release 2.29 (#5325)
* bump composer packages
* fixes #5329 quotes for ANSI_MODE
* improve year selection
* improve year selection via dropdown
* added range selector in month-picker
* fix week number if week starts with sunday
* fix first day of month in URL
* predefined options for week chooser
* z-index issue with sticky table header
* replace duplicated translations
* add logout button to allow user switch without having to re-login in "remember me" login
* new flag to detect if invoice entry is a fixed rate
* improve export column lengths
2025-02-09 00:16:03 +01:00
Weblate (bot)
8444928ae4 Translated using Weblate (#5342)
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Serhii Horichenko <serhii@horichenko.com>
2025-02-08 19:29:33 +01:00
Weblate (bot)
b250edc2a1 Translated using Weblate (#5318)
Co-authored-by: Antonín JUDYTKA <judytka@judytka.cz>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Lukáš Granatier <lukas.granatier@compacer.cz>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Ricky Tigg <ricky.tigg@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: on the road simson <d-youtube@kopaszhegy.hu>
Co-authored-by: polarwood <polarwood@users.noreply.hosted.weblate.org>
Co-authored-by: Максим Горпиніч <maksimgorpinic2005a@gmail.com>
2025-02-08 19:27:49 +01:00
Kevin Papst
4a8c2a79c9 added last months and last quarters to daterange-picker selections (#5317) 2025-01-24 15:21:54 +01:00
Weblate (bot)
bff72b30cc Translations update from Hosted Weblate (#5306)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: TaaviLepik <info@brunex.ee>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
2025-01-24 13:37:03 +01:00
Kevin Papst
9d7b418d99 fix date column in export (#5308) 2025-01-20 16:09:29 +01:00
Kevin Papst
f2fb338539 Release 2.28 (#5253)
* fix year in dashboard
* make batch actions accessible via javascript
* bump packages
* remove BOM from CSV
* rebuild assets
* fix duplicated automated-email warning
2025-01-18 01:49:16 +01:00
Weblate (bot)
1b3ff212d2 Translated using Weblate (#5293)
Co-authored-by: Evgeniy Khramov <65224669+thejenja@users.noreply.github.com>
Co-authored-by: John Titor <utkin2007@gmail.com>
Co-authored-by: Ricky Tigg <ricky.tigg@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
2025-01-18 01:48:48 +01:00
Maarten Becker
c07979e3a9 fix usage of activity api globals parameter (#5284) 2025-01-10 10:02:14 +01:00
Weblate (bot)
23e8dcf495 Translated using Weblate (added Tamil) (#5254)
Co-authored-by: Biscuittttt <biscuitwithtea.tall310@passinbox.com>
Co-authored-by: Carlos Carreras <mytriponlinux@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Languages add-on <noreply-addon-languages@weblate.org>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: abdelbasset jabrane <ribago9317@cubene.com>
Co-authored-by: yblis <yblisss@yahoo.fr>
Co-authored-by: Максим Горпиніч <mgorpinic2005@gmail.com>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
2025-01-09 12:16:45 +01:00
Kevin Papst
4332ef95a2 Release 2.27 (#5212) 2024-12-22 22:50:42 +01:00
Weblate (bot)
4fdfb6f478 Translations update from Hosted Weblate (#5211)
Co-authored-by: Dawid <dawidgorski.m@gmail.com>
Co-authored-by: Florent Berthelot <florentius.b@gmail.com>
Co-authored-by: Giorgos Skafidas <giorgos@skafidas.online>
Co-authored-by: Kamborio <Kamborio15@users.noreply.hosted.weblate.org>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Serhii Horichenko <serhii@horichenko.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Максим Горпиніч <mgorpinic2005@gmail.com>
Co-authored-by: BouenMarsh <mveretsuk@yandex.ru>
2024-12-22 19:15:32 +01:00
Kevin Papst
136104d4b0 faster spreadsheet exporter based on opensout and other export improvements (#5238) 2024-12-22 18:36:47 +01:00
Kevin Papst
c7f0508707 Upgrade tests to PhpUnit 10 (#5252) 2024-12-22 01:25:30 +01:00
buti1021
9bd37fb695 update php versions (#5246) 2024-12-20 14:56:06 +01:00
Kevin Papst
21c031f2c8 export filtered timesheets without additional search form (#5234) 2024-12-15 18:38:30 +01:00
Kevin Papst
17a815e5a9 updated frontend builds (#5210)
* do not rely on node_modules path
* bump eslint to v9, run eslint via npm task, remove from build task
* loosen dependencies and update all packages
* rebuild assets with latest frontend packages
* bump webpack encore and dependencies
* bump to latest stable yarn
* explicitly mention dependencies
2024-12-06 14:31:04 +01:00
Kevin Papst
648686c001 added open collective 2024-12-06 14:27:06 +01:00
Kevin Papst
82a3b99a31 Release 2.26 (#5189)
* bring back deprecated methods
* bump packages
* fix SAML redirect
* config flag for break times
* use class constant instead of string in attributes
* throw if all tags were not found - fixes #4792
2024-12-05 10:42:07 +01:00
Weblate (bot)
70741eebfd Translations update from Hosted Weblate (#5192)
Co-authored-by: Lassi Määttä <lassi.maetta@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
2024-12-05 09:42:37 +01:00
Weblate (bot)
eb933e7021 Translations update from Hosted Weblate (#5185)
Co-authored-by: Ricky Tigg <ricky.tigg@gmail.com>
2024-11-30 14:26:07 +01:00
Weblate (bot)
372f3c8507 Translations update from Hosted Weblate (#5179)
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Serhii Horichenko <m@sgg.im>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Doctorredits_here <alkaf.alkaf2018@tutamail.com>
2024-11-27 15:35:26 +01:00
Kevin Papst
e030ff08db API endpoints to delete customer/project/activity (#5181)
* added service methods with events to delete customer, project, activity
* added API endpoints to delete customer, project, activity
* added tests for new API endpoints
2024-11-27 15:25:13 +01:00
Kevin Papst
f13b81ede7 Query hints & persistent cache for latest approvals (#5176) 2024-11-25 21:04:53 +01:00
Weblate (bot)
46c4449504 Translations update from Hosted Weblate (#5172)
Co-authored-by: Languages add-on <noreply-addon-languages@weblate.org>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Serhii Horichenko <m@sgg.im>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
2024-11-25 21:04:22 +01:00
Kevin Papst
8b55cd3693 trigger form change upon copy-data event 2024-11-25 20:46:34 +01:00
Kevin Papst
406ac7b9cb allow PHP 8.4 (#5173) 2024-11-21 23:00:00 +01:00
Kevin Papst
0c26a2678e Release 2.25 (#5109) 2024-11-21 22:44:49 +01:00
Weblate (bot)
49eb7068c9 Translated using Weblate (#5130)
Co-authored-by: Adrien N <adriennathaniel1999@gmail.com>
Co-authored-by: Igor Coimbra Carvalheira <igorccarvalheira111@gmail.com>
Co-authored-by: John Titor <utkin2007@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Peter Dave Hello <hsu@peterdavehello.org>
Co-authored-by: Serhii Horichenko <m@sgg.im>
Co-authored-by: hugoalh <hugoalh@users.noreply.hosted.weblate.org>
2024-11-18 13:52:50 +01:00
Kevin Papst
dcc52f1a95 API begin and end fields for Admins (#5134) 2024-10-25 10:47:58 +02:00
Weblate (bot)
31bae44f3c Translated using Weblate (#5120)
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Peter Dave Hello <hsu@peterdavehello.org>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2024-10-20 22:30:35 +02:00
Kevin Papst
84a0ca5ce6 removed duplicate installation call 2024-10-14 23:37:45 +02:00
Kevin Papst
9e736b26f6 Improve docker installation (#5115)
* ignore certain connection errors on startup
* remove invalid code that checks for the existence of the migration table
* fetch kimai code via tar archive instead of git clone, to respect .gitattributes
2024-10-14 23:09:14 +02:00
Weblate (bot)
32a1306394 Translated using Weblate (#5110)
Co-authored-by: Dklfajsjfi49wefklsf32 <nlincus@users.noreply.hosted.weblate.org>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Максим Горпиніч <mgorpinic2005@gmail.com>
2024-10-14 21:46:28 +02:00
Kevin Papst
96043afd6a better support for installing plugins via composer (#5112)
* merge installation and update commands
* generate metadata from array
* new command to list available packages
* added a management script to simplify updates
* added directory for dev files
* helper functions for installation and listing of packages
* run plugin database installers
2024-10-14 21:44:42 +02:00
Kevin Papst
255c7d77d6 Ignore files from showing up in a release (#5111)
* moved email css files to template directory
* prevent developer files from showing up in a release
2024-10-12 23:45:13 +02:00
Weblate (bot)
e6d5a720bf Translations update from Hosted Weblate (#5098)
Co-authored-by: Lukáš Kaňka <lukas.kanka@outlook.cz>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2024-10-11 22:33:57 +02:00
Kevin Papst
ff9bf163ee Release 2.24 (#5097) 2024-10-11 21:56:54 +02:00
Kevin Papst
5fac6a642c Docker improvements (#5096)
* install missing unzip
* run update and install in one step
* remove unused TRUSTED_HOSTS env
2024-10-11 19:36:40 +02:00
Kevin Papst
b1b81ee8a6 remove dev dependencies from prod image 2024-10-04 17:35:25 +02:00
Kevin Papst
1ea64bf18e allow to manually run workflow 2024-10-04 17:03:31 +02:00
Kevin Papst
0c4fdda00a allow to manually run workflow 2024-10-04 17:01:25 +02:00
Kevin Papst
215bd6a01a allow to manually run workflow 2024-10-04 16:57:48 +02:00
Kevin Papst
63b8164926 install missing buildx 2024-10-04 16:45:51 +02:00
Weblate (bot)
8c26ff9aed Translated using Weblate (#5092)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
2024-10-04 11:24:50 +02:00
Kevin Papst
921a703ea2 Merge Docker images (#5094) 2024-10-04 11:14:10 +02:00
Kevin Papst
855a546683 Docker improvements (#5093) 2024-10-04 10:25:46 +02:00
Kevin Papst
52b949daa3 cleanup docker environment variables (#5074) 2024-10-03 14:27:33 +02:00
Weblate (bot)
ee040d29b6 Translations update from Hosted Weblate (#5079)
Co-authored-by: Doctorredits_here <alkaf.alkaf2018@tutamail.com>
Co-authored-by: Hien <hienly@yandex.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Ricky Tigg <ricky.tigg@gmail.com>
Co-authored-by: Roman Ondráček <mail@romanondracek.cz>
Co-authored-by: Tito Tapiola <ikirouta013@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Kevin Papst <kevinpapst@users.noreply.github.com>
2024-10-03 10:38:48 +02:00
Kevin Papst
fb9a0dc499 Release 2.23.0 (#5075) 2024-10-03 10:34:20 +02:00
Kevin Papst
40154be8f9 Upgrade Tabler frontend to 1.0.21 (#5066) 2024-09-23 18:31:33 +02:00
Kevin Papst
13649e146c Improve pagination support in API (#5073) 2024-09-22 17:26:02 +02:00
Kevin Papst
4076e1c3d3 Support for changeable work contract types (#5069) 2024-09-22 16:18:21 +02:00
Kevin Papst
8de54e1fa7 Added API endpoints to fetch invoices (#5070)
* added serializer attributes for API usage
* new setters to fill invoice data from fixture
* re-usable fixture helper methods
* added API endpoints to fetch invoices
* adjust tests
2024-09-22 16:17:45 +02:00
Weblate (bot)
1965c35b43 Translated using Weblate (#5045)
Co-authored-by: Doctorredits_here <alkaf.alkaf2018@tutamail.com>
Co-authored-by: Hien <hienly@yandex.com>
Co-authored-by: Jose Delvani <jsdelvani@users.noreply.hosted.weblate.org>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Reza Almanda <rezaalmanda27@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: albanobattistella <albano_battistella@hotmail.com>
Co-authored-by: enly sure <enlysure@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2024-09-22 15:38:51 +02:00
Kevin Papst
3fd770047e allow Authorization header in CORS request 2024-09-20 23:26:29 +02:00
Kevin Papst
036b297a76 fix hydration issues in favorites (#5068) 2024-09-20 22:43:16 +02:00
Kevin Papst
537c120ad9 Release 2.22.0 (#5043) 2024-09-20 14:30:11 +02:00
Weblate (bot)
3e0dadc0c8 Translated using Weblate (#5037)
Co-authored-by: Jose Delvani <jsdelvani@users.noreply.hosted.weblate.org>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: hugoalh <hugoalh@users.noreply.hosted.weblate.org>
2024-09-01 14:58:47 +02:00
Kevin Papst
004ac5a6b9 re-phrase 2024-09-01 14:57:07 +02:00
Kevin Papst
3204dcb03e bump PHPSpreadsheet major version (#5040) 2024-08-31 23:42:41 +02:00
Kevin Papst
b1903ba183 Release 2.21.0 (#5014) 2024-08-28 17:16:37 +02:00
Weblate (bot)
75fa7a20b8 Translated using Weblate (#5012)
Co-authored-by: BeckeBauer <berko@gmx.de>
Co-authored-by: Biscuittttt <biscuitwithtea.tall310@passinbox.com>
Co-authored-by: Héctor Borrás Aleixandre <hborrasaleixandre@gmail.com>
Co-authored-by: John Titor <utkin2007@gmail.com>
Co-authored-by: Léane GRASSER <leane.grasser@proton.me>
Co-authored-by: Prefill add-on <noreply-addon-prefill@weblate.org>
Co-authored-by: Reza Almanda <rezaalmanda27@gmail.com>
Co-authored-by: Uporabnik Alen <obutimacek556@gmail.com>
Co-authored-by: XblateX <blate@users.noreply.hosted.weblate.org>
Co-authored-by: tygyh <jonis9898@hotmail.com>
2024-08-28 17:15:57 +02:00
Kevin Papst
a19426147a added event to send email to user (#5034) 2024-08-28 14:04:36 +02:00
Kevin Papst
9d933f62c0 refactored repositories and DB queries (#5026)
* removed unused teams from export order
* added new paginator for query instead of querybuilder
* added field hydrate enums
* hide PARTIAL deprecation
* never log deprecations in production
* replaced InvoiceLoader with native Doctrine feature
* prevent excessive permission queries
* support loading customers of team
* improved findByIds
* internalized API
* fix null string deprecations
2024-08-27 10:11:19 +02:00
Kevin Papst
9e3d243b4b use enabled_locales logic to handle locales (#5017)
* allow to skip locales (here: catalan)
* use enabled_locales and replace app_locales with kimai_locales
* added test to call all reports once for super_admin
2024-08-11 17:43:20 +02:00
Kevin Papst
62047c7c01 link security guidelines on the website 2024-08-05 18:44:38 +02:00
Kevin Papst
0bcd45babe clarify test exclusions 2024-08-05 13:23:53 +02:00
Kevin Papst
2a72815481 remove invalid label 2024-08-04 19:38:47 +02:00
Kevin Papst
ff6a3e8262 Release 2.20.0 (#4987) 2024-08-04 18:22:27 +02:00
Kevin Papst
0947b88d36 added OCI docker labels (#4996) 2024-08-04 16:43:46 +02:00
Kevin Papst
5de5b4fef5 BC: Cleanup Docker tags (#4995) 2024-08-04 16:37:55 +02:00
robjuz
cde856a9c1 BC: Docker support for encoded characters in DATABASE_URL (#5000) 2024-08-04 16:02:08 +02:00
Kevin Papst
6f8877a740 new export of project overview list (#5009) 2024-08-03 00:43:05 +02:00
Kevin Papst
e7d71bff64 remove comments from XLIFF files 2024-08-02 22:43:36 +02:00
Weblate (bot)
cca0657291 Update translation files (#5010) 2024-08-02 21:49:13 +02:00
Weblate (bot)
a4904d3335 Update translation files (#5007)
Co-authored-by: Héctor Borrás <hborras@cyberclick.net>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Naoko Takano <naokomc@gmail.com>
Co-authored-by: Reza Almanda <rezaalmanda27@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: stuntworks <stuntworks@saber.games>
2024-08-02 21:43:29 +02:00
Kevin Papst
b9c1036b21 Revert Docker credentials urldecode (#4998) 2024-07-28 18:04:18 +02:00
Weblate (bot)
818c080d28 Translated using Weblate (#4990)
Co-authored-by: Ldm Public <ldmpub@gmail.com>
Co-authored-by: Wouter Meeusen <wouter.meeusen@outlook.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2024-07-27 17:37:10 +02:00
Weblate (bot)
a5a6ae065b Translated using Weblate (#4984)
Co-authored-by: Adrien N <adriennathaniel1999@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
2024-07-23 10:03:56 +02:00
Kevin Papst
8b06ca9d10 unify CSRF token usage in comment sections (#4986) 2024-07-23 08:33:02 +02:00
Kevin Papst
7e1025d61d fix financial year issue, fix test, improve DateTimeFactory (#4985) 2024-07-23 07:20:11 +02:00
Kevin Papst
8788311faf Release 2.19 (#4922) 2024-07-22 17:51:03 +02:00
Weblate (bot)
ce22520d7f Translated using Weblate (#4946)
Co-authored-by: Ahmad Dakhlallah <ahmad@linuxarabia.co>
Co-authored-by: Bent Haar <BentHaar@users.noreply.hosted.weblate.org>
Co-authored-by: Carlos Carreras <mytriponlinux@gmail.com>
Co-authored-by: David Bauer <dbs23.dbs23@gmail.com>
Co-authored-by: Jose Delvani <delvani.eletricista@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Ldm Public <ldmpub@gmail.com>
Co-authored-by: Mads R. Andersen <madsdk_789@hotmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Mikkel Ricky <rimi@aarhus.dk>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Quiwy <github@quiwy.ninja>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: geekom13 <geekom13@proton.me>
Co-authored-by: lilosti <lilosti@aarhus.dk>
Co-authored-by: ssantos <ssantos@web.de>
2024-07-20 17:36:02 +02:00
robjuz
f5d76cfd9a fix database URLs with special characters for docker (#4976) 2024-07-20 17:20:23 +02:00
Chinmay Purav
27f7f14539 fixed case of AS keyword in Dockerfile (#4943) 2024-06-29 21:45:14 +02:00
Kevin Papst
f7c32e633a bump docker action versions to fix GH deprecations 2024-06-17 11:05:49 +02:00
Kevin Papst
6d9055826f bump docker action versions to fix GH deprecations 2024-06-17 10:07:27 +02:00
Toby Batch
4627a9047e feat: stop multiarch images being lost on re tagging docker images (#4856) 2024-06-17 10:03:11 +02:00
Kevin Papst
987b46bf8f Release 2.18 (#4878) 2024-06-16 13:15:49 +02:00
Weblate (bot)
8792a1df09 Translated using Weblate (#4876)
Co-authored-by: Chan Young Park <designbycy@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Oh Wow! <kasra.hashemi1999@gmail.com>
Co-authored-by: René Bischoff <rene.bischoff@gmail.com>
Co-authored-by: Wei-Cheng Yeh (IID) <iid@ccns.ncku.edu.tw>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: wkwkjddndjdusiq <wkwkjddndjdusiq@onionmail.com>
2024-06-16 13:02:27 +02:00
Kevin Papst
a8678892d6 yarn upgrade 2024-06-15 11:40:35 +02:00
Kevin Papst
72350b76c0 improve equality detection of same user 2024-06-15 11:40:28 +02:00
Kevin Papst
8578bbe033 improve project end handling 2024-06-13 22:31:33 +02:00
Kevin Papst
93ca983e0b invoice: do not use activity name as fallback for description (#4884)
* added replacement field description_safe
2024-06-03 19:01:40 +02:00
Kevin Papst
e29ef25581 link domains for donations 2024-05-22 14:19:11 +02:00
Kevin Papst
a617eba535 link about pages for donations 2024-05-22 14:15:42 +02:00
Kevin Papst
0c445d1bc4 Release 2.17 (#4836)
see https://github.com/kimai/kimai/pull/4836
2024-05-19 17:42:03 +02:00
Weblate (bot)
5f7114e008 Translated using Weblate (#4862)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: Wei-Cheng Yeh (IID) <iid@ccns.ncku.edu.tw>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2024-05-19 17:03:48 +02:00
Habibhaidari1
e2c511cf46 Update RateCalculatorInterface (#4851) 2024-05-17 22:55:08 +02:00
Weblate (bot)
e042ef6bfa Translated using Weblate (#4850)
Co-authored-by: Barna László <barna.laszlo@lscomputer.hu>
Co-authored-by: Wei-Cheng Yeh (IID) <iid@ccns.ncku.edu.tw>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2024-05-12 12:41:06 +02:00
Daniel Langemann
c059e51b3c Fix typo in markdown link (#4845) 2024-05-07 09:30:33 +02:00
Kevin Papst
661bb16342 Fix hidden API token (#4828) 2024-05-03 11:38:33 +02:00
Weblate (bot)
94d6b43dcc Cleanup translation files (#4827) 2024-05-03 11:06:35 +02:00
Kevin Papst
99c296a751 Release 2.16 (#4780) 2024-05-01 14:24:24 +02:00
Weblate (bot)
8f8d228fb3 Translated using Weblate (#4826)
Co-authored-by: Bogumił Kraszewski <gogulcio@gmail.com>
Co-authored-by: Colgrave <hanqixu.blogs@simplelogin.co>
Co-authored-by: Freek <info@f3k.tech>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Nicoara Alex <alex.nicoara@yahoo.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Wei-Cheng Yeh (IID) <iid@ccns.ncku.edu.tw>
Co-authored-by: qeepoo <pfrade1996@protonmail.com>
2024-05-01 13:43:31 +02:00
Weblate (bot)
1214e508fe Translated using Weblate (#4814)
Co-authored-by: Bogumił Kraszewski <gogulcio@gmail.com>
Co-authored-by: Jose Delvani <delvani.eletricista@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: streaming s <fsrmllll1111@gmail.com>
2024-04-24 06:36:55 +02:00
Andreas Brain
7d394fbe56 added ldap-libs to for TLS certificate verification (#4802) 2024-04-23 10:33:51 +02:00
Weblate (bot)
fd4dfc6be4 Translated using Weblate (#4812)
Co-authored-by: Andre Costa <andrecaeu@gmail.com>
Co-authored-by: Balanda Nazarii <balaraz@tuta.io>
Co-authored-by: Joaquim Homrighausen <joho@boojam.se>
Co-authored-by: Jose Delvani <delvani.eletricista@gmail.com>
Co-authored-by: Julia <juliadeo@proton.me>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Languages add-on <noreply-addon-languages@weblate.org>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nicoara Alex <alex.nicoara@yahoo.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Petar Babić <petar@jesteibice.com>
Co-authored-by: SGpro <mark520fay35@gmail.com>
Co-authored-by: Tito Tapiola <ikirouta013@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: حاج حسین نجفی <hajhsynnjfy@gmail.com>
2024-04-22 18:44:21 +02:00
Kevin Papst
9dc9c71a46 added "api_access" permission for limiting API access (#4779) 2024-04-13 17:27:51 +02:00
Kevin Papst
345bb6601e fix test 2024-04-13 17:00:13 +02:00
Kevin Papst
5c8c21d609 fix menu name 2024-04-13 16:52:44 +02:00
Kevin Papst
7219b3f421 Release 2.15 (#4749) 2024-04-12 19:03:09 +02:00
Weblate (bot)
b76a5d5c35 Translations update from Hosted Weblate (#4765)
Co-authored-by: Andre Costa <andrecaeu@gmail.com>
Co-authored-by: Balanda Nazarii <balaraz@tuta.io>
Co-authored-by: Joaquim Homrighausen <joho@boojam.se>
Co-authored-by: Jose Delvani <delvani.eletricista@gmail.com>
Co-authored-by: Julia <juliadeo@proton.me>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Petar Babić <petar@jesteibice.com>
Co-authored-by: Tito Tapiola <ikirouta013@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Kevin Papst <kevinpapst@users.noreply.github.com>
2024-04-12 16:22:17 +02:00
Kevin Papst
40a9027d34 try v5 without discussion 2024-04-06 11:09:02 +02:00
Kevin Papst
553bd20e06 internal: bump versions due to node16 deprecation 2024-04-06 10:33:53 +02:00
Kevin Papst
3ea5803e08 revert to @v4 2024-04-06 10:29:15 +02:00
Kevin Papst
4949afb098 try different token 2024-04-06 10:28:27 +02:00
Kevin Papst
d328badca1 enable debug 2024-04-06 10:26:47 +02:00
Kevin Papst
175d371ef9 change name 2024-04-06 10:17:12 +02:00
Kevin Papst
6bb7b38252 bump version 2024-04-06 10:15:56 +02:00
Kevin Papst
afe0656502 added API tokens, deprecate API passwords (#4637) 2024-04-05 23:51:16 +02:00
Kevin Papst
dd51c8dfba utilize UserService for SAML (#4748) 2024-04-05 19:22:13 +02:00
Kevin Papst
b6c98f871d Release 2.14 (#4710)
- show "link has expired message" in password reset screen
- added date objects as hydrator variables - for custom date formats in invoice templates
- show meta-fields with null values (e.g. booleans with `false` where hidden)
- fix permission check: allow to remove `view_own_timesheet` but still record times
- prevent error 500 if customer country is empty
- fix API 500 error if project does not exist when creating new timesheet
- fix tags are not created in remote-search mode
- do not check "export items" by default
- fix daterange query, if user an request locale are different
- added logging for invalid SAML responses (see various discussions)
2024-04-05 12:38:21 +02:00
Weblate (bot)
19b2d47591 Translated using Weblate (#4746)
Co-authored-by: Joaquim Homrighausen <joho@boojam.se>
Co-authored-by: Jose Delvani <delvani.eletricista@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
2024-04-04 17:50:23 +02:00
Kevin Papst
a636683dee Configurable activity and project number (#4729)
* added configurable activity number
* added configurable project number
* fix deprecations
* added some tests for entity exporter
* better configuration of dropdown pattern for customer, project and activity
2024-04-04 17:43:22 +02:00
Kevin Papst
c1f5d3def4 do not export items by default 2024-04-04 17:35:43 +02:00
Kevin Papst
3e88a007d0 allow to change locale in DateRangeType 2024-04-04 17:35:16 +02:00
Kevin Papst
1fdd11e94c link to wall of love 2024-04-04 00:20:31 +02:00
Toby Batch
2ac783a300 split docker to use base image for faster builds (#4586) 2024-04-02 17:50:24 +02:00
Weblate (bot)
3a358b1434 Translated using Weblate (#4722)
Co-authored-by: Jean-Michel <arsene_lupin_57@hotmail.fr>
Co-authored-by: Joaquim Homrighausen <joho@boojam.se>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Thanh <pancakes21f@gmail.com>
2024-04-02 01:06:57 +02:00
Yannik Beaulieu
216da19cc9 Add support for negative durations in All Users reports (#4717) 2024-03-27 23:57:52 +01:00
Kevin Papst
dee90bb15e Release 2.13 (#4659) 2024-03-10 15:35:59 +01:00
Weblate (bot)
a78e8ed8c4 Translated using Weblate (#4693)
Co-authored-by: Andre Costa <andrecaeu@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2024-03-10 15:29:27 +01:00
Weblate (bot)
e293d62aa1 Translated using Weblate (#4658)
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: DOHEX <xuyaohui617@outlook.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Сергій <sergiy.goncharuk.1@gmail.com>
2024-02-22 18:00:51 +01:00
Kevin Papst
f016221e8e Fixes for 1.12 (#4655)
* fix missing locales
* bump composer packages
* changed translations
* assert timezone on customer
* include user accountNumber in excel export
* improve next customer number calculation
* fix z-index of contextmenu / action dropdown
2024-02-22 13:03:09 +01:00
Kevin Papst
36c578452e show top nav links as buttons (#4633) 2024-02-12 17:50:22 +01:00
Kevin Papst
6e643ee99c revert to classical bootstrap form layout (#4632) 2024-02-12 17:35:30 +01:00
Kevin Papst
58cbf1776f Weekly hours improvements (#4631)
* fix table padding
* reduced minimum quick-entry recent activity row amount
* use activity favorites in weekly hours
2024-02-12 14:20:17 +01:00
Kevin Papst
85a16a9363 Release 2.12 (#4609) 2024-02-07 23:47:25 +01:00
Kevin Papst
7abe787778 added project filter in user-list reports (#4615) 2024-02-07 18:00:29 +01:00
Weblate (bot)
e98732f44a Translated using Weblate (#4614)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
2024-02-06 16:06:40 +01:00
Kevin Papst
c2afebbb5e Fix Doctrine deprecations (#4608) 2024-02-02 15:48:11 +01:00
Kevin Papst
49e69d1ae3 Release 2.11 (#4580) 2024-02-02 13:52:24 +01:00
Andreas Brain
a9a32c83ac Add library to re-enable TLS certificate verification for LDAP connections (#4598) 2024-02-02 13:46:40 +01:00
Weblate (bot)
64fa67f15d Translated using Weblate (#4587)
Co-authored-by: Alex Terlan <terlan2012@gmail.com>
Co-authored-by: Bruno Paré-Simard <bruno.p@brunops.com>
Co-authored-by: Bálint László <blaszlobors@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Reza Almanda <rezaalmanda27@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: abdelbasset jabrane <ribago9317@cubene.com>
Co-authored-by: delvani <inavleb@users.noreply.hosted.weblate.org>
2024-02-02 13:44:25 +01:00
Kevin Papst
df3ca9d5a9 Split user language (UI translation) from locale (formatted values) (#4595) 2024-01-30 00:09:53 +01:00
Kevin Papst
12ef19df28 support default time on date-time-picker (#4579) 2024-01-21 01:59:30 +01:00
Kevin Papst
a5b4a92086 new phpstan version 2024-01-21 00:28:03 +01:00
Kevin Papst
3aaaf9ffc0 bump packages 2024-01-20 02:12:26 +01:00
Weblate (bot)
3f73f2c570 Translated using Weblate (#4576)
Co-authored-by: Bálint László <blaszlobors@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Saveliy <jitropolit@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2024-01-20 01:27:25 +01:00
Kevin Papst
46739795ff Release 2.10 (#4549) 2024-01-19 12:05:07 +01:00
Kevin Papst
afd60a67f6 merged and removed small translation files (#4572)
* merged about with messages
* merged invoice-numbergenerator with messages
2024-01-16 23:39:13 +01:00
Weblate (bot)
bb325888a1 Translated using Weblate (#4551)
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Miloš Havlíček <milos.havlicek@cothema.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: albanobattistella <albano_battistella@hotmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: сэр Аноним <mcptminei@gmail.com>
2024-01-16 23:16:46 +01:00
Kevin Papst
fdda9841fa allow to edit username (#4559) 2024-01-14 13:02:44 +01:00
Ronald Derksen
5acd33dd64 Make 'pagebreak' optional in pdf layout exporter (#4561) 2024-01-13 14:44:31 +01:00
Kevin Papst
6531e7fe52 Release 2.9.0 (#4526)
* added fix to work around bc break in new phpword version
* fix phpoffice deprecations
* mark unused option as deprecated
* support for DateTimeInterface and DateTimeImmutable where possible
* use TRUSTED_PROXIES setting - fixes #4533
* re-enable Kimai test in docker test build script (#4541)
* bump dependencies
2024-01-10 12:43:07 +01:00
Weblate (bot)
c6a651456e Translated using Weblate (#4531)
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: yangyangdaji <1504305527@qq.com>
Co-authored-by: Сергій <sergiy.goncharuk.1@gmail.com>
2024-01-09 23:53:56 +01:00
Kevin Papst
8eeb9c120a Release 2.8.0 (#4508) 2024-01-03 00:28:35 +01:00
Janne Heß
d8f89d9f3d release-drafter: adapt supported PHP versions (#4512) 2024-01-03 00:25:24 +01:00
Simon Schaufelberger
26a89725eb fix wrong default protocol for customer homepage (#4514) 2024-01-02 15:20:24 +01:00
Weblate (bot)
9f0165ef4d Translated using Weblate (#4517)
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Сергій <sergiy.goncharuk.1@gmail.com>
2024-01-01 21:05:29 +01:00
Kevin Papst
3d0a35f0cd bump checkout action version 2023-12-27 02:10:46 +01:00
Kevin Papst
c5dcf9e0fd replace deprecated set-output with environment usage, deactivate broken test-lite 2023-12-26 17:18:08 +01:00
Kevin Papst
ad645f5b58 Release 2.7.0 (#4506)
* added api URL for simpler integration
* allow to request password change upon next login
* make ModifiedAt timesheet independent
* improved plugin api
* replace kernel calls with AutoconfigureTag and TaggedIterator attributes
* new translation keys (e.g. for days)
* support setting min and max date on date and daterange pickers
2023-12-26 14:49:11 +01:00
Weblate (bot)
f86eca05ae Translated using Weblate (#4507)
Co-authored-by: Alan Aparecido da coneicao <alanaparecidodaconeicao@gmail.com>
Co-authored-by: Balanda Nazarii <balaraz@tuta.io>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nikolay Soloshin <nigiriits@users.noreply.hosted.weblate.org>
Co-authored-by: Petal <Petalzu@outlook.com>
Co-authored-by: Thomas <jzh20180312@163.com>
Co-authored-by: Vipul Hangadiya <hangadiyavipul@gmail.com>
Co-authored-by: Wei-Cheng Yeh (IID) <iid@ccns.ncku.edu.tw>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2023-12-26 01:32:18 +01:00
Kevin Papst
ac2a6ba2c8 use a full mysql database URL as default (#4504) 2023-12-25 23:41:13 +01:00
Christian Schupfner
e23d0474fd Upgrade Docker to PHP 8.2 (#4476)
- base image changed to PHP 8.2
- base images changed to bookworm
- libicu63 upgraded to libicu72
2023-12-17 17:05:38 +01:00
Kevin Papst
2edcbcca50 sort invoice items by date before passing to template (#4495) 2023-12-17 16:50:47 +01:00
Kevin Papst
5f4b6d3cfa Release 2.6.0 (#4472)
- Added: calendar entry title combination for customer, project and activity
- Added: show not_invoiced and not_exported data in detail screens
- Added: force logout if user is disabled
- Added: reduced amount of database queries on several screens
- Fixed: open-close status on work-contract screen for users without configuration
- Fixed: failsafe order/orderBy in query if manually manipulated to be null
- Fixed: unify statistic calculation (not_invoiced and not_exported) across screens
- Tech: bump packages
- Tech: Symfony 6.4
2023-12-17 16:19:50 +01:00
Kevin Papst
af82fd040d removed deprecated test script (#4490) 2023-12-14 12:12:17 +01:00
Kevin Papst
e0769bc3dc allow PHP 8.3 (#4471)
Fix use of range() and auto-width columns for Excel exports
2023-12-01 22:40:02 +01:00
Weblate (bot)
8fd2e7029e Translated using Weblate (#4466)
Co-authored-by: EngageIndo <engageindo@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Shimpei <sfutami0821@gmail.com>
Co-authored-by: albanobattistella <albano_battistella@hotmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: nigiriits <i79046290200@gmail.com>
Co-authored-by: nigiriits <nigiriits@users.noreply.hosted.weblate.org>
Co-authored-by: xorly <patrikbachan@gmail.com>
2023-12-01 22:38:32 +01:00
Kevin Papst
f570b5506a added missing translations 2023-12-01 18:33:09 +01:00
Kevin Papst
0e1bd818bf bump packages 2023-12-01 16:42:51 +01:00
Kevin Papst
02bcd45116 Release 2.5.0 (#4454)
- added command to list users
- corrected wrong german translation
- work contract validations
- prevent error with missing params
- use collapsible, minor UI improvement
- added classes to target menu buttons in custom rules
- disable webpack notifier, incompatible with mac arm
- use explicit menu service to generate menu
- bump to fontawesome 6 and replace restart icon
- change repeat icon for recent activities
- moved user bookmarks (favorites) to top nav
- fix totp seconds window (leeway)
- new migration to fix remaining user preferences with dots in name
- remove duplicate named column in user screen
- unify and added translations
- added missing filter and tags to InvoiceSecurity
2023-12-01 11:38:17 +01:00
Kevin Papst
16d4a691f8 Fix LDAP with internal users (#4453)
* added logging, in case Laminas libs are not available
* make sure that internal users can still login if LDAP is activated
2023-11-20 21:33:36 +01:00
Kevin Papst
20164295f8 Release 2.4.0 (#4427)
* button to duplicate old timesheets, even those from lockdown period
* bump composer packages
* fixes tooltip remains in view #4426
* fix js error if all widgets were removed
* allow to open timesheet edit dialog from export listing
* css classes for timesheet context menu, so they can be hidden
* added flag to force a user to set password upon login
* enable lazy-ghost-objects to fix deprecation
* change user, username, internal_rate export column labels
* helper method to find user by displayname
* log improvements and format changes
* deactivate broken schema validation
2023-11-19 16:05:43 +01:00
Weblate (bot)
9d8e5ecd7a Translated using Weblate (#4447)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Matti O <matt1@users.noreply.hosted.weblate.org>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Patrick Kartschewski <weblate@patrick-kartschewski.de>
Co-authored-by: Reza Almanda <rezaalmanda27@gmail.com>
Co-authored-by: Victor Hitriy <pvnhome@yandex.ru>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: albanobattistella <albano_battistella@hotmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2023-11-19 16:01:35 +01:00
Kevin Papst
8a1059fdd1 added docker build and publish workflow (#4446) 2023-11-17 14:37:32 +01:00
Kevin Papst
92c6922afb fix LDAP issues and allow to migrate from local to LDAP account (#4445) 2023-11-17 14:37:00 +01:00
Kevin Papst
2fb9ea9239 bump packages 2023-11-17 13:22:50 +01:00
Toby Batch
350875be2a moved dockerfile to main repo (#4393) 2023-11-17 13:07:51 +01:00
Kevin Papst
6a828cc9bd 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
2023-11-08 22:30:22 +01:00
Weblate (bot)
7034066de9 Translated using Weblate (#4346)
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Benjamin Alan Jamie <benjamin@weblate.org>
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Den SE <dense800@gmail.com>
Co-authored-by: EngageIndo <engageindo@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Liam Azofra <liamazofra@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Prefill add-on <noreply-addon-prefill@weblate.org>
Co-authored-by: Serhii Horichenko <m@sgg.im>
Co-authored-by: Singh <spamio@protonmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: albanobattistella <albano_battistella@hotmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: yangyangdaji <1504305527@qq.com>
Co-authored-by: مهدی امیری راد <mahdiamererad@gmail.com>
2023-11-07 12:41:57 +01:00
Kevin Papst
2a9bdb7982 fix locale definitions starting with AM/PM (#4408)
* adapt locale script to fix locales starting with AM/PM
* fix korean locales that start with AM / PM
* added missing uk and zh_Hant locales
2023-11-07 12:27:11 +01:00
Kevin Papst
a1d9874c13 added role cards to permission screen (#4401)
* simplify creating new roles by auto-replacing input
2023-11-04 20:17:05 +01:00
Kevin Papst
0b1625175b remove link to external docker repo 2023-11-03 00:06:19 +01:00
Kevin Papst
0f6a6e7561 Update docker.yml (#4395) 2023-11-03 00:05:21 +01:00
Kevin Papst
7bbd497ef1 change URL to support landing page 2023-11-02 23:55:42 +01:00
Kevin Papst
0b3f645bda added docker bug report template 2023-11-02 23:54:29 +01:00
Kevin Papst
c840fee911 Release 2.2.1 (#4389)
* added missing functions to invoice security policy
2023-11-01 01:16:17 +01:00
Simon Schaufelberger
e06acc95c5 add parameter types and fix a phpstan issue (#4384) 2023-10-31 17:03:26 +01:00
Kevin Papst
95f15e6c88 Release 2.2.0 (#4359)
* deactivate deprecation logging in prod for now
* fix several deprecations
* enable CSRF for logout
* allow more twig methods and functions in InvoiceSecurity policy
2023-10-31 16:41:09 +01:00
Kevin Papst
114617a052 clarify EOL of Kimai 1 2023-10-20 16:30:20 +02:00
Kevin Papst
38e37f1c2e Release 2.1.0 (#4321)
* fix deprecations
* remove unused config
* replace invalid annotation type with attribute
* use AsDoctrineListener to fix deprecation
* new ModifiedSubscriber to support custom logic and fix deprecation
* removed inheritdoc comment
* new ModifiedSubscriber to support custom logic and fix deprecation
* cleanup event dispatcher interface
* re-order annotation params
* one more doctrine based deprecation
* fix query to count active timesheets
* link to "all times" to identify active timesheets
* link icon instead of text
* fix "skin" translation in wizard
* use duration filter to show duration
* added login link command and controller
* bump tabler theme to 1.0
* added wizard to force password reset by user
* allow to configure that new accounts need to reset their password
* prevent uploading twig templates by default
* bump composer packages
* enable sandbox and basic security measures for custom twig templates for invoice and export
* bump to symfony 6.3.5
* allow to export single user reports to excel
* removed broken method to reload twig cache
* added api parameter to fetch user collection fully serialized
* allow to replace or append description via timesheet batch update
* show api username above form
2023-10-19 11:21:50 +02:00
Kevin Papst
7a5b12762a Release 2.0.35 (#4302) 2023-09-23 18:15:22 +02:00
Kevin Papst
de419350b2 Release 2.0.34 (#4281) 2023-09-17 22:32:01 +02:00
Weblate (bot)
a6b237936e Translated using Weblate (#4282)
Co-authored-by: Kieran W <alarmcuddly@outlook.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Mykola Skira <mykola.skira@icloud.com>
Co-authored-by: No Pasaran <damiengourdin@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: yangyangdaji <1504305527@qq.com>
Co-authored-by: Łukasz Kosiński <lukikosin@gmail.com>
2023-09-11 23:18:07 +02:00
Kevin Papst
6e1207578e Release 2.0.33 (#4273)
* added function to check if meta-field is defined by a plugin
* hide un-defined meta-fields in details view
* fix default charset = utf8mb4
* remove broken DATABASE_VERSION fallback
* split off upgrade infos for version 1.x
* fix page out of range #4279
2023-09-07 22:24:08 +02:00
Kevin Papst
31348da4c0 Release 2.0.32 (#4256) 2023-08-31 15:33:53 +02:00
Bruno Paré-Simard
452de88e18 change isWeekend() handling to use work-hour configuration (#4261) 2023-08-31 13:38:58 +02:00
Weblate (bot)
18d953e79b Translated using Weblate (#4267)
Co-authored-by: Ali Evcil <evcil@proton.me>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
2023-08-31 12:51:37 +02:00
Kevin Papst
636422e342 show global form errors - fixes #4233 2023-08-21 20:38:32 +02:00
Weblate (bot)
20149ae765 Translated using Weblate (#4252)
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2023-08-21 20:31:38 +02:00
Kevin Papst
a392f61d61 Release 2.0.31 (#4245)
* replace strings by class references
* allow 64 chars for username
* fix time can be optional and null
* fix timezone is not respected
* bump version
* fix br in attribute
* support different visible duration from booked duration
* fix image URL
2023-08-21 20:24:24 +02:00
Kevin Papst
3e61e0dce6 added supervisor setting for user (#4251) 2023-08-20 13:18:35 +02:00
Kevin Papst
9baa477bed fix payload 2023-08-17 22:58:28 +02:00
Kevin Papst
4d182ad1a7 validate version 2023-08-17 22:54:35 +02:00
Kevin Papst
e77056c4b7 fix payload and validate version 2023-08-17 22:22:53 +02:00
Johannes Przymusinski
d7f1df2987 update website version automatically (#4248) 2023-08-17 21:16:36 +02:00
Kevin Papst
8c1a793b0a added workflow to update website version 2023-08-16 22:33:25 +02:00
Kevin Papst
adc0779912 Release 2.0.30 (#4225) 2023-08-16 18:20:14 +02:00
Weblate (bot)
c7bc8fae73 Translated using Weblate (#4210)
Co-authored-by: Evgeniy Khramov <thejenjagamertjg@gmail.com>
Co-authored-by: Joaquim Homrighausen <joho@boojam.se>
Co-authored-by: John Aleksander Jazbec <johnny@xhorizont.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Matthew Durajka <logrcz@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: PatoGordo <icariusv@gmail.com>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: Serhii Horichenko <m@sgg.im>
Co-authored-by: Tobs Hart <tobias@2bproduction.net>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Yaroslaw <bruce.levitangens@gmail.com>
Co-authored-by: beq <beqbdean@gmail.com>
Co-authored-by: full name <iaeqgz09gu6d@opayq.com>
Co-authored-by: jhtm <jhtm@users.noreply.hosted.weblate.org>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2023-08-16 15:08:22 +02:00
Kevin Papst
0a0ffb4ac9 remove text from tag choice after selection - fixes #4076 2023-08-04 13:03:11 +02:00
Kevin Papst
b831532323 Release 2.0.29 (#4178)
- show button title if delete is used in page actions
- fix invoice due date depends on invoice date, replace DateTime with DateTimeI… 
- lowercase all font names in PDFs, otherwise they fail loading
- hide empty fieldset (work-contract page)
- activate contract_other_profile by default for admin and super-admin
- deactivate rule to check "maximum duration of entries" by default
- allow to deactivate presets in DateRange Picker (for Devs)
2023-07-26 15:16:59 +02:00
Kevin Papst
385753fbc3 Release 2.0.28 (#4172)
See https://github.com/kimai/kimai/pull/4172
2023-07-09 15:27:27 +02:00
Kevin Papst
651f812da8 Release 2.0.27 (#4107) 2023-07-04 17:01:29 +02:00
Weblate (bot)
6a99ad41ca Translated using Weblate (#4109)
Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Matthew Durajka <logrcz@gmail.com>
Co-authored-by: Matúš Bulla <matbull12345@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: Sergii Horichenko <m@sgg.im>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Yonggen <vizualizer@gmail.com>
Co-authored-by: bigvictorio <bigvictorio12345@gmail.com>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2023-07-04 00:17:38 +02:00
Kevin Papst
dd89363c72 Improve UX for invoice template management (#4121)
change translations and to explain that calculator actually group items by fields
2023-06-21 08:17:54 +02:00
Weblate (bot)
983bf2c88b Translated using Weblate (#4099)
Co-authored-by: Arjan Houben <arjan@houben.es>
Co-authored-by: Jiri Nakola <github@nakola.fi>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Sebastiaan <djsebas@home.nl>
Co-authored-by: Tomas Koutek <spam@hug0.cz>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: akawshi <zenranoakawshi@gmail.com>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2023-06-13 14:17:37 +02:00
Kevin Papst
ce7fe67fcc use modern flat form styles with more icons (#4098) 2023-06-09 19:16:36 +02:00
Kevin Papst
053a1d9017 use collapsible element instead of collapsible card (#4096) 2023-06-09 18:17:32 +02:00
Kevin Papst
2e2bf986a4 Support visibility for tags (#4086) 2023-06-09 17:07:49 +02:00
Kevin Papst
6e781b59e2 Release 2.0.26 (#4087)
- setting "rounding days" not required
- developer: added user pref for public holiday group (to be used by plugins)
- developer: added WorkingTimeYearEvent (to be used by plugins)
- user pref: cleanup work contract form and support more fields (to be used by plugins)
- code cleanup
- bump theme and composer packages
2023-06-09 16:29:19 +02:00
Kevin Papst
0663995d06 Release 2.0.25 (#4066)
* added support for hourly rate column in detail table
* allow to register icon in extension
* allow to show QR code secret
* new translations
* bump theme and packages
* fix validation for invoice-document-filenames with uppercase character
* max upload size 1MB
* fix last month in daterange-picker in certain situations, more years in quick-select
* remove unused package-versions-deprecated
* link preferences from contract warning message
* added page_setup page layout
* prevent DROP TABLE in addSQL() and replace drop table with schema call
* added azuyalabs/yasumi
2023-06-06 23:05:20 +02:00
Kevin Papst
2ba9cff281 bump theme to get navigation id specific classes (#4065) 2023-05-26 22:39:07 +02:00
Kevin Papst
9c1150c50e added JS api to access current user in frontend (#4064) 2023-05-26 18:40:54 +02:00
Kevin Papst
b4a4d81ca8 Fix nullable parameter in work-contract API (#4063) 2023-05-26 18:39:44 +02:00
Kevin Papst
2681b81990 calendar: update popover content when shown (#4045) 2023-05-22 18:41:30 +02:00
Kevin Papst
97092acae9 fix single dropdown became two lines (#4041) 2023-05-21 17:49:44 +02:00
Kevin Papst
fdb6cf5cf8 allow to remove date from non-required field (#4040) 2023-05-21 17:13:41 +02:00
Kevin Papst
7ab0a8cea1 dynamic favicon that indicates if an entry is running (#4038) 2023-05-21 15:40:45 +02:00
Kevin Papst
2664d6117f show available github release only if newer version exists (#4037) 2023-05-20 13:49:31 +02:00
Kevin Papst
6bdf27fc9b change parameter name 2023-05-20 12:46:16 +02:00
Weblate (bot)
f0298335ee Translated using Weblate (#4036)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Sabri Ünal <libreajans@gmail.com>
Co-authored-by: Sebastiaan <djsebas@home.nl>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2023-05-20 12:08:36 +02:00
Kevin Papst
a58a33fc7d Release 2.0.22 (#4032)
* fix version string in migration
* disable search in order and order_by
* reduce divider spacing for context menu and select with optgroup
2023-05-20 12:08:01 +02:00
Kevin Papst
9bd5965ecd Release 2.0.21 (#4030)
* increase padding in wizard
* fix theme chooser in wizard
* improve dynamic export columns in PDFs
* added label for total column
* bump theme bundle
* improve avatar list spacing
* be more flexible parsing times - fixes #4031
2023-05-17 15:02:10 +02:00
Kevin Papst
29624354a2 Release 2.0.20 (#4028)
* max duration per entry increased from 8 to 10 hours
* fixes #3981 - clickable area in dropdown too small
* fixes #4008 - duplicate activities in project-details report
* headers and summary styling in project-details report
* show billable stats in project-details report
* added new invoice variable for entry.duration_format
2023-05-15 22:30:37 +02:00
Kevin Papst
04422f3530 frontend update to tabler beta 19 (#4029) 2023-05-15 19:10:00 +02:00
Kevin Papst
43bd7bf1ab added API for handling work contract times (#4016) 2023-05-13 01:24:15 +02:00
Kevin Papst
4b2a3669e6 Release 2.0.19 (#4022)
* prevent invoices with exceeding filename
* fixed invalid LDAP log level
* support locale switching in action events
2023-05-12 14:45:51 +02:00
Kevin Papst
1099e76244 Release 2.0.18 (#4003)
* prevent too long values for user preferences
* add chart value 0 to y-axis if last value > 0, to always display the zero line (project details)
* add user-preferences to invoice hydrator
* DateTime vs DateTimeInterface
* simplify permission config
* fix query for teamleads limiting to only selected teams not possible
2023-05-08 17:11:55 +02:00
Weblate (bot)
d8f72b8b88 Translated using Weblate (#4010)
Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com>
Co-authored-by: Hama Czech <hamaczech13@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Mæve Rey <martin.rey@mailbox.org>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Sanji Finsmok <khldeilamil@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2023-05-08 13:07:59 +02:00
Weblate (bot)
b2314de315 Translated using Weblate (#4002)
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
2023-05-02 00:44:49 +02:00
Kevin Papst
66413d789c Release 2.0.17 (#3992)
* prevent empty title for select options
* removed css for unused sweetalert
* fix isWeekend() check with DateTimeInterface
* reset timesheet rates on "create copy"
* wrap long names in multi-selects - fix #4001
* rename profile menus
* show all possible links in user profile dropdown
* check if plugin is compatible before displaying the buy link
2023-05-02 00:40:43 +02:00
Kevin Papst
7112e932a2 Allow 2FA for SAML and LDAP users (#4000)
* inline totp image as data uri to prevent caching issues
* allow 2fa for ldap and saml users
* allow 2FA access for super admin to all profiles
2023-05-01 08:28:35 +02:00
Kevin Papst
01e26dca9e Release 2.0.16 (#3990)
https://github.com/kimai/kimai/pull/3990
2023-04-27 18:48:31 +02:00
Weblate (bot)
844062b90e Translated using Weblate (#3991)
Co-authored-by: Anders Johansson <johansson@aljmedia.se>
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com>
Co-authored-by: Petr Daniel Ambrož <paces@paces.cz>
2023-04-27 18:22:01 +02:00
Kevin Papst
f60065d089 split timesheet validator to simplify imports (#3974) 2023-04-27 13:56:07 +02:00
Kevin Papst
046ed313c9 Release 2.0.15 (#3970) 2023-04-16 00:44:00 +02:00
Weblate (bot)
ecd8ee85f3 Translated using Weblate (#3968)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Kyotaro Iijima <kyotaro.eyes@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: gnu-ewm <gnu.ewm@protonmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: tachyglossues <tachyglossues@gmail.com>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2023-04-06 22:03:33 +02:00
Kevin Papst
0c397e5080 Release 2.0.14 (#3963)
- show customer totals in single-user reports
- support custom fonts in export / invoice templates
- require daterange for export and invoice searches
- improve help label for user locale
- show decimal formats in help controller
- cache tag amount per request
- composer updates
- improved code styles
- added default label to date picker
- new macros & use own macro
2023-04-05 19:14:49 +02:00
Kevin Papst
01226a1243 Release 2.0.13 (#3955)
- added missing escape to prevent HTML injection
- added missing color attribute
- upgrade theme
  - use dropdown submenu if title is set, otherwise dropdown tends to get too long
  - allow to use card-table instead of card-body
  - added `required` attribute to username and password field
- fix pagination back to page 1
- prevent tag name too long
- re-add missing user preferences link
2023-03-30 01:08:15 +02:00
Weblate (bot)
7164ec126f Translated using Weblate (#3945)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: gnu-ewm <gnu.ewm@protonmail.com>
Co-authored-by: tachyglossues <tachyglossues@gmail.com>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2023-03-30 01:06:24 +02:00
Kevin Papst
04b5eb4c38 Release 2.0.12 (#3947)
- added submenus in action drodowns, to shorten them
- show all user-edit-screens in action dropdown
- fix cascade delete teams through customer
- fix cascade delete customer/project/activity through teams
- fix responsive classes for "internal rate" column
- clarify error message if invoice number generator or calculator is missing
2023-03-24 00:47:36 +01:00
Kevin Papst
3a5d7a62de Release 2.0.11 (#3932)
- added "today" as selector in date-range dropdown
- added feature to prevent auto-select of dropdowns with only one entry
- added hint that no changes were detected in batch update
- added negative invoice sums are possible (e.g. for credit notes)
- fix project list is expanded after submission
- fix invalid date parsing causes 500
- fix: prevent auto-select of activities in export and invoice form (in case only one global activity exists)
- fix team assignments for customer and project were not saved (using API now)
- fix form fieldset with legend styling (e.g. team project assignment)
- fix required meta-field were forced to have a value in batch update
- fix tomselect meta-field was not disabled in batch update
- fix unset internal rate is shown as 0
- fix one minute rounding problem in duration-only mode  with "now" being default time
- fix column width and label for duration-only mode
- tech debt: cleanup invoice template (remove invoice layout)
- tech debt: reorder for simpler comparison with invoice form
- possible BC for devs: remove unused methods from form trait
- bump composer packages (includes new translations for auth screens)
2023-03-21 12:42:18 +01:00
Weblate (bot)
252652082d Translated using Weblate (#3937)
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Blueberry <igory.ygr200@gmail.com>
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Felipe Nogueira <contato.fnog@gmail.com>
Co-authored-by: Jeffrey <kjw5608kjw@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Lars Vogdt <lars.vogdt@suse.com>
Co-authored-by: Ondřej Mach <machondra2003@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Tang Yin <bingyuanshiye@126.com>
Co-authored-by: Viktor Kryvda <ivic4u@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: tygyh <jonis9898@hotmail.com>
2023-03-18 22:06:36 +01:00
Kevin Papst
f007697a73 Release 2.0.10 (#3927)
* allow API calls via GET
* allow to stop timesheet via GET
* improve form handling and validation
* improve stop button handling
* bump version
2023-03-15 23:02:28 +01:00
Kevin Papst
1a8c78944a Release 2.0.9 (#3922)
* fix api definition
* include customer number in validation message
* fix doctrine deprecation, prepare for DBAL 4
* added DataSubscriberInterface to identify certain doctrine subscribers
2023-03-14 23:51:49 +01:00
Kevin Papst
8449eafcb6 Release 2.0.8 (#3914)
* support parsing negative durations in JS
* bump luxon dependency
* make sure that 2FA is not required for session based API calls
* show name of items to delete
* fix permission issue for recent activity items
2023-03-13 01:48:53 +01:00
Kevin Papst
1310285133 bump version 2023-03-08 23:30:45 +01:00
Weblate (bot)
588e85d48f Translated using Weblate (#3905) 2023-03-08 21:05:19 +01:00
Kevin Papst
aebd57e311 added translation domain for dashboard widgets (#3909) 2023-03-08 19:01:49 +01:00
Kevin Papst
9d503300f6 Release 2.0.6 (#3900)
* cleanup invoice templates
* cleanup invoice translations
* fix invoice datetime for now
* support invoice archive order by number and status
* bump version
* allow meta-field sub-classing
* removed unused translation task.delete
* prevent null in str_replace
2023-03-08 00:38:10 +01:00
Weblate (bot)
80f8f70695 Translated using Weblate (#3902)
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Felipe Nogueira <contato.fnog@gmail.com>
Co-authored-by: Jeffrey <kjw5608kjw@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Ondřej Mach <machondra2003@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2023-03-07 21:39:42 +01:00
Weblate (bot)
c6fc06222f Unify language files (#3899)
Co-authored-by: Felipe Nogueira <contato.fnog@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2023-03-05 15:23:18 +01:00
Weblate (bot)
8926f7677e Update translation files (#3898) 2023-03-05 04:40:00 +01:00
Weblate (bot)
517e7eae89 Update translation files (#3897) 2023-03-05 04:38:12 +01:00
Weblate (bot)
8b53980ce7 Update translation files (#3896) 2023-03-05 04:36:34 +01:00
Weblate (bot)
d13083fc6f Cleanup translation files (#3895) 2023-03-05 04:34:54 +01:00
Weblate (bot)
34a79b1e3a Translated using Weblate (#3894)
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
2023-03-05 03:52:28 +01:00
Weblate (bot)
ea8bf6d1fa Cleanup translation files (#3893) 2023-03-05 03:48:04 +01:00
Weblate (bot)
cc39f25d37 Update translation files (#3887)
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Dan <denqwerta@gmail.com>
Co-authored-by: Felipe Nogueira <contato.fnog@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Ondřej Mach <machondra2003@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: i3sey <deniskedrovsky@mail.ru>
Co-authored-by: tygyh <jonis9898@hotmail.com>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2023-03-05 03:44:28 +01:00
Kevin Papst
0cbf0053d2 Release 2.0.5 (#3888)
- Fixed: mandatory fields / form validation for invoice template
- Added: Duration as calendar title replacer (open: running records)
- Fixed: HTML injection in Calendar
- Fixed: Doctrine Proxies are not initialized (leads to empty customer/project)
- Fixed: tag creation
- Fixed: validation errors do not need to be logged in prod
- Removed: Customer VCard download, as used library is outdated and not maintained
- Added: supporting translations domains in many new places (menu, help_text, page_setup, report, exporter, calendar)
2023-03-05 03:08:43 +01:00
Kevin Papst
3b93afabc8 Revert "bump packages"
This reverts commit d03fbf0ef9.
2023-03-02 15:15:01 +01:00
Kevin Papst
d03fbf0ef9 bump packages 2023-03-02 15:10:23 +01:00
Weblate (bot)
5c473ad39b Translated using Weblate (#3882)
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Felipe Nogueira <contato.fnog@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Ondřej Mach <machondra2003@gmail.com>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: tygyh <jonis9898@hotmail.com>
2023-03-02 14:22:19 +01:00
Kevin Papst
3f09a2674b Release 2.0.4 (#3883)
* fix column data truncated
* calculate internal rate from user
* show internal rate in timesheet listing
* Fixed: responsivenss and size of report start page icons
* fix: name display in dropdowns (and added tests)
* translate reload button
* fix invoice date might be in the past
* fail safe customer name handling
* translate invoice_date and invoice_date help
* prevent URLs like start=null
* prevent to reload select twice
2023-03-02 14:04:06 +01:00
Kevin Papst
a8b972f8a5 added permission caching (#3877) 2023-02-25 20:57:48 +01:00
Weblate (bot)
3c28288cac Translated using Weblate (#3867)
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Noemi <mikrometer-gearbeitet-0v@icloud.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Sergii Horichenko <m@sgg.im>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2023-02-25 20:49:01 +01:00
Kevin Papst
2cb29bfef5 Release 2.0.3 (#3879) 2023-02-25 20:37:52 +01:00
Kevin Papst
068e9425eb added action to download invoice document (#3878) 2023-02-25 19:23:45 +01:00
Kevin Papst
a9849fc6cf added action to reload twig invoice template (#3876) 2023-02-25 19:10:29 +01:00
Kevin Papst
266c4bad25 Cleanup after 2.0 (#3868)
* removed duration_only mode
* cleanup database
* remove deleted user preference keys
2023-02-22 15:06:54 +01:00
Weblate (bot)
f04e0d92aa Translations update from Hosted Weblate (#3863)
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Sergii Horichenko <m@sgg.im>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
2023-02-22 12:47:13 +01:00
Kevin Papst
cca3fa6b8a Improve inline stats (#3865)
* deactivate timesheet stats if no filter was chosen (otherwise a full table scan would be triggered for each listing display)
* hide duration stat if duration = 0 (timesheet, invoice, export)
2023-02-22 11:46:58 +01:00
Kevin Papst
1bc1fadc56 Move recent activities to modal (#3864)
* automatically remove deleted timesheets from bookmarks
2023-02-22 01:45:40 +01:00
Weblate (bot)
e7eb89dfd9 Translated using Weblate (#3830)
Co-authored-by: Anders Johansson <johansson@aljmedia.se>
Co-authored-by: Lars Vogdt <lars.vogdt@suse.com>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: jhtm <jhtm@users.noreply.hosted.weblate.org>
Co-authored-by: sandronidi <sandro.niederhauser@gmail.com>
2023-02-21 19:36:46 +01:00
Kevin Papst
25469113fd 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
2023-02-21 19:21:49 +01:00
Kevin Papst
e474087257 Version 2.0.1 (#3853)
* configure email validation mode to fix deprecation message
* allow to use non brand icon in saml provider
* new method getCalculatedDuration()
* getRawData() by id
* only stop entries if new one is running
* fix validator tampering with timesheet duration
* fix allow setting null as customer
* bump packages
2023-02-18 14:19:16 +01:00
Kevin Papst
75aea7c51b added incompatible-plugins sentence 2023-02-15 00:35:38 +01:00
Kevin Papst
a64b44a74b simplify docs and cleanup links 2023-02-15 00:34:58 +01:00
Kevin Papst
d481f68266 remove user registration settings (#3832)
* can be re-activated through kimai.yaml
2023-02-07 19:36:10 +01:00
Kevin Papst
8095ae298f 2.0 RC 2 (#3825)
* fix menu highlight (invoice sub-pages)
* move calendar drag & drop boxes to right
* bump composer packages and install rate-limiter
* added login throttling
2023-02-07 01:01:15 +01:00
Weblate (bot)
99ad182358 Translated using Weblate (#3820)
Co-authored-by: Anders Johansson <johansson@aljmedia.se>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Pierre QUILLERY <pierre@quillery.fr>
Co-authored-by: ssantos <ssantos@web.de>
2023-02-06 18:48:18 +01:00
Weblate (bot)
f32448b9f5 Translated using Weblate (#3819)
Co-authored-by: Anders Johansson <johansson@aljmedia.se>
2023-02-05 20:14:28 +01:00
Weblate (bot)
f3b4078c6a Translated using Weblate (#3803)
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Massimo Pissarello <mapi68@gmail.com>
Co-authored-by: Roya K <royakhajavi@gmail.com>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: gnu-ewm <gnu.ewm@protonmail.com>
2023-02-05 20:07:12 +01:00
Kevin Papst
ca846b5fbf 2.0 RC 1 - new ConfigurationService (#3810)
* use html5 email validation
* remove static cache seed, for compatibility with non default (file based) caches
* added caching ConfigurationService, removed use of doctrine result cache
* simplify configuration API
2023-02-05 19:51:08 +01:00
Kevin Papst
63a3ae1147 2.0 release candidate (#3808)
* use SAML interface instead of implementation
* moved implementation of SAML configs to system-configuration base class
* bump composer packages
* simplify configuration for different env
2023-02-02 00:45:50 +01:00
Weblate (bot)
5711c15eac Translated using Weblate (#3800)
Co-authored-by: Dan <denqwerta@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
2023-01-27 23:44:43 +01:00
Kevin Papst
a705703996 cleanup translation keys 2023-01-27 00:58:07 +01:00
Kevin Papst
326dc64f65 2.0 beta 3 (#3786)
* added id for custom js options
* readme
* composer update
* fix migration filename
2023-01-27 00:50:04 +01:00
Kevin Papst
974e1b3b5a cleanup translation keys 2023-01-27 00:44:26 +01:00
Kevin Papst
f7f1765c2e cleanup translation keys 2023-01-27 00:14:17 +01:00
Kevin Papst
aae31c567c remove empty translation files 2023-01-26 23:28:27 +01:00
Hosted Weblate
49f307d605 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (345 of 345 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 51.3% (177 of 345 strings)

Translated using Weblate (Greek)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Faroese)

Currently translated at 71.3% (246 of 345 strings)

Translated using Weblate (Finnish)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Portuguese)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Turkish)

Currently translated at 99.7% (344 of 345 strings)

Translated using Weblate (Swedish)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Slovak)

Currently translated at 74.4% (257 of 345 strings)

Translated using Weblate (Russian)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Romanian)

Currently translated at 82.0% (283 of 345 strings)

Translated using Weblate (Polish)

Currently translated at 83.7% (289 of 345 strings)

Translated using Weblate (Dutch)

Currently translated at 77.3% (267 of 345 strings)

Translated using Weblate (Japanese)

Currently translated at 55.3% (191 of 345 strings)

Translated using Weblate (Hungarian)

Currently translated at 83.7% (289 of 345 strings)

Translated using Weblate (Basque)

Currently translated at 68.9% (238 of 345 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (345 of 345 strings)

Translated using Weblate (Esperanto)

Currently translated at 81.7% (282 of 345 strings)

Translated using Weblate (German (Switzerland))

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Danish)

Currently translated at 64.0% (221 of 345 strings)

Translated using Weblate (Czech)

Currently translated at 82.0% (283 of 345 strings)

Translated using Weblate (English)

Currently translated at 100.0% (345 of 345 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (345 of 345 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 51.0% (176 of 345 strings)

Translated using Weblate (Greek)

Currently translated at 81.7% (282 of 345 strings)

Translated using Weblate (Faroese)

Currently translated at 70.7% (244 of 345 strings)

Translated using Weblate (Finnish)

Currently translated at 81.7% (282 of 345 strings)

Translated using Weblate (Portuguese)

Currently translated at 82.0% (283 of 345 strings)

Translated using Weblate (Turkish)

Currently translated at 99.4% (343 of 345 strings)

Translated using Weblate (Swedish)

Currently translated at 82.0% (283 of 345 strings)

Translated using Weblate (Slovak)

Currently translated at 74.2% (256 of 345 strings)

Translated using Weblate (Russian)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Polish)

Currently translated at 83.1% (287 of 345 strings)

Translated using Weblate (Japanese)

Currently translated at 54.7% (189 of 345 strings)

Translated using Weblate (Italian)

Currently translated at 81.7% (282 of 345 strings)

Translated using Weblate (Hungarian)

Currently translated at 83.7% (289 of 345 strings)

Translated using Weblate (Basque)

Currently translated at 68.6% (237 of 345 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (345 of 345 strings)

Translated using Weblate (Esperanto)

Currently translated at 81.1% (280 of 345 strings)

Translated using Weblate (German (Switzerland))

Currently translated at 81.7% (282 of 345 strings)

Translated using Weblate (Danish)

Currently translated at 63.7% (220 of 345 strings)

Translated using Weblate (Czech)

Currently translated at 81.7% (282 of 345 strings)

Translated using Weblate (English)

Currently translated at 100.0% (345 of 345 strings)

Translated using Weblate (German (Switzerland))

Currently translated at 3.5% (1 of 28 strings)

Translated using Weblate (Faroese)

Currently translated at 46.4% (13 of 28 strings)

Translated using Weblate (Portuguese)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Greek)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (28 of 28 strings)

Translated using Weblate (Swedish)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Slovak)

Currently translated at 82.1% (23 of 28 strings)

Translated using Weblate (Romanian)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (28 of 28 strings)

Translated using Weblate (Italian)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Hungarian)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Basque)

Currently translated at 82.1% (23 of 28 strings)

Translated using Weblate (Esperanto)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Czech)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Finnish)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (German (Switzerland))

Currently translated at 0.0% (0 of 28 strings)

Translated using Weblate (Faroese)

Currently translated at 42.8% (12 of 28 strings)

Translated using Weblate (Portuguese)

Currently translated at 85.7% (24 of 28 strings)

Translated using Weblate (Greek)

Currently translated at 85.7% (24 of 28 strings)

Translated using Weblate (Finnish)

Currently translated at 85.7% (24 of 28 strings)

Translated using Weblate (Turkish)

Currently translated at 96.4% (27 of 28 strings)

Translated using Weblate (Swedish)

Currently translated at 85.7% (24 of 28 strings)

Translated using Weblate (Slovak)

Currently translated at 78.5% (22 of 28 strings)

Translated using Weblate (Romanian)

Currently translated at 85.7% (24 of 28 strings)

Translated using Weblate (Polish)

Currently translated at 96.4% (27 of 28 strings)

Translated using Weblate (Hungarian)

Currently translated at 85.7% (24 of 28 strings)

Translated using Weblate (Basque)

Currently translated at 78.5% (22 of 28 strings)

Translated using Weblate (Esperanto)

Currently translated at 85.7% (24 of 28 strings)

Translated using Weblate (Czech)

Currently translated at 85.7% (24 of 28 strings)

Translated using Weblate (Hungarian)

Currently translated at 83.7% (289 of 345 strings)

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (German (Switzerland))

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Slovak)

Added translation using Weblate (Korean)

Added translation using Weblate (Faroese)

Added translation using Weblate (Finnish)

Added translation using Weblate (Swedish)

Added translation using Weblate (Dutch)

Added translation using Weblate (Arabic)

Added translation using Weblate (Hungarian)

Added translation using Weblate (Vietnamese)

Added translation using Weblate (Portuguese)

Added translation using Weblate (Czech)

Added translation using Weblate (Japanese)

Added translation using Weblate (Romanian)

Added translation using Weblate (Russian)

Added translation using Weblate (Basque)

Added translation using Weblate (Esperanto)

Added translation using Weblate (Greek)

Added translation using Weblate (Danish)

Added translation using Weblate (Chinese (Traditional))

Translated using Weblate (Chinese (Traditional))

Currently translated at 51.3% (177 of 345 strings)

Translated using Weblate (German (Switzerland))

Currently translated at 0.0% (0 of 28 strings)

Translated using Weblate (Faroese)

Currently translated at 42.8% (12 of 28 strings)

Translated using Weblate (Portuguese)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Greek)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Greek)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Faroese)

Currently translated at 71.3% (246 of 345 strings)

Translated using Weblate (Finnish)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Finnish)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Portuguese)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (28 of 28 strings)

Translated using Weblate (Swedish)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Slovak)

Currently translated at 82.1% (23 of 28 strings)

Translated using Weblate (Romanian)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (28 of 28 strings)

Translated using Weblate (Dutch)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Hungarian)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Basque)

Currently translated at 82.1% (23 of 28 strings)

Translated using Weblate (Esperanto)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Danish)

Currently translated at 67.8% (19 of 28 strings)

Translated using Weblate (Czech)

Currently translated at 89.2% (25 of 28 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (345 of 345 strings)

Translated using Weblate (Swedish)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Slovak)

Currently translated at 74.7% (258 of 345 strings)

Translated using Weblate (Romanian)

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Polish)

Currently translated at 83.7% (289 of 345 strings)

Translated using Weblate (Dutch)

Currently translated at 77.6% (268 of 345 strings)

Translated using Weblate (Japanese)

Currently translated at 55.3% (191 of 345 strings)

Translated using Weblate (Hungarian)

Currently translated at 79.7% (275 of 345 strings)

Translated using Weblate (Basque)

Currently translated at 68.9% (238 of 345 strings)

Translated using Weblate (Esperanto)

Currently translated at 81.7% (282 of 345 strings)

Translated using Weblate (German (Switzerland))

Currently translated at 82.3% (284 of 345 strings)

Translated using Weblate (Danish)

Currently translated at 64.0% (221 of 345 strings)

Translated using Weblate (Czech)

Currently translated at 82.3% (284 of 345 strings)

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Chinese (Traditional))

Added translation using Weblate (Chinese (Traditional))

Translated using Weblate (Arabic)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Arabic)

Currently translated at 88.4% (23 of 26 strings)

Translated using Weblate (Arabic)

Currently translated at 94.2% (325 of 345 strings)

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: ButterflyOfFire <ButterflyOfFire@protonmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Kis Momesz <kismomesz@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/cs/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/da/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/de_CH/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/el/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/eo/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/eu/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/fi/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/fo/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/hu/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/it/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/nl/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/pl/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/pt/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/ro/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/sk/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/sv/
Translate-URL: https://hosted.weblate.org/projects/kimai/actions/tr/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/ar/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/cs/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/da/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/de_CH/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/el/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/en/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/eo/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/es/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/eu/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/fi/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/fo/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/hu/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/it/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/ja/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/nl/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/pl/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/pt/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/ro/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/ru/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/sk/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/sv/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/tr/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/uk/
Translate-URL: https://hosted.weblate.org/projects/kimai/messages/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/kimai/teams/ar/
Translate-URL: https://hosted.weblate.org/projects/kimai/validations/ar/
Translation: Kimai - Time tracking/Actions (Dropdowns and Toolbars)
Translation: Kimai - Time tracking/Main application
Translation: Kimai - Time tracking/Teams
Translation: Kimai - Time tracking/Validations
2023-01-26 23:20:18 +01:00
Weblate (bot)
f93d081a88 Translated using Weblate (#3784)
Co-authored-by: ButterflyOfFire <ButterflyOfFire@protonmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2023-01-25 17:59:54 +01:00
Kevin Papst
a230be77dd beta 3 (#3780)
* merge master - allow to upload twig invoice templates via UI
* support adding existing teams with same name
* permissions cannot be set right after role was created - fixes #3777
* allow to deactivate unique customer number validation - fixes #3762 
* invalid message when trying to edit locked or exported timesheets in calendar - fixes #3766
* updated icons and manifest - fixes #3761
2023-01-21 14:49:55 +01:00
Weblate (bot)
b62253e1f3 Translated using Weblate (#3760)
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: gnu-ewm <gnu.ewm@protonmail.com>
2023-01-18 14:59:45 +01:00
Kevin Papst
0e91dd886e release 2.0 beta 2 (#3757)
* do not traverse into invoice template subdirectories (#3735)
* fix security open api definition
* fix currency can be null, removed fluent interface
* merged release 1.30.3
* allow to pre-fill timesheet metafields via URL
* fix api description
* added test accounts with simpler names and password
* upgrade to Symfony 6.2
* removed FrameworkExtraBundle (by Sensio) and replaced with new native SF annotations
* fixed symfony 6.2 deprecations
* fixed #3768
2023-01-18 14:47:48 +01:00
Kevin Papst
6e0500972e fix bug report template 2023-01-12 21:32:44 +01:00
Kevin Papst
8069e332fe release 2.0 beta (#3722)
* remove twitter link
* remove WIP file
* adjust release draft message
* reset code coverage threshold back to 0.5
* changed wordings
* re-activate wizard for fixture accounts
* fix repo url and license
* license identifier
* bump version
* moved Kimai 1 import command from core to plugin
* do not traverse into invoice template subdirectories (#3735)
* fix branch alias
* composer update
* switch language on wizard select
* new twig function to create qr code
* fix daily stats in timesheet listing
* improved html invoice templates
2023-01-12 12:10:11 +01:00
Weblate (bot)
cbd65f1f1d Translated using Weblate (#3723)
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Dan <denqwerta@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Magdalena Turek <magdalena.2rek@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Sergii Horichenko <m@sgg.im>
Co-authored-by: Sima Teimourianmotlagh <simateimourian@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: gnu-ewm <gnu.ewm@protonmail.com>
Co-authored-by: h <tachyglossues@gmail.com>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2023-01-12 01:43:58 +01:00
Kevin Papst
90a0fd8a22 Next major version 2 with PHP 8.1, Symfony 6, Tabler UI, 2FA ... (#2902) 2022-12-31 21:19:55 +01:00
Weblate (bot)
95e06746bd Translated using Weblate (#3705)
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2022-12-28 15:47:57 +01:00
Kevin Papst
1e492624cc fixed owner name 2022-12-26 17:27:25 +01:00
Kevin Papst
6a524f9f7c changed repository url (#3708) 2022-12-26 17:09:07 +01:00
Weblate (bot)
84cc65b008 Translated using Weblate (#3655)
Co-authored-by: Jonas Tisell <jonas.tisell@live.no>
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2022-12-17 01:43:45 +01:00
Kevin Papst
b8b3a3c8ab fix find activity for project (#3681) 2022-12-07 22:42:02 +01:00
Kevin Papst
db0e555eae weekly timesheet uses automatic billable mode, auto responsiveness (#3679) 2022-12-07 18:44:17 +01:00
Kevin Papst
58a9facc6d Release 1.30 (#3651)
* exclude all 403 and 404 from logs
* bump version
* cleanup tag handling
* prevent mandatory user preferences turning null
2022-12-04 15:02:36 +01:00
Kevin Papst
11dac19c8c added mastodon link 2022-11-25 20:45:29 +01:00
Weblate (bot)
2d82f0400d Translated using Weblate (#3649)
Co-authored-by: Teng You Jyun <youjyun0728@gmail.com>
2022-11-24 14:37:52 +01:00
Kevin Papst
94a6b99c57 fix php 8.1 deprecations (#3648)
* show session maxlifetime in doctor
* rephrase compatibility in release notes
* bump version
2022-11-24 13:12:18 +01:00
Pieter Frenssen
2aa5eccc7c Add accessibility attributes to sortable table headers. (#3647) 2022-11-23 11:36:57 +01:00
Weblate (bot)
52f5e5640e Translated using Weblate (#3628)
Co-authored-by: BeckeBauer <berko@gmx.de>
Co-authored-by: Sergii Horichenko <m@sgg.im>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
2022-11-21 21:17:02 +01:00
Kevin Papst
d6c15bb1cb respect project start and end dates in quick-entry form (#3642) 2022-11-21 19:07:33 +01:00
Kevin Papst
4f698f73dc added username parameter to export command (#3638) 2022-11-19 18:38:13 +01:00
Kevin Papst
e413325337 added project + customer setting for calendar entry titles (#3636) 2022-11-16 23:02:26 +01:00
Kevin Papst
608a45408a Release 1.29 (#3622) 2022-11-06 20:44:30 +01:00
Weblate (bot)
323baa2d65 Translations update from Hosted Weblate (#3607)
Co-authored-by: Laurens Wuyts <laurens@mapix.be>
Co-authored-by: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
Co-authored-by: MohammadReza Baeedi (M.R.B) <mohammadreza.baeedi@gmail.com>
Co-authored-by: Sergii Horichenko <m@sgg.im>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
2022-11-06 19:54:22 +01:00
Kevin Papst
6235d18dab improve user unique check (#3621) 2022-11-06 14:15:21 +01:00
Kevin Papst
3d0f480d9e added missing permission check on project rates in monthly report (#3627) 2022-11-05 11:39:18 +01:00
Kevin Papst
642d31432a bump dependencies and improved export command (#3606) 2022-10-30 11:34:17 +01:00
Weblate (bot)
421be6835e Translated using Weblate (#3586)
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Bogi Napoleon Wennerstrøm <bogi.wennerstrom@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: MohammadReza Baeedi (M.R.B) <mohammadreza.baeedi@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Sergii Horichenko <m@sgg.im>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: gnu-ewm <gnu.ewm@protonmail.com>
Co-authored-by: yangyangdaji <1504305527@qq.com>
Co-authored-by: Мистер Перевод <sergei@racingrebel.com>
2022-10-29 18:23:28 +02:00
Kevin Papst
d58720252e create exports via command (#3605) 2022-10-29 18:20:19 +02:00
Kevin Papst
0461539f4b new stateless firewall to prevent new sessions for API calls (#3602) 2022-10-28 15:13:40 +02:00
Kevin Papst
78749ad3b4 copy teams from logged-in user for new projects (#3599) 2022-10-25 16:31:34 +02:00
Kevin Papst
8b4828f236 allow 4 decimals for rounded rates (#3596) 2022-10-24 16:21:57 +02:00
Kevin Papst
e5614b92a0 fix test 2022-10-24 11:59:05 +02:00
Kevin Papst
f5b725e32b added first and last fields for invoices (#3594) 2022-10-24 11:46:13 +02:00
Kevin Papst
006de60f66 Release 1.28 (#3587)
* bump version
* extract toolbar cleanup logic to helper class
* allow 3 digits in invoice template tax rate
2022-10-24 11:42:56 +02:00
Kevin Papst
14f4530de0 added team filter in timesheet search forms (#3590)
* added team filter in export and invoice search form
* added teams select to timesheet filter
* added team select to report filter
* hide user and team filter if count < 2
2022-10-21 16:14:39 +02:00
Kevin Papst
2022fa54d3 added customer name as pattern option in project dropdown (#3589) 2022-10-21 15:26:53 +02:00
Kevin Papst
73ef090b9e fix several rendering issues in markdown (#3588)
- fix double escaping of html entities: &quot; instead of "
- fix table is missing css class "table"
- fix quotes are not rendered
2022-10-19 21:17:49 +02:00
Kevin Papst
6d7054c18c Release 1.27.0 (#3571)
* bump version
* ignore .disabled for plugins
* simplify gitignore
* prevent duration field from showing up in the API
* change release template wording
* prepare method for later usage
* add 8.2 to issue template
2022-10-19 08:55:42 +02:00
Weblate (bot)
4549d826dd Translations update from Hosted Weblate (#3570)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Sergii Horichenko <m@sgg.im>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: gnu-ewm <gnu.ewm@protonmail.com>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2022-10-19 08:44:42 +02:00
Kevin Papst
7eacb1dc3c improved issue templates 2022-10-19 01:00:22 +02:00
Kevin Papst
5264dd111d fix markdown 2022-10-19 00:13:32 +02:00
Kevin Papst
a4f0b6a97e fix markdown 2022-10-19 00:12:48 +02:00
Kevin Papst
46af5e8ebf fix markdown 2022-10-19 00:12:19 +02:00
Kevin Papst
35fb15fe9f fix filename 2022-10-19 00:08:56 +02:00
Kevin Papst
662259468d improve issue templates 2022-10-18 23:42:16 +02:00
Kevin Papst
1e1b9a6919 allow to order by hourlyRate (#3582) 2022-10-16 12:01:57 +02:00
Kevin Papst
5fa10dfdf1 fix one-minute rounding bug in quick-entries (#3580)
* fix one-minute rounding bug for quick entries form
* allow to delete and create/update timesheets in one go
* prevent issues with negative durations
2022-10-16 01:05:38 +02:00
Kevin Papst
a5556a0c63 do not show potential invoices with a negative total (#3579) 2022-10-13 12:29:11 +02:00
Kevin Papst
0cefcf0e16 allow negative duration via internal API (#3573) 2022-10-10 17:47:11 +02:00
Kevin Papst
1959d4d8df added filter for globalActivities in project collection (#3565) 2022-10-01 23:25:33 +02:00
Kevin Papst
1d445d9eb6 Project API and globalActivities flag (#3564)
* expose globalActivities setting in project entity
* fix globalActivities being true by default if created via API
2022-10-01 18:14:22 +02:00
Weblate (bot)
6cfcbccabc Translated using Weblate (#3549)
Co-authored-by: Daniel <danchao@freedom.net.tw>
Co-authored-by: Eric <hamburger1024@mailbox.org>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Nguyễn Hoàng Minh <mingu03@yandex.com>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: SHINJI.K <shinkuroshi@gmail.com>
Co-authored-by: adam Petro <grimnoobster@gmail.com>
Co-authored-by: office256 <ohofman@seznam.cz>
Co-authored-by: power meshal <powermeshal@gmail.com>
Co-authored-by: Мистер Перевод <sergei@racingrebel.com>
Co-authored-by: 이정희 <daemul72@gmail.com>
2022-10-01 17:40:42 +02:00
Kevin Papst
de39623378 prepare release 1.26.0 (#3554)
* bump version
* suppress deprecation
* composer update to fix twig security issue
* make sure to use the same timezone in all test runs
2022-10-01 17:23:15 +02:00
Kevin Papst
96d0d4943b update composer packages (#3502)
drop full database schema in test
2022-09-25 17:06:49 +02:00
Kevin Papst
bfab6f42d0 use saml config interface instead of generic system configuration (#3551) 2022-09-23 13:29:46 +02:00
Weblate (bot)
b38fc96623 Translated using Weblate (#3542)
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Maamon AlHaqli <mamon321@hotmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nguyễn Hoàng Minh <mingu03@yandex.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: skotperez <skotperez@voragine.net>
2022-09-20 15:53:32 +02:00
Kevin Papst
b7bade20ea make project and customer available in summaries (#3543) 2022-09-16 13:57:03 +02:00
Kevin Papst
283ab80fc7 configurable calendar drag and drop behavior (#3537) 2022-09-14 23:29:26 +02:00
Kevin Papst
d705287510 prepare release 1.25.0 (#3531)
* remove unused variable
* allow to set field name in form helper
* fix edge case permission check in menu
2022-09-14 15:16:06 +02:00
Weblate (bot)
47d17af593 Translated using Weblate (#3532)
Co-authored-by: Nguyễn Hoàng Minh <mingu03@yandex.com>
Co-authored-by: phande <phanwiki@gmail.com>
Co-authored-by: skotperez <skotperez@voragine.net>
2022-09-14 14:43:35 +02:00
Kevin Papst
496a74f7a3 added keyboard shortcuts (#3536) 2022-09-14 14:30:15 +02:00
Kevin Papst
7eded6e126 fix resname 2022-09-08 18:08:42 +02:00
Weblate (bot)
4c9d3222d7 Translated using Weblate (#3523)
Co-authored-by: Daniel <danchao@freedom.net.tw>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jordy Heutinck <jordyheutinck@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
2022-09-08 18:02:10 +02:00
Kevin Papst
5a2b539003 version 1.24.0 (#3515) 2022-09-04 23:55:52 +02:00
Weblate (bot)
a9252701c5 Translated using Weblate (Faroese) (#3496) 2022-09-04 23:18:18 +02:00
Alexander Pankow
2fbbbe7260 added inline disposition for PDF previews (#3486) 2022-09-04 12:15:47 +02:00
Alexander Pankow
1d1f5835da allow to hide tax rows in invoice templates if vat rate is zero (#3484) 2022-09-04 11:43:38 +02:00
Alexander Pankow
a04b72e866 use custom fonts in mpdf via twig template (#3509) 2022-09-04 00:58:54 +02:00
Kevin Papst
3f4f63dc33 fix datetime modify to now (#3511) 2022-09-03 01:11:48 +02:00
Jelle Sebreghts
1763a2efff fix grace period in quick-entry form (#3504) 2022-09-03 00:49:16 +02:00
Kevin Papst
00906851b5 bump version to 1.23.1 (#3499) 2022-09-01 13:15:17 +02:00
Kevin Papst
844a805de6 fix unit test failing on month borders (#3494) 2022-08-31 15:12:18 +02:00
Kevin Papst
718e0b5c1e prevent accidental invoice template updates (#3493) 2022-08-31 13:18:21 +02:00
Weblate (bot)
ad20fd1c64 Translated using Weblate (#3482)
Co-authored-by: Cường Bá <cuongba956@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: SDGArmenia <webadmin@armstat.am>
Co-authored-by: Tom Sawyer <weblate@grymkoll.se>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2022-08-30 18:02:44 +02:00
Kevin Papst
0eb5c0a08a fixed multiple budget validation checks (#3489)
* fix budget check for monthly budgets for records with a changed month
* fix API update of begin and end
* fix update of project and activity
2022-08-29 01:03:44 +02:00
Kevin Papst
7c3a08057d Order quick entries by project name (#3488) 2022-08-27 17:11:48 +02:00
Weblate (bot)
c3a43fe677 Translated using Weblate (#3462)
Co-authored-by: Ahmed Saleh <sniperasa8@gmail.com>
Co-authored-by: Alireza Mousavi <alrzmsv@gmail.com>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Jiri Nakola <github@nakola.fi>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: yangyangdaji <1504305527@qq.com>
2022-08-18 14:28:35 +02:00
Kevin Papst
1c613d0a52 do not require user_preference permission when creating new user (#3474) 2022-08-16 21:13:26 +02:00
Kevin Papst
303ec5be11 bump composer packages for version 1.22.1 (#3455) 2022-08-01 18:56:48 +02:00
Kevin Papst
0e33da7760 fix invoice preview opening in current tab (#3454) 2022-08-01 18:09:41 +02:00
Kevin Papst
64c752bea3 disable create-invoice links after click to prevent double invoices (#3452) 2022-08-01 14:45:22 +02:00
Weblate (bot)
cb2938b5c2 Translations update from Hosted Weblate (#3436)
Co-authored-by: ID-86 <id86dev@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jan Čejka <posta@jancejka.cz>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nubovik <babushkin.nikita.2008@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: andt <andywondering@protonmail.com>
2022-08-01 14:44:52 +02:00
Kevin Papst
1b8a26d36b rebuild assets for croatian (#3451) 2022-08-01 14:14:17 +02:00
Milo Ivir
afdcc88342 added javascript translations for croatian (#3447) 2022-08-01 13:57:54 +02:00
Kevin Papst
7238f404f7 technical debts (#3438)
* reformat release notes
* deactivate transactions in migrations by default
* fix migration base class
* fix default value
* composer update
2022-07-27 00:54:43 +02:00
Kevin Papst
1b8948a086 show total hourly rate in detail pages (#3441) 2022-07-27 00:52:10 +02:00
Kevin Papst
95ab9bda2d saml: allow to keep existing roles on login (#3440) 2022-07-26 23:18:04 +02:00
Kevin Papst
ed7f89cfe1 allow to restrict usage of global activities for projects (#3437) 2022-07-23 01:17:24 +02:00
Kevin Papst
8d695d03df link customer, project and activity in invoice listing (#3428) 2022-07-22 13:26:17 +02:00
Kevin Papst
ad880b5b97 bump version 1.22 (#3429)
* adjusted release note template
* stabilize test
* deactivate audit listener, more pre-validation for kimai 1 importer
2022-07-22 12:41:49 +02:00
Kevin Papst
c0f3f31095 total sums for duration and rate in invoice and export preview (#3431) 2022-07-22 12:39:50 +02:00
Kevin Papst
e2ac6a0b17 Project date-range report: allow budget-type independent project-listing (#3430) 2022-07-22 12:27:53 +02:00
Kevin Papst
0dba83d8e9 Budget graph in project details (#3406)
* do not copy description if restarting via calendar
* added support to display negative durations
* fix charts for larger numbers
2022-07-13 17:21:36 +02:00
Weblate (bot)
245dd47082 Translated using Weblate (Polish) (#3399)
Co-authored-by: Alejandro Malo <malo@pinion.education>
Co-authored-by: Anupam Malhotra <anpm.malhotra@gmail.com>
Co-authored-by: DNSE <kty5663@gmail.com>
Co-authored-by: Jiri Nakola <github@nakola.fi>
Co-authored-by: Jozef Cibík <jozef.cibik@fatchillimedia.com>
Co-authored-by: KonradMazur <konrad@mazur.legal>
2022-07-13 17:15:00 +02:00
Kevin Papst
dc40a05ebd allow to filter for canceled invoices (#3415) 2022-07-13 12:21:57 +02:00
Kevin Papst
0616506b31 re-style overlapping border (#3400) 2022-07-05 20:23:10 +02:00
Kevin Papst
196ca4f1cb new command to delete empty translations (#3392)
* composer update and phpstan issues
* bump version
2022-06-30 14:19:56 +02:00
Weblate (bot)
2d9677eefa Translations update (#3356)
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: haoyubox <3306221756@qq.com>
Co-authored-by: phlostically <phlostically@mailinator.com>
Co-authored-by: whisley.wang <whisley.wang@amsrbt.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2022-06-30 14:05:18 +02:00
Kevin Papst
cd297150ea suppress deprecation notice, convert route param (#3391) 2022-06-30 12:14:01 +02:00
Kevin Papst
665f0d0ca7 require a language for invoice templates (#3387) 2022-06-27 22:57:15 +02:00
Kevin Papst
bd1097f7b5 fix en_GB format definition (#3383) 2022-06-27 22:37:31 +02:00
Kevin Papst
f30bb89597 remove currency symbol if unknown (#3381) 2022-06-25 01:23:16 +02:00
Kevin Papst
9f1f7b989c allow to set api token when creating user via API (#3380) 2022-06-25 00:26:39 +02:00
Kevin Papst
aa8549b633 reoad permissions page after role was created (#3377) 2022-06-24 16:57:59 +02:00
Kevin Papst
222056f973 removed invalid destroy calls to daterangepicker (#3371) 2022-06-23 01:59:09 +02:00
Kevin Papst
e431a1ad9e Export invoice metafields (#3366) 2022-06-21 14:06:23 +02:00
Kevin Papst
452cc46d67 fix original filenames for translations (#3363) 2022-06-19 18:01:08 +02:00
Kevin Papst
c956d075d9 added release drafter workflow (#3362) 2022-06-19 17:42:09 +02:00
Kevin Papst
cdf5a545eb fix calendar drag and drop for regular user (#3358) 2022-06-14 13:07:57 +02:00
Weblate (bot)
a60df65062 Translations update from Weblate (#3339)
* Translated using Weblate (Croatian)
Co-authored-by: ABDULLAH MOHAMMED ALMONTSHRI <acc302@gmail.com>
Co-authored-by: Bogi Napoleon Wennerstrøm <bogi.wennerstrom@gmail.com>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jiri Nakola <github@nakola.fi>
Co-authored-by: Luiz Carlos Lucasv <csversut@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: majorwave <majorwavebeats@gmail.com>
2022-06-11 13:53:10 +02:00
Kevin Papst
f8cb8900d6 Release 1.20.3 (#3340)
* fix edit timesheet link
* fix drag & drop creates record for wrong user
* fix search with multiple bindings
* hide user switcher in calendar if there is only one user to choose
* make quick entry responsive for mobile-only users
* mark invoices as exported by default
* fix serialization deprecation warning
* fix duration calculation for fixed rate entries
* updated composer packages
* fix checkbox for horizontal forms
* support pdfContext for PDF invoice templates
2022-06-11 13:25:50 +02:00
Kevin Papst
b46fdcefad added new permission to separate time and money budget (#3352) 2022-06-11 12:23:02 +02:00
Kevin Papst
3f827b3104 code cleanup (#3338) 2022-05-31 18:08:41 +02:00
Kevin Papst
88bf534573 added invoice text field to project and activity (#3335) 2022-05-31 17:49:23 +02:00
Weblate (bot)
a93e78bd34 Translated using Weblate (Norwegian Bokmål) (#3329)
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2022-05-31 17:41:30 +02:00
Kevin Papst
4eb1fffeb2 added meta-field names to listing pages as css classes (#3336) 2022-05-31 17:38:53 +02:00
Kevin Papst
889e3c0d4a pre-select an option if it is the only available one (#3337) 2022-05-31 17:38:21 +02:00
Andreas Pollak
184026f5f1 added css class for custom fields (#3328) 2022-05-26 17:11:02 +02:00
Weblate (bot)
3c14fee36c Translated using Weblate (#3321)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2022-05-26 14:08:09 +02:00
Kevin Papst
5fb326db4d Release 1.20.2 (#3320) 2022-05-24 16:28:14 +02:00
Kevin Papst
d5f8655827 Release 1.20.1 (#3317)
- improved timesheet calculator with changesets and priority
- calculate and include exported stats (e.g. available in export templates)
- added hourly rate column to timesheet listing
2022-05-21 13:13:56 +02:00
Kevin Papst
3e6100f368 bump version to 1.20 (#3315) 2022-05-19 01:36:12 +02:00
Kevin Papst
3c71640547 allow switching user displayed in calendar (#3314) 2022-05-18 21:30:58 +02:00
Kevin Papst
913839727c permission check for mark-as-exported buttons (#3313) 2022-05-18 12:54:59 +02:00
Kevin Papst
9e2a295182 Release 1.19.8 (#3296)
* unify extension check
* fix updating one config section redirects to all sections
* weekly times: configure number of weeks for recent activities
* weekly times: configure minimum number of rows
* added explicit formats for en_GB and pt
2022-05-17 11:52:45 +02:00
Lukas Steinmann
27c60d9fc4 Prevent bookings with same start / stop time (#3304) 2022-05-17 11:12:08 +02:00
Weblate (bot)
f409ce5364 Translated using Weblate (#3310)
Co-authored-by: SHINJI.K <shinkuroshi@gmail.com>
Co-authored-by: poog <poogchamp@gmail.com>
2022-05-17 10:36:20 +02:00
Weblate (bot)
68cd879d1e Translated using Weblate (Portuguese) (#3276)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
2022-05-08 22:27:48 +02:00
Kevin Papst
c8098b2e00 Release 1.19.7 (#3286)
* fix isWeekend() test for sunday fdow
* re-use the pattern for optgroup title
* prevent method on null
* composer update
* pre-select an option if it is the only available one
* added command to stop all active timesheets
2022-05-07 23:47:32 +02:00
Kevin Papst
100f8a5165 Release 1.19.6 (#3277) 2022-04-29 18:14:12 +02:00
Kevin Papst
76899d2fdb Release 1.19.5 (#3265) 2022-04-26 18:48:43 +02:00
j0hannesr0th
41e8e196ec fix: billable not respected in api post request (#3275) 2022-04-26 17:46:44 +02:00
Kevin Papst
ef5977bcfe allow changing calendar entry title (#3272) 2022-04-25 18:18:48 +02:00
Weblate (bot)
e94d47bf0f Translations update from Hosted Weblate (#3267)
Co-authored-by: SHINJI.K <shinkuroshi@gmail.com>
Co-authored-by: Tamás Papp <tamas.papp.it@gmail.com>
Co-authored-by: xiexieqing <xqmayone@outlook.com>
2022-04-25 16:59:55 +02:00
Weblate (bot)
f8bbb3065c Translated using Weblate (#3263)
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: adam Petro <grimnoobster@gmail.com>
Co-authored-by: dkstiler <dkstiler@gmail.com>
2022-04-19 13:12:44 +02:00
Kevin Papst
bc908b4534 Release 1.19.4 (#3255)
* login redirects to homepage if already being logged-in
* fix budget check for entries that were moved to another moth
* invoice: fix amount should be decimal if decimal template is used
* added new month grouped by project/activity/user report
2022-04-18 12:41:45 +02:00
Kevin Papst
a179719c3e version 1.19.3 (#3250) 2022-04-05 18:10:09 +02:00
Kevin Papst
2ca3a3f7db interface for saml config (#3249) 2022-04-05 17:49:41 +02:00
Kevin Papst
f2a8cf0930 Release 1.19.2 (#3244) 2022-04-05 00:59:13 +02:00
Weblate (bot)
966701f94e Translated using Weblate (#3235)
Co-authored-by: ANIGO R. (AR) <franigoyt@gmail.com>
Co-authored-by: leuedaniel <leuenberger.daniel@bluewin.ch>
2022-04-04 18:20:55 +02:00
Kevin Papst
1a183a4825 allow arbitrary string length for system configurations (#3243) 2022-04-04 17:38:50 +02:00
Kevin Papst
3a7e3b2168 bump version 1.19.1 (#3229) 2022-03-30 22:23:12 +02:00
Kevin Papst
eb2664ac79 support more complex metafield queries (#3228) 2022-03-30 19:01:22 +02:00
Kevin Papst
31743cf962 fix billable calculation on timesheet restart (#3225) 2022-03-29 23:24:22 +02:00
Kevin Papst
2c2ba2e32c show user account number in report export (#3224) 2022-03-29 12:48:42 +02:00
Weblate (bot)
4ff2153e15 Translated using Weblate (#3221)
Co-authored-by: ButterflyOfFire <ButterflyOfFire@protonmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Mzw <466271552@qq.com>
2022-03-29 12:31:35 +02:00
Kevin Papst
3c6b5c6c1e fix relative times in budget calculation in export (#3216) 2022-03-22 21:02:29 +01:00
Kevin Papst
6c1d79fe5b release 1.19 (#3215) 2022-03-21 23:42:56 +01:00
Weblate (bot)
e5f1df8c70 Translated using Weblate (#3208)
Co-authored-by: Gil <almontegil@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Taplou <ploutarchosgram@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: 이정희 <daemul72@gmail.com>
2022-03-21 21:32:46 +01:00
Kevin Papst
d6b59f6799 defensive javascript (#3210) 2022-03-20 21:08:59 +01:00
Kevin Papst
4b069edd33 added event to extend detail pages (#3209) 2022-03-19 23:54:40 +01:00
Kevin Papst
a8ac6b2eda Release 1.18.3 (#3204)
* fix truncated comments for customer, project and activity
* fix export button label for non-translated renderer
* fixed avatar size if image or SVG is used
* filter timesheets by billable state in API
2022-03-18 23:45:41 +01:00
Weblate (bot)
5c925f0ca5 Translated using Weblate (#3194)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Taplou <ploutarchosgram@gmail.com>
2022-03-18 23:25:22 +01:00
Kevin Papst
30c7782d6e automatic billable calculation (#3200) 2022-03-18 22:31:50 +01:00
Weblate (bot)
f7480902b4 Translated using Weblate (#3181)
Co-authored-by: ButterflyOfFire <ButterflyOfFire@protonmail.com>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Tiger <tigercrl@icloud.com>
2022-03-11 23:50:37 +01:00
Kevin Papst
00b5a65859 1.18.2 (#3190)
* improve console version output
* fix empty string issue in csv export (DDE protection) - fixes #3189
* fix twig sort deprecation in php 8
* sort user by displayName in users report
* fix missing custom translations in edit modal
* fix font-family in invoice.css
* invoice template "freelancer pdf" - added customer number, moved some fields around
* invoice template "default" - relocate customer number and order number in
2022-03-11 23:25:23 +01:00
Kevin Papst
317ac59f47 fix select2 and dropdown width for quick-entry form (#3188) 2022-03-07 14:22:16 +01:00
Kevin Papst
b08c156552 1.18.1 - fix description pattern in title (#3179)
* bump version
* add comment to customer/project/activity entity and collections api 
* improve title pattern usage
2022-02-28 16:32:41 +01:00
Weblate (bot)
2ad7629c2a Translations update from Hosted Weblate (#3177)
* fix broken files containing keys from messages namespace
* pre-fill missing translations with english
* new command to pre-fill empty translations
* fix locale in filename
* activate locales fa and nb_NO

Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2022-02-28 16:02:40 +01:00
Kevin Papst
42963ead5c switch to excel cell formats for report exports (#3178) 2022-02-27 13:36:52 +01:00
Kevin Papst
c0168ecc5b 1.18 (#3158)
* bump version
* fix translation ids
* added css classes to modify form with custom css
* improve export pdf file names
* respect financial year in new report
* added new InvoiceCalculator: price
* upgrade packages and node-sass to v7
* title pattern for customer, project and activity via API
* support negative money without currency
* fix sub-locale in print export template
* fix overbooking validation for monthly budget
* fix copying entities with different set of custom-fields compared to the current configuration
2022-02-25 20:41:56 +01:00
Weblate (bot)
34649d809e Translated using Weblate (Croatian) (#3174)
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
2022-02-25 20:40:16 +01:00
Weblate (bot)
ee0f6b0ccf Translations update from Hosted Weblate (#3171)
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
2022-02-25 15:30:37 +01:00
Kevin Papst
c8b47d1033 added explicit classes for widgets (#3170) 2022-02-22 21:15:19 +01:00
Weblate (bot)
3d3ae97af4 Translations update from Hosted Weblate (#3160)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
2022-02-22 13:29:48 +01:00
fredyb
d7066a2bbc support subtotal in filtered spreadsheet (#3166) 2022-02-22 13:29:03 +01:00
Weblate (bot)
7f8545f1dc Translations update from Hosted Weblate (#3105)
Co-authored-by: Miovio <mgrundemar@gmail.com>
Co-authored-by: ButterflyOfFire <ButterflyOfFire@protonmail.com>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2022-02-16 12:57:47 +01:00
Kevin Papst
85a63c4b78 new user-year reporting and data-type chooser (#3155) 2022-02-16 12:18:04 +01:00
Kevin Papst
1852d71974 export user-list reports in excel (#3154) 2022-02-14 17:55:10 +01:00
Kevin Papst
7da7468965 configure display of customer, project and activity in dropdown lists (#3151) 2022-02-14 17:43:05 +01:00
Kevin Papst
83a894823f release 1.17.2 (#3135)
* allow to input password interactively in console
* added block to simplify overwriting export template parts
* prevent installation in PHP 8.1
* composer update
* phpunit version to 9
* support negative amounts in excel export
* added system configuration actions for calendar, weekly timesheet, users
* added method to render text with full markdown support
2022-02-14 17:33:52 +01:00
Kevin Papst
4cb0ac37a6 unify access to custom fields (#3106) 2022-01-28 00:04:58 +01:00
Weblate (bot)
7a6fab8624 Translations update from Hosted Weblate (#3093)
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Bogi Napoleon Wennerstrøm <bogi.wennerstrom@gmail.com>
Co-authored-by: Oliver Darvishi <nimawm81@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
2022-01-25 14:07:30 +01:00
Kevin Papst
6416b67c63 fix admin access for customer in invoice module (#3095) 2022-01-25 14:06:09 +01:00
Kevin Papst
1e269a6f82 improve team member handling (#3097) 2022-01-25 13:44:49 +01:00
Kevin Papst
8694a3bfe4 added invoice delete event (#3096) 2022-01-24 21:33:13 +01:00
Kevin Papst
9e320674c1 phpstan improvements (#3092) 2022-01-23 15:49:38 +01:00
Kevin Papst
9047e9e785 optimize prod error messages (#3091) 2022-01-23 15:29:41 +01:00
Kevin Papst
b8d8f0c16d release 1.17 (#3090) 2022-01-23 01:33:00 +01:00
Kevin Papst
8b8e9b001e bump dependencies (#3089) 2022-01-22 17:11:30 +01:00
Weblate (bot)
9c40bd98aa Translations update from Hosted Weblate (#3048)
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: 黄煜祺 <QQBB18646265284@163.com>
Co-authored-by: Hibiki Kimura <h.kimura787@gmail.com>
Co-authored-by: 좀비때려잡아 <mickey9301@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2022-01-22 13:38:45 +01:00
Kevin Papst
1a0608f49e new export template (#3082) 2022-01-22 13:20:22 +01:00
Kevin Papst
3543e0a1b5 code improvements (#3088) 2022-01-22 02:46:02 +01:00
Kevin Papst
97c23f75dd improve permission handling for quick entry controller (#3081) 2022-01-20 22:24:19 +01:00
Kevin Papst
49bb9980b8 added invoice model to invoice created event (#3079)
* added model to InvoiceCreatedEvent
* allow to switch formatter locale
2022-01-20 18:41:55 +01:00
Kevin Papst
fd4cbb43c1 bugfixes (#3078)
* fix phpdoc
* fix invoice export field order
* prevent empty migration warning
* do not trigger export validation on new timesheets
* update license year
* remove trailing comma in function call for php compatibility
* add new composer plugin config
* bump phpunit schema version
2022-01-20 17:10:56 +01:00
Kevin Papst
40242b7dcc support custom fields for invoices (#3077) 2022-01-20 16:59:26 +01:00
Kevin Papst
9731023014 1.16.10 (#3047) 2022-01-01 18:12:57 +01:00
Weblate (bot)
0abbba7a56 Translations update from Hosted Weblate (#3032)
Co-authored-by: easyjoh <johannes@easyplusplus.net>
Co-authored-by: Dmitry <dmitrydmitry761@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: 拉姆徐 <xulong_715138082@qq.com>
Co-authored-by: Michal Gajewski <gajewmic@gmail.com>
Co-authored-by: DJScias <djscias@gmail.com>
2021-12-30 22:53:01 +01:00
Kevin Papst
cc809183ae added comment field to invoice (#3045) 2021-12-30 21:49:30 +01:00
Kevin Papst
f7b3f4ed76 improve export permission checks (#3027) 2021-12-17 01:10:49 +01:00
Kevin Papst
04fc954769 allow to configure the amount of recent activity rows in an empty week (#3026) 2021-12-16 16:58:10 +01:00
Kevin Papst
3621b8c27c fix invoice budget calculation (#3024) 2021-12-15 17:56:18 +01:00
Kevin Papst
358959522d release 1.16.9 (#3018)
* fix filter action display
* allow to set system configuration during runtime
* bump version
* use deepl pro free to translate missing keys
* replacing broken Github action
2021-12-14 02:29:06 +01:00
Weblate (bot)
19cd5962aa Translations update from Hosted Weblate (#3013)
Co-authored-by: Trần Công Minh <minhhp198x@gmail.com>
2021-12-14 00:10:26 +01:00
Kevin Papst
961336f35c fix project are not filtered after submit (#3016) 2021-12-11 15:51:23 +01:00
Kevin Papst
573fa9f7f3 fix create invoice token issue (#3007) 2021-12-09 01:36:58 +01:00
Kevin Papst
22ce6b047a new invoice template variables for budgets (#3005) 2021-12-08 22:15:07 +01:00
Kevin Papst
82525f382d fix invoice preview (#3002) 2021-12-08 14:21:15 +01:00
Kevin Papst
ec9dd08970 cleanup duplicate translation ids (#3001) 2021-12-08 01:49:44 +01:00
Kevin Papst
9ec0280334 improve translation test and fix error (#2998)
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
2021-12-07 16:56:08 +01:00
Kevin Papst
0861dbd75d new command to work with translation files (#2993) 2021-12-05 14:54:02 +01:00
Kevin Papst
f5949b6b9a use new trustedAuthors flag in CI action (#2992) 2021-12-04 22:46:39 +01:00
Weblate (bot)
99905497e1 Translations update from Hosted Weblate (#2951)
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: BeckeBauer <berko@gmx.de>
Co-authored-by: Bogi Napoleon Wennerstrøm <bogi.wennerstrom@gmail.com>
Co-authored-by: Miovio <mgrundemar@gmail.com>
Co-authored-by: Roman Ondráček <ondracek.roman@centrum.cz>
Co-authored-by: Dronrs <Dutythinking@protonmail.com>
Co-authored-by: Michal Matúšov <kubof.hromoslav@gmail.com>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-12-04 02:37:04 +01:00
Kevin Papst
4ae18b73d1 bump version (#2991) 2021-12-04 02:27:32 +01:00
Kevin Papst
1da26e041d fix invoice create and search (#2990) 2021-12-04 01:18:49 +01:00
Kevin Papst
4e42911f3d more csrf protection for invoice and search (#2984) 2021-12-02 18:01:51 +01:00
Kevin Papst
b0045a910c prevent that lock files will be committed in PRs (#2983) 2021-12-02 13:06:23 +01:00
Kevin Papst
9491f07ade fix deleting invoice documents (#2980) 2021-11-29 15:57:39 +01:00
Kevin Papst
d994339de5 fix two opening form tags (#2972) 2021-11-29 15:49:54 +01:00
Kevin Papst
0464054a2b bump version 2021-11-24 12:55:38 +01:00
Kevin Papst
b062164277 allow to delete invoice documents (#2968) 2021-11-24 10:30:49 +01:00
Kevin Papst
ff9acab0fc improve permissison handling in invoice screen (#2965) 2021-11-21 16:41:03 +01:00
Kevin Papst
76e09447c8 make sure that markdown uses safe mode (#2961) 2021-11-19 23:07:27 +01:00
Kevin Papst
9470699798 escape data in calendar popover (#2960) 2021-11-19 22:57:03 +01:00
Kevin Papst
89bfa82c61 escape customer, project and activity name in javascript (#2959) 2021-11-19 19:45:37 +01:00
Kevin Papst
859131308a improve export filename (#2958) 2021-11-19 18:53:43 +01:00
tdozbun-reno
56d02673ed Update CSRF Token IDs for Issue kevinpapst/kimai2#2947 (#2948)
* bump version
* removed not needed token, as it is already contained in the form
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-11-18 18:32:00 +01:00
Kevin Papst
b28e9c120c version 1.16.2 (#2942)
* bump version
* include calendar week in week chooser
* table names in SQL
* show save flash message
* prevent migration warning
* drop default value to prevent error when server version is not set
* csrf token for duplicate actions
* updated translations
2021-11-18 12:33:13 +01:00
Kevin Papst
c858edf5c9 release 1.16.1 (#2938)
* optional csrf token name
* fix regression when selecting all projects as super user
* prevent invalid sql
2021-11-16 21:48:50 +01:00
Kevin Papst
99ebd1d503 deactivate codecov patch percentage check (#2937) 2021-11-16 12:09:41 +01:00
Kevin Papst
f63a2c8ef6 Release 1.16 (#2929)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
2021-11-16 10:51:01 +01:00
Kevin Papst
95796ab256 improve csrf handling (#2936) 2021-11-16 10:17:26 +01:00
Kevin Papst
a1992494d3 fetch user preferences via API (#2905) 2021-11-15 21:14:45 +01:00
Kevin Papst
5896ae26c6 improve error handling during invoice generation (#2932)
* prevent that items will be marked as exported if invoice can not be generated
* check for existing invoice number to prevent that invalid invoices will be generated
* allow to add a unique id to invoice preview files on batch export
* hide delete invoice action with deactivated permission
* try to automatically fix duplicate invoice id
2021-11-15 19:21:22 +01:00
Weblate (bot)
8978c181ee Translations update from Weblate (#2915)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Anna Gonzalez Mellado <annagm615@gmail.com>
Co-authored-by: Gil <almontegil@gmail.com>
2021-11-15 00:57:59 +01:00
Kevin Papst
ae975d07db submit invoice search after changing the template (#2931) 2021-11-15 00:20:43 +01:00
Kevin Papst
6b49535b52 prevent csrf to flush logs (#2930) 2021-11-14 20:39:22 +01:00
Kevin Papst
8b0962e192 configure am/pm time-format as user preference (#2789) 2021-11-14 18:18:26 +01:00
pkaltenboeck
dce0578a2b new ProjectConstraint to add dynamic project validation (#2747) 2021-11-14 16:56:52 +01:00
Kevin Papst
a483184372 PDF memory optimizations (#2736) 2021-11-14 02:51:52 +01:00
Kevin Papst
6e6c60b29a added new invoice status: canceled (#2922) 2021-11-10 12:37:36 +01:00
Kevin Papst
21dbfdb4f9 do not reset password for LDAP and SAML users or rehash on API calls (#2916) 2021-11-10 11:34:50 +01:00
Kevin Papst
73ab26c7b7 added resname for tool compatibility (#2912) 2021-11-05 14:40:31 +01:00
Weblate (bot)
3e61b60c4e Translations update from Weblate (#2850)
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Anders Johansson <johansson@aljmedia.se>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Roman Shabanov <romash2605@gmail.com>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Artem <Localizer_in_Russian@protonmail.com>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: KanI <twinklingnerd@gmail.com>
Co-authored-by: ButterflyOfFire <ButterflyOfFire@protonmail.com>
2021-11-05 14:18:37 +01:00
Kevin Papst
bd2fe32d5a optimizations (#2904)
* calc once, then re-use
* prevent invalid theme switch
* allow to turn off weekly-quick-entries by permissions
* remove 00:00 from date-times that likely do not need a time
* fix datepicker out of window
2021-11-05 10:28:48 +01:00
Kevin Papst
c8854b0775 change data filter on project month report (#2911) 2021-11-05 09:45:12 +01:00
iusgit
042c119058 extend project orderNumber to 50 characters (#2828) 2021-11-03 16:48:35 +01:00
Kevin Papst
b92488e32f include roles and teams in user create form (#2849) 2021-11-03 16:24:22 +01:00
Kevin Papst
2bc76e7adc prevent empty migration warning (#2901) 2021-11-03 15:48:42 +01:00
Kevin Papst
d4278996ae composer upgrade, prevent dbal upgrade, new phpstan version (#2900) 2021-11-03 14:58:10 +01:00
Kevin Papst
eb63dae405 added invoice replacer for currently logged-in user (#2899) 2021-11-03 12:00:52 +01:00
Kevin Papst
1b35356f81 activate bleeding edge phpstan rules (#2898) 2021-11-02 13:33:21 +01:00
Kevin Papst
36c08b0dea fix weekly view day format (#2893)
* make duplicate project action available on details page
* move "weekly hours" form to main menu
* changed label of week chooser
* hide quick entries menu for punch mode users
2021-11-01 20:23:17 +01:00
Kevin Papst
1d32e4ecee use token in invoice delete route (#2889) 2021-10-30 15:17:06 +02:00
Kevin Papst
40061e43bb simplify building theme independent plugins (#2888) 2021-10-30 14:48:05 +02:00
Kevin Papst
7ed1998d04 fixes for new quick-entry week form (#2887) 2021-10-29 21:35:48 +02:00
Kevin Papst
fd2490c135 added workflow to trigger new docker images on release (#2882) 2021-10-28 10:42:53 +02:00
Kevin Papst
9ab098af86 weekly quick-entry form (#2793) 2021-10-18 11:12:46 +02:00
Kevin Papst
64893e0a95 release 1.15.6 (#2863) 2021-10-18 00:30:35 +02:00
Kevin Papst
6fdc304313 improve sunday FDOW handling (#2862) 2021-10-17 19:17:47 +02:00
Kevin Papst
fb265ed732 make sure that minute_increment is not zero (#2860) 2021-10-16 13:38:28 +02:00
Kevin Papst
e2be5b401c improve summary rows in reports (#2861) 2021-10-16 13:38:08 +02:00
Kevin Papst
8539938b8a use new codecov action (#2854) 2021-10-14 17:23:45 +02:00
Kevin Papst
bbf25823b8 release 1.15.5 (#2848) 2021-10-13 18:31:28 +02:00
Kevin Papst
6b066046c6 default value for billable flag and support in batch update (#2851) 2021-10-13 15:49:20 +02:00
Weblate (bot)
9226daa891 Translations update from Weblate (#2823)
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Péter Gyetvai <gyetpet@mailbox.org>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Eric <spice2wolf@gmail.com>
Co-authored-by: Frank.wu <me@wuzhiping.top>
Co-authored-by: web chigusa <chigusaweb66@gmail.com>
Co-authored-by: KasukeLp <kasukelp23@yahoo.com>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-10-13 14:09:15 +02:00
Kevin Papst
843cd8fb67 refactor system configuration title and wording (#2847) 2021-10-13 13:37:44 +02:00
Kevin Papst
6d7d441d42 fix missing meta fields in duplicate timesheet action (#2845) 2021-10-12 23:41:27 +02:00
Kevin Papst
1c4da30b61 fix version number 2021-10-07 16:42:17 +02:00
Kevin Papst
84e25851d3 set security options on cookies (#2825) 2021-10-07 12:40:06 +02:00
Kevin Papst
3a52daedab fix open budget calculation (#2821) 2021-10-07 11:46:48 +02:00
Kevin Papst
b7cf9cd776 added croatian language (#2817) 2021-10-06 13:41:05 +02:00
Kevin Papst
ccb184b17f Release 1.15.3 (#2813) 2021-10-05 15:30:29 +02:00
Weblate (bot)
162ff07bd5 Translations update from Weblate (#2791)
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Daniel' Ishmaev <dan.samara@gmail.com>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-10-05 15:22:45 +02:00
Kevin Papst
7326a452c3 re-added lock threads app 2021-10-04 17:09:59 +02:00
Kevin Papst
9453947309 export budget, timeBudget and budgetType (#2812) 2021-10-04 16:57:45 +02:00
Kevin Papst
d25653b6ed removed export and system-config subtitles (#2811) 2021-10-04 14:36:17 +02:00
Kevin Papst
ea415e33f5 do not apply rate factor multiple times (#2807) 2021-10-03 17:40:36 +02:00
Kevin Papst
b6430d5622 allow to customize dashboard permissions for latest row (#2806) 2021-10-03 17:17:01 +02:00
Kevin Papst
6fcd50ecdf hide not started projects in widget (#2805) 2021-10-03 13:53:52 +02:00
Kevin Papst
6857d92c4f respect customer visibility in project-overview report (#2804) 2021-10-03 13:41:14 +02:00
Weblate (bot)
4bb9edb2b5 Translations update from Weblate (#2781)
Co-authored-by: frooog in raain <sadsatan211@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Mokhtar Garmehi <Mokhtar_garmeh@yahoo.com>
Co-authored-by: Pham Mina <phamthinhalinh93@gmail.com>
Co-authored-by: Ana Carla Vasconcelos <anacarlavgs@gmail.com>
Co-authored-by: SC <lalocas@protonmail.com>
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: Kevin Papst <kevinpapst@users.noreply.github.com>
2021-09-24 15:16:36 +02:00
Input-BDF
dd881bb856 prevent whitespace on line endings in created docx invoices (#2756) 2021-09-24 15:02:01 +02:00
Kevin Papst
204e0bc179 1.15.2 (#2782)
* fix division by zero
* cleanup required directories, check configured data directory, do not check for freetype support
* bump version number
2021-09-24 14:47:40 +02:00
Guillaume-Duc-95
d026460106 copy the billable status when restarting timesheet (#2778) 2021-09-20 16:23:23 +02:00
Kevin Papst
934a7855b9 remove duplicate statistic events (#2776) 2021-09-18 13:15:23 +02:00
Kevin Papst
54d7c4490f added customer number in invoice export (#2775) 2021-09-18 02:49:47 +02:00
Kevin Papst
fa6af3d148 fix api doc (teams) (#2773) 2021-09-17 14:31:37 +02:00
Kevin Papst
063753b569 improve upgrade docs (for LDAP users in 1.15) (#2772) 2021-09-17 13:42:55 +02:00
Kevin Papst
baff2d78d9 prepare release 1.15 (#2707)
* bump version
* fix invisible class on labels
* fail safe removal of foreign key
* check if optional form field exists before accessing it
* silently ignore stopped timesheets
* prevent colliding parameter names
* make sure decimal duration is always rendered with two decimals
* simplify translation
* fix #2751 ANSI_QUOTES
* rename composer task
* fix billable statistic rates
* added missing translation for export
2021-09-17 00:58:25 +02:00
Weblate (bot)
8f832856a5 Translations update from Weblate (#2739)
Co-authored-by: Sérgio Morais <lalocas@protonmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: Yan Kazachkov <yankazachkov@gmail.com>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: pisquan8 <cimurro@outlook.de>
Co-authored-by: Maamon AlHaqli <mamon321@hotmail.com>
Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Krishna Chand <krishna_chand67@naver.com>
Co-authored-by: Anders Johansson <johansson@aljmedia.se>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-09-16 17:16:29 +02:00
Kevin Papst
f2eec4f315 API fixes (#2766) 2021-09-16 17:06:32 +02:00
Weblate (bot)
2536105ad0 Translations update from Weblate (#2717)
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Ville Kovacs <regpile@mailbox.org>
Co-authored-by: Simona Iacob <s@zp1.net>
Co-authored-by: Andrea Martini <andrea.martini.7002@gmail.com>
Co-authored-by: Лолло Нуб <lollo.samp@mail.ru>
Co-authored-by: Peter Valo <pvalo@abcom.sk>
Co-authored-by: A M <augim3@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Ana Carla Vasconcelos <anacarlavgs@gmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-08-26 02:08:50 +02:00
Kevin Papst
98a3fc99a2 store search in session (#2735)
* allow to detect used query filters
* allow to set label in action buttons
* allow to reset last search from session
* migrate invoice archive to new search system
* display number of used search filters
2021-08-26 01:37:40 +02:00
Kevin Papst
56524a9773 data-table sorting icons and alignment (#2734) 2021-08-26 00:56:36 +02:00
Kevin Papst
fae525c82f fix duplicating timesheet if allow overlapping is deactivated (#2732) 2021-08-25 19:31:48 +02:00
Kevin Papst
5023fa6189 prevent email or username from being non-unique (#2730) 2021-08-25 15:18:46 +02:00
Kevin Papst
f743503705 added search modal for timesheet export (#2728) 2021-08-24 19:01:48 +02:00
Kevin Papst
f6a82ba119 fix team edit with deactivated users (#2716) 2021-08-11 01:23:55 +02:00
Weblate (bot)
305d3ba6fe Translations update from Weblate (#2672)
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Victor Cleaner <victor.cleaner@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: edo-2313 <edo2313@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Jack-Benny Persson <jack-benny@cyberinfo.se>
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: dottypottylotty <muzzbuzzer@outlook.com>
Co-authored-by: Adam K <uz@zu.uz>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-08-10 15:14:30 +02:00
Kevin Papst
7873bd812e fix statistics in user profile for first year not starting in january (#2712) 2021-08-10 14:39:52 +02:00
Kevin Papst
b31ded22b9 minor restyling of login screen (#2711) 2021-08-10 14:25:36 +02:00
Toby Batch
f80fe0e4d0 allow to prefill timesheet description by get param (#2580) 2021-08-08 14:29:12 +02:00
Kevin Papst
c063aed867 fixes for 1.15 (#2704) 2021-08-08 12:38:19 +02:00
Kevin Papst
b2d3272151 support multiple teamleads in each team (#2702)
* fix jumping avatars
* fix line-break after color dot for long names
2021-08-07 18:05:41 +02:00
Kevin Papst
e9986c92d6 code cleanup (#2700)
* fix doctrine definition
* do not count api calls as login
* remove unknown form options
* fix annotations
* cleanup deprecations in tests
2021-08-07 01:36:59 +02:00
Kevin Papst
3a7dba437c move supported languages logic to service (#2701) 2021-08-07 01:11:42 +02:00
Kevin Papst
cefd747e91 monthly budget, monthly report, unified report calculation (#2684) 2021-08-06 18:38:41 +02:00
Jelle Sebreghts
21f785638c added calendar configuration event (#2698) 2021-08-06 18:35:37 +02:00
Kevin Papst
df62c8a428 improved play and stop button (#2692)
* improved play and stop button if only one record is allowed
* stop button first in action menu
* fix skin colors
* autofocus term field in search form
* fix responsive column layout in invoice listing
* improve responsive header for small screens
2021-07-30 19:57:57 +02:00
Kevin Papst
37e02365c7 importer supports merge of multiple Kimai 1 installations (#2691) 2021-07-28 14:16:49 +02:00
Kevin Papst
7352c9a394 allow 65535 character in meta fields (#2690) 2021-07-27 19:41:12 +02:00
Kevin Papst
5b8510be56 fix ldap issues due to new security components (#2689) 2021-07-27 19:31:49 +02:00
Kevin Papst
6d5244aa5d LDAP: fixing issues for re-authenticating users (#2681) 2021-07-23 16:12:38 +02:00
Kevin Papst
f1f60042d8 bugfixes (#2669)
* allow storage of multiple .env without git
* clarify requirements
* fail safe statistic queries
* remove unused translations
* reduce customer statistic calls by 50%
2021-07-23 15:15:54 +02:00
Weblate (bot)
6558bcae1d Translations update from Weblate (#2665)
Co-authored-by: Viktor Żakowski <pocomito250@gmail.com>
Co-authored-by: phlostically <phlostically@mailinator.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Tur <tur+translate@simplelogin.fr>
Co-authored-by: Adaś <adam.prosniak@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Eugenia Russell <eugenia.russell2019@gmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-07-19 01:02:11 +02:00
Kevin Papst
828b9c8b4a added account number field to user (#2671) 2021-07-19 00:13:39 +02:00
Kevin Papst
7d052eba00 make sure that timezone is properly validated (#2663) 2021-07-13 23:23:18 +02:00
Weblate (bot)
43a31efeac updated french (#2661)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
2021-07-13 16:16:20 +02:00
Kevin Papst
f12f1ae60d bugfixes and improvements (#2660) 2021-07-13 15:51:27 +02:00
Weblate (bot)
9dc94084c1 Translations update from Weblate (#2613)
Co-authored-by: phlostically <phlostically@mailinator.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: Yan Kazachkov <yankazachkov@gmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-07-13 14:49:46 +02:00
Kevin Papst
03d5d3c70c better readability for drag and drop boxes (#2659) 2021-07-13 12:12:10 +02:00
Kevin Papst
27cea996c0 configurable print export (#2657) 2021-07-13 10:11:20 +02:00
Kevin Papst
7661d43327 improve permission checks for report access (#2658) 2021-07-13 06:21:31 +02:00
Kevin Papst
a1f90ffaba limit amount of items in calendar drag and drop boxes (#2291) 2021-07-11 15:03:18 +02:00
Kevin Papst
2583fdf20e small bugfixes (#2655)
* improve report visibility
* fix timesheet duration, which breaks validation
* added contributing section in README
* do not allow to change project for existing activities - fixes #2576
* bump theme version to fix FOSUserBundle dependency
* use entity color instead of inherited one - fixes #2200
2021-07-10 00:37:03 +02:00
Kevin Papst
9ddb87a6fd added project detail report (#2651)
- avatars via css only
- random colors for entities
- improves print view
- added colors for teams
- added color to tag
2021-07-06 22:01:20 +02:00
Kevin Papst
cc6031bfde invoice number pattern for customer-name and number (#2640) 2021-06-30 17:23:20 +02:00
Kevin Papst
6d196879b4 refactor configurations (#2626)
* composition instead of inheritance
* refactored some twig extensions to runtime extensions
2021-06-26 13:03:54 +02:00
Kevin Papst
3d1fba650b improve color chooser and name validation (#2622) 2021-06-25 16:35:16 +02:00
Kevin Papst
0d5e0b3e80 fix url under certain environments (#2621) 2021-06-25 09:48:38 +02:00
Kevin Papst
7460647d58 added setting to limit the maximum length of a timesheet record (#2612) 2021-06-12 01:05:33 +02:00
Weblate (bot)
53e01177d9 Translations update from Weblate (#2577)
Co-authored-by: Maamon AlHaqli <mamon321@hotmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Tymofij Lytvynenko <till.svit@gmail.com>
Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Nerdiin <dznissei10@gmail.com>
Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Co-authored-by: Richard Mangahas <richard.mangahas.aeom@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: phlostically <phlostically@mailinator.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-06-12 00:56:24 +02:00
Kevin Papst
6709ef4c4c removed soft_limit setting (#2611) 2021-06-10 16:01:09 +02:00
Kevin Papst
0b519e9d08 fix datepicker appears out of screen (#2610) 2021-06-10 15:51:26 +02:00
Kevin Papst
7f20cb045c Refactor authentication system (#2602)
Make auth configuration available via UI, remove FOSUserBundle and SAML-Bundle dependency
2021-06-10 15:34:13 +02:00
Kevin Papst
286b63e2c8 allow to configure timezone for the lockdown period (#2593) 2021-06-02 00:05:44 +02:00
Kevin Papst
c1eb5ba90a lint container, workflows and composer update (#2591) 2021-06-01 19:20:12 +02:00
Kevin Papst
4859ac8ecb Support for PHP 8 (#2158)
painful 66 commits later: required PHP version bumped to 7.3, plugin updates using migrations necessary!
2021-05-31 14:53:22 +02:00
Kevin Papst
df6bd30d03 fix calendar totals for empty weeks (#2581) 2021-05-21 15:27:10 +02:00
Kevin Papst
70fd0ae269 show revenues in dashboard to admins only, not teamleads (#2573) 2021-05-16 20:36:43 +02:00
Kevin Papst
dd83872339 new permission to hide user choice in report (#2572) 2021-05-16 00:52:42 +02:00
Kevin Papst
f7aa3c1e13 financial year setting + new users working time per year report (#2547) 2021-05-14 18:40:48 +02:00
dkstiler
a9da5f8476 added greek language (#2568) 2021-05-14 18:04:46 +02:00
Weblate (bot)
06f3a1ecd4 Translations update from Weblate (#2546)
Co-authored-by: Guilherme Dimas <guilhermedimasrosa@gmail.com>
Co-authored-by: dkstiler <dkstiler@gmail.com>
Co-authored-by: P-A Lindkvist <pa.lindkvist@gmail.com>
Co-authored-by: Henrik Dankvardt <dankvardt@gmail.com>
Co-authored-by: 김주열 <quick3377@gmail.com>
Co-authored-by: Nerdiin <dznissei10@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: whenwesober <naomi16i_1298q@cikuh.com>
Co-authored-by: Ido Ido <kobid88923@mxcdd.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-05-14 17:06:37 +02:00
Kevin Papst
bed3ade221 Improve progressbar values in report (#2569) 2021-05-14 11:45:03 +02:00
Kevin Papst
f2b32b211b use dialog to duplicate timesheet (#2567)
* fix: display time budget in customer listing if set
* updated api methods with annotations
* do not require checkboxes for system configurations
* open dialog for duplicated timesheets
2021-05-12 22:32:08 +02:00
Kevin Papst
f81f9ba492 added API route to fetch infos about installed plugins (#2561) 2021-05-12 14:03:46 +02:00
Kevin Papst
f10aad927f fix timesheet collection fetch via API with end datetime set (#2552) 2021-05-05 13:02:09 +02:00
Kevin Papst
4fcd97b142 do not include running entries in invoices (#2551) 2021-05-04 12:29:20 +02:00
Kevin Papst
dad1b8b772 version 1.14.1 (#2532)
* no back links in modal pages
* remove unused service links to bountysource and gitter
* add validation for budget and time-budget fields
* display time budget if set
* remove console log
* sanitize DDE payloads
* do not show status and name in version string
2021-04-29 18:29:03 +02:00
Weblate (bot)
22af82cb15 Translations update from Weblate (#2528)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: phlostically <phlostically@mailinator.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
2021-04-29 12:00:27 +02:00
Kevin Papst
e4b176a4d5 use events for budget calculation (#2544) 2021-04-29 11:50:48 +02:00
Kevin Papst
bb94b11e37 support tags in invoices (#2526) 2021-04-23 17:06:42 +02:00
Weblate (bot)
67d23ec6b2 Translations update from Weblate (#2474)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: phlostically <phlostically@mailinator.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Bogi Napoleon Wennerstrøm <bogi.wennerstrom@gmail.com>
Co-authored-by: Martin Didriksen <martindidriksen@hotmail.com>
Co-authored-by: Christian Eichert <c@zp1.net>
Co-authored-by: Gontzal Manuel Pujana Onaindia <thadahdenyse@gmail.com>
Co-authored-by: DJScias <djscias@gmail.com>
Co-authored-by: Bruno Oliveira Rosa <brunokauaoliveira@gmail.com>
Co-authored-by: Mohammad Firuzabadi <mohmmad.fi@gmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-04-22 01:22:39 +02:00
Kevin Papst
ff7a402bd4 fix locale date format in report header and more (#2520)
* fix problem with empty end datetime in edit time
* fixed calendar creation with tags in "pre-defined tags" mode
* fix locale date format in report header
2021-04-21 22:23:32 +02:00
Kevin Papst
305a2fd4f6 show daily sum in calendar week and day view (#2519) 2021-04-21 16:11:31 +02:00
Kevin Papst
09c9a95fcf added activity events for plugins (#2516) 2021-04-21 15:56:17 +02:00
Kevin Papst
08a144ac31 drag & drop to delete entries from the calendar (#2513) 2021-04-20 14:50:23 +02:00
Kevin Papst
7ddcde62dd fix sunday being first day of week (#2483) 2021-04-19 18:32:21 +02:00
Kevin Papst
b6462b406d updated all packages (#2512) 2021-04-19 17:25:06 +02:00
Kevin Papst
0330f45c6a billable timesheets, inactive projects report, bookmark export search (#2503) 2021-04-18 21:51:27 +02:00
Kevin Papst
8664d94ea6 release 1.14 (#2498) 2021-04-11 14:11:09 +02:00
Kevin Papst
af9dea9226 prepare release 1.14 (#2495)
* removed un-maintained docker file
* update all packages
* fix deprecations
* only show one line descriptions for customer, projects and activities
* allow to show export column in timesheet listing
2021-04-08 18:07:57 +02:00
Kevin Papst
2ce6e815ff new report: week for users (#2494) 2021-04-07 22:20:19 +02:00
Kevin Papst
cdad5913ca highlight invisible items (#2493) 2021-04-07 19:14:33 +02:00
Kevin Papst
68bb01d064 allow to pre-define colors to choose from (#2481) 2021-04-06 00:45:54 +02:00
Weblate (bot)
f4dbdbb427 Translations update from Weblate (#2401) 2021-03-29 11:45:03 +02:00
Philipp
d84beb957c add subtotal and payment date to invoices (#2450) 2021-03-29 00:51:34 +02:00
Kevin Papst
7029bde555 improve project overview (#2467) 2021-03-28 14:46:45 +02:00
Kevin Papst
7427187647 fix api 404 on page parameter (#2468) 2021-03-28 11:30:35 +02:00
Kevin Papst
f8a5ff7315 create multiple invoices at once (#2465) 2021-03-27 20:47:53 +01:00
Kevin Papst
87d07ffaaf save default search options (#2445)
* set default times for daterange objects
* allow to show order and order by fields
* move search to modal
* more options for page size
* save export visibility in cookie
2021-03-20 01:10:45 +01:00
Kevin Papst
954ba7c937 improve project view table (#2441) 2021-03-16 15:59:31 +01:00
Kevin Papst
16e8e8a5e5 fix deprecations (move same controller) (#2440) 2021-03-16 14:06:15 +01:00
Kevin Papst
75e62b800c added version ID for simpler comparison (#2439) 2021-03-16 11:24:19 +01:00
Kevin Papst
e1c9af795c refactored page actions to event subscriber (#2420) 2021-03-15 14:18:44 +01:00
Kevin Papst
9a2fd9ba91 allow increasing invoice numbers per day (#2433) 2021-03-14 13:53:36 +01:00
Kevin Papst
c0378b4f51 add user preference: default report (#2430) 2021-03-14 13:32:47 +01:00
Kevin Papst
0a6ea6be42 hide expired projects in team-projects widget (#2432) 2021-03-14 13:24:24 +01:00
Kevin Papst
ec0eca39ff show budget and time-budget columns in listing views (#2429) 2021-03-13 20:44:10 +01:00
Kevin Papst
3e9371bd6a Timesheet validator: prevent overbooking budgets (#2422) 2021-03-13 14:41:29 +01:00
Kevin Papst
db1344573f search and export from invoice archive (#2408) 2021-03-10 01:50:27 +01:00
Willian Gustavo Veiga
c34e9f576d added new report: project view (#1738) 2021-03-09 23:19:11 +01:00
Kevin Papst
0b7d551048 added more columns to spreadsheet exports (#2413) 2021-03-08 18:32:11 +01:00
Kevin Papst
30ac5e4c24 Drop SQLite support (#2405) 2021-03-08 16:06:22 +01:00
Kevin Papst
70f7f35009 allow to select reports as initial view (#2403) 2021-03-06 12:59:13 +01:00
Kevin Papst
5583caa9e4 User profile layout (#2402) 2021-03-06 12:34:34 +01:00
Kevin Papst
d3099aca39 remove redundant translation key (#2394) 2021-03-03 13:19:06 +01:00
Weblate (bot)
765ea63aed Translations update from Weblate (#2293) 2021-03-03 12:58:42 +01:00
Kevin Papst
adf8c09fd4 refactored permission templates to match controller (#2391) 2021-03-03 11:31:29 +01:00
Maxim Butakov
5a90b36734 fix unreadable notice for delete modals (#2379) 2021-02-28 15:20:05 +01:00
Kevin Papst
2e7bfc822c Widget fixes (#2373)
* fix click on row in team-projects
* hide deactivated users in team listing
2021-02-21 00:51:46 +01:00
Kevin Papst
607d09aefb performance improvements (#2329)
* remove work from constructor
* refactor twig extensions
* upgrade theme
* replace sub-request with direct template rendering
2021-02-20 23:52:01 +01:00
Kevin Papst
9eb25c412e prevent duplicate if overlapping records are disabled (#2311) 2021-02-06 17:31:14 +01:00
Kevin Papst
8d41fa20bd prepare release 1.13 (#2290)
* make voters a final class
* upgrade dependencies
* sort project alphabetically in dashboard widget
* open detail page on row click
* do not break on null tag name
* added max height to scrollable widgets on dashboard
* added timesheet duplicate event
* allow to deactivate browser title update
* improve comment box
* moved role permissions to own menu
* removed tabs in user screen
* fix user can remove super-admin from own account
2021-02-01 23:43:47 +01:00
Kevin Papst
a034b3519e added de_AT and pt as languages (#2292) 2021-01-23 00:00:30 +01:00
Weblate (bot)
ebf0b4de51 Translations update from Weblate (#2253)
Co-authored-by: MikKrz <mik.zly@gmail.com>
Co-authored-by: badlop <badlop@process-one.net>
Co-authored-by: Peter Donka <peter.donka@gmail.com>
Co-authored-by: 知者无涯 <wasd_jkl@outlook.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Omer I.S <omeritzicschwartz@gmail.com>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2021-01-22 20:45:39 +01:00
Kevin Papst
c9ccdb5f77 replace "freelancer" invoice template with pdf version (#2289) 2021-01-22 19:47:05 +01:00
Kevin Papst
88b4d3842f improve API validation error messages (#2278) 2021-01-20 18:57:16 +01:00
Kevin Papst
3cd7e01a2c show calculated lockdown date in config screen (#2274) 2021-01-20 17:50:50 +01:00
Kevin Papst
bd39666759 do not break excel invoice templates with replacer inside formulas (#2272) 2021-01-19 17:25:16 +01:00
Kevin Papst
67d5cba09f improve permission checks for timesheets with activated lockdown (#2271) 2021-01-17 17:50:37 +01:00
Kevin Papst
8d72d114c7 improved duration and minute selector (#2264)
* do not close modal if form is dirty
* deprecated TimesheetConfiguration
* inject timezone in form types
* cleanup usage of UserDateTimeFactory
* allow to configure increment steps for minutes
* use 15 minutes step for datetimepicker in project edit form
* use rounding rules for increments in minute select for begin and end
* allow duration in multi user and admin timesheet forms
* make dropdown values configurable
2021-01-17 14:04:13 +01:00
Kevin Papst
e2324b7d51 fix calendar problem with UTC (#2268) 2021-01-16 00:00:47 +01:00
Kevin Papst
1eae149c75 remove drag&drop on calendar for print views (#2261) 2021-01-14 20:53:18 +01:00
Kevin Papst
2a986517f7 fix pagination on invoice templates page (#2260) 2021-01-14 13:12:34 +01:00
Kevin Papst
bf47bb1840 hide multi update in tags view if delete_tag permission is missing (#2259) 2021-01-14 12:44:56 +01:00
Kevin Papst
cb6924e6d6 added event for recent activities (#2254) 2021-01-11 19:13:14 +01:00
Philipp Strobel
1de6b5d385 use the correct javascript event name (#2210) 2021-01-08 16:27:00 +01:00
Philipp Strobel
4c73fc825c Fix dropdowns on the bottom of a page (#2212) 2021-01-08 15:42:09 +01:00
Weblate (bot)
d0a0786cce Translations update from Weblate (#2226)
* Translated using Weblate (Polish)
* Translated using Weblate (Swedish)
* Translated using Weblate (Portuguese (Brazil))
* Translated using Weblate (Slovak)

Co-authored-by: Michał Jastrzębski <michu9010@gmail.com>
Co-authored-by: Andreas Håll <ante_skalman@hotmail.com>
Co-authored-by: Augusto Milão <augusto.milao01@gmail.com>
Co-authored-by: Aris <aatiger2007@gmail.com>
2021-01-08 15:22:54 +01:00
Kevin Papst
b7390ece39 week numbers by ISO (#2248) 2021-01-08 15:20:35 +01:00
Kevin Papst
1aae4f4d0f fix first week in year shows wrong year (#2239) 2021-01-08 15:12:42 +01:00
Kevin Papst
244169d6d5 make sure to generate valid filenames (#2238) 2021-01-08 14:50:23 +01:00
Kevin Papst
a5fdf81df5 fix deprecations (#2225) 2020-12-27 20:47:09 +01:00
Kevin Papst
c1a54abc58 simplify html timesheet exporter (#2224) 2020-12-27 20:44:39 +01:00
Weblate (bot)
7e649dff3b Translations update from Weblate (#2195)
Co-authored-by: Jan Hladik <jan.hladik@iquentin.cz>
Co-authored-by: Anaa Ara <martakanuu@protonmail.com>
Co-authored-by: LL Magical <lolayami2004@gmail.com>
Co-authored-by: Jakub Fabijan <animatorzPolski@gmail.com>
Co-authored-by: Hahato Toshino <ameer.amino95@gmail.com>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: ikmaak <info@ikmaak.nl>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
2020-12-26 16:57:37 +01:00
Kevin Papst
40eda01c22 added export context (#2216) 2020-12-22 18:41:00 +01:00
Kevin Papst
74b3917e69 wrong decimal duration for more than 1000 hours (#2214) 2020-12-21 13:08:43 +01:00
Kevin Papst
6ada0b649c dashboard: fix years with 53 weeks (#2206) 2020-12-18 13:09:28 +01:00
Kevin Papst
e21fc656e4 replace striptags with validator (#2192) 2020-12-14 00:28:30 +01:00
Kevin Papst
f4f5c8fa88 escape configurable fields (#2191) 2020-12-13 03:15:46 +01:00
Kevin Papst
64d1aecf16 support mysqli in connection string (#2190) 2020-12-13 03:13:04 +01:00
Kevin Papst
26c2d5aa81 prepare release 1.12 (#2183)
* updated dependencies (#2125)
* display application name and version in console (#2150)
2020-12-10 16:25:14 +01:00
Weblate (bot)
78d8212e57 Translations update from Weblate (#2136)
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: koffevar <egor.kafisov@gmail.com>
Co-authored-by: Anaa Ara <martakanuu@protonmail.com>
Co-authored-by: 朱伟 <2676988242@qq.com>
Co-authored-by: yn <bilisenyou@outlook.com>
Co-authored-by: Woodyx <shiposhouyou@gmail.com>
Co-authored-by: thekeymethod <csokan.andras87@protonmail.ch>
Co-authored-by: Daniel de Souza Melo <jxzk@protonmail.com>
Co-authored-by: João Tiago Antunes <jtiago.cbr@gmail.com>
2020-12-10 15:06:10 +01:00
Kevin Papst
7a3388646b allow custom export repositories (#2182) 2020-12-10 15:00:14 +01:00
Kevin Papst
c3fe8d1c39 access custom-fields in twig invoice templates (#2168) 2020-12-09 10:49:48 +01:00
Kevin Papst
fcd9974a7c suppress notice for tempnam (#2166) 2020-12-09 10:01:50 +01:00
Kevin Papst
53dc322fd1 improve permission screen (#2177) 2020-12-09 01:17:48 +01:00
Kevin Papst
4cab1d323c remove support as issue types (#2173) 2020-12-08 23:11:48 +01:00
Kevin Papst
686d55de6e added config for issue templates (#2172) 2020-12-08 20:23:15 +01:00
Kevin Papst
0d2d40791a allow to reassign timesheets from delete-user form (#2159) 2020-12-03 22:52:58 +01:00
Kevin Papst
4302ecd6ea fixed broken test (#2151) 2020-11-29 19:40:51 +01:00
Weblate (bot)
fc12056ba2 updated polish translations (#2135)
Co-authored-by: Piotr Bub <pbubacz@live.com>
2020-11-21 11:43:42 +01:00
Weblate (bot)
72edce86ba Translations update from Weblate - Slovak 89% Romanian 100% (#2106)
Co-authored-by: MikeSierraRO <razvan@zeces.ro>
Co-authored-by: Anaa Ara <martakanuu@protonmail.com>
2020-11-17 11:51:42 +01:00
Kevin Papst
288fc5dd08 fix timezone for timesheets created by other users (#1509) 2020-11-13 17:46:32 +01:00
Kevin Papst
7503899a9b re-order fields in search form (#2120) 2020-11-12 11:14:43 +01:00
Kevin Papst
49a4d1069a sort teams alphabetically in team_list (#2119) 2020-11-12 11:03:37 +01:00
Kevin Papst
f916e0ce25 fix timesheet importer for entries passing midnight (#2098) 2020-11-10 16:02:30 +01:00
Kevin Papst
bd4efad22b added event to manage javascript translations (#2104) 2020-11-09 13:28:22 +01:00
Weblate (bot)
66865b553e updated Hebrew translations (#2102) 2020-11-09 10:08:09 +01:00
Weblate (bot)
62bfe0af2b updated Korean translations (#2093)
Co-authored-by: BeckeBauer <berko@gmx.de>
Co-authored-by: 김옥현 <dhrgusdlrns3@gmail.com>
2020-11-07 20:05:40 +01:00
Kevin Papst
db8714a87b fix styling issues in PDF invoice (#2097) 2020-11-07 19:31:18 +01:00
Kevin Papst
5868741fe3 use different event to reload recent activities (#2096) 2020-11-07 16:51:30 +01:00
Kevin Papst
08e284c51b sort composer packages in doctor (#2089) 2020-11-03 23:59:44 +01:00
Kevin Papst
1757ffd8ee improved api docs styling (#2085) 2020-11-02 10:58:38 +01:00
Weblate (bot)
2d3c46957f Translations update from Weblate (#2081)
Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
2020-11-02 10:35:34 +01:00
Kevin Papst
ae0a6ebfb5 fix Sunday as first dow of week in date-picker (#2084) 2020-11-02 10:32:46 +01:00
Kevin Papst
aba06ba3f0 improve customer validation (#2083) 2020-11-02 00:50:26 +01:00
Weblate (bot)
b012332d82 Translations update from Weblate (#2071)
* Translated using Weblate (Portuguese (Brazil))
* Translated using Weblate (Dutch)
* Translated using Weblate (Portuguese)
* Translated using Weblate (Spanish)

Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Leonardo Ferreira <miwibib401@ezeca.com>
Co-authored-by: Bruno Arakaki <brn.arakaki@gmail.com>
Co-authored-by: IxFail <mitchelnijkamp1@msn.com>
2020-10-30 13:22:34 +01:00
Kevin Papst
4a94525320 prepare release 1.11.1 (#2073) 2020-10-28 20:35:27 +01:00
Kevin Papst
1444593bbd validate color (#2072) 2020-10-28 20:01:08 +01:00
Kevin Papst
82e1d6b917 fix assertion deprecation (#2068) 2020-10-28 16:56:09 +01:00
Kevin Papst
61c0cbc887 fix auto-stop when starting timesheet with tags (#2067) 2020-10-27 18:35:22 +01:00
Weblate (bot)
8c39b4197e Translated using Weblate (French) (#2066)
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
2020-10-27 13:36:45 +01:00
Kevin Papst
e24c647b18 release 1.11 (#2063) 2020-10-26 12:55:24 +01:00
Kevin Papst
6db21d7b34 fix xss (#2060) 2020-10-26 11:35:31 +01:00
Kevin Papst
7ae55c1980 switch to php workflow v2 (#2061) 2020-10-26 11:21:03 +01:00
IxFail
bd167b6088 Dutch translation update (#2058) 2020-10-26 01:28:46 +01:00
vilu85
b9b7bf845c Finnish translations (#2046) 2020-10-26 00:27:10 +01:00
Weblate (bot)
fc5ebb619e Translations update from Weblate (#2011)
Co-authored-by: Bruno Arakaki <brn.arakaki@gmail.com>
Co-authored-by: Katarzyna Sobolewska <kasia.sobolewska1@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: aquilesi8 <adamdavies7@protonmail.com>
Co-authored-by: koffevar <egor.kafisov@gmail.com>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Co-authored-by: David Ordás <davorpatech@gmail.com>
Co-authored-by: iglv <ilv0609@gmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2020-10-25 23:15:46 +01:00
Kevin Papst
abd31e3785 allow to configure database version via ENV var (#2055) 2020-10-24 21:00:43 +02:00
Kevin Papst
8a8f5cb6ce Fix Composer 2 compatibility (#2056) 2020-10-24 19:33:49 +02:00
Kevin Papst
2ad8f8a4bb prevent export and invoice from breaking on equal sign (#2054) 2020-10-23 02:00:50 +02:00
Kevin Papst
4533c994a3 SQL and performance improvements (#2017) 2020-10-23 00:31:53 +02:00
Kevin Papst
6ed7ee76e7 support custom fields in timesheet batch update (#2043) 2020-10-21 17:10:11 +02:00
Kevin Papst
167a826f50 improved timesheet importer (#2049) 2020-10-21 11:44:07 +02:00
Kevin Papst
032db11b48 added dateformat and timezone options to project importer (#2042) 2020-10-16 12:53:33 +02:00
Kevin Papst
996f05c73a added project importer and grandtotal converter (#1468) 2020-10-11 22:08:00 +02:00
Kevin Papst
0ce02b4f06 some arbitrary improvements (#2032)
* show version in doctor
* added flag to import activities as global
2020-10-08 17:17:21 +02:00
Kevin Papst
fb31319fcf open create form for activity/project/customer in modals (#2025) 2020-10-08 01:12:34 +02:00
Kevin Papst
46bf01d93e lifecycle events for projects (#2013) 2020-10-07 19:44:55 +02:00
Kevin Papst
c2ec15aeb3 add a i18n api field for the users "now" datetime (#2007) 2020-10-07 00:04:20 +02:00
Kacper Rogula
bb97611349 Execute migrations in kimai:reset-dev command (#1982) 2020-10-03 14:56:51 +02:00
Kevin Papst
825e492891 Notifications by SweetAlert2 (#1508) 2020-10-02 19:37:30 +02:00
Kevin Papst
0aa6baea2f explain limited access if project or customer has team permission (#2006) 2020-10-01 19:16:31 +02:00
Weblate (bot)
cafd84cee4 Translations update from Weblate (#1994)
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Kevin Papst <kevin@kevinpapst.de>
Co-authored-by: Balázs Fülöp <fulopbalazs91@gmail.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Juri Grabowski <hosted-weblate@jugra.de>
Co-authored-by: Katarzyna Sobolewska <kasia.sobolewska1@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: Péter Gyetvai <gyetpet@mailbox.org>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: Kevin Papst <kpapst@gmx.net>
2020-10-01 10:52:11 +02:00
Kevin Papst
0751c14907 highlight reporting in navigation for user-by-week report (#2005) 2020-09-30 18:47:17 +02:00
Kevin Papst
de0a9f8303 Fix user-email validation (#2004) 2020-09-30 18:38:34 +02:00
Kevin Papst
145116f657 fix backdrop location of sweetalert2 modals (#1997) 2020-09-28 19:22:53 +02:00
Kevin Papst
6a8c820e09 Update issue templates 2020-09-25 23:58:22 +02:00
Kevin Papst
2b033710e2 events: extend system configurations and set invoice formatter (#1995) 2020-09-25 19:51:23 +02:00
Kevin Papst
23f484a14d fix restart timesheet with meta-fields (#1993) 2020-09-24 16:55:23 +02:00
Kevin Papst
4cfa7347e9 ascending order for invoice items in command (#1980) 2020-09-18 12:08:09 +02:00
Toby Batch
aa1ea98579 added cwd in kimai:reload command (#1951) 2020-09-18 11:53:53 +02:00
Kevin Papst
38249e6b5e base plugin installation command (#1953) 2020-09-18 01:10:48 +02:00
Kevin Papst
c02a882eff allow to decrement invoice counter (#1947)
* added increment for cc, ccy, ccn, ccd
2020-09-17 02:53:38 +02:00
Kevin Papst
9ef32e75c5 added drag and drop for new records via calendar (#1962) 2020-09-17 01:13:48 +02:00
Kevin Papst
14b3de4300 translation fixes for weblate compatibility (#1970) 2020-09-13 12:18:46 +02:00
Kevin Papst
02d54fd208 weblate compatibility (#1969) 2020-09-13 12:06:01 +02:00
Kevin Papst
d1e9e3e43f fixing "translation id" in hebrew and romanian (#1968) 2020-09-13 10:57:10 +02:00
Kevin Papst
f279302009 adjusted translation file references (#1966) 2020-09-13 01:44:45 +02:00
Kevin Papst
e2a742b5c1 cleanup global context (#1943) 2020-09-08 20:35:14 +02:00
Kevin Papst
217960de60 configure first day of week for calendar and date-picker (#1952) 2020-09-05 18:31:37 +02:00
Kevin Papst
ed528eb19a bump tests to phpstan level 5 (#1922) 2020-09-05 16:48:19 +02:00
Kevin Papst
b69ea0648c bugfix release 1.10.2 (#1942) 2020-08-30 12:19:20 +02:00
IxFail
193d193352 Dutch translation update (#1939) 2020-08-30 11:37:04 +02:00
Kevin Papst
8e801c6829 added support for ordering meta fields (#1940) 2020-08-30 11:24:12 +02:00
Kevin Papst
e7da2b408a fixing formatting issues for money without currency (#1932) 2020-08-29 16:30:35 +02:00
Luca Buoncristiani
14255d71f7 Update italian translations (1.10) (#1929)
Co-authored-by: Luca Buoncristiani <luca.buoncristiani@bonificaumbra.it>
2020-08-27 13:33:46 +02:00
Kevin Papst
a258516322 bump version 1.10.1 (#1927) 2020-08-27 11:48:08 +02:00
Kevin Papst
d25bcfe29c use configured language for non-twig invoice templates (#1924) 2020-08-26 23:41:47 +02:00
Kevin Papst
8464cd925e query widget data for user (#1917) 2020-08-24 18:37:42 +02:00
Kevin Papst
c2c4f087e4 cleanup for 1.10 (#1906) 2020-08-22 19:15:54 +02:00
IxFail
064d083db6 updated dutch translations (#1905) 2020-08-21 21:52:24 +02:00
Kevin Papst
ede21fe46a more extension points for plugins (#1904) 2020-08-21 19:38:17 +02:00
Kevin Papst
5c79e68c77 reporting cleanup (#1903)
- show form error when trying to load invalid user
- added non-breaking space to first table cells to allow copy&paste to excel
- added several css classes to allow customizations
- remove team assignment check for user selection
2020-08-21 11:31:42 +02:00
Kevin Papst
e6d01f2a23 allow to order tables by more fields (#1902) 2020-08-21 10:48:57 +02:00
Kevin Papst
af4101c9fe fix distinct vs group_by (#1901) 2020-08-20 22:29:28 +02:00
Kevin Papst
b9ee811cbf helper for handling billable fields (#1900) 2020-08-20 15:03:57 +02:00
Kevin Papst
7a1dada9dc stacked bars in dashboard widget (#1893)
* cleanup global context usage in widgets
* allow empty strings as time format
* fix order and update of user settings form
* added link to reporting documentation
2020-08-19 13:19:08 +02:00
Kevin Papst
1de76ba266 added link to reporting documentation 2020-08-19 10:46:08 +02:00
Kevin Papst
ec612d1046 fix duration calculation for multiple entries of same activity 2020-08-19 10:08:25 +02:00
Kevin Papst
15c3acfa0b updated test 2020-08-19 00:37:49 +02:00
Kevin Papst
6aac85bddb updated test 2020-08-19 00:03:11 +02:00
Kevin Papst
d8ae7635d1 fix order and update of user settings form 2020-08-18 23:22:16 +02:00
Kevin Papst
fbb3dd89cf removed unused dependency 2020-08-18 15:08:43 +02:00
Kevin Papst
8d1e24ae90 removed unused dependency 2020-08-18 15:06:49 +02:00
Kevin Papst
367a901207 allow empty strings as time format 2020-08-18 15:03:46 +02:00
Kevin Papst
9597015413 cleanup global context usage in widgets 2020-08-18 11:39:41 +02:00
Kevin Papst
08696651fd Merge branch 'master' into stacked-working-hours 2020-08-17 19:04:00 +02:00
Kevin Papst
661c3897b0 new form type to select a daytime in system-configuration (#1895) 2020-08-17 00:18:51 +02:00
Kevin Papst
4200208c7b Bugfix in JS for project/activity selection in timesheet edit dialog (#1894) 2020-08-16 16:20:24 +02:00
Kevin Papst
aba7e05ee2 Merge branch 'master' into stacked-working-hours 2020-08-16 12:24:18 +02:00
Kevin Papst
ed4b82f4b1 Weekly reporting view (#1892) 2020-08-16 12:23:41 +02:00
Kevin Papst
2d4cfbe821 Weekly reporting view (#1892) 2020-08-16 12:20:33 +02:00
Kevin Papst
34a1e07824 adapt test 2020-08-16 01:50:40 +02:00
Kevin Papst
bb4233ddfe use stacked bars in dashboard to show different working tasks per day 2020-08-16 01:43:38 +02:00
Kevin Papst
2449a1e8bf fix serialized dates from API (#1888) 2020-08-12 21:56:47 +02:00
synaestic
dc9bc8a8ca assign existing tag on timesheet import (#1877) (#1883) 2020-08-12 21:54:00 +02:00
Kevin Papst
0914ebf737 added team permissions for activities (#1872) 2020-08-08 18:50:04 +02:00
Kevin Papst
dc162bf385 bump serializer bundle (#1867) 2020-08-04 10:28:43 +02:00
Kevin Papst
86add9b9f7 fix batch update resets export state (#1866) 2020-08-04 10:05:05 +02:00
Kevin Papst
476e6ca150 remove usage of getenv from codebase (#1861) 2020-08-02 01:02:04 +02:00
Kevin Papst
6f8c0e3cb6 disable headings in markdown (#1843) 2020-07-26 21:06:33 +02:00
Kevin Papst
6bd2390acf fix test 2020-07-26 20:47:06 +02:00
Kevin Papst
599b18ac99 link reporting screen for users and month charts (#1842) 2020-07-26 20:28:48 +02:00
Kevin Papst
130e6ac057 handle hidden users in teams (#1841)
* allow to add disabled users to team
* allow to include disabled users in user-select
* include disabled users when editing team members ONLY if they are already part of team
2020-07-26 13:13:06 +02:00
Kevin Papst
ecea92942c prepare release 1.10 (#1837) 2020-07-21 17:07:40 +02:00
Kevin Papst
12e348544d invoice: increase number, customer specific counter (#1836) 2020-07-21 16:11:52 +02:00
Kevin Papst
4b8f743fa6 added some more tests (#1835) 2020-07-21 15:27:29 +02:00
Kevin Papst
aee063bb3c added annotation based exporter (#1831)
* added user exporter
* added project exporter
* added customer exporter
* added activity exporter
2020-07-21 03:37:51 +02:00
Kevin Papst
93a23f3fa3 fix group by with ONLY_FULL_GROUP_BY mode (#1830) 2020-07-18 10:16:15 +02:00
Kevin Papst
7907b43ef7 UI improvement (#1829)
* open "create new project/activity" form in modal
* re-use action translation for create action title
* do not pre-select first customer in list - fixes #1828
* sort user preferences in sections for better visual grouping
* show comment date only in hover of user avatar
2020-07-17 20:32:11 +02:00
Kevin Papst
c843dba29a API improvements (#1826) 2020-07-17 20:30:16 +02:00
Kevin Papst
5864c7e127 added username to export (#1827) 2020-07-17 02:32:39 +02:00
Kevin Papst
f57b314466 Preparations for coming features (#1818)
* removed unused convert_tz code
* added timestampable listener to support automatic updates of change columns
* added modified_at, billable and category timesheet fields
* new timesheet API query parameter modified_after
2020-07-13 23:35:06 +02:00
Kevin Papst
f2dd2331a5 polish detail pages (#1817) 2020-07-12 20:11:13 +02:00
Kevin Papst
164af7ae02 added reporting screen (#1805) 2020-07-12 14:05:14 +02:00
Kevin Papst
b97d9f692d added team permissions on user queries (#1815) 2020-07-12 01:18:57 +02:00
Kevin Papst
32c1e3258e invoices: unified money, number and date formats and fully respect configured language (#1814) 2020-07-10 15:09:52 +02:00
Kevin Papst
19e4ebf88c several enhancements (#1808)
* show all fields in timesheet api docs
* fix action dropdown links #1806
* apply same validation rules for passwords and for api-tokens #1753
* added "duplicate team" action #1136
2020-07-10 03:57:15 +02:00
Kevin Papst
ea39d5c74d new translations to clarify working time periods (#1802) 2020-07-04 19:44:44 +02:00
Kevin Papst
682681afa5 added domain logic for permission checks (#1803) 2020-07-04 13:29:03 +02:00
Honza Kopecký
091740f407 timesheet lockdown with grace period (#1644) 2020-07-02 18:54:17 +02:00
Kevin Papst
e22830790b new system-config to prevent overlapping records (#1720) 2020-06-28 22:09:50 +02:00
Kevin Papst
e566305426 updated composer dependencies (#1796) 2020-06-28 15:43:38 +02:00
Maarten Kooyman
8530a03449 added support for weekly invoices (#1780) 2020-06-28 15:13:35 +02:00
Oscariremma
1a24aabb6f Fixed SV locale date format (#1790) 2020-06-25 19:34:53 +02:00
Kevin Papst
381f46cdd8 Invoices: show only custom documents in upload form (#1786) 2020-06-19 18:31:08 +02:00
Kevin Papst
470a6b30e0 configuration improvements (#1784) 2020-06-16 18:35:09 +02:00
Kevin Papst
ea4e930cbb Store sessions in database (#1736) 2020-06-11 16:54:51 +02:00
Kevin Papst
a75bdc52f6 Invoice: switch from and to address (#1776) 2020-06-11 15:19:29 +02:00
Kevin Papst
21d8e8bbb8 improve configurations for usage in multi-environment setups (#1775) 2020-06-11 01:26:57 +02:00
Oscariremma
57b4473bc8 Updated swedish translations (#1774) 2020-06-09 22:54:58 +02:00
Kevin Papst
ae6beff5d8 Allow to recalculate rates via bulk edit (#1768) 2020-06-05 12:25:56 +02:00
Kevin Papst
da5563960b Added Vietnamese translations (#1758) 2020-06-04 16:21:12 +02:00
Kevin Papst
3b6df1cb84 fix by-project and by-customer queries creating empty invoices (#1756) 2020-06-02 12:56:08 +02:00
Kevin Papst
91736e89cc added hebrew translations (#1724)
first day of week in datepicker is locale specific now
2020-05-24 13:58:13 +02:00
Kevin Papst
e2a4998341 added romanian translations (#1722) 2020-05-23 12:07:57 +02:00
Kevin Papst
3c511df7f7 fix required fields in API (#1718) 2020-05-19 11:24:30 +02:00
Kevin Papst
e61ffe4db4 create timesheet for multiple users (#1716) 2020-05-18 23:35:43 +02:00
Kevin Papst
9da46bbdcd re-using menu translation for tags (#1717) 2020-05-18 16:03:45 +02:00
Kevin Papst
e3749c8e8f added pdf template and other invoice improvements (#1693) 2020-05-10 16:19:59 +02:00
Kevin Papst
4e1ffedc20 make export layout definitions changeable (#1684) 2020-05-02 12:55:30 +02:00
Kevin Papst
35f864256f include project name in invoice name (#1672) 2020-04-29 18:51:33 +02:00
Kevin Papst
ad2698dae2 fixed multilineIndent (#1669) 2020-04-28 17:13:02 +02:00
Kevin Papst
46a7b13293 display more columns in invoice template listing (#1663) 2020-04-25 16:34:15 +02:00
Kevin Papst
cbd7124cec fix removing single permissions from event (#1661) 2020-04-24 19:02:21 +02:00
Kevin Papst
0debc70ead support budget and timeBudget in API calls (#1658) 2020-04-23 18:49:48 +02:00
Kevin Papst
f8331b74c7 using font awesome icon to render color dot (#1656) 2020-04-23 16:47:50 +02:00
Kevin Papst
12c4205785 added translate filter for meta-fields in detail pages (#1655) 2020-04-23 16:45:50 +02:00
Kevin Papst
8f5c4dc4ec fix API annotation for customer collection (#1654) 2020-04-23 16:28:03 +02:00
Kevin Papst
711139ad4c delete invoices (#1652)
* include all meta fields as template variables
* support invoice preview via command
* support deletion of generated invoices
2020-04-23 12:19:07 +02:00
Kevin Papst
cfe0724620 prepare release 1.9 (#1635) 2020-04-19 19:31:43 +02:00
Kevin Papst
aeef1dae2e bump version 2020-04-19 15:39:19 +02:00
Kevin Papst
0f3fa8fdbe Code improvements (#1649)
* use global namespace for faster lookups
* phpstan level 5
2020-04-19 14:37:14 +02:00
Lukas
7b25e9acaf added events for timesheet actions (#1598) 2020-04-15 18:07:14 +02:00
Kevin Papst
be00a519b3 show expired projects in search filter (#1641) 2020-04-15 16:19:32 +02:00
Kevin Papst
4254c2590a remove roles from users when role is deleted (#1640) 2020-04-15 15:44:28 +02:00
Kevin Papst
57254bf175 fix duration calculation in admin timesheet view (#1639) 2020-04-15 11:48:18 +02:00
Kevin Papst
fe8fecafeb minimize count and visibility columns for better table alignments (#1636) 2020-04-15 11:46:54 +02:00
jojoemade
0bc9e74853 added colors to tags (#1631) 2020-04-14 14:18:11 +02:00
KuboF Hromoslav
1dfceeea99 Update Czech translation (#1630) 2020-04-12 18:36:59 +02:00
Kevin Papst
68d703d1e3 added internal rates (#1591) 2020-04-08 14:50:15 +02:00
KuboF Hromoslav
82c713031e Esperanto translations (#1607) 2020-04-07 22:19:52 +02:00
Kevin Papst
5579c3d04f allow to create default team if none with the project/customer name exists (#1624) 2020-04-07 19:07:06 +02:00
Kevin Papst
5e7b0c7826 fixed restart timesheet with tags with active record (#1622) 2020-04-07 17:30:39 +02:00
Kevin Papst
9e1e1a7a96 added event before rendering permissions (#1599) 2020-03-30 01:22:57 +02:00
Kevin Papst
7becddc3a4 allow all characters as search term in API (#1597) 2020-03-30 01:06:18 +02:00
Kevin Papst
dfe949264f update funding for sponsors information 2020-03-28 10:49:32 +01:00
Kevin Papst
163fb1be4a fix non-ascii character break invoice download (#1592) 2020-03-27 00:55:23 +01:00
Kevin Papst
33f76f426c customize html and pdf exports with twig templates (#1582) 2020-03-23 01:51:02 +01:00
Kevin Papst
1ca1b00d11 added json, xml and txt invoice renderer (#1576) 2020-03-21 01:01:47 +01:00
Kevin Papst
c89750fe94 ensure user attributes are truncated (#1580) 2020-03-21 00:21:06 +01:00
Adrian Rudnik
fb2ce0d30a xlsx improvements (#1518) 2020-03-20 18:29:26 +01:00
Kevin Papst
b8c5323ece added command to create invoices via bash (#1574) 2020-03-20 13:14:05 +01:00
Kevin Papst
7b13ea860a switch to kimai specific user-bundle fork (#1568) 2020-03-17 21:24:51 +01:00
Kevin Papst
4b1cfa5840 added multi-select for customer, project and activity (#1557) 2020-03-16 14:06:26 +01:00
Kevin Papst
6eeb01ad48 validate v1 data before import (#1552) 2020-03-15 23:34:14 +01:00
Kevin Papst
e6e6a1eeea added invoice archive & configurable invoice numbers (#1541) 2020-03-14 01:16:58 +01:00
Kevin Papst
dd64eb98f9 support more columns in listings (#1548) 2020-03-13 18:21:16 +01:00
Kevin Papst
9cd111bae5 fix timesheet permissions for non-admins (#1542) 2020-03-13 18:02:35 +01:00
Kevin Papst
137dcbf7e1 update to latest composer libs (#1545) 2020-03-12 19:33:11 +01:00
Kevin Papst
fbdc668a22 show short summary under export table (#1547) 2020-03-12 17:05:51 +01:00
Kevin Papst
7f931cbfd3 highlight overlapping times (#1534) 2020-03-12 16:35:25 +01:00
Kevin Papst
7b7a962e04 fix deprecations in migrations (#1544) 2020-03-12 00:42:47 +01:00
Sebastian Schreiber
e4610af235 migrate from zend-ldap to laminas-ldap (#1530) 2020-03-12 00:34:23 +01:00
Kevin Papst
e7458e76e1 improve kimai v1 importer for projects without customer (#1543) 2020-03-12 00:20:22 +01:00
Luca Buoncristiani
04a43378d8 Italian translations update (#1538) 2020-03-11 16:38:28 +01:00
Honza Kopecký
809acb47bf Import groups from Kimai v1 (#1532) 2020-03-08 12:34:17 +01:00
Kevin Papst
ace2788b57 fix pdf creation for very large exports (#1533) 2020-03-08 00:24:49 +01:00
Sebastian Schreiber
d60e738bd2 Escape distinguished name in ldap search (#1528) 2020-03-06 16:16:31 +01:00
Kevin Papst
a50a59bbca inline css for html invoices (#1526) 2020-03-06 03:21:39 +01:00
Adrian Rudnik
76a6ea57a1 fixed sweet alerts blocking major ui elements (#1517) 2020-03-06 03:02:30 +01:00
Kevin Papst
9907694ef6 disable title on small reponsive screens (#1527) 2020-03-06 02:20:30 +01:00
Kevin Papst
20b3c31cbd code cleanup for phpstan level 4 (#1522) 2020-03-05 02:15:16 +01:00
Kevin Papst
25a74ffeee fixing user specific rates in kimai v1 importer (#1521) 2020-03-05 00:18:31 +01:00
Kevin Papst
b8273c4441 prepare release 1.8 (#1505) 2020-03-01 14:25:59 +01:00
Kevin Papst
8d3a305ec3 handle negative duration (#1510) 2020-03-01 13:46:37 +01:00
Kevin Papst
72b73bc9a6 support multi-line values in excel invoices (#1507) 2020-02-29 20:06:45 +01:00
Kevin Papst
ec31d206e2 added UI configuration for default start-time (#1506) 2020-02-28 16:06:00 +01:00
Kevin Papst
bf11de82fc Upload invoice documents via UI (#1495) 2020-02-27 23:19:19 +01:00
Kevin Papst
34d2228d5d option to use decimal format in user timesheet export (#1489) 2020-02-24 18:03:30 +01:00
Kevin Papst
0e507804b1 human friendly name for bundles (#1491) 2020-02-22 22:56:37 +01:00
Kevin Papst
6c7477f1a9 edit single system config section in modal (#1490) 2020-02-22 18:53:03 +01:00
Kevin Papst
886fc8d74e action to duplicate timesheet record (#1478) 2020-02-18 15:32:33 +01:00
Kevin Papst
7b218c33f9 added generic rules for auth firewall (#1472) 2020-02-18 13:54:03 +01:00
Kevin Papst
c67617262f duplicate projects with all settings (#1465) 2020-02-13 16:47:20 +01:00
Kevin Papst
057c824e9f replaced mailer library, added email templates (#1462) 2020-02-12 16:05:13 +01:00
Kevin Papst
1b4f4bba22 added option to use only pre-defined tags (#1463) 2020-02-12 15:35:42 +01:00
Philipp Strobel
847798eec1 use different arrow for paginated box widget (#1431) 2020-02-10 22:16:16 +01:00
Kevin Papst
52c7437076 added user-specific rates (#1455) 2020-02-10 20:29:43 +01:00
Kevin Papst
465d7166d4 remove pagerfanta bundle (#1458) 2020-02-10 16:38:26 +01:00
MikKrz
733aa58de8 added Polish translations (#1426) 2020-02-10 00:23:37 +01:00
Kevin Papst
9620627ea6 fix dates in project API (#1451) 2020-02-10 00:16:44 +01:00
Kevin Papst
e06314e802 replace travis with github actions (#1452) 2020-02-09 23:54:04 +01:00
Kevin Papst
986d922855 invoices: choose language and duration format (#1438) 2020-02-04 20:27:36 +01:00
Kevin Papst
75dcae6fbe update to Symfony 4.4 (#1275) 2020-02-04 15:29:26 +01:00
Luca Buoncristiani
375691365e added missing italian translation files (#1437) 2020-02-04 13:31:20 +01:00
infeeeee
5c5af05408 fixed glyphs in pdf export table header (#1435) 2020-02-03 17:18:39 +01:00
Kevin Papst
69cf7015d8 optimize detail pages, add new permission for comment posting (#1432) 2020-02-02 18:16:23 +01:00
Kevin Papst
6a533579b7 added support for saml login (#1408) 2020-01-31 19:47:34 +01:00
Kevin Papst
3ff46e06c0 code improvements (#1423)
* removed unused mapping information
* added support for further field types
* fixed changing date objects for begin and end
* added more project fields as invoice variables
* theme update and asset rebuild
2020-01-31 17:07:14 +01:00
Kevin Papst
9e2fccb105 added pagination to working time widget (#1418) 2020-01-30 21:51:27 +01:00
Kevin Papst
f2c6d8aee1 better handling of custom field columns in tables (#1419) 2020-01-29 15:18:10 +01:00
Kevin Papst
836a530b86 API methods to handle teams and users (#1384) 2020-01-28 22:28:31 +01:00
Kevin Papst
a31e027c54 updated slovak translations (#1414) 2020-01-28 22:02:37 +01:00
Kevin Papst
a1b554b3ac various code improvements (#1415) 2020-01-28 21:57:34 +01:00
Kevin Papst
79c4c237fa support for auto linking urls with file protocol (#1402) 2020-01-22 17:25:11 +01:00
Kevin Papst
85a35a3063 prepare release 1.7 (#1388) 2020-01-19 21:50:29 +01:00
Kevin Papst
e0e391efbe prepare release 1.7 (#1388) 2020-01-19 21:49:41 +01:00
Kevin Papst
9eff89963c prepare release 1.7 (#1388) 2020-01-19 21:49:04 +01:00
Lukas
352fac26f3 added missing raw filter (#1393) 2020-01-19 21:47:40 +01:00
Lukas
8c16bf126a added missing raw filter (#1393) 2020-01-19 21:47:17 +01:00
Lukas
42de968f8f added missing raw filter (#1393) 2020-01-19 21:46:47 +01:00
ikusimakusi
ed8f024e42 added Basque translations (#1382) 2020-01-17 15:28:12 +01:00
Kevin Papst
e534369c5b fix widgets imports (#1387) 2020-01-17 00:02:02 +01:00
Kevin Papst
fed797df93 order user roles and permissions (#1372) 2020-01-16 16:54:42 +01:00
Kevin Papst
6a44dbfe83 detail pages for customers and projects (#1371) 2020-01-16 16:25:28 +01:00
Kevin Papst
28c5357f11 allow to hide rate or duration in html export summary (#1370) 2020-01-14 13:46:07 +01:00
Kevin Papst
a8824f92a1 added support on PHP 7.4 (#1355) 2020-01-07 21:43:33 +01:00
Kevin Papst
e57b69973f re-written exporter for simpler extendability (#1349) 2020-01-07 21:20:45 +01:00
Kevin Papst
d6798eed1e added project start and end date (#1303)
* added sortable js library
* activity in invoice is optional
* added javascript widget for paginated boxes
* fix activity dropdown for globals only
* added timesheet service to reduce code duplication
* use repository to query for teams in dropdowns
* added project validator
* validate project start and end against timesheet
* include begin and end in dynamic form requests for projects
* added timezone and language option to import flag, improve timesheet import speed
* deactivate cross-timezone filter
* add virtual fields to field order list
* composer update
* added param to ignore dates
* position loader icon fixed - fixes #1330
* permission problem when creating a new project - fixes #1340
* remove dev dependencies webserver and thanks bundle
* stop information leak (begin and end date) in duration mode - fixes #1307
* unify timesheet edit dialog for user and admins
* fix security issue, own rates exposed to unauthorized users in multi-update dialog
2020-01-05 02:49:01 +01:00
hmr-it-jr
50383673ca added api endpoint to return instance specific timesheet config (#1335) 2020-01-04 01:44:11 +01:00
Kevin Papst
022dbe32e5 allow empty date in export (#1338) 2019-12-31 20:24:47 +01:00
Kevin Papst
baac4eb698 set rates via batch update (#1326) 2019-12-29 16:52:43 +01:00
Kevin Papst
8aa8f452d5 added exported filter in timesheet view (#1327) 2019-12-29 13:55:15 +01:00
Kevin Papst
54255cf923 validate tag name (#1325) 2019-12-16 16:55:34 +01:00
Kevin Papst
bd3d82d224 fix daterange filter for multi-timezone setups (#1321) 2019-12-16 16:23:03 +01:00
Kevin Papst
b14ad9f3ab renamed translation files from .xliff to .xlf (#1314) 2019-12-09 13:25:31 +01:00
Kevin Papst
261b4646e4 added chinese translations (#1310) 2019-12-09 12:56:38 +01:00
Kevin Papst
d62e1c4468 simplify to add widgets via plugin (#1308) 2019-12-06 23:36:03 +01:00
benzel
5b0266c462 clarified translation (#1309) 2019-12-06 22:05:33 +01:00
Kevin Papst
06118dcabb loose email validation on customer (#1224) 2019-12-02 15:06:06 +01:00
Kevin Papst
984c852ab6 Release 1.6.2 (#1289)
* include user teams in user entity
* prevent unauthorized access via API
* improve teamlead permission handling in team timesheets
* add team data to user entity
* add security tests
* highlight menu for invoice template copy
* unified handling of invoice data across all templates
* access to the current users data in invoice templates
* permission improvement in invoice form
* allow to skip record rows
* allow to add new invoice locations without overwriting the global ones
* allow to order user preferences
* change permission for normal users with access to view_other_timesheets
* properly validate invoice template field length
* allow to replace multiple variables in cell values text
* upgraded office invoice template
* doctrine deprecation fix
* upgrade phpoffice/phpword
* fix future begin check for default rounding rules
* dashboard widget counter: respect visibility and teams - fixes #1161
* fix future begin check for default rounding rules
* added new events for pre and post invoice rendering
* fix permission issue for users without team seeing all records
* prevent error in spreadsheet renderer for empty invoices
2019-12-02 10:57:03 +01:00
Badgie
47414cfd0e Danish translations (#1296) 2019-12-02 00:25:28 +01:00
Kevin Papst
fdf4fdfb6a fix sqlite installer (#1283) 2019-11-26 19:32:16 +01:00
Kevin Papst
5ee0396a02 Release 1.6.1 (#1282) 2019-11-26 17:22:31 +01:00
Kevin Papst
724eb9c658 release 1.6 (#1277) 2019-11-24 15:29:01 +01:00
Kevin Papst
936ab05882 prepare release 1.6 (#1270) 2019-11-24 00:02:43 +01:00
Kevin Papst
817a43b178 added csv importer for timesheet and project data (#1216) 2019-11-23 22:02:55 +01:00
Kevin Papst
0f16f42887 Select2 search enhancement (#1276) 2019-11-23 14:26:35 +01:00
Kevin Papst
641c199c8c API: allow to set user for timesheet (#1259) 2019-11-23 14:21:46 +01:00
Aptevo
04dd6b900f added de_CH language (#1272) 2019-11-23 11:29:29 +01:00
Kevin Papst
536a05210e enable interactive features of Swagger UI (#1273) 2019-11-22 21:59:25 +01:00
Kevin Papst
60d16016e8 allow to configure calendar slot duration (#1269) 2019-11-22 01:30:25 +01:00
Kevin Papst
9222075c7a Added update command (#1268) 2019-11-21 23:15:41 +01:00
1willem
641dcdff85 Dutch translation files (#1226) 2019-11-18 21:48:16 +01:00
Kevin Papst
668649be7a use homepage link to redirect from error page (#1260) 2019-11-18 12:29:21 +01:00
Kevin Papst
0de936d474 fix the password reset page layout (#1261) 2019-11-18 12:28:59 +01:00
Kevin Papst
47bd8b0ce7 added new invoice fields, improved invoice templates (#1258) 2019-11-18 12:01:26 +01:00
Kevin Papst
2287c9951c invoice: money fields without currency, title cleanup (#1254) 2019-11-15 18:54:08 +01:00
Kevin Papst
94c28ebbc5 Update and delete multi timesheets and tags (#1240) 2019-11-15 01:25:31 +01:00
Kevin Papst
b4739f8f03 allow to include bundle configuration in system configuration screen (#1235) 2019-11-14 19:25:38 +01:00
Kevin Papst
c32cd36861 fix reset input for forms (#1251) 2019-11-14 19:09:55 +01:00
Kevin Papst
945562b34d fixes wrong foreign keys on timesheet_tags join table (#1242) 2019-11-14 01:57:58 +01:00
Kevin Papst
af0f89774e User roles and permission management via Admin UI (#1231) 2019-11-10 18:53:56 +01:00
Kevin Papst
c6c4098759 rounding rules via admin screen, round begin when starting record (#1229) 2019-11-10 13:57:05 +01:00
Kevin Papst
fa1c79e15c support different formats in user timesheet exports (#1222) 2019-11-08 16:10:38 +01:00
Kevin Papst
0705c26513 highlight menus on sub-pages (#1220) 2019-11-07 11:19:10 +01:00
Kevin Papst
140fa4b7c0 prepare release 1.5 (#1214) 2019-11-03 17:31:33 +01:00
Kevin Papst
cd88901868 re-style error pages (#1210) 2019-10-31 14:20:53 +01:00
Kevin Papst
8eec97deb5 respect users timezone in statistic widgets (#1207) 2019-10-31 00:17:31 +01:00
Kevin Papst
4331a7c9f4 fix error pages (#1209) 2019-10-31 00:16:25 +01:00
Kevin Papst
f4fcfeba9d dynamic branding options (#1205) 2019-10-30 14:22:34 +01:00
Kevin Papst
48aefb1862 fix avatar path for subdirectory installations (#1201) 2019-10-30 14:00:48 +01:00
Kevin Papst
bda9584346 reformat edit forms (#1192) 2019-10-30 13:59:53 +01:00
Kevin Papst
ed1154af67 fix absolute url (#1200) 2019-10-30 13:45:59 +01:00
Kevin Papst
c368eacd87 fixed renamed filter name, added that disabled users cannot be filtered (#1193) 2019-10-27 13:56:45 +01:00
Kevin Papst
949c59230f improve list views (#1191) 2019-10-25 16:21:30 +02:00
Kevin Papst
1114538f41 duration field in timesheet edit dialog (#1180) 2019-10-24 23:46:22 +02:00
Kevin Papst
b0f83291ee upgraded to phpunit 8 (#1155) 2019-10-24 17:35:05 +02:00
Kevin Papst
e91e4ff430 support search term in API collection requests (#1185) 2019-10-24 17:31:15 +02:00
Ahmed Şeref
4ad290d4bd added turkish translations (#1160) 2019-10-24 17:30:34 +02:00
Kevin Papst
37c6e2c0af added order-date field to project (#1186) 2019-10-24 17:04:21 +02:00
Kevin Papst
b4a45afce9 fix API login in subdirectory installations (#1181) 2019-10-24 11:06:12 +02:00
yayitazale
330ff6eb47 updated spanish translations (#1183) 2019-10-24 10:53:23 +02:00
Adrian Rudnik
c681eb1bdb docker fix to hide details for 500 errors (#1173) 2019-10-21 16:22:29 +02:00
Kevin Papst
de533e7031 Kimai 1.4.2 (#1167) 2019-10-14 12:30:11 +02:00
Kevin Papst
ae6ed3f23f Bugfixes for Kimai 1.4.1 (#1158)
* fix missing translation for preset datatable headers
* better dependency check for avatar service
* show only own teams to teamleads
2019-10-07 16:04:19 +02:00
Kevin Papst
32aa209b75 prepare release 1.4 (#1154) 2019-10-04 07:36:59 +02:00
Kevin Papst
e8c25d8ac5 added avatars, show user teams in list, new team dashboard widgets (#1150) 2019-10-03 13:44:16 +02:00
Kevin Papst
718ad4b398 fix migrations for older database versions (#1148) 2019-09-27 14:52:22 +02:00
Kevin Papst
8d81a394ee updated theme, fix deprecations in events dispatching (#1145) 2019-09-25 19:12:12 +02:00
Kevin Papst
d661c8b54e fix closing search dropdown (#1142)
* using a different library for javascript selects, fixing the closing search dropdown
* fix closing dropdown for daterangepicker
* added missing search button for mobile on customer page
* fix meta fields with same names than existing columns
2019-09-25 18:34:25 +02:00
Kevin Papst
e45e782e7d fix invoice preview (#1129) 2019-09-20 16:00:03 +02:00
Kevin Papst
5aa422dde1 Display meta-fields in datatables (#1116) 2019-09-19 20:28:31 +02:00
Kevin Papst
24cbe3d281 post 1.3 fixes (#1106) 2019-09-17 22:20:36 +02:00
Kevin Papst
13f5e76015 added czech translations (#1075) 2019-09-16 23:19:46 +02:00
Kevin Papst
35c65ba890 composer update (#1104) 2019-09-13 17:16:53 +02:00
Kevin Papst
8f2b82b832 bump version to 1.3 (#1102) 2019-09-12 00:36:48 +02:00
Kevin Papst
7f1a206a52 support installation specific translations (#1099) 2019-09-11 23:18:35 +02:00
Kevin Papst
8c503a226e fix API version string (#1096) 2019-09-11 21:44:14 +02:00
Kevin Papst
cdcf9eaf67 handles session timeouts in modals (#1092) 2019-09-10 17:07:34 +02:00
Kevin Papst
a651e55dc9 added table-column ordering (#1086) 2019-09-09 23:47:42 +02:00
Kevin Papst
d041a3f4f9 improved tag auto-completion and added tag management (#1083) 2019-09-04 23:47:33 +02:00
Kevin Papst
3ea05cb705 support multiple invoice repositories (#1084) 2019-09-04 22:50:53 +02:00
hmr-it-jr
3f27ab1e44 added mail icons (#1077) 2019-09-04 19:49:03 +02:00
Kevin Papst
e99b170d0a refactored search with free search term support (#1064) 2019-09-04 18:54:06 +02:00
Kevin Papst
49e1a1c410 use timesheet description in invoices (#1079) 2019-09-04 10:54:21 +02:00
Kevin Papst
93ab3d5666 post release 1.2 fixes (#1068)
* fix release command
* fix permission name in UPGRADING
* added missing korean calendar translations
* fixed entry.total for invoice with fixed rates
2019-09-03 11:59:34 +02:00
Kevin Papst
94f8159fdc prepare release 1.2 (#1059) 2019-08-27 18:37:42 +02:00
Kevin Papst
8fb0b1445a added korean translations (#1039) 2019-08-26 15:00:59 +02:00
Kevin Papst
15673555a2 added API functions to save meta fields (#1063) 2019-08-26 14:30:39 +02:00
Kevin Papst
ceeec7b8a6 improved invoice handling for fixed rates (#1058) 2019-08-24 00:02:16 +02:00
Kevin Papst
46e5650882 refactored invoice and export screens (#1046) 2019-08-22 18:56:21 +02:00
Kevin Papst
405ea0076b fix empty user language (#1054) 2019-08-21 11:16:44 +02:00
Kevin Papst
8cd7f7de3f do not delete team if linked entity is deleted (#1053) 2019-08-21 01:04:58 +02:00
Kevin Papst
7cd17154fc support creating new roles (#1050) 2019-08-20 14:02:15 +02:00
Kevin Papst
299fcb091a added documentation links to all screens (#1044) 2019-08-19 12:53:36 +02:00
Kevin Papst
025c6b0e7b added css class to target running records in timesheet tables (#1042) 2019-08-16 22:34:41 +02:00
Kevin Papst
388c3ec188 reduce field size to 150 chars to prevent index out of length (#1031) 2019-08-16 16:57:09 +02:00
Kevin Papst
b6d9bb0d2a fix team opens in modal (#1041) 2019-08-16 16:55:56 +02:00
Kevin Papst
561ec3b1e9 added team permissions (#996) 2019-08-16 01:22:33 +02:00
Kevin Papst
9611646bc6 added decimal format variable for invoice duration (#1037) 2019-08-15 21:31:13 +02:00
Kevin Papst
b5972bb680 added invoice variable to display month numerical (#1033) 2019-08-14 23:30:45 +02:00
Kevin Papst
455861ec69 copy timesheet meta fields on restart record (#1030) 2019-08-13 18:41:20 +02:00
trentks
5affa0de82 fix various minor english grammar translations (#1002) 2019-08-08 23:04:02 +02:00
Kevin Papst
e11a2a6089 upgraded FosUserBundle and Symfony 4.3 (#1005) 2019-08-02 16:52:30 +02:00
Kevin Papst
614a50ce0b added command to show plugin versions (#994) 2019-08-02 08:53:51 +02:00
Kevin Papst
66594b286a remove default role from user filter and role select (#993) 2019-08-02 08:31:45 +02:00
Kevin Papst
8e06f94bdd composer prod dependencies and commands (#986) 2019-08-01 23:21:43 +02:00
trentks
b0e03bb0b8 Fix english translation for 'info' (#995) 2019-08-01 23:01:02 +02:00
Kevin Papst
22e30b1871 fix activity import Kimai v1 (#1001) 2019-08-01 21:38:28 +02:00
Kevin Papst
8104a67e3e travis builds with mysql (#924) 2019-08-01 19:25:38 +02:00
Kevin Papst
654ffda454 respect users timezone when populating working-time dashboard widget (#988) 2019-07-30 23:57:20 +02:00
cdahinten
3f51437569 optimize DE translations (#950) 2019-07-29 13:31:00 +02:00
Kevin Papst
1bd784eef3 added calendar slot_duration config (#989) 2019-07-26 23:51:29 +02:00
yayitazale
0d11aded40 spanish update - more natural translations (#945) 2019-07-25 18:26:39 +02:00
Kevin Papst
00925d38aa fix migration for sqlite users (#985) 2019-07-25 18:00:53 +02:00
Kevin Papst
12803b3957 prepare release 1.1 (#983) 2019-07-24 19:38:46 +02:00
Kevin Papst
7583498735 added invoice calculator to sum by day (#982) 2019-07-24 18:36:06 +02:00
Kevin Papst
53eda31179 project grouped invoice calculator (#892) 2019-07-24 17:45:51 +02:00
Kevin Papst
56e276939b trigger template events in authentication layout as well (#981) 2019-07-24 15:32:46 +02:00
Kevin Papst
39abccb35d dashboard is missing in initial view (#974) 2019-07-24 14:47:07 +02:00
Toby Batch
dae8866053 Fixes regexp for search timesheets by tag (#978) 2019-07-22 15:34:40 +02:00
Kevin Papst
a0e8aa3a43 fixed xss in timesheet description (#962) 2019-07-14 13:58:10 +02:00
Kevin Papst
e68b7da1f8 added slovakian translations (#952) 2019-07-12 15:52:30 +02:00
Marcos Ellys Rocha Honorato
fcce7a531a updated Portuguese (Brazilian) translations (#942) 2019-07-11 00:18:42 +02:00
Kevin Papst
f23dcbec17 run migrations always in kimai:install command (#944) 2019-07-10 19:19:03 +02:00
Kevin Papst
8a1d28563d fix changing project for existing entries (#940) 2019-07-10 19:17:34 +02:00
Kevin Papst
c33a87a07c toolbar dropdown and visibility improvements (#933) 2019-07-09 16:34:11 +02:00
Toby Batch
b833e1ce27 pre-populate tags for new timesheet records via request params (#930) 2019-07-09 16:32:40 +02:00
Kevin Papst
6de1a55d73 updated swedish translations (#934) 2019-07-09 14:02:11 +02:00
Kevin Papst
cbf9086e10 performance improvements (#927) 2019-07-09 03:40:48 +02:00
Kevin Papst
eb4aa23577 allow non-interactive installation (#932) 2019-07-09 03:03:27 +02:00
Kevin Papst
bf9ae44775 fix LDAP edge-case initialization error (#931) 2019-07-08 20:35:41 +02:00
Kevin Papst
f0822fa2b1 prepare release 1.0.1 (#922) 2019-07-05 19:25:06 +02:00
Kevin Papst
f966d34929 updated all composer packages (#920) 2019-07-05 15:07:03 +02:00
Kevin Papst
d51136f8f4 cleanup prod log config (#921) 2019-07-05 13:48:24 +02:00
Kevin Papst
19843760e5 allow to configure default values for users (#919) 2019-07-05 02:42:50 +02:00
Kevin Papst
3457f93ed0 fix 500 happening in error pages (#914) 2019-07-04 17:00:55 +02:00
Kevin Papst
625ac2f1d7 fix default calendar config (#918) 2019-07-04 16:59:57 +02:00
Kevin Papst
061581c4ff use pre-defined icons in menu as well (#913) 2019-07-04 14:59:03 +02:00
Kevin Papst
a0116422c6 remove scrutinizer (#915) 2019-07-04 14:57:07 +02:00
yayitazale
94e49ea86f updated Spanish translations (#906) 2019-07-02 12:10:38 +02:00
heddi.nabbisen
040409eac7 Update japanese translation (#905) 2019-07-02 12:07:01 +02:00
Kevin Papst
baa2fca7ca Release 1.0 (#885) 2019-07-02 02:36:46 +02:00
infeeeee
1fd8139214 Update Hungarian translation (#902) 2019-07-02 00:14:31 +02:00
Kevin Papst
db5f9f639e fix selectbox is not resettable (#901) 2019-07-02 00:14:06 +02:00
Kevin Papst
90980f40f5 allow to disable user preferences by permission (#895) 2019-07-01 19:37:20 +02:00
Kevin Papst
94d68c8b64 fixed short invoice (#891) 2019-06-30 18:38:02 +02:00
Kevin Papst
834a0a873f fix migration for sqlite (#881) 2019-06-30 15:16:44 +02:00
Kevin Papst
d8621f0b7a support custom fields for timesheets, customers, projects and activities (#871) 2019-06-26 00:39:05 +02:00
Kevin Papst
994c671fd8 order users by username (#880) 2019-06-26 00:35:54 +02:00
Kevin Papst
7b95750dcf added LDAP config to set filter for finding user attributes (#877) 2019-06-23 12:38:11 +02:00
Kevin Papst
9fbbaf9b88 performance tuning on timesheets (#874) 2019-06-20 16:05:31 +02:00
Jacob Blanco
bb8572a364 fix LDAP hydration with multi-value email field (#862) 2019-06-20 15:35:22 +02:00
Kevin Papst
bdd05a275d use default_begin in duration only mode (#873) 2019-06-20 01:38:28 +02:00
Toby Batch
dcdbf23b6d load plugins in test env (#864) 2019-06-19 23:10:06 +02:00
Kevin Papst
ce6ad0bbb8 export tags in spreadsheets (#860) 2019-06-16 15:35:22 +02:00
Kevin Papst
59d2946b91 add "duration + fixed start time" tracking mode (#859) 2019-06-15 23:04:53 +02:00
Kevin Papst
92f3f4ee57 added config to brand Kimai with logo and company name (#856) 2019-06-13 19:06:02 +02:00
Kevin Papst
3311f17bbb users weekly stats as bar-chart in dashboard (#847) 2019-06-13 18:38:49 +02:00
yayitazale
e1f862507e Spanish translate updated (#852) 2019-06-13 13:41:26 +02:00
Thierry Pasquier
7e040ac216 Update of the French translation (#850) 2019-06-13 13:02:12 +02:00
Kevin Papst
515c19422d improved fixture data for demo (#848) 2019-06-11 14:55:25 +02:00
Kevin Papst
5702d7afa8 added hourly and money budgets to activity, project and customer (#843) 2019-06-11 13:18:57 +02:00
Kevin Papst
833968a87d fix LDAP install for systems without ldap extension (#846) 2019-06-11 01:25:49 +02:00
Kevin Papst
0c0e9c2f71 LDAP authentication support (#815) 2019-06-07 22:48:39 +02:00
Kevin Papst
bcf1ebd778 fixed pdf temp directory (#845) 2019-06-07 18:17:45 +02:00
heddi.nabbisen
4c82f9767f updated japanese translations (#837) 2019-06-05 13:57:08 +02:00
Kevin Papst
ab405f671e updated dockerfile (#840) 2019-06-05 13:56:31 +02:00
Kevin Papst
325d204332 added installation command (#838) 2019-06-04 23:51:37 +02:00
Kevin Papst
97feed0be6 updated frontend stack to latest versions (#729) 2019-06-03 01:43:49 +02:00
Kevin Papst
19636582ab use codecov for code coverage (#833) 2019-06-01 11:53:27 +02:00
Kevin Papst
393abe9e62 phpstan level 3, fixed deprecations, code cleanup (#811) 2019-05-28 12:24:21 +02:00
Kevin Papst
d9dca96a32 added punch-in punch-out / time-clock mode (#812) 2019-05-27 01:36:43 +02:00
Kevin Papst
ebff4a765a refactored permissions for simpler customizations (#808) 2019-05-25 17:23:15 +02:00
Kevin Papst
d18019159b fix tag query to show all tags of an item, even if not included in query (#810) 2019-05-25 16:27:01 +02:00
Kevin Papst
46905e9504 allow markdown for customer, project and activity comments (#807) 2019-05-25 00:29:23 +02:00
Kevin Papst
8b1c15ccb6 added github funding config (#804) 2019-05-24 13:16:25 +02:00
Kevin Papst
8873947a1b added phpstan for code analyzes (#806) 2019-05-24 01:11:03 +02:00
Kevin Papst
cdef22b4d1 added SECUTRITY.md for reporting vulnerabilities (#805) 2019-05-23 21:42:52 +02:00
Kevin Papst
29209105d3 improved html export (#802) 2019-05-23 18:19:56 +02:00
Kevin Papst
fea3495098 lock exported timesheets (#798) 2019-05-22 22:28:29 +02:00
Kevin Papst
871b2e52c7 use dropdown for entity actions on detail pages (#801) 2019-05-21 23:21:26 +02:00
Kevin Papst
ec174a38a9 timesheet controller refactoring (#796) 2019-05-19 23:52:43 +02:00
Kevin Papst
46ff78a4c4 fix phpunit annotations (#794) 2019-05-19 17:05:07 +02:00
Kevin Papst
d2ad87d09c improved calendar (#784) 2019-05-19 16:16:20 +02:00
Kevin Papst
1903d6fb77 fix column and max key length (#789) 2019-05-14 23:09:33 +02:00
Kevin Papst
bbe1f9beda restart via API allows to copy description (#782) 2019-05-13 17:32:01 +02:00
heddi.nabbisen
1f5710eaba updated japanese translations (#779) 2019-05-13 13:16:27 +02:00
Kevin Papst
392f8239f5 bugfix for API selects (#780) 2019-05-12 17:22:24 +02:00
Kevin Papst
5c227888f2 delete timesheets via api (#776) 2019-05-12 03:26:31 +02:00
Mathias
e29e183e84 added tags for timesheets (#604) 2019-05-12 01:40:04 +02:00
Kevin Papst
f31118292c translate date picker and charts (#775) 2019-05-12 00:56:00 +02:00
heddi.nabbisen
5f4a5364b0 add japanese translation (#774) 2019-05-11 22:37:36 +02:00
Kevin Papst
09da7cd242 javascript and api to stop and display active records (#772) 2019-05-10 13:45:09 +02:00
Björn Weinbrenner
e619b5fd31 added more entity actions (#757) 2019-05-10 02:10:37 +02:00
Kevin Papst
b1855447b8 recent activities via API (#761) 2019-05-07 22:24:28 +02:00
Kevin Papst
98f386dad6 refactored javascript to ES6 classes (#759) 2019-05-06 15:22:52 +02:00
Kevin Papst
80af3fb010 fix toolbar requests for empty choice (#758) 2019-05-05 08:31:13 +02:00
Kevin Papst
6e224c63ef improve cross database engine compatibility (#756) 2019-05-05 03:09:02 +02:00
Kevin Papst
aa113cc300 dynamically update title and visible durations for running records (#752) 2019-05-05 03:01:25 +02:00
Kevin Papst
65df1ff909 colors for visual grouping of customer, projects and activities (#751) 2019-05-04 01:45:52 +02:00
Kevin Papst
e92c2d168e entity action buttons re-designed (#746) 2019-05-03 21:10:16 +02:00
Kevin Papst
455d772095 moved shared entity fields and functions to trait (#750) 2019-05-02 18:03:40 +02:00
Kevin Papst
e80973c4d2 refactored column visibility modal to ES6 (#733) 2019-05-01 22:18:57 +02:00
Kevin Papst
721ecdbf3d prevent jumping icons in navbar between collapsed and open state (#739) 2019-04-30 18:50:31 +02:00
Kevin Papst
e6b3d4349e navbar block cleanup (#742) 2019-04-30 18:10:25 +02:00
Kevin Papst
b865add1b3 translate time-tracking in login screen and browser title (#738) 2019-04-30 17:52:19 +02:00
Kevin Papst
b35022d161 use bootstrap tooltips instead of own solution (#741) 2019-04-30 17:00:10 +02:00
Kevin Papst
62b091c77b always query timesheets by begin date (#740) 2019-04-30 14:31:10 +02:00
Kevin Papst
cdb112df05 theme update for swedish auth screens (#737) 2019-04-30 14:29:52 +02:00
Kevin Papst
6dc4fa0811 fix tests that failed around midnight (#735) 2019-04-29 02:29:40 +02:00
Kevin Papst
fb17af1afd prepare release 0.9 (#730) 2019-04-29 01:48:27 +02:00
Kevin Papst
b8811924c3 reduce config complexity by converting php format to js format (#734) 2019-04-29 00:24:23 +02:00
Kevin Papst
1b0b45649d added swedish (#732) 2019-04-28 23:55:27 +02:00
Kevin Papst
e49bd05ae6 updated authorization screen styles (#727) 2019-04-27 19:58:32 +02:00
Kevin Papst
32f0d80729 configs: overwrite via prepend, mode instead of duration_only (#715) 2019-04-26 16:14:28 +02:00
Simone Gasparini
f0f757cf75 allow dynamic export types (#703) 2019-04-25 19:33:06 +02:00
Kevin Papst
ccf4e32523 added delete timesheet API endpoint (#726) 2019-04-25 18:27:58 +02:00
Kevin Papst
56fe14c451 UI updates - new user menu, updated about and profile screen and more (#723) 2019-04-25 17:50:28 +02:00
Kevin Papst
28801bf1ea remove invalid cache header (#722) 2019-04-24 18:14:08 +02:00
Kevin Papst
460391136f API: changed date-format, camelCase instead of snake_case, null values, update and create for customer and project (#718) 2019-04-24 18:13:33 +02:00
Kevin Papst
215d4fc8bf apply users timezone to toolbar queries (#716) 2019-04-22 16:21:22 +02:00
horlabs
46cb021260 API: added activities create and update (#717) 2019-04-22 16:16:06 +02:00
Kevin Papst
f9c8028ea1 updated to Symfony 4.2 (#710) 2019-04-21 01:41:08 +02:00
Kevin Papst
32b36f42f0 remove unused role ROLE_CUSTOMER (#712) 2019-04-19 18:42:25 +02:00
Kevin Papst
48f3ad842d fix validation for create user command (#709) 2019-04-17 00:20:38 +02:00
Simone Gasparini
3251b26d9e added floor and ceil rounding modes (#695) 2019-04-16 17:36:47 +02:00
Simone Gasparini
136df3724f removed active flag in user preferences form for own profile (#696) 2019-04-16 17:30:51 +02:00
Kevin Papst
0d6b8486c4 remove the total counter from all admin pages (#708) 2019-04-16 17:20:53 +02:00
Kevin Papst
3a4aa5a001 added plugin screen (#671) 2019-04-08 18:38:56 +02:00
Kevin Papst
5bea9915f5 improved activity-project assignment in importer (#679) 2019-04-05 23:29:16 +02:00
hmr-it-jr
26de367bc5 added content-type to allowed cors header for api (#672) 2019-04-01 21:51:46 +02:00
infeeeee
3c361c9414 Updated hungarian translation (#661) 2019-03-26 15:37:28 +01:00
Kevin Papst
0d4fdc38e4 remove mailer url from about debug info (#657) 2019-03-23 13:31:52 +01:00
Kevin Papst
6f7035e4cf fixing default env var for cors header (#656) 2019-03-23 13:24:15 +01:00
Kevin Papst
38ae013e03 added cors bundle to allow external api access (#655) 2019-03-23 11:04:55 +01:00
Kevin Papst
13d9f8f3f7 added database driven system configurations with admin screen (#647) 2019-03-22 20:58:38 +01:00
Kevin Papst
e990ae4800 fix modal autofocus problem, datepicker not shown on begin date (#653) 2019-03-22 15:00:59 +01:00
Kevin Papst
6a68dc6e4f added route to redirect locale to configured homepage (#654) 2019-03-22 14:37:54 +01:00
Kevin Papst
cfc19dca25 fix pdf export cache directory (#650) 2019-03-22 14:37:25 +01:00
Kevin Papst
50318a8fc5 added command to create release packages (for FTP user) (#642) 2019-03-18 11:57:26 +01:00
Kevin Papst
bde791fa55 added begin, end and export filter for API timesheets (#639) 2019-03-14 03:34:54 +01:00
Kevin Papst
2e6f3ed864 delete directory with invalid case (#643) 2019-03-13 18:50:34 +01:00
Kevin Papst
fb6bf4319f removed dynamic database prefix (#641) 2019-03-13 15:17:18 +01:00
Kevin Papst
19bfff9899 set autofocus attribute on form fields for better keyboard support (#640) 2019-03-13 00:09:02 +01:00
Kevin Papst
f4d53e9006 replaced delete confirm dialog with modal (#638) 2019-03-12 23:24:22 +01:00
Kevin Papst
46655ad462 support subdirectories and subdomains for assets (#636) 2019-03-12 01:02:42 +01:00
blueowl04
1b6b957b23 allow non-interactive timezone conversion (#637) 2019-03-11 18:44:54 +01:00
Kevin Papst
0f6334314e removed inline documentation (#624) 2019-03-11 15:10:51 +01:00
Kevin Papst
3ac72a5c89 enhanced plugin support (#634)
- refactored admin controller and templates
- plugin support for entity actions
- changed column mail to email in customer table
- refactored theme events
2019-03-11 14:46:30 +01:00
Kevin Papst
519be2d5a2 remove invisible entities from toolbars (#628) 2019-03-08 20:22:58 +01:00
Kevin Papst
e8bc45f7dd fix random order in recent activities (#631) 2019-03-08 16:09:37 +01:00
Kevin Papst
76c3c5f2f6 fix for firefox datepicker focus problem in modals (#630) 2019-03-08 01:16:10 +01:00
Kevin Papst
54cd30c564 added support for Ante meridiem and Post meridiem format (#615) 2019-03-06 10:59:31 +01:00
Kevin Papst
e260dd84ad Improve create and start permission handling (#613) 2019-03-06 10:24:27 +01:00
Kevin Papst
bce85b04d6 added filter for global activities (#614) 2019-03-05 01:42:06 +01:00
Kevin Papst
642db480ce added new rounding mode: closest (#611) 2019-03-03 20:33:35 +01:00
Kevin Papst
bea4be881b Edit and create timesheet records in modal (#603)
- added loading indicator for datatables
- fix multiple reloads of datatable content
2019-03-03 19:43:12 +01:00
Kevin Papst
86832fb703 code cleanup (#602) 2019-02-26 02:26:37 +01:00
Kevin Papst
03aa4c9ddc Plugins support (#592) 2019-02-24 15:54:38 +01:00
Kevin Papst
36a158a805 simplified theme settings and standard layout (#586) 2019-02-23 13:51:44 +01:00
Kevin Papst
32fbebd469 order datatable items by name (#594) 2019-02-23 02:27:56 +01:00
Kevin Papst
3d4b0c3fd6 UI improvements for datatables (#593) 2019-02-22 21:25:43 +01:00
Kevin Papst
1f7ec6769a release 0.8.1 (#595) 2019-02-22 18:05:45 +01:00
Kevin Papst
239be527b8 post release fixes (#584) 2019-02-22 17:20:41 +01:00
Kevin Papst
fd4a87e3a6 Support foreign keys with SQLite (#590) 2019-02-20 20:06:19 +01:00
Kevin Papst
3f535cc506 stop navbar from breaking on mobile views (#583) 2019-02-20 00:35:04 +01:00
Kevin Papst
0b57bd51ca fix sql for only_full_group_by (#581) 2019-02-19 13:39:08 +01:00
Kevin Papst
49c78ddd9d updated CHANGELOG (#580) 2019-02-19 12:49:02 +01:00
Kevin Papst
47b7046743 release 0.8 (#567) 2019-02-19 11:03:11 +01:00
Kevin Papst
b4f1cae323 fix pagination in combination with daterange picker (#568) 2019-02-14 01:09:23 +01:00
Kevin Papst
17856e0b96 handle deleted user during import from v1 (#569) 2019-02-14 00:26:54 +01:00
Kevin Papst
8005679e60 allow to query other users timesheets via api (#563) 2019-02-14 00:04:27 +01:00
Kevin Papst
ef33233624 fix timezone problems in timesheet forms (#555) 2019-02-13 21:37:54 +01:00
Kevin Papst
2c6f57c7ce daily stats in timesheet (#552) 2019-02-13 15:36:59 +01:00
Kevin Papst
fd60d5bb17 Updated HTML invoice templates (#560) 2019-02-12 15:35:33 +01:00
Kevin Papst
742e6eb3a3 updated composer packages (#559) 2019-02-11 20:38:40 +01:00
infeeeee
331ea586f1 updated php requirements in dev-documentation (#551) 2019-02-11 16:28:27 +01:00
infeeeee
afb0eabaa4 styles: year selector width, recent activities menu width (#549) 2019-02-09 23:13:47 +01:00
Kevin Papst
afa0aa5b3a improve recent activities (#550) 2019-02-09 23:01:35 +01:00
Kevin Papst
1f99f69ecd fix daterange-picker for fr, hu and ar (#547) 2019-02-08 20:02:23 +01:00
Kevin Papst
d00596d297 convert timesheets to UTC with support for user timezone (#372) 2019-02-08 18:24:33 +01:00
Kevin Papst
8dcc18dde3 improved installation docs (#548) 2019-02-08 18:16:53 +01:00
Sanjit Patel
616d514d5a Use Symfony formatter for currency symbol placement (#542) 2019-02-08 16:56:47 +01:00
Kevin Papst
b2587c71b8 do not limit timesheet-export page size (#545) 2019-02-07 23:43:20 +01:00
Kevin Papst
816866549c added export module (#538) 2019-02-05 21:37:33 +01:00
Kevin Papst
062735c9e3 added daterange-picker and localized date-inputs (#540) 2019-02-03 21:24:30 +01:00
Kevin Papst
aae9183de6 highlight current day in date-picker (#527) 2019-02-02 15:27:02 +01:00
Kevin Papst
7f3e2d453f updated documentation (#536) 2019-02-01 16:33:55 +01:00
Kevin Papst
1b42aed34c support remote data in beta-test selectpicker (#529) 2019-01-31 12:59:25 +01:00
Kevin Papst
974806d145 Improve allowed running records (#528) 2019-01-29 20:45:04 +01:00
Kevin Papst
fe4c3c10d6 added configurable view after login (#523) 2019-01-29 02:15:12 +01:00
Kevin Papst
67dab35b57 prepare release 0.7 (#514) 2019-01-28 01:40:42 +01:00
Kevin Papst
55d8bc9ba5 pagination without reload while keeping filters applied (#521) 2019-01-23 18:48:17 +01:00
Kevin Papst
572f01ed74 go back to calendar after editing and creation of time-records (#519) 2019-01-23 17:30:45 +01:00
Kevin Papst
ee32d6f926 fix wrong include filename in user registration (#520) 2019-01-23 14:16:37 +01:00
Kevin Papst
89abaa9dda fetch toolbar results without page reload (#518) 2019-01-23 02:45:33 +01:00
Kevin Papst
a9ece209ae Form and theme improvements (#513) 2019-01-21 13:10:53 +01:00
Lukas
47ac50b4d0 Only one running timesheet: automatically stop others (#386) 2019-01-21 12:49:22 +01:00
Kevin Papst
5539f68a54 validation for future and negative times (#512) 2019-01-21 01:51:57 +01:00
Kevin Papst
5b1ec1eb8f alphabetical order for selectboxes (#510) 2019-01-19 19:24:29 +01:00
Kevin Papst
a609cbf84a export team timesheets (#508) 2019-01-19 00:25:00 +01:00
Kevin Papst
1ad440f488 support template variable entry.row for docx if description is not used (#504) 2019-01-18 16:19:02 +01:00
Kevin Papst
64330e6cc4 display invoice entries in ascending order (#505) 2019-01-18 14:32:08 +01:00
Kevin Papst
03421c099a fix broken sql in activity admin (#506)
* fix broken sql in activity admin
* pre-select customer for existing activities
2019-01-18 14:30:20 +01:00
Lukas
b5c4084452 support anchor links for inline documentation (#482) 2019-01-17 23:30:02 +01:00
Kevin Papst
5d5b971f57 do not display admin menu if it has no children (#500) 2019-01-17 01:25:00 +01:00
Lukas
825d31af20 improve login screen and simplify customizations (#493) 2019-01-17 01:01:30 +01:00
Toby Batch
7880f980a8 Better composer install in docker (#481) 2018-12-21 14:32:04 +01:00
Steve Colson
137fd69f47 Update dockerfile for https in composer installer (#478) 2018-12-20 13:01:09 +01:00
Kevin Papst
ed8efcf139 support line breaks in docx (#466) 2018-12-07 11:24:39 +01:00
Kevin Papst
7fa3b67cc4 updated README and installation docu (#465) 2018-12-05 23:47:59 +01:00
Kevin Papst
93c500fbf2 fix segmentation fault - rollback composer dependencies (#463) 2018-12-05 00:01:48 +01:00
Kevin Papst
c58c12ea3d fixed null project for advanced invoice calculator (#462) 2018-12-03 22:36:38 +01:00
Kevin Papst
35305ad107 updated all composer packages (#459) 2018-12-03 20:24:22 +01:00
Kevin Papst
589d750e59 allow decimals in users hourly rate (#460) 2018-12-03 20:23:52 +01:00
Kevin Papst
43b488f21f moved some packages to dev requirements (#456) 2018-12-01 19:53:44 +01:00
Matheus
54d06462fc added portuguese translations (#446) 2018-11-28 18:22:05 +01:00
Kevin Papst
2d6109d587 simplify timesheet edit form if only one customer is existing (#443) 2018-11-28 15:05:12 +01:00
Kevin Papst
8fddf627bf added configurable permission system (#424) 2018-11-26 13:20:32 +01:00
Kevin Papst
0334f6ce86 added project variables for invoice templates (#439) 2018-11-23 15:56:06 +01:00
Kevin Papst
025558e58e fix restart timesheet button (#436) 2018-11-22 21:48:05 +01:00
Kevin Papst
f74547008d prepare release 0.6.1 (#433) 2018-11-19 16:17:28 +01:00
Kevin Papst
67dc1c7640 fix migration for MySQL (#430) 2018-11-19 15:24:00 +01:00
Kevin Papst
40322c6de4 fix importer for MySQL #428 (#429) 2018-11-19 00:32:12 +01:00
Kevin Papst
417675b3df prepare release 0.6 (#412) 2018-11-18 20:45:00 +01:00
Lukas
321ac74b6a added parsedown extension for header ids (#388) (#399) 2018-11-18 20:31:37 +01:00
Kevin Papst
b1c06eed7b API endpoint for Timesheet entries (#332) 2018-11-18 19:43:58 +01:00
Kevin Papst
8cb52e22b1 fix column visibility if unconfigured / no cookie existing (#423) 2018-11-18 02:13:44 +01:00
Kevin Papst
a073064900 redirect to user language after profile update (#421) 2018-11-15 12:06:57 +01:00
Kevin Papst
07cceca67e fix duration and rate for html invoices (#414) 2018-11-12 23:32:05 +01:00
Kevin Papst
540318fcd0 toolbar - always allow to choose global activities (#410) 2018-11-12 15:00:25 +01:00
Kevin Papst
e9cbb872d0 added further timesheet related invoice fields (#411) 2018-11-12 12:19:57 +01:00
Kevin Papst
f9dc42d1f9 option to move entries from one entity to another upon deletion (#409) 2018-11-12 00:01:49 +01:00
Kevin Papst
1dabeedaa0 show toolbar filter after submission (#407) 2018-11-11 15:32:41 +01:00
Kevin Papst
dc70ff128c full configurable data columns in all screen sizes (#404) 2018-11-10 22:22:08 +01:00
Kevin Papst
b012b7170b added global activity support in importer (#402) 2018-11-10 03:05:33 +01:00
Toby Batch
0a1c2d8440 updated docker documentation #397 (#398) 2018-11-09 14:07:49 +01:00
Toby Batch
d72596f000 added links to docker hub and production docker repo (#396) 2018-11-08 23:07:33 +01:00
Lukas
33029b2a11 fixed docu: issues- & milestone links (#395) 2018-11-07 00:45:58 +01:00
Kevin Papst
bae24dd0ec beta test: added quick search box for customers, projects and activities (#392) 2018-11-06 23:35:09 +01:00
Kevin Papst
db7de3aac1 added global activities (#259) 2018-11-06 23:10:34 +01:00
Kevin Papst
c66dfbc653 added links to further docker images by the community (#394) 2018-11-06 22:30:44 +01:00
Kevin Papst
51c207e025 fixed broken toolbar form with empty date (#391) 2018-11-05 22:26:57 +01:00
Lukas
e44e2442af updated invoice documentation (#387) 2018-11-04 15:55:34 +01:00
infeeeee
86f40083ef Added Hungarian translation (#385) 2018-11-02 23:38:12 +01:00
Kevin Papst
f45fbbce60 improved docs and cross-linked docker (#383) 2018-11-02 16:11:40 +01:00
srdco
c648866cb4 Update installation instructions for non-server (#382) 2018-11-01 12:28:39 +01:00
Kevin Papst
f8adafdabe invoice calculator to group entries by activity (#380) 2018-10-31 15:10:06 +01:00
Toby Batch
ab4a1a0a1d added dockerfile for development (#377) 2018-10-31 13:19:48 +01:00
Kevin Papst
34a3f4e275 about screen with debug information for super-admin (#378) 2018-10-29 15:28:52 +01:00
Kevin Papst
55aedcd4a8 bump version number for development (#375) 2018-10-25 22:27:43 +02:00
Kevin Papst
6633c550f5 user-profile - sidebar links and language settings (#369) 2018-10-23 23:59:38 +02:00
Kevin Papst
0165658659 added config for initial calendar view (#363) 2018-10-21 15:43:16 +02:00
Toby Batch
3075276a52 added default settings for new customer form (#358) 2018-10-21 15:27:43 +02:00
Kevin Papst
b46e752d0a decrease minimum username length to 3 character (#362) 2018-10-19 16:50:03 +02:00
Kevin Papst
ad171e7706 removed deprecated symfony/lts and updated all other packages (#354) 2018-10-12 17:51:38 +02:00
Kevin Papst
92c665436a updated admin lte theme bundle (#350) 2018-10-08 20:58:21 +02:00
Kevin Papst
2dbf433474 fixed redirect route after password reset (#345) 2018-10-07 19:12:59 +02:00
Kevin Papst
56ac642446 arabic translations and locale support in datepicker (#337) 2018-10-07 18:29:12 +02:00
Kevin Papst
2f6c0d2208 updated timesheet and email documentation (#349) 2018-10-07 16:50:20 +02:00
Kevin Papst
a32614fff8 updated required dependencies (#346) 2018-10-07 16:43:54 +02:00
Kevin Papst
53053c127e prepare release 0.5 (#326) 2018-09-27 13:35:03 +02:00
Kevin Papst
a89ef41e81 added copy invoice template action (#331) 2018-09-26 17:50:46 +02:00
Kevin Papst
eee7cb9bf4 fix spreadsheet renderer for invoices with one entry (#328) 2018-09-25 21:16:41 +02:00
Kevin Papst
98dc38ed99 timesheet export (#317)
* remove autocomplete for begin and end
* fix minute display in timesheet-edit form
* toolbar form label in separate row
* added export action
2018-09-24 16:46:10 +02:00
Kevin Papst
7bcd6a6382 added version command and api endpoint (#321) 2018-09-24 15:56:29 +02:00
Kevin Papst
73e0a75585 invoice VAT as float and database key length (#323) 2018-09-24 15:03:51 +02:00
Kevin Papst
71aa899f77 added invoice voter (#316) 2018-09-22 22:38:51 +02:00
Kevin Papst
53f82a808b improved invoices with new renderer (#306)
* added docx renderer and demo template
* added csv renderer and demo template
* added xlsx renderer and demo template
* added ods renderer and demo template
* added user calculator
* added invoice documentation
2018-09-21 01:27:56 +02:00
Kevin Papst
b035fc9ebd add stable controller tests (#305) 2018-09-07 00:44:57 +02:00
Kevin Papst
8cae5e8b3f added fixed-rate and hourly-rate for customer, project and activity (#304) 2018-09-06 23:37:25 +02:00
Kevin Papst
6163f33abf add hourly_rate and fixed_rate to timesheet entries (#302) 2018-09-05 15:27:39 +02:00
Kevin Papst
a636faa4ab added freelancer invoice template (#254) 2018-09-02 21:29:49 +02:00
Kevin Papst
ee4df36735 allow to switch language on any page (#299) 2018-09-02 20:58:19 +02:00
Thierry Pasquier
4ede5463f9 Fix duration_short format for french (#297) 2018-09-02 17:03:38 +02:00
Kevin Papst
4c277fe1b5 allow markdown in timesheet descriptions (#296) 2018-09-02 12:10:49 +02:00
Kevin Papst
9f6079ad8a added option to delete invoice template (#294) 2018-09-02 11:36:04 +02:00
Kevin Papst
6fb6a16246 prepare release 0.4 (#292) 2018-09-01 21:05:29 +02:00
Kevin Papst
3af8070a57 fixed money display in dashboard widgets (#291) 2018-09-01 19:47:03 +02:00
Kevin Papst
ebe007eb78 added configurable formats for duration (#287) 2018-09-01 17:54:17 +02:00
Kevin Papst
55b7e192aa Symfony update 4.1.4 (#290) 2018-09-01 14:23:38 +02:00
Kevin Papst
62f91f4d38 do not allow to stop already stopped timesheets (#289) 2018-09-01 13:00:30 +02:00
Kevin Papst
b1546c0568 Updated russian translations (#286) 2018-09-01 11:20:54 +02:00
Thierry Pasquier
af2d1c3a6e fix french date format and update translations (#279) 2018-08-23 20:46:30 +02:00
Thierry Pasquier
ca893b303a Fix standard french date format 2018-08-19 10:15:24 +02:00
Kevin Papst
142369d651 activated spanish, french and italian 2018-08-18 23:39:40 +02:00
Thierry Pasquier
3241c73e7c Added French translations (#275) 2018-08-18 23:39:40 +02:00
Ivan Castro
d6d9abd05e added Spanish translations (#266)
Spanish translation for kimai
2018-08-18 23:39:40 +02:00
Kevin Papst
85ff2ff9de updated to AdminLTE 2.4.8 (#274) 2018-08-17 23:54:26 +02:00
Kevin Papst
dbbb434723 dashboard widgets are configurable via config (#269) 2018-08-17 23:17:02 +02:00
Ingo Ebel
7804ef83ce fixing migration_v1.md url (#270) 2018-08-13 10:15:34 +02:00
Kevin Papst
fb2d898e4c fixed calendar for empty timesheet descriptions (#265) 2018-08-10 08:19:30 +02:00
Kevin Papst
c6e99b35d5 moved twig globals to dynamic compiler pass (#264) 2018-08-10 00:11:48 +02:00
Kevin Papst
3dcd38eca7 Added config setting to disable password-reset and user-registration (#261) 2018-08-09 20:44:49 +02:00
Kevin Papst
39ea44fdc3 fixed .htaccess for apache users (#260) 2018-08-08 23:35:02 +02:00
Kevin Papst
2f84f3751a Added basic API endpoints (#258) 2018-08-08 23:10:45 +02:00
Kevin Papst
a7780dac9e added italian translation (#253) 2018-08-08 00:00:24 +02:00
Kevin Papst
e549a0824f Hotfix for Symfony Flex incompatibility with latest composer changes (#257) 2018-08-07 20:17:56 +02:00
Kevin Papst
8b8583d48b Merge branch 'translations' into master 2018-07-31 17:37:59 +02:00
Kevin Papst
a8a8424ced Added delete user feature #225 (#249) 2018-07-31 13:16:40 +02:00
Kevin Papst
0996eca3c5 dashboard widgets from event (#246) 2018-07-28 23:18:28 +02:00
Kevin Papst
e6f8bc8ae2 Added timesheet-calendar view (#236) 2018-07-27 20:19:56 +02:00
Kevin Papst
5ccc1c991b Improved data fixtures with Faker (#234) 2018-07-24 19:24:58 +02:00
Kevin Papst
20a2d94996 prepare release 0.3 (#231) 2018-07-23 00:43:30 +02:00
Kevin Papst
f41eea2768 Easier creation of Tasks/Projects/User (#230) 2018-07-22 23:18:47 +02:00
Kevin Papst
2cf7d976d3 added email configuration docs (#228) 2018-07-22 18:46:07 +02:00
Kevin Papst
194a1f204c Show revenue only for ROLE_ADMIN (#227) 2018-07-22 15:31:59 +02:00
Kevin Papst
75246e9db2 Integrated FOSUserBundle (#216) 2018-07-21 22:36:36 +02:00
Kevin Papst
2d2525cff2 added favicons and webapp metadata (#211) 2018-07-15 21:15:24 +02:00
Kevin Papst
5160b640c4 fixed responsiveness (#220) 2018-07-15 16:07:35 +02:00
Kevin Papst
d18ab3fe75 added yunohost installation link #194 (#212) 2018-07-13 15:15:26 +02:00
Kevin Papst
d15cf72474 added auto-script to install assets (#214) 2018-07-13 15:14:39 +02:00
Kevin Papst
d8f7a5dfa4 added FAQ and database requirement docu #196 (#210)
* added FAQ and database requirement docu - fixes #196
* added FTP installation docu - see #199
* moved migration guide from Kimai v1 to its own docu chapter
2018-07-12 22:34:34 +02:00
Kevin Papst
e68bef7ea7 Updated to AdminLTEBundle 1.0 #201 (#206) 2018-07-12 20:37:08 +02:00
Kevin Papst
7a0d690101 replaced AvanzuAdminTheme with AdminLTE bundle #201 (#202) 2018-07-09 18:25:08 +02:00
Kevin Papst
0eb8ae5117 allow empty invoice template terms #188 (#189) 2018-06-29 19:49:01 +02:00
Kevin Papst
b05d416e80 improved install docs and composer (#187) 2018-06-29 18:08:54 +02:00
Kevin Papst
497a8f7a11 added lock-bot config #183 (#186) 2018-06-29 16:41:14 +02:00
Kevin Papst
3bdf0dc6a6 composer package name (#185) 2018-06-28 23:44:02 +02:00
Kevin Papst
b299302da4 added dynamic column filter #174 (#184) 2018-06-28 22:56:04 +02:00
Kevin Papst
2f0c64ae17 added browser info to readme (#177) 2018-06-26 20:18:08 +02:00
Kevin Papst
b58de9be9c updated to font-awesome 5 (#181) 2018-06-26 19:58:20 +02:00
Kevin Papst
d4a46cf257 language specific money and date display (#180)
* improved date translation
* language specific date and money display
2018-06-25 16:41:12 +02:00
Kevin Papst
f563e0703d prepare v0.2 release #177 (#178)
* added CHANGELOG.md and support for github-changelog-generator
2018-06-24 01:18:55 +02:00
Kevin Papst
c3251ee435 various documentation updates (#176)
* updated README
* improved CONTRIBUTING guidelines
* improved wording on developer docu
2018-06-23 21:20:20 +02:00
Kevin Papst
e9e61afc76 code styles: header_comment and ordered_imports (#175) 2018-06-23 11:41:58 +02:00
Simon Schaufelberger
1dd5f2b72f Translations 2018-06-23 00:48:11 +02:00
Kevin Papst
cd7cbeae88 improved code styles #158 (#172)
* use php-cs-fixer instead of phpcodesniffer
* updated scrutinizer config
* adjusted code yules to all files
* updated CONTRIBUTING guidelines
2018-06-22 21:09:10 +02:00
Kevin Papst
773d27bb0e set default locale for tests (#171) 2018-06-21 22:44:32 +02:00
Kevin Papst
0eaa81578a hide success notification after 5 seconds #169 (#170) 2018-06-21 18:47:13 +02:00
Kevin Papst
3dc054b839 help text and link for form labels #138 (#143)
* added help for timesheet duration form field - fixes #138
* added label option to link to manual chapter
* created docu chapter "timesheet" and added duration mode docu
* allow field and form option "documentation" to link to chapters in the documentation
2018-06-21 18:25:11 +02:00
Kevin Papst
8c686b0714 Added validation for end date before start date (#167)
* added validation for end date before start date
* added unit test for new validations
2018-06-20 23:27:56 +02:00
Kevin Papst
071abc8fc8 Update issue templates 2018-06-20 21:37:57 +02:00
Kevin Papst
75a6bf3ef6 Updated security expressions #148 (#166)
* replace has_role() with is_granted()
* added basic integration test classes for main controller
* added basic integration test classes for admin controller
2018-06-19 22:08:44 +02:00
Kevin Papst
856e7ccaeb Composer updates (#165)
* updated composer dependencies
* updated README about composer install
2018-06-18 23:13:29 +02:00
Kevin Papst
bfa32a90db Update to Symfony 4.1 #149 (#160)
* updated to Symfony 4.1 #149
* updated to phpunit 7 #149
* downgrade ocramius/proxy-manager for PHP 7.1 compatibility #149
* fixed symfony deprecations #149
* replaced AdvancedUserInterface with custom user checker
* code sniffer fixes
2018-06-18 22:26:00 +02:00
Kevin Papst
4e629fcaf8 some wording changes 2018-06-18 21:37:39 +02:00
Kevin Papst
01bce05da4 added scrutinizer config #158 (#161) 2018-06-08 00:16:12 +02:00
Kevin Papst
8a19af4efc Travis integration #120 (#159)
* fixed php versions used in travis #120
* fixed broken test #120
* updated developer docu
2018-06-06 21:36:24 +02:00
Kevin Papst
6eef9f6f37 Mobile alignments and toolbar #151 (#157)
* improved toolbar position #151
* fixed alignments on mobile #151
* fixed moment js #151
2018-06-05 23:15:25 +02:00
Kevin Papst
0445a255d0 added local config to overwrite settings #153 (#156) 2018-06-05 23:06:47 +02:00
Kevin Papst
451cf4cd1d Filter in hidden toolbar - improved mobile #151 (#155)
* improved toolbar: hide data table form in collapsible + filter button
* added collapsible area for toolbar form #151
2018-06-05 21:49:13 +02:00
Kevin Papst
7206d064a5 Improved mobile view #151 (#150)
- fixed group by for mysql mode
- only user can edit own prefs
- updated installation README
- pagerfanta shows less links
- improved manual tab
- moved user profile link to pref tabs
- added menu links to top navbar
- moved page actions to breadcrumb position
- integrated daterangepicker and improved toolbar forms
- bugfix for time rounding
2018-06-05 21:28:25 +02:00
Kevin Papst
db5b6f8e2e added russian translation #95 (#147)
* added russian translation #95
* added config for duration_only mode and adjusted timesheet views #131
2018-06-02 19:57:12 +02:00
Kevin Papst
9d9860e495 bugfix for duration_only mode #137 (#142)
* replaced durationForEntry with duration filter
* fixed duration problem - fixes #137
2018-06-02 19:39:03 +02:00
Kevin Papst
1c0f8cdad1 Bugfix importer (#145) (#146)
* Fix importer #145
2018-06-01 15:06:29 +02:00
Simon Schaufelberger
4af0e277b4 Make the back link appear like a normal link instead of a button (#139) 2018-02-18 12:12:24 +01:00
Kevin Papst
5a4bb0d081 Duration only mode #131 (#134) 2018-02-10 22:19:49 +01:00
Simon Schaufelberger
93e1cd5095 Secure create-user command #123 (#127)
* ask the user for the password #123
* added integration test #123
2018-02-10 19:11:30 +01:00
Simon Schaufelberger
5527f29caf Use short array syntax (#135) 2018-02-10 19:05:19 +01:00
Simon Schaufelberger
4c6158c1ea Merge pull request #132 from kevinpapst/inline-docu-129
added controller to render markdown documentation #129
2018-02-07 21:41:42 +01:00
Kevin Papst
6431fbecf6 code review fixes #129 2018-02-07 21:29:35 +01:00
Kevin Papst
29699572bd added controller to render markdown documentation #129 2018-02-07 15:07:53 +01:00
Kevin Papst
2e60e14132 added rounding rules and hourly rates factor #112 (#128)
* added unit tests and documentation #112
* fixed DashboardController
* added CONTRIBUTION guidelines
* fixed license year
2018-02-07 12:51:00 +01:00
Simon Schaufelberger
65790f1fb7 using new license header #124 (#119) 2018-02-03 18:23:47 +01:00
Simon Schaufelberger
76d4cba596 Add github issue and pull request template (#118) 2018-02-03 18:19:51 +01:00
Simon Schaufelberger
974cee0b6e compile assets with hash after filename #125 (#126) 2018-02-03 17:52:26 +01:00
Kevin Papst
7deaba8368 added webpack-encore for managing frontend assets #113 (#122)
* updated installation docu #113
* rewritten login page #113
* added icheck plugin #113
* changed to YesNoType in edit forms #113
* updated CONTRIBUTING.md #113
* added start of developer docu #113
* added compile scripts and compiled assets #113
2018-02-01 22:26:19 +01:00
Kevin Papst
e35d73eab5 fixed short invoice calculator (#114)
* fixed money display and address field for InvoiceTemplate entity
* added quick start button for users without active records
* rearranged columns on project and customer admin page
* improved extensions docu
2018-01-28 12:08:44 +01:00
Kevin Papst
9bbaf0ec71 added first docu on extending kimai with bundles #106 (#109) 2018-01-27 11:21:52 +01:00
Kevin Papst
1958bb9d09 added order number to projects #107 (#108) 2018-01-25 21:42:18 +01:00
Kevin Papst
7f5b5ac254 added short invoice calculator and timesheet invoice template #104 (#105) 2018-01-23 22:30:41 +01:00
Kevin Papst
50b5e93a10 added command to import data from kimai v1 #102 (#103) 2018-01-23 00:23:41 +01:00
Kevin Papst
6ae9bc4df5 added layout and translation to error pages #100 (#101) 2018-01-21 22:53:10 +01:00
Kevin Papst
4cbc5391c0 added basic invoice rendering #97 #93 (#99) 2018-01-21 22:50:46 +01:00
Kevin Papst
9a161b8fd9 added remember me feature #53 (#98)
cleanup event subscriber
2018-01-17 19:55:26 +01:00
Kevin Papst
7df21f3f5a code-cleanup: removed unused classes, added role constants, phpcs fixes (#96) 2018-01-16 23:56:55 +01:00
Kevin Papst
0a65965187 load doctrine extensions during kernel bootstrap #84 (#92) 2018-01-16 21:35:23 +01:00
Kevin Papst
3f221fcdb8 support theme options via user preferences #89 (#91) 2018-01-15 22:58:07 +01:00
Kevin Papst
827b1ae9ad fixed dynamic user preferences #9
added missing Chart.min.js
2018-01-14 23:02:50 +01:00
Kevin Papst
49d8796f6b added dynamic user preferences #7 #9 (#90)
- fixed user settings database #9
- added dynamic user preferences #9
- added form to edit user preferences #9
- removed user language #7
2018-01-14 22:47:20 +01:00
Kevin Papst
023fef6a70 added control sidebar #10 (#87)
- added configurable sidebar #10
- added language switch in sidebar preferences tab #10
- added sidebar tab with kimai beta-info message #10
- use trait for repositories
- improved README
2018-01-14 01:36:07 +01:00
Kevin Papst
d5e689e307 code cleanup 2018-01-13 00:20:41 +01:00
Kevin Papst
fc9ce52d69 removed unused files #74 2018-01-13 00:19:23 +01:00
Kevin Papst
c7935da16a added english translation #8 (#82)
* reformatted translation file #8
* set default language to en #8
* added english translations #8
2018-01-12 22:21:15 +01:00
Kevin Papst
1833a6632a skip broken tests, added browserkit for integration tests 2018-01-12 21:21:43 +01:00
Kevin Papst
4d7fe3d595 fixes for symfony4 #74 #81 2018-01-12 21:07:20 +01:00
Kevin Papst
a87355695e upgraded to symfony 4 #74 (#81) 2018-01-12 20:39:07 +01:00
3021 changed files with 325643 additions and 21758 deletions

30
.codecov.yml Normal file
View File

@@ -0,0 +1,30 @@
codecov:
notify:
require_ci_to_pass: yes
coverage:
precision: 2
round: down
range: "80...100"
status:
project:
default:
threshold: 0.5%
patch: off
changes: no
parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no
comment:
layout: "diff, flags, files"
behavior: default
require_changes: yes
require_base: no
require_head: yes
branches: null

20
.docker/000-default.conf Normal file
View File

@@ -0,0 +1,20 @@
<VirtualHost *:8001>
ServerAdmin webmaster@localhost
DocumentRoot /opt/kimai/public
PassEnv MAILER_FROM
PassEnv APP_ENV
PassEnv APP_SECRET
PassEnv DATABASE_URL
PassEnv MAILER_URL
PassEnv TRUSTED_PROXIES
<Directory "/opt/kimai/public">
Require all granted
DirectoryIndex index.php
AllowOverride All
</Directory>
</VirtualHost>
ServerName localhost

51
.docker/dbtest.php Normal file
View File

@@ -0,0 +1,51 @@
<?php
$DATABASE_HOST = urldecode($argv[1]);
$DATABASE_BASE = urldecode($argv[2]);
$DATABASE_PORT = $argv[3];
$DATABASE_USER = urldecode($argv[4]);
$DATABASE_PASS = urldecode($argv[5]);
echo "Testing DB:";
try {
$pdo = new \PDO("mysql:host=$DATABASE_HOST;dbname=$DATABASE_BASE;port=$DATABASE_PORT", "$DATABASE_USER", "$DATABASE_PASS", [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
]);
} catch(\Exception $ex) {
switch ($ex->getCode()) {
case 1045:
// we can immediately stop here and show the error message
echo 'Access denied (1045)';
die(1);
case 1049:
// error "Unknown database (1049)" can be ignored, the database will be created by Kimai
return;
// a lot of errors share the same meaningless error code zero
case 0:
// this error includes the database name, so we can only search for the static part of the error message
if (stripos($ex->getMessage(), 'SQLSTATE[HY000] [1049] Unknown database') !== false) {
// error "Unknown database (1049)" can be ignored, the database will be created by Kimai
return;
}
switch ($ex->getMessage()) {
// eg. no response (fw) - the startup script should retry it a couple of times
case 'SQLSTATE[HY000] [2002] Operation timed out':
echo 'Operation timed out (0-2002)';
die(4);
// special case "localhost" with a stopped db server (should not happen in docker compose setup)
case 'SQLSTATE[HY000] [2002] No such file or directory':
echo 'Connection could not be established (0-2002)';
die(5);
// using IP with stopped db server - the startup script should retry it a couple of times
case 'SQLSTATE[HY000] [2002] Connection refused':
echo 'Connection refused (0-2002)';
die(5);
}
echo $ex->getMessage() . " (0)";
die(7);
default:
// unknown error
echo $ex->getMessage() . " (?)";
die(10);
}
}

102
.docker/entrypoint.sh Executable file
View File

@@ -0,0 +1,102 @@
#!/bin/bash -x
KIMAI=$(cat /opt/kimai/version.txt)
echo $KIMAI
function waitForDB() {
# Parse sql connection data
DATABASE_USER=$(awk -F '[/:@]' '{print $4}' <<< "$DATABASE_URL")
DATABASE_PASS=$(awk -F '[/:@]' '{print $5}' <<< "$DATABASE_URL")
DATABASE_HOST=$(awk -F '[/:@]' '{print $6}' <<< "$DATABASE_URL")
DATABASE_PORT=$(awk -F '[/:@]' '{print $7}' <<< "$DATABASE_URL")
DATABASE_BASE=$(awk -F '[/?]' '{print $4}' <<< "$DATABASE_URL")
re='^[0-9]+$'
if ! [[ $DATABASE_PORT =~ $re ]] ; then
DATABASE_PORT=3306
fi
echo "Wait for database connection ..."
until php /dbtest.php "$DATABASE_HOST" "$DATABASE_BASE" "$DATABASE_PORT" "$DATABASE_USER" "$DATABASE_PASS"; do
echo Checking DB: $?
sleep 3
done
echo "Connection established"
}
function handleStartup() {
# set mem limits and copy in custom logger config
if [ -z "$memory_limit" ]; then
memory_limit=512M
fi
sed -i "s/memory_limit.*/memory_limit=$memory_limit/g" /usr/local/etc/php/php.ini
cp /assets/monolog.yaml /opt/kimai/config/packages/monolog.yaml
if [ -z "$USER_ID" ]; then
USER_ID=$(id -u www-data)
fi
if [ -z "$GROUP_ID" ]; then
GROUP_ID=$(id -g www-data)
fi
# if group doesn't exist
if grep -w "$GROUP_ID" /etc/group &>/dev/null; then
echo Group already exists
else
echo www-kimai:x:"$GROUP_ID": >> /etc/group
grpconv
fi
# if user doesn't exist
if id "$USER_ID" &>/dev/null; then
echo User already exists
else
echo www-kimai:x:"$USER_ID":"$GROUP_ID":www-kimai:/var/www:/usr/sbin/nologin >> /etc/passwd
pwconv
fi
if [ -e /use_apache ]; then
export APACHE_RUN_USER=$(id -nu "$USER_ID")
# This doesn't _exactly_ run as the specified GID, it runs as the GID of the specified user but WTF
export APACHE_RUN_GROUP=$(id -ng "$USER_ID")
export APACHE_PID_FILE=/var/run/apache2/apache2.pid
export APACHE_RUN_DIR=/var/run/apache2
export APACHE_LOCK_DIR=/var/lock/apache2
export APACHE_LOG_DIR=/var/log/apache2
export LANG=C
elif [ -e /use_fpm ]; then
sed -i "s/user = .*/user = $USER_ID/g" /usr/local/etc/php-fpm.d/www.conf
sed -i "s/group = .*/group = $GROUP_ID/g" /usr/local/etc/php-fpm.d/www.conf
echo "Setting fpm to run as ${USER_ID}:${GROUP_ID}"
else
echo "Error, unknown server type"
fi
}
function prepareKimai() {
# These are idempotent, so we can run them on every start-up
/opt/kimai/bin/console -n kimai:install
if [ ! -z "$ADMINPASS" ] && [ ! -a "$ADMINMAIL" ]; then
/opt/kimai/bin/console kimai:user:create admin "$ADMINMAIL" ROLE_SUPER_ADMIN "$ADMINPASS"
fi
echo "$KIMAI" > /opt/kimai/var/installed
echo "Kimai is ready"
}
function runServer() {
# Just while I'm fixing things
/opt/kimai/bin/console kimai:reload --env="$APP_ENV"
chown -R $USER_ID:$GROUP_ID /opt/kimai/var
if [ -e /use_apache ]; then
exec /usr/sbin/apache2 -D FOREGROUND
elif [ -e /use_fpm ]; then
exec php-fpm
else
echo "Error, unknown server type"
fi
}
waitForDB
handleStartup
prepareKimai
runServer

48
.docker/monolog.yaml Normal file
View File

@@ -0,0 +1,48 @@
when@prod:
monolog:
channels: ["deprecation"]
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [403, 404]
nested:
type: stream
level: info
path: php://stderr
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine"]
deprecation:
type: stream
channels: ["deprecation"]
path: php://stderr
when@dev:
monolog:
channels: ["deprecation"]
handlers:
main:
type: stream
path: php://stderr
level: info
channels: ["!event"]
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!console"]
deprecation:
type: stream
channels: ["deprecation"]
path: php://stderr
when@test:
monolog:
handlers:
main:
type: stream
path: php://stderr
level: info
channels: ["!event"]

27
.editorconfig Normal file
View File

@@ -0,0 +1,27 @@
; top-most EditorConfig file
root = true
; Unix-style newlines
[*]
end_of_line = lf
charset = utf-8
[*.php]
indent_style = space
indent_size = 4
[*.twig]
indent_style = space
indent_size = 4
[*.yaml]
indent_style = space
indent_size = 4
[*.yml]
indent_style = space
indent_size = 4
[*.xml]
indent_style = space
indent_size = 4

51
.env.dist Normal file
View File

@@ -0,0 +1,51 @@
#
# You should NOT use this file in production, but instead move the environment variables to your webserver configuration.
# The .env file is only existing to simplify the initial setup!
#
#================================================================================
# Configure your database connection and set the correct server version.
#
# You have to replace the following values with your defaults:
# - the version "5.7" (the database server version, examples for MySQL and MariaDB below)
# - the database username "user"
# - the password "password" for "user"
# - the database schema "database"
# - you might have to adapt port "3306" and server IP "127.0.0.1" as well
#
# For MySQL that would be "serverVersion=5.7" as in:
# DATABASE_URL=mysql://user:password@127.0.0.1:3306/database?charset=utf8mb4&serverVersion=5.7
#
# For MariaDB it would be "serverVersion=10.5.8-MariaDB":
# DATABASE_URL=mysql://user:password@127.0.0.1:3306/database?charset=utf8mb4&serverVersion=10.5.8-MariaDB
#
DATABASE_URL=mysql://user:password@127.0.0.1:3306/database?charset=utf8mb4&serverVersion=10.5.8-MariaDB
#================================================================================
# The full documentation can be found at https://www.kimai.org/documentation/emails.html
#
# Email will be sent with this address as sender:
MAILER_FROM=kimai@example.com
# Email connection (disabled by default) - see documentation for the format
MAILER_URL=null://null
#================================================================================
# do not change, unless you are developing for Kimai
APP_ENV=prod
#================================================================================
# should be changed to a unique character sequence, used for hashing cookies
APP_SECRET=change_this_to_something_unique
#================================================================================
# Running behind reverse proxies? Try these:
# TRUSTED_PROXIES=127.0.0.1,127.0.0.2
# TRUSTED_HOSTS=localhost|example.com
#================================================================================
# unlikely, that you need to change this one
CORS_ALLOW_ORIGIN=^https?://localhost(:[0-9]+)?$
###> symfony/messenger ###
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
###< symfony/messenger ###

18
.gitattributes vendored Normal file
View File

@@ -0,0 +1,18 @@
.docker export-ignore
.github export-ignore
assets export-ignore
tests export-ignore
.codecov.yml export-ignore
.editorconfig export-ignore
eslint.config.js export-ignore
.gitattributes export-ignore
.gitignore export-ignore
php-cs-fixer.dist.php export-ignore
babel.config.js export-ignore
package.json export-ignore
php-cs-fixer.sh export-ignore
phpstan.neon export-ignore
phpstan.sh export-ignore
phpunit.xml.dist export-ignore
webpack.config.js export-ignore
yarn.lock export-ignore

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
github: [kevinpapst]
open_collective: kimai
custom: ["https://www.kimai.org/", "https://www.kimai.cloud/", "https://www.kevinpapst.de/"]

74
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,74 @@
name: Bug report
description: Create a report to help us improve Kimai
labels: [ "bug" ]
body:
- type: markdown
attributes:
value: |
Thank you for reporting an issue on Kimai! This form will guide you to create a useful issue report.
- type: textarea
id: what-happened
attributes:
label: Describe the issue
description: "A clear and concise description of the problem you are facing. Is that a browser issue? Then add device information: Ubuntu 20.04 with Brave 1.46, Windows 10 with Chrome 85, iPhone 10, Mac with Safari 16"
placeholder: Tell us what you see! Include the steps necessary to reproduce the behavior (e.g. go to, scroll down and click here ...)
validations:
required: true
- type: checkboxes
id: tried
attributes:
label: I already tried
description: If you didnt try already, try to search the documentation and existing issues what you wrote above.
options:
- label: I've read and searched [the documentation](https://www.kimai.org/documentation/).
required: true
- label: I've searched for similar issues in this repository.
required: true
- label: I've searched for similar issues in [the discussions](https://github.com/kimai/kimai/discussions).
required: true
- type: input
id: version
attributes:
label: Kimai version
description: Which version of Kimai are you running (see Doctor/About/Kimai-Cloud screen)
placeholder: 1.xx.x or 2.xx.x
validations:
required: true
- type: dropdown
id: installation
attributes:
label: How do you run Kimai?
options:
- Virtual Server or alike
- KIMAI CLOUD
- Docker
- Synology
- Plesk
- Shared-Hosting
- Other (please mention below)
validations:
required: true
- type: dropdown
id: php
attributes:
label: Which PHP version are you using?
options:
- "8.4"
- "8.2"
- "8.3"
- "8.1"
- Unknown
- Other (please mention below)
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logfile
description: Please paste the last lines from your logfile at "var/log/prod.log" or "Doctor > Logs", around the time when the problem happened.
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If applicable, add screenshots to better explain your problem.

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Read our documentation
url: https://www.kimai.org/documentation/
about: Save your time! There is an instant solution for many issues in the documentation.
- name: Ask a Question
url: https://github.com/kimai/kimai/discussions
about: Want to discuss something with a community? Do it in discussions!
- name: Get Professional support
url: https://www.kimai.org/en/support.html
about: As a customer, you will always receive fast replies from the developer.

40
.github/ISSUE_TEMPLATE/docker.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Docker issue
description: Experiencing an issue with your Docker Setup?
labels: [ "docker" ]
body:
- type: markdown
attributes:
value: |
Thank you for reporting an issue with your docker setup! This form will guide you to create a useful issue report.
- type: textarea
id: describe
attributes:
label: Describe the problem
description: >
Please provide a clear and concise description of what the issue is and the steps to reproduce the behaviour:
1. Start the container '...'
2. Click on '....'
3. See error xyz
validations:
required: true
- type: textarea
id: environment
attributes:
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]
Docker compose file:
version: '3.5'
services:
image: ...
validations:
required: true
- type: input
id: command
attributes:
label: Command used to run the container
description: e.g. docker run -v ....

View File

@@ -0,0 +1,34 @@
name: Feature request
description: Suggest an idea to make Kimai better
labels: [ "feature request" ]
body:
- type: markdown
attributes:
value: |
Thank you for reporting an issue on Kimai! This form will guide you to create a useful issue report.
- type: textarea
id: describe
attributes:
label: Describe the problem
description: >
Is your feature request related to a problem? If so, please provide
a clear and concise description of what the issue is.
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what the new feature should do.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered.
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If applicable, add screenshots to better explain your problem.

12
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,12 @@
## Description
A clear and concise description of what this pull request adds or changes.
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
## Checklist
- [ ] I verified that my code applies to the guidelines (`composer code-check`)
- [ ] I updated the documentation (see [here](https://github.com/kimai/www.kimai.org/tree/master/_documentation))
- [ ] I agree that this code is used in Kimai (see [license](https://github.com/kimai/kimai/blob/main/LICENSE))

29
.github/release-drafter.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name-template: '$RESOLVED_VERSION'
tag-template: '$RESOLVED_VERSION'
exclude-labels:
- 'duplicate'
- 'invalid'
- 'wontfix'
- 'release'
exclude-contributors:
- 'dependabot'
- 'weblate'
change-template: '- $TITLE (#$NUMBER)'
change-title-escapes: '\<*_&`#@'
version-resolver:
minor:
labels:
- 'feature request'
- 'release'
patch:
labels:
- 'technical debt'
- 'bug'
- 'translation'
default: patch
template: |
**Compatible with PHP 8.1 to 8.4**
$CHANGES
Involved in this release: $CONTRIBUTORS

93
.github/workflows/docker.yaml vendored Normal file
View File

@@ -0,0 +1,93 @@
name: 'Docker Build'
on:
workflow_dispatch:
inputs:
kimai_tag:
description: 'Kimai tag to build'
required: true
release:
types: [released]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{secrets.DOCKERHUB_USERNAME}}
password: ${{secrets.DOCKERHUB_PASSWORD}}
- name: Determine version
run: |
input="${{ github.event.inputs.kimai_tag }}"
# Determine between manual trigger and release event
if [ -z "$input" ]; then
echo "Using release tag: ${{ github.event.release.tag_name }}"
version="${{ github.event.release.tag_name }}"
else
echo "Using tag provided: $input"
version="$input"
fi
if [[ ! $version =~ ^2\.(0|[1-9]*)(0?)\.(0|[0-9]*)(0?)$ ]]; then
echo "Invalid version number: $version"
exit 1
fi
echo "kimai_version=$version" >> $GITHUB_ENV
- name: FPM image
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
build-args: |
KIMAI=${{ env.kimai_version }}
BASE=fpm
target: prod
platforms: linux/amd64,linux/arm64
tags: |
kimai/kimai2:latest
kimai/kimai2:fpm
kimai/kimai2:fpm-${{ env.kimai_version }}
push: true
- name: Apache image
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
build-args: |
KIMAI=${{ env.kimai_version }}
BASE=apache
target: prod
platforms: linux/amd64,linux/arm64
tags: |
kimai/kimai2:apache
kimai/kimai2:apache-${{ env.kimai_version }}
push: true
- name: Development image
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
build-args: |
KIMAI=${{ env.kimai_version }}
BASE=apache
target: dev
platforms: linux/amd64,linux/arm64
tags: |
kimai/kimai2:dev
push: true

29
.github/workflows/lock-threads.yaml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: 'Lock Threads'
on:
schedule:
- cron: '17 1 * * *'
workflow_dispatch:
permissions:
issues: write
pull-requests: write
concurrency:
group: lock-threads
jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
with:
process-only: 'issues, prs'
github-token: ${{ secrets.GITHUB_TOKEN }}
issue-inactive-days: '90'
issue-comment: >
This thread has been automatically locked since there has not been any recent activity after it was closed.
Please share your experience with the community and [leave a testimonial](https://love.kimai.org/) to support Kimai.
issue-lock-reason: 'resolved'
pr-inactive-days: '180'
log-output: true

21
.github/workflows/lockfiles.yaml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Check .lock files
on:
pull_request_target: null
push:
branches:
- main
permissions:
pull-requests: read
jobs:
lockfiles:
runs-on: ubuntu-latest
name: Verify lock file integrity
steps:
- name: Prevent file change
uses: xalvarez/prevent-file-change-action@v3
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
pattern: .*\.lock$|^\.github\/.*$
trustedAuthors: kevinpapst, dependabot

30
.github/workflows/release-drafter.yaml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Release Drafter
on:
push:
branches:
- main
permissions:
contents: read
jobs:
correct_repository:
permissions:
contents: none
runs-on: ubuntu-latest
steps:
- name: fail on fork
if: github.repository_owner != 'kimai'
run: exit 1
update_release_draft:
permissions:
contents: write # for release-drafter/release-drafter to create a github release
pull-requests: write # for release-drafter/release-drafter to add label to PR
needs: correct_repository
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

125
.github/workflows/testing.yaml vendored Normal file
View File

@@ -0,0 +1,125 @@
name: Tests
on:
pull_request: null
push:
branches:
- main
jobs:
integration:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:latest
env:
MYSQL_ALLOW_EMPTY_PASSWORD: false
MYSQL_ROOT_PASSWORD: kimai
MYSQL_DATABASE: kimai
ports:
- 3306/tcp
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
matrix:
php: ['8.1', '8.2', '8.3', '8.4']
name: Integration (${{ matrix.php }})
steps:
- name: Clone Kimai
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: pcov
extensions: ctype, gd, iconv, intl, ldap, mbstring, mysql, xml, zip
tools: cs2pr, symfony-cli
env:
fail-fast: true
- name: Determine software versions
run: mysql --version && php --version
- name: Determine composer cache directory
id: composer-cache
run: echo "composer_cache_directory=$(composer config cache-dir)" >> $GITHUB_ENV
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: "${{ env.composer_cache_directory }}"
key: ${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
- name: Install dependencies
run: composer install
- name: Validate Composer
run: composer validate --strict --no-check-all
- name: Warmup cache
run: APP_ENV=dev bin/console kimai:reload -n
- name: Check codestyles
run: vendor/bin/php-cs-fixer fix --dry-run --verbose --config=.php-cs-fixer.dist.php --using-cache=no --show-progress=none --format=checkstyle | cs2pr
- name: Run PHPStan for application
run: vendor/bin/phpstan analyse -c phpstan.neon --no-progress --error-format=checkstyle | cs2pr
- name: Run PHPStan for tests
run: vendor/bin/phpstan analyse -c tests/phpstan.neon --no-progress --error-format=checkstyle | cs2pr
- name: Lint codebase
run: composer linting
- name: Install LDAP package (for tests)
run: composer require laminas/laminas-ldap
- name: Setup problem matchers (for PHPUnit)
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
- name: Run quick unit-tests
run: composer tests-unit
env:
DATABASE_URL: mysql://root:kimai@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/kimai?charset=utf8mb4&serverVersion=8.0.35
APP_ENV: test
MAILER_URL: null://localhost
- name: Full test-suite
if: matrix.php != '8.2'
run: vendor/bin/phpunit tests/
env:
DATABASE_URL: mysql://root:kimai@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/kimai?charset=utf8mb4&serverVersion=8.0.35
APP_ENV: test
MAILER_URL: null://localhost
- name: Full test-suite with coverage
if: matrix.php == '8.2'
run: vendor/bin/phpunit tests/ --coverage-clover=coverage.xml
env:
DATABASE_URL: mysql://root:kimai@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/kimai?charset=utf8mb4&serverVersion=8.0.35
APP_ENV: dev
MAILER_URL: null://localhost
- name: Upload code coverage
if: matrix.php == '8.2'
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
fail_ci_if_error: true
- name: Run migrations on MySQL
run: |
bin/console doctrine:database:drop --if-exists --force -n
bin/console doctrine:database:create --if-not-exists -n
bin/console doctrine:migrations:migrate -n
bin/console doctrine:migrations:migrate first -n
env:
DATABASE_URL: mysql://root:kimai@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/kimai?charset=utf8mb4&serverVersion=8.0.35
APP_ENV: dev
MAILER_URL: null://localhost
- name: Check for security issues in packages
run: symfony security:check

42
.github/workflows/website.yaml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: 'Website update'
on:
workflow_dispatch:
inputs:
kimai_version:
description: 'Kimai version for the website'
required: true
release:
types: [released]
jobs:
build:
name: Trigger version update for website
runs-on: ubuntu-latest
steps:
- name: "Determine Version"
run: |
input="${{ github.event.inputs.kimai_version }}"
# Determine between manual trigger and release event
if [ -z "$input" ]; then
echo "No input provided, using release tag"
version="${{ github.event.release.tag_name }}"
else
echo "Using input provided: $input"
version="$input"
fi
echo "kimai_version=$version" >> $GITHUB_ENV
if [[ ! $version =~ ^2\.(0|[1-9]*)(0?)\.(0|[0-9]*)(0?)$ ]]; then
echo "Invalid version number: $version"
exit 1
fi
- name: Emit repository_dispatch
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.WEBSITE_ACCESS_TOKEN }}
repository: kimai/www.kimai.org
event-type: kimai_release
client-payload: '{"kimai_version": "${{ env.kimai_version }}"}'

97
.gitignore vendored
View File

@@ -1,57 +1,64 @@
# Cache and logs (Symfony2)
/app/cache/*
/app/logs/*
!app/cache/.gitkeep
!app/logs/.gitkeep
# some hosters require a htaccess to change the PHP version
/public/.htaccess
/.env-*
/.idea/
.DS_Store
# Email spool folder
/app/spool/*
# custom apache rules e.g. to deactivate ioncube loader
/public/.user.ini
# Cache, session files and logs (Symfony3)
# for symfony local webserver
/php.ini
/.php-version
# YARN 2
/.yarnrc.yml
/.yarn
# for keeping empty directories
/config/packages/local.yaml
/config/bundles-local.php
/var/dev/*
/var/data/*
/var/cache/*
/var/logs/*
/var/invoices*
/var/export*
/var/log/*
/var/sessions/*
!var/cache/.gitkeep
!var/logs/.gitkeep
!var/sessions/.gitkeep
/var/packages/*
/var/plugins*
/var/plugins/*/*.disabled
# Parameters
/app/config/parameters.yml
/app/config/parameters.ini
# Managed by Composer
/app/bootstrap.php.cache
/var/bootstrap.php.cache
/bin/*
!bin/console
!bin/symfony_requirements
###> symfony/framework-bundle ###
/.env.local
/.env.local.php
/.env.*.local
/config/secrets/prod/prod.decrypt.private.php
.env
/public/bundles/
/vendor/
###< symfony/framework-bundle ###
# Assets and user uploads
/web/bundles/
/web/uploads/
# Assets managed by Bower
/web/assets/vendor/
# PHPUnit
/app/phpunit.xml
###> phpunit/phpunit ###
/phpunit.xml
/.phpunit.result.cache
###< phpunit/phpunit ###
# Build data
/build/
###> friendsofphp/php-cs-fixer ###
.php_cs
.php_cs.cache
.php-cs-fixer.cache
###< friendsofphp/php-cs-fixer ###
# Composer PHAR
/composer.phar
###> symfony/phpunit-bridge ###
.phpunit
###< symfony/phpunit-bridge ###
# Backup entities generated with doctrine:generate:entities command
*/Entity/*~
###> symfony/webpack-encore-bundle ###
/node_modules/
npm-debug.log
yarn-error.log
###< symfony/webpack-encore-bundle ###
/nbproject/*
# IDE
.idea/
# SQLite files
/app/data/timesheet.sqlite
# generated install and setup files
/web/theme/
.dockerhub.secrets

184
.php-cs-fixer.dist.php Normal file
View File

@@ -0,0 +1,184 @@
<?php
$fileHeaderComment = <<<COMMENT
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.
COMMENT;
$fixer = new PhpCsFixer\Config();
$fixer->setUnsupportedPhpVersionAllowed(true);
$fixer
->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
->setRiskyAllowed(true)
->setRules([
'encoding' => true,
'full_opening_tag' => true,
'blank_line_after_namespace' => true,
'control_structure_braces' => true,
'control_structure_continuation_position' => ['position' => 'same_line'],
'declare_parentheses' => true,
'no_multiple_statements_per_line' => true,
'statement_indentation' => true,
'class_definition' => true,
'elseif' => true,
'function_declaration' => true,
'indentation_type' => true,
'line_ending' => true,
'constant_case' => ['case' => 'lower'],
'lowercase_keywords' => true,
'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline', 'after_heredoc' => true],
'header_comment' => ['header' => $fileHeaderComment, 'separate' => 'both'],
'no_php4_constructor' => true,
'ordered_imports' => true,
'no_break_comment' => true,
'no_closing_tag' => true,
'no_spaces_after_function_name' => true,
'spaces_inside_parentheses' => ['space' => 'none'],
'no_trailing_whitespace' => true,
'no_trailing_whitespace_in_comment' => true,
'single_blank_line_at_eof' => true,
'single_class_element_per_statement' => ['elements' => ['property']],
'single_import_per_statement' => true,
'single_line_after_imports' => true,
'switch_case_semicolon_to_colon' => true,
'switch_case_space' => true,
'php_unit_method_casing' => true,
'array_syntax' => [
'syntax' => 'short'
],
'binary_operator_spaces' => true,
'blank_line_after_opening_tag' => true,
'blank_line_before_statement' => [
'statements' => ['return'],
],
'cast_spaces' => true,
'class_attributes_separation' => ['elements' => ['method' => 'one']],
'concat_space' => ['spacing' => 'one'],
'declare_equal_normalize' => true,
'type_declaration_spaces' => ['elements' => ['function', 'property']],
'include' => true,
'lowercase_cast' => true,
'lowercase_static_reference' => true,
'magic_constant_casing' => true,
'native_function_casing' => true,
'new_with_parentheses' => true,
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_blank_lines' => ['tokens' => [
'curly_brace_block',
'extra',
'parenthesis_brace_block',
'square_brace_block',
'throw',
'use',
]],
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_mixed_echo_print' => ['use' => 'echo'],
'no_multiline_whitespace_around_double_arrow' => true,
'no_short_bool_cast' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_spaces_around_offset' => true,
'no_trailing_comma_in_singleline' => true,
'no_unneeded_braces' => true,
'no_unneeded_final_method' => true,
'no_unused_imports' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'normalize_index_brace' => true,
'object_operator_without_whitespace' => true,
'php_unit_fqcn_annotation' => true,
'phpdoc_align' => [
'align' => 'left',
'tags' => [
'method',
'param',
'property',
'return',
'throws',
'type',
'var',
],
],
'phpdoc_annotation_without_dot' => true,
'phpdoc_indent' => true,
'phpdoc_inline_tag_normalizer' => true,
'phpdoc_no_access' => true,
'phpdoc_no_alias_tag' => true,
'phpdoc_no_empty_return' => false,
'phpdoc_no_package' => true,
'phpdoc_no_useless_inheritdoc' => true,
'phpdoc_return_self_reference' => true,
'phpdoc_scalar' => true,
'phpdoc_separation' => false,
'phpdoc_single_line_var_spacing' => true,
'phpdoc_summary' => false,
'phpdoc_to_comment' => true,
'phpdoc_trim' => true,
'phpdoc_types' => true,
'phpdoc_var_without_name' => true,
'protected_to_private' => true,
'return_type_declaration' => true,
'semicolon_after_instruction' => true,
'short_scalar_cast' => true,
'blank_lines_before_namespace' => ['min_line_breaks' => 2, 'max_line_breaks' => 2],
'single_line_comment_style' => [
'comment_types' => ['hash'],
],
'single_quote' => true,
'space_after_semicolon' => [
'remove_in_empty_for_expressions' => true,
],
'standardize_increment' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'trailing_comma_in_multiline' => false,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'whitespace_after_comma_in_array' => true,
'yoda_style' => false,
'ternary_to_null_coalescing' => true,
'modifier_keywords' => ['elements' => [
'const',
'method',
'property',
]],
'native_function_invocation' => [
'include' => [
'@compiler_optimized'
],
'scope' => 'namespaced'
],
'native_type_declaration_casing' => true,
'no_alias_functions' => [
'sets' => [
'@internal'
]
],
'list_syntax' => ['syntax' => 'short'],
'assign_null_coalescing_to_coalesce_equal' => true,
'non_printable_character' => true,
'octal_notation' => true,
'heredoc_indentation' => ['indentation' => 'start_plus_one'],
'no_space_around_double_colon' => true,
'no_useless_nullsafe_operator' => true,
'clean_namespace' => true,
'no_unset_cast' => true,
])
->setFinder(
PhpCsFixer\Finder::create()
->in([
__DIR__ . '/migrations/',
__DIR__ . '/src/',
__DIR__ . '/tests/',
])
)
->setFormat('checkstyle')
;
return $fixer;

View File

@@ -1,26 +0,0 @@
language: php
sudo: false
cache:
directories:
- $HOME/.composer/cache/files
matrix:
fast_finish: true
include:
- php: 5.5
- php: 5.6
- php: 7.0
- php: hhvm
allow_failures:
- php: hhvm
before_install:
- if [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini; fi
- composer self-update
install:
- composer install
script:
- phpunit

3
CHANGELOG.md Normal file
View File

@@ -0,0 +1,3 @@
# Changelog
See [GitHub release page](https://github.com/kimai/kimai/releases).

View File

@@ -1,20 +1,16 @@
Contributing
============
# Contributing
The Kimai application is an open source project. Contributions made by
the community are welcome. Send us your ideas, code reviews, pull requests and
feature requests to help us improve this project.
Kimai is an open source project, contributions made by the community are welcome.
But we can only accept contributions with a signed CLA (Contributor License Agreement) to prevent issues in the future (you will see a link when opening a PR).
Web Assets Management
---------------------
Send your ideas, code reviews, pull requests and feature requests to help to improve this project.
This project manages its web assets in a special way to allow them to work
without configuring any option, installing any tool or executing any command.
If your contribution changes CSS styles or JavaScript code in any way, make
sure to regenerate the `web/css/app.css` and `web/js/app.js` files. To do so,
uncomment the Assetic blocks in the `app/Resources/views/base.html.twig` and
execute the following command:
## Pull request rules
```bash
$ php bin/console assetic:dump --no-debug
```
- Make your changes in a new git branch, based on the latest code in `main`
- Apply our code-style by running `composer codestyle-fix`
- Run the static code analysis with `composer phpstan`
- Verify everything still works with `composer tests-unit`
- Add tests for your changes
Further documentation can be found in the [developer documentation](https://www.kimai.org/documentation/developers.html).

330
Dockerfile Normal file
View File

@@ -0,0 +1,330 @@
# _ ___ _
# | |/ (_)_ __ ___ __ _(_)
# | ' /| | '_ ` _ \ / _` | |
# | . \| | | | | | | (_| | |
# |_|\_\_|_| |_| |_|\__,_|_|
#
# Kimai images for:
# - plain PHP FPM (kimai/kimai2:fpm)
# - Apache with PHP (kimai/kimai2:apache)
# - Development (kimai/kimai2:dev)
# ---------------------------------------------------------------------
# For local testing by maintainer:
#
# docker build --no-cache -t kimai-fpm --build-arg BASE=fpm .
# docker build --no-cache -t kimai-apache --build-arg BASE=apache .
# docker run -d --name kimai-apache-app kimai-apache
# docker exec -ti kimai-apache-app /bin/bash
# ---------------------------------------------------------------------
# Official PHP images: https://hub.docker.com/_/php/
# https://github.com/docker-library/docs/blob/master/php/README.md#supported-tags-and-respective-dockerfile-links
# Pass-through Arguments: https://benkyriakou.com/posts/docker-args-empty
# Best practices: https://docs.docker.com/build/building/best-practices/
# ---------------------------------------------------------------------
# Source base, one of: fpm, apache
ARG BASE="fpm"
# Kimai branch/tag to run
ARG KIMAI="main"
# Timezone for images
ARG TIMEZONE="Europe/Berlin"
###########################
# Shared tools
###########################
# composer base image
FROM composer:latest AS composer
###########################
# PHP extensions
###########################
# fpm alpine php extension base
FROM php:8.3-fpm-alpine AS fpm-php-ext-base
RUN apk add --no-cache \
# build-tools
autoconf \
dpkg \
dpkg-dev \
file \
g++ \
gcc \
icu-dev \
libatomic \
libc-dev \
libgomp \
libmagic \
m4 \
make \
mpc1 \
mpfr4 \
musl-dev \
perl \
re2c \
# gd
freetype-dev \
libpng-dev \
# icu
icu-dev \
icu-data-full \
# ldap
openldap-dev \
libldap \
# zip
libzip-dev \
# xsl
libxslt-dev
# apache debian php extension base
FROM php:8.3-apache-bookworm AS apache-php-ext-base
RUN apt-get update && \
apt-get install -y \
libldap2-dev \
libicu-dev \
libpng-dev \
libzip-dev \
libxslt1-dev \
libfreetype6-dev
# php extension gd - 13.86s
FROM ${BASE}-php-ext-base AS php-ext-gd
RUN docker-php-ext-configure gd \
--with-freetype && \
docker-php-ext-install -j$(nproc) gd
# php extension intl : 15.26s
FROM ${BASE}-php-ext-base AS php-ext-intl
RUN docker-php-ext-install -j$(nproc) intl
# php extension ldap : 8.45s
FROM ${BASE}-php-ext-base AS php-ext-ldap
RUN docker-php-ext-configure ldap && \
docker-php-ext-install -j$(nproc) ldap
# php extension pdo_mysql : 6.14s
FROM ${BASE}-php-ext-base AS php-ext-pdo_mysql
RUN docker-php-ext-install -j$(nproc) pdo_mysql
# php extension zip : 8.18s
FROM ${BASE}-php-ext-base AS php-ext-zip
RUN docker-php-ext-install -j$(nproc) zip
# php extension xsl : ?.?? s
FROM ${BASE}-php-ext-base AS php-ext-xsl
RUN docker-php-ext-install -j$(nproc) xsl
# php extension opcache
FROM ${BASE}-php-ext-base AS php-ext-opcache
RUN docker-php-ext-install -j$(nproc) opcache
###########################
# fpm base build
###########################
FROM php:8.3-fpm-alpine AS fpm-base
ARG TIMEZONE
RUN apk add --no-cache \
bash \
coreutils \
freetype \
haveged \
icu \
icu-data-full \
libldap \
libpng \
libzip \
libxslt-dev \
fcgi \
tzdata && \
touch /use_fpm && \
sed -i "s/;ping.path/ping.path/g" /usr/local/etc/php-fpm.d/www.conf && \
sed -i "s/;access.suppress_path\[\] = \/ping/access.suppress_path\[\] = \/ping/g" /usr/local/etc/php-fpm.d/www.conf
EXPOSE 9000
HEALTHCHECK --interval=20s --timeout=10s --retries=3 \
CMD \
SCRIPT_NAME=/ping \
SCRIPT_FILENAME=/ping \
REQUEST_METHOD=GET \
cgi-fcgi -bind -connect 127.0.0.1:9000 || exit 1
###########################
# apache base build
###########################
FROM php:8.3-apache-bookworm AS apache-base
ARG TIMEZONE
RUN apt-get update && \
apt-get install -y \
bash \
haveged \
libicu72 \
libldap-common \
libpng16-16 \
libzip4 \
libxslt1.1 \
libfreetype6 \
unzip && \
echo "Listen 8001" > /etc/apache2/ports.conf && \
a2enmod rewrite && \
touch /use_apache
COPY .docker/000-default.conf /etc/apache2/sites-available/000-default.conf
EXPOSE 8001
HEALTHCHECK --interval=20s --timeout=10s --retries=3 \
CMD curl -f http://127.0.0.1:8001 || exit 1
###########################
# global base build
###########################
FROM ${BASE}-base AS php-base
ARG TIMEZONE
ENV TIMEZONE=${TIMEZONE}
RUN ln -snf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && echo ${TIMEZONE} > /etc/timezone && \
# make composer home dir
mkdir /composer && \
chown -R www-data:www-data /composer
# copy composer
COPY --from=composer /usr/bin/composer /usr/bin/composer
# copy php extensions
# PHP extension xsl
COPY --from=php-ext-xsl /usr/local/etc/php/conf.d/docker-php-ext-xsl.ini /usr/local/etc/php/conf.d/docker-php-ext-xsl.ini
COPY --from=php-ext-xsl /usr/local/lib/php/extensions/no-debug-non-zts-20230831/xsl.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/xsl.so
# PHP extension pdo_mysql
COPY --from=php-ext-pdo_mysql /usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini /usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini
COPY --from=php-ext-pdo_mysql /usr/local/lib/php/extensions/no-debug-non-zts-20230831/pdo_mysql.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/pdo_mysql.so
# PHP extension zip
COPY --from=php-ext-zip /usr/local/etc/php/conf.d/docker-php-ext-zip.ini /usr/local/etc/php/conf.d/docker-php-ext-zip.ini
COPY --from=php-ext-zip /usr/local/lib/php/extensions/no-debug-non-zts-20230831/zip.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/zip.so
# PHP extension ldap
COPY --from=php-ext-ldap /usr/local/etc/php/conf.d/docker-php-ext-ldap.ini /usr/local/etc/php/conf.d/docker-php-ext-ldap.ini
COPY --from=php-ext-ldap /usr/local/lib/php/extensions/no-debug-non-zts-20230831/ldap.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/ldap.so
# PHP extension gd
COPY --from=php-ext-gd /usr/local/etc/php/conf.d/docker-php-ext-gd.ini /usr/local/etc/php/conf.d/docker-php-ext-gd.ini
COPY --from=php-ext-gd /usr/local/lib/php/extensions/no-debug-non-zts-20230831/gd.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/gd.so
# PHP extension intl
COPY --from=php-ext-intl /usr/local/etc/php/conf.d/docker-php-ext-intl.ini /usr/local/etc/php/conf.d/docker-php-ext-intl.ini
COPY --from=php-ext-intl /usr/local/lib/php/extensions/no-debug-non-zts-20230831/intl.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/intl.so
# PHP extension opcache
COPY --from=php-ext-opcache /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini
###########################
# fetch Kimai sources
###########################
FROM alpine:latest AS git-prod
ARG KIMAI
ARG TIMEZONE
# the convention in the Kimai repository is: tags are always version numbers, branch names always start with a letter
# if the KIMAI variable starts with a number (e.g. 2.24.0) we assume its a tag, otherwise its a branch
RUN [[ $KIMAI =~ ^[0-9] ]] && export REF='tags' || export REF='heads' && \
wget -O "/opt/kimai.tar.gz" "https://github.com/kimai/kimai/archive/refs/${REF}/${KIMAI}.tar.gz" && \
tar -xpzf /opt/kimai.tar.gz -C /opt/ && \
mv /opt/kimai-${KIMAI} /opt/kimai
###########################
# global base build
###########################
FROM php-base AS base
ARG KIMAI
ARG TIMEZONE
LABEL org.opencontainers.image.title="Kimai" \
org.opencontainers.image.description="Kimai is a time-tracking application." \
org.opencontainers.image.authors="Kimai Community" \
org.opencontainers.image.url="https://www.kimai.org/" \
org.opencontainers.image.documentation="https://www.kimai.org/documentation/" \
org.opencontainers.image.source="https://github.com/kimai/kimai" \
org.opencontainers.image.version="${KIMAI}" \
org.opencontainers.image.vendor="Kevin Papst" \
org.opencontainers.image.licenses="AGPL-3.0"
ENV KIMAI=${KIMAI}
ENV TIMEZONE=${TIMEZONE}
RUN ln -snf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && echo ${TIMEZONE} > /etc/timezone && \
mkdir -p /composer && \
chown -R www-data:www-data /composer
# copy startup script & DB checking script
COPY .docker/dbtest.php /dbtest.php
COPY .docker/entrypoint.sh /entrypoint.sh
ENV DATABASE_URL="mysql://kimai:kimai@127.0.0.1:3306/kimai?charset=utf8mb4&serverVersion=8.3"
ENV APP_SECRET=change_this_to_something_unique
# The default container name for nginx is nginx
ENV TRUSTED_PROXIES=nginx,localhost,127.0.0.1
ENV MAILER_FROM=kimai@example.com
ENV MAILER_URL=null://localhost
ENV ADMINPASS=
ENV ADMINMAIL=
ENV USER_ID=
ENV GROUP_ID=
# default values to configure composer behavior
ENV COMPOSER_MEMORY_LIMIT=-1
ENV COMPOSER_ALLOW_SUPERUSER=1
VOLUME [ "/opt/kimai/var" ]
CMD [ "/entrypoint.sh" ]
###########################
# final builds
###########################
# development build
FROM base AS dev
# copy kimai develop source
COPY --from=git-prod --chown=www-data:www-data /opt/kimai /opt/kimai
COPY .docker /assets
# do the composer deps installation
RUN \
export COMPOSER_HOME=/composer && \
composer --no-ansi install --working-dir=/opt/kimai --optimize-autoloader && \
composer --no-ansi clearcache && \
composer --no-ansi require --working-dir=/opt/kimai laminas/laminas-ldap && \
cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini && \
chown -R www-data:www-data /opt/kimai /usr/local/etc/php/php.ini && \
mkdir -p /opt/kimai/var/logs && chmod 777 /opt/kimai/var/logs && \
sed "s/128M/-1/g" /usr/local/etc/php/php.ini-development > /opt/kimai/php-cli.ini && \
sed -i "s/env php/env -S php -c \/opt\/kimai\/php-cli.ini/g" /opt/kimai/bin/console && \
/opt/kimai/bin/console kimai:version | awk '{print $2}' > /opt/kimai/version.txt
ENV APP_ENV=dev
ENV DATABASE_URL=
ENV memory_limit=512M
# the "prod" stage (production build) is configured as last stage in the file, as this is the default target in BuildKit
FROM base AS prod
# copy kimai production source
COPY --from=git-prod --chown=www-data:www-data /opt/kimai /opt/kimai
COPY .docker /assets
# do the composer deps installation
RUN \
export COMPOSER_HOME=/composer && \
composer --no-ansi install --working-dir=/opt/kimai --no-dev --optimize-autoloader && \
composer --no-ansi clearcache && \
composer --no-ansi require --update-no-dev --working-dir=/opt/kimai laminas/laminas-ldap && \
cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini && \
sed -i "s/expose_php = On/expose_php = Off/g" /usr/local/etc/php/php.ini && \
sed -i "s/;opcache.enable=1/opcache.enable=1/g" /usr/local/etc/php/php.ini && \
sed -i "s/;opcache.memory_consumption=128/opcache.memory_consumption=256/g" /usr/local/etc/php/php.ini && \
sed -i "s/;opcache.interned_strings_buffer=8/opcache.interned_strings_buffer=24/g" /usr/local/etc/php/php.ini && \
sed -i "s/;opcache.max_accelerated_files=10000/opcache.max_accelerated_files=100000/g" /usr/local/etc/php/php.ini && \
sed -i "s/opcache.validate_timestamps=1/opcache.validate_timestamps=0/g" /usr/local/etc/php/php.ini && \
sed -i "s/session.gc_maxlifetime = 1440/session.gc_maxlifetime = 604800/g" /usr/local/etc/php/php.ini && \
mkdir -p /opt/kimai/var/logs && chmod 777 /opt/kimai/var/logs && \
sed "s/128M/-1/g" /usr/local/etc/php/php.ini-development > /opt/kimai/php-cli.ini && \
chown -R www-data:www-data /opt/kimai /usr/local/etc/php/php.ini && \
/opt/kimai/bin/console kimai:version | awk '{print $2}' > /opt/kimai/version.txt
ENV APP_ENV=prod
ENV DATABASE_URL=
ENV memory_limit=512M

674
LICENSE
View File

@@ -1,19 +1,661 @@
Copyright (c) 2016 Kevin Papst
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
Preamble
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.

146
README.md
View File

@@ -1,114 +1,88 @@
# Kimai v2 - Time Tracking
<p align="center">
<img src="https://raw.githubusercontent.com/kimai/images/main/repository-header.png" alt="Kimai logo">
</p>
Kimai v2 - the reloaded open source Time-Tracking application.
<p align="center">
<a href="https://github.com/kimai/kimai/actions"><img alt="CI Status" src="https://github.com/kimai/kimai/actions/workflows/testing.yaml/badge.svg"></a>
<a href="https://codecov.io/gh/kimai/kimai"><img alt="Code Coverage" src="https://codecov.io/gh/kimai/kimai/branch/main/graph/badge.svg"></a>
<a href="https://packagist.org/packages/kimai/kimai"><img alt="Latest stable version" src="https://poser.pugx.org/kimai/kimai/v/stable"></a>
<a href="https://www.gnu.org/licenses/agpl-3.0.en.html"><img alt="License" src="https://poser.pugx.org/kimai/kimai/license"></a>
<a href="https://phpc.social/@kimai" rel="me"><img alt="Mastodon" src="https://img.shields.io/badge/toot-%40kimai-8c8dff"></a>
</p>
[![Build Status](https://travis-ci.org/kevinpapst/kimai2.svg?branch=master)](https://travis-ci.org/kevinpapst/kimai2)
<h1 align="center">Kimai - time-tracker</h1>
## Introduction
Kimai is a professional grade time-tracking application, free and open-source.
It handles use-cases of freelancers as well as companies with dozens or hundreds of users.
Kimai was build to track your project times and ships with many advanced features, including but not limited to:
This is (or will be in the future, currently a lot of features are still missing) the reloaded version of the open source time-tracking application [Kimai](http://www.kimai.org).
JSON API, invoicing, data exports, multi-timer and punch-in punch-out mode, tagging, multi-user - multi-timezones - multi-language ([over 30 translations existing](https://hosted.weblate.org/projects/kimai/)!),
authentication via SAML/LDAP/Database, two-factor authentication (2FA) with TOTP, customizable role and team permissions, responsive design,
user/customer/project specific rates, advanced search & filtering, money and time budgets, advanced reporting, support for [plugins](https://www.kimai.org/store/)
and so much more.
It is based on the following PHP components:
- [Symfony Framework 3.4](https://github.com/symfony/symfony)
- [AdminThemeBundle](https://github.com/avanzu/AdminThemeBundle/) (based on [AdminLTE](https://github.com/almasaeed2010/AdminLTE/))
- [Doctrine](https://github.com/doctrine/)
- Bower
### Links
## Requirements
- [Home](https://www.kimai.org) — Kimai project homepage
- [Blog](https://www.kimai.org/blog/) — Read the latest news
- [Documentation](https://www.kimai.org/documentation/) — Learn how to use Kimai
- PHP 7 or higher
- One PHP extension of PDO-SQLite and/or PDO-MySQL enabled
- and the [usual Symfony application requirements](http://symfony.com/doc/current/reference/requirements.html)
### Requirements
If unsure about meeting these requirements, download the demo application and
browse to the <http://localhost:8000/config.php> script to get more detailed information.
- PHP 8.1.3 minimum (support for PHP 8.2, 8.3, 8.4)
- MariaDB or MySQL
- A webserver and subdomain (subdirectory is not supported)
- PHP extensions: `gd`, `intl`, `json`, `mbstring`, `pdo`, `tokenizer`, `xml`, `xsl`, `zip`
## Installation
First, install Git and [Composer](https://getcomposer.org/doc/00-intro.md)
if you haven't already. Then, clone this repo and execute this command in the cloned directory:
- Caddy with Docker-Compose at [Hetzner](https://www.kimai.org/documentation/hosting-hetzner-cloud.html) and [DigitalOcean](https://www.kimai.org/documentation/hosting-digital-ocean.html)
- [SSH setup](https://www.kimai.org/documentation/installation.html) with Git and Composer
- [Docker images](https://hub.docker.com/r/kimai/kimai2) with FPM only or incl. Apache
- [Synology](https://www.kimai.org/documentation/synology.html) user can host the Docker version
- [Developer setups](https://www.kimai.org/documentation/developers.html) if you want to create Kimai integrations
```bash
$ git clone https://github.com/kevinpapst/kimai2.git
$ cd kimai2/
```
There are more documented ways for [on-premise hosting](https://www.kimai.org/documentation/chapter-on-premise.html).
Lets prepare the environment by installing all dependencies. You will be asked for your application parameter,
like the database connection afterwards (if you don't have a [app/config/parameters.yml](blob/master/app/config/parameters.yml.dist) yet):
And if you don't want to host Kimai, you can use [the Cloud version](https://www.kimai.cloud/) of it.
```bash
$ composer install
```
### Updating Kimai
The next command will create the database, the schema and install all web assets:
```bash
$ bin/console kimai:install --relative
```
- [Update Kimai](https://www.kimai.org/documentation/updates.html) — get the latest version
- [UPGRADING guide](UPGRADING.md) — version specific steps
### Installation (live)
### Plugins
All thats left to do is to create your first user:
- [Plugins](https://www.kimai.org/store/) — paid and free plugin marketplace
- [Developer documentation](https://www.kimai.org/documentation/developers.html) — how to create a plugin
```bash
$ bin/console kimai:create-user admin admin@example.com password en ROLE_SUPER_ADMIN
```
## Roadmap and releases
For available roles, please refer to [the user documentation](app/Resources/docs/users.md).
You can see a rough development [roadmap](https://github.com/orgs/kimai/projects/2), which is open for changes and input from the community, your [ideas](https://github.com/kimai/kimai/issues) are welcome.
### Installation (development / demo)
Release versions will be created on a regular basis, every couple of weeks latest.
Every code change, whether it's a new feature or a bugfix, will be done on the `main` branch.
Lets boostrap your environment by executing this commands (which is only available in dev environment):
```bash
$ bin/console kimai:dev:reset
```
## Contributing
You just imported demo data, to test the application in its full beauty and with several different user accounts and permission sets.
You want to contribute to this repository? This is so great!
The best way to start is to [open a new issue](https://github.com/kimai/kimai/issues) for bugs or feature requests or a [discussion](https://github.com/kimai/kimai/discussions) for questions, support and such.
You can now login with these accounts:
In case you want to contribute, but you wouldn't know how, here are some suggestions:
| Username | Password | Role |
|---|:---:|---|
| clara_customer | kitten | Customer |
| john_user | kitten | User |
| chris_user | kitten | User (deactivated) |
| tony_teamlead | kitten | Teamlead |
| anna_admin | kitten | Administrator |
| susan_super | kitten | Super-Administrator |
- Spread the word: Please [write a testimonial for our Wall of love](https://love.kimai.org), vote for Kimai on any software platform, you can toot or tweet about it, share it on LinkedIn, Reddit and any other social media platform!
- Answer questions: You know the answer to another user's problem? Share your knowledge.
- Something can be done better? An essential feature is missing? Create a feature request.
- Report bugs makes Kimai better for everyone.
- You don't have to be programmer, the documentation and translation could always use some attention.
- Sponsor the project: free software costs money to create!
Demo data can always be deleted by dropping the schema and re-creating it.
ATTENTION - this will erase all your data:
There is one simple rule in our "Code of conduct": Don't be an ass!
```bash
$ bin/console doctrine:schema:drop --force
$ bin/console doctrine:schema:create
```
### Credits
The `kimai:dev:reset` command can always be executed later on to reset your dev database and cache. I use it very frequently.
## Usage
There is no need to configure a virtual host in your web server to access the application for testing.
Just use the built-in web server for your first tests:
```bash
$ APP_FRONT_CONTROLLER=app.php bin/console server:run
```
This command will start a web server for Kimai. Now you can access the application in your browser at <http://127.0.0.1:8000/>.
You can stop the built-in web server by pressing `Ctrl + C` while you're in the terminal.
> **NOTE**
>
> If you want to use a fully-featured web server (like Nginx or Apache) to run
> Kimai, configure it to point at the `web/` directory of the project.
> For more details, see:
> http://symfony.com/doc/current/cookbook/configuration/web_server_configuration.html
## Troubleshooting
Cannot see any assets (like images) and/or missing styles? Try executing:
```bash
$ php bin/console assets:install --symlink
```
Kimai is based on modern technologies and frameworks such as [PHP](https://www.php.net/),
[Symfony](https://github.com/symfony/symfony) and [Doctrine](https://github.com/doctrine/),
[Bootstrap](https://github.com/twbs/bootstrap) and [Tabler](https://tabler.io/),
and [countless](composer.json) [others](package.json).

10
SECURITY.md Normal file
View File

@@ -0,0 +1,10 @@
# Security Policy
As announced in the [README](README.md) security fixes will only be added to the `main` branch.
| Version | Supported |
|----------------------|--------------------|
| main branch | :white_check_mark: |
| older releases | :x: |
You find all information in our [Bughunter documentation](https://www.kimai.org/documentation/bughunter.html).

368
UPGRADING-1.md Normal file
View File

@@ -0,0 +1,368 @@
# Upgrading Kimai - Version 1.x
_Make sure to create a backup before you start!_
Read the [updates documentation](https://www.kimai.org/documentation/updates.html) to find out how
you can upgrade your Kimai installation to the latest stable release.
Check below if there are more version specific steps required, which need to be executed after the normal update process.
Perform EACH version specific task between your version and the new one, otherwise you risk data inconsistency or a broken installation.
## [1.16](https://github.com/kimai/kimai/releases/tag/1.16)
If you are using MariaDB, it must be at least version 10.1, older versions are not supported any longer.
**DEVELOPER**
- Removed `formDateTime` field from API model `I18nConfig`
- Upgraded to Doctrine DBAL 3, see [docs](https://github.com/doctrine/dbal/blob/3.1.x/UPGRADE.md) - you might have to update your bundle
## [1.15](https://github.com/kimai/kimai/releases/tag/1.15)
**Many database changes: don't forget to [run the updater](https://www.kimai.org/documentation/updates.html).**
Updating the database might take quite a while, depending on the amount of timesheet entries and speed of your database server (~1 minute per 100k records).
**ATTENTION**
- This release bumps the minimum required [PHP version to 7.3](https://www.kimai.org/blog/2021/php8-support-php72-dropped/)
- Self-registration is disabled by default
- Self-registration now always requires email confirmation
- All plugins that use own databases need to be updated as well
- Removed the YearChart widget and the related configs named `userRecapThisYear`, `userRecapLastYear`, `userRecapTwoYears`, `userRecapThreeYears`
**LDAP & SAML**
Please verify your config with the [LDAP](https://www.kimai.org/documentation/ldap.html) and [SAML](https://www.kimai.org/documentation/saml.html) documentation, especially:
- SAML users: activate it by setting the `kimai.saml.activate: true` config key
- LDAP users: activate it by setting the `kimai.ldap.activate: true` config key
- LDAP and SAML users need to remove the complete `security` section from their `local.yaml`
**DEVELOPER**
PHP 8 compatibility forced to upgrade MANY libraries, including but not limited to:
- Removed FOSUserBundle and hslavich/oneloginsaml
- Doctrine Migrations, whose new major version forces plugin updates
- Gedmo v3 (which include BC breaks in definitions)
- Doctrine DBAL and others, which required PHP 7.3 as well
**API BC break**: Due to team structure changes, it was impossible to keep the (writing) API structure. Please adjust your code accordingly!
## [1.14](https://github.com/kimai/kimai/releases/tag/1.14)
**CRITICAL BC break**: SQLite support was removed. If you are using SQLite, you have to [read this blog post](https://www.kimai.org/blog/2021/sqlite-and-ftp-support-removed/) and migrate to MySQL/MariaDB first!
**New database tables and fields: don't forget to [run the updater](https://www.kimai.org/documentation/updates.html).**
Permission changes:
- `history_invoice` - removed permission entirely
## [1.13](https://github.com/kimai/kimai/releases/tag/1.13)
- Deprecated `now` variable in export templates: create it yourself with `{% set now = create_date('now', app.user) %}`
- Changed invoice filename generation (check if you use cronjob for invoices)
- **BC break**: duration entered as plain numbers will now be treated as decimal duration in hours instead of seconds
## [1.12](https://github.com/kimai/kimai/releases/tag/1.12)
- Export templates can now include items from plugins (eg. Expenses).
## [1.10](https://github.com/kimai/kimai/releases/tag/1.10)
**New database tables and fields were created, don't forget to [run the updater](https://www.kimai.org/documentation/updates.html).**
- Invoice renderer `CSV` was removed
- Sessions are now stored in the database (all users have to re-login after upgrade)
- New permissions: `lockdown_grace_timesheet`, `lockdown_override_timesheet`, `view_all_data`
- Fixed team permissions on user queries: depending on your previous team & permission setup your users might see less data (SUPER_ADMINS see all data, but new: ADMINS only see all data if they own the `view_all_data` permission)
- Markdown does not support headings anymore, text like `# foo` is not converted to `<h1 id="foo">foo</h1>` anymore
### Developer
- **BC break**: removed registration of `.env` with `putenv()` - do not rely on `getenv()` as it is not thread-safe
- **BC break**: interface method signature `HtmlToPdfConverter::convertToPdf()` changed
- **BC break**: the macros `badge` and `label` do not apply the `|trans` filter any more
- **BC Break**: removed `getVisible()` (deprecated since 1.4) method on Customer, Project and Activity (use `isVisible()` instead, templates are still working)
- **BC Break**: API changes
- some representation names changed (eg. from `ActivityMetaField` to `ActivityMeta`, `TimesheetSubCollection` vs `TimesheetCollectionExpanded`), you could use `class_alias()` if you use auto-generated code from Swagger-Gen or alike
- new result types were introduced
- result data changed in some areas to smooth out inconsistencies (eg. TeamEntity fields changed in nested results)
## [1.9](https://github.com/kimai/kimai/releases/tag/1.9)
**New database tables and fields were created, don't forget to [run the updater](https://www.kimai.org/documentation/updates.html).**
- The directory `var/data/invoices/` will be used to store archived invoice files (check file permissions)
- The default invoice number format changed. If you want to use the old one: configure `{date}` as format - see [invoice documentation](https://www.kimai.org/documentation/invoices.html)
- HTML invoice templates are now treated like other files and offered as download. If you are using relative URLs for including assets (CSS, images) you need to either inline them (see the default templates) or use absolute URLs
- Invoice templates that use the templates variables `${activity.X}` or `${project.X}` should be checked and possibly adapted, as multi-select is now possible for filtering
- Invoice templates have access to all meta-fields as variables, not only the ones marked as visible
- Rates configuration/structure changed for customer, project and activity
- **Invoice templates**: rates variables were removed
Permission changes:
- `history_invoice` - NEW: grants all features for the new invoice archive (by default for all admins)
### Developer
- **BC break**: `InvoiceItemInterface` has new methods `getType()` and `getCategory()`
- **BC break**: API fields changed - see new `/rates` endpoints
## [1.8](https://github.com/kimai/kimai/releases/tag/1.8)
**New database tables and fields were created, don't forget to [run the updater](https://www.kimai.org/documentation/updates.html).**
- New PHP requirement: `ext-xsl` - which should be pre-installed in most environments when `ext-xml` is loaded
- New mailer library: check if emails are still working (eg. by using the "password forgotten" function) or if you need to adjust your configuration, [see docs at symfony.com](https://symfony.com/doc/current/components/mailer.html#transport)
- Support for line breaks in multiline invoice fields for spreadsheets (check your invoice templates after the update)
Permission changes:
- `comments_create_customer` - NEW: permission that allows to add new comments for customers
- `comments_create_team_customer` - NEW: permission that allows to add new comments for team members of the current customer
- `comments_create_teamlead_customer` - NEW: permission that allows to add new comments for a teamlead of the current customer
- `comments_create_project` - NEW: permission that allows to add new comments for project
- `comments_create_team_project` - NEW: permission that allows to add new comments for team members of the current project
- `comments_create_teamlead_project` - NEW: permission that allows to add new comments for a teamlead of the current project
- `edit_teamlead_project` - removed default permission from ROLE_TEAMLEAD (if you use it: change it in the Role & Permission UI)
- `edit_teamlead_customer` - removed default permission from ROLE_TEAMLEAD (if you use it: change it in the Role & Permission UI)
- `upload_invoice_template` - NEW: permission that allows to upload invoice documents from the UI
## [1.7](https://github.com/kimai/kimai/releases/tag/1.7)
**New database tables and fields were created, don't forget to [run the updater](https://www.kimai.org/documentation/updates.html).**
New permissions:
- `comments_customer` - show comment list on customer detail page (new feature)
- `details_customer` - show detail information for customers (customer number, vat, rates, meta-fields, assigned teams ...)
- `comments_project` - show comment list on project detail page (new feature)
- `details_project` - show detail information for projects (rates, meta-fields, assigned teams ...)
If you are using teams, please read on: The following list of permissions are now also available in the UI and they (can) replace the `X_project` and `X_customer` permissions.
They are more strict, as they allow only access to team specific items, the older permissions without `_teamlead_`/`_team_` work on a global level instead.
- `view_teamlead_customer`, `edit_teamlead_customer`, `budget_teamlead_customer`, `permissions_teamlead_customer`, `comments_teamlead_customer`, `details_teamlead_customer` - allows access to customer data when user is teamlead of a team assigned to the customer (replaces more global permission like `view_customer` for teamleads)
- `view_team_customer`, `edit_team_customer`, `budget_team_customer`, `comments_team_customer`, `details_team_customer` - allows access to customer data when user is member of a team assigned to the customer (replaces more global permission like `view_customer` for users)
- `view_teamlead_project`, `edit_teamlead_project`, `budget_teamlead_project`, `permissions_teamlead_project`, `comments_teamlead_project`, `details_teamlead_project` - allows access to customer data when user is teamlead of a team assigned to the project (replaces more global permission like `view_project` for teamleads)
- `view_team_project`, `edit_team_project`, `budget_team_project`, `comments_team_project`, `details_team_project` - allows access to customer data when user is member of a team assigned to the project (replaces more global permission like `view_project` for users)
### ExpenseBundle
**ATTENTION** due to incompatibilities in the underlying frameworks users of the ExpenseBundle need to do one more step:
You need to delete the bundle before updating: `rm -r var/plugins/ExpenseBundle`, otherwise you will run into errors during the update.
After the Kimai update was successful, you have to re-install the latest bundle version, which is compatible with Kimai 1.7 only.
### Developer
- Projects now have a start and end date and the API will only return those, which are either unconfigured or currently active, you might want to reload the list of projects once the user entered begin and end datetime OR use the new `ignoreDates` parameter.
- Doctrine bundle was updated to v2, check your code for [the usage of RegistryInterface and ObjectManager](https://github.com/doctrine/DoctrineBundle/blob/master/UPGRADE-2.0.md)
- Removed the webserver bundle and the command `server:run` - see [docs](https://www.kimai.org/documentation/developers.html)
## [1.6](https://github.com/kimai/kimai/releases/tag/1.6), [1.6.1](https://github.com/kimai/kimai/releases/tag/1.6.1), [1.6.2](https://github.com/kimai/kimai/releases/tag/1.6.2)
**New database tables and fields were created, don't forget to [run the updater](https://www.kimai.org/documentation/updates.html).**
- Invoice changes:
- Moved CSV, ODS and XSLX invoice templates to [another repository](https://github.com/Keleo/kimai2-invoice-templates). Using them? Install them manually (see [invoice documentation](https://www.kimai.org/documentation/invoices.html)).
- Added new invoice fields (VAT, contact, payment details) and customer field (VAT). Used the twig settings before? Move them to the respective invoice template settings.
- Permissions can be managed via Admin UI. Please move your permission settings from [local.yaml to your database](https://www.kimai.org/documentation/permissions.html).
- Important permission change: regular users with the `view_other_timesheet` permission could see all timesheets. This was a legacy from the time before team permissions were introduced. If you rely on this behavior, you need to create a team with all users and the teamlead being the user who needs access to all timesheets.
### Developer
Please add default permissions to your [plugin](https://www.kimai.org/documentation/plugins.html).
## [1.5](https://github.com/kimai/kimai/releases/tag/1.5)
[Update as usual](https://www.kimai.org/documentation/updates.html)
## [1.4](https://github.com/kimai/kimai/releases/tag/1.4)
**There is a new directory, which needs to be writable by the webserver: `public/avatars/`.**
New permission (used in new dashboard widget):
- `view_team_member` - display team assignments (names, teamleads and members) for the current user
Activated Javascript select component by default (check mobile devices).
### Developer: BC breaks
- Dashboard widgets and rows need to define their `type` by FQCN
- Switched to Symfony 4.3 event types, this could fail in plugins, but only if they didn't use the official constants for event names
## [1.3](https://github.com/kimai/kimai/releases/tag/1.3)
Added `manage_tag` permission for new tag features
### Developer: BC breaks
- Refactored toolbars and search, plugins needs to be checked
- Invoices now supports multiple repositories, some method signatures had to be changed (eg. `calculateSumIdentifier()`)
## [1.2](https://github.com/kimai/kimai/releases/tag/1.2)
**If you are still using 0.7 or below, you need to upgrade to 1.1 before upgrading to this version.**
- Deleted timezone conversion command.
- Minimum password length raised from 5 to 8 character (applies only for password changes and new users)
- Maximum customer name length lowered to 150 character
- Maximum project name length lowered to 150 character
- Maximum activity name length lowered to 150 character
- Added new permission: `manage_invoice_template`
- Removed permissions: `view_invoice_template`, `create_invoice_template`, `edit_invoice_template`, `delete_invoice_template`
- Removed permission: `view_export` (using `create_export` only)
### Developer: BC breaks
- Custom export renderer need to check for usage of `Timesheet::getEnd()` as running entries can now be exported as well
## [1.1](https://github.com/kimai/kimai/releases/tag/1.1)
[Update as usual](https://www.kimai.org/documentation/updates.html), nothing special for this release if you upgrade from 1.0 / 1.0.1.
## [1.0](https://github.com/kimai/kimai/releases/tag/1.0)
This release contains several changes, as I still have the goal to stabilize the code base to prevent
such "challenges" after 1.0 for a while.
### Changes for your local.yaml
New permissions are available. You have to add them to your `local.yaml` ONLY if you use a custom permission structure,
otherwise you can't use the new features:
- `view_tag` - view all tags
- `delete_tag` - delete tags
- `edit_exported_timesheet` - allows to edit records which were exported
- `role_permissions` - view calculated permissions for user roles
- `budget_activity` - view and edit budgets for activities
- `budget_project` - view and edit budgets for projects
- `budget_customer` - view and edit budgets for customers
Removed permission:
- `system_actions` - removed experimental feature to flush app cache from the about screen
### BC BREAKS
- API: Format for queries including a datetime object fixed to use HTML5 format (previously `2019-03-02 14:23` - now `2019-03-02T14:23:00`)
- **Permission config**: the `permissions` definition in your `local.yaml` needs to be verified/changed, as the internal structure was highly optimized to simplify the definition.
Thanks to the new structure, you should be able to remove almost everything from your `local.yaml` (tip: start over from scratch!). Please read [the updated permission docu](https://www.kimai.org/documentation/permissions.html).
- default widgets were removed from `kimai.yaml`, that shouldn't cause any issues ... but if something is odd: [look here for help](https://www.kimai.org/documentation/dashboard.html)
## [0.9](https://github.com/kimai/kimai/releases/tag/0.9)
Remember to execute the necessary timezone conversion script, if you haven't updated to 0.8 before (see below)!
### BC BREAKS
This release contains some BC breaks which were necessary before 1.0 will be released (_now or never_), to prevent those BC breaks after 1.0.
- **Kimai requires PHP 7.2 now => [PHP 7.1 expired 4 month ago](https://www.php.net/supported-versions.php)**
- The `.env` variable `DATABASE_PREFIX` was removed and the table prefix is now hardcoded to `kimai2_`. If you used another prefix,
you have to rename your tables manually before starting the update process. You can delete the row `DATABASE_PREFIX` from your `.env` file.
- API: Format for DateTime objects changed, now including timezone identifier (previously `2019-03-02 14:23` - now `2019-03-02T14:23:00+00:00`), see [#718](https://github.com/kimai/kimai/pull/718)
- API: changed from snake_case to camelCase (affected fields: hourlyRate vs hourly_rate / fixedRate vs fixed_rate / orderNumber vs order_number / i18n config object)
- Plugin mechanism changed: existing Plugins have to be deleted or updated
### Apply necessary changes to your `local.yaml`:
New permissions are available:
- `system_configuration` - for accessing the new system configuration screen
- `system_actions` - for the experimental feature to flush your cache from the about screen
- `plugins` - for accessing the new plugins screen
The setting `kimai.timesheet.mode` replaces the setting `kimai.timesheet.duration_only`. If you used the duration_only mode, you need to change your config:
```yaml
# Before
kimai:
timesheet:
duration_only: true
# After
kimai:
timesheet:
mode: duration_only
```
Or switch the mode directly in the new System configuration screen within Kimai.
## [0.8.1](https://github.com/kimai/kimai/releases/tag/0.8.1)
A bug fixing release. Remember to execute the necessary timezone conversion script, if you haven't updated to 0.8 before (see below)!
## [0.8](https://github.com/kimai/kimai/releases/tag/0.8)
After you followed the normal update and database migration process (see above), you need to execute a bash command to convert your timesheet data for timezone support:
- Read this [pull request](https://github.com/kimai/kimai/pull/372) BEFORE you follow the instructions to convert the
timezones in your existing time records with `bin/console kimai:convert-timezone`. Without that, you will end up with wrong times in your database.
### Apply necessary changes to your `local.yaml`:
- A new boolean setting `kimai.timesheet.rules.allow_future_times` was introduced
- New permissions are available:
- `view_export` - for the new export feature
- `create_export` - for the new export feature
- `edit_export_own_timesheet` - for the new export feature
- `edit_export_other_timesheet` - for the new export feature
- `system_information` - to see the new about screen
## [0.7](https://github.com/kimai/kimai/releases/tag/0.7)
The configuration `kimai.theme.active_warning` was deprecated and should be replaced in your local.yaml,
[read config docs for more information](https://www.kimai.org/documentation/timesheet.html#limit-active-entries).
## [0.6.1](https://github.com/kimai/kimai/releases/tag/0.6.1)
A bugfix release to address database compatibility issues with older MySQL/MariaDB versions.
## [0.6](https://github.com/kimai/kimai/releases/tag/0.6)
The API has some minor BC breaks: some fields were renamed and entities have a larger attribute set than collections.
Be aware that the API is still is development mode and shouldn't be considered stable for now.
## [0.5](https://github.com/kimai/kimai/releases/tag/0.5)
Some configuration nodes were removed, if you have one of them in your `local.yaml` you need to delete them before you start the update:
- `kimai.invoice.calculator`
- `kimai.invoice.renderer`
- `kimai.invoice.number_generator`
The new config `kimai.invoice.documents` was introduced, holding a list of directories ([read more](https://www.kimai.org/documentation/invoices.html)).
**BC break:** InvoiceTemplate name was changed from 255 characters to 60. If you used longer invoice-template names, they will be truncated when upgrading the database.
Please make sure that they are unique in the first 60 character before you upgrade your database with `doctrine:migrations:migrate`.
## [0.4](https://github.com/kimai/kimai/releases/tag/0.4)
In the time between 0.3 and 0.4 there was a release of composer that introduced a BC break,
which leads to problems between Composer and Symfony Flex, resulting in an error like this when running it:
```
[ErrorException]
Declaration of Symfony\Flex\ParallelDownloader::getRemoteContents($originUrl, $fileUrl, $context) should be compatible with Composer\Util\RemoteFilesystem::getRemoteContents($originUrl, $fileUrl, $context, ?array &$responseHeaders = NULL)
```
This can be fixed by updating Composer and Flex before executing the Kimai update:
```
sudo composer self-update
sudo -u www-data composer update symfony/flex --no-plugins --no-scripts
```
## [0.3](https://github.com/kimai/kimai/releases/tag/0.3)
You need to adjust your `.env` file and add your `from` address for [all emails](https://www.kimai.org/documentation/emails.html) generated by Kimai 2:
```
MAILER_FROM=kimai@example.com
```
Create a file and database backup before executing the following steps:
```bash
git pull origin master
sudo -u www-data composer install --no-dev --optimize-autoloader
sudo -u www-data bin/console cache:clear --env=prod
sudo -u www-data bin/console cache:warmup --env=prod
bin/console doctrine:migrations:version --add 20180701120000
bin/console doctrine:migrations:migrate
```

24
UPGRADING-3.md Normal file
View File

@@ -0,0 +1,24 @@
# Upgrading Kimai - Version 3.x
_Make sure to create a backup before you start!_
Read the [updates documentation](https://www.kimai.org/documentation/updates.html) to find out how you can upgrade your Kimai installation to the latest stable release.
Check below if there are more version specific steps required, which need to be executed after the normal update process.
Perform EACH version specific task between your version and the new one, otherwise you risk data inconsistency or a broken installation.
## 3.0
**!! This release requires minimum PHP version 8.4 !!**
### Developer
Removed translations:
- `action.edit`: use `edit` instead
- `my.profile`: use `user_profile` instead
- `stats.userAmountToday`: use `` instead
- `stats.userAmountWeek`: use `` instead
- `stats.userAmountMonth`: use `` instead
- `stats.userAmountYear`: use `` instead
- `stats.userAmountTotal`: use `` instead
- `update_multiple`

50
UPGRADING.md Normal file
View File

@@ -0,0 +1,50 @@
# Upgrading Kimai - Version 2.x
_Make sure to create a backup before you start!_
Read the [updates documentation](https://www.kimai.org/documentation/updates.html) to find out how
you can upgrade your Kimai installation to the latest stable release.
Check below if there are more version specific steps required, which need to be executed after the normal update process.
Perform EACH version specific task between your version and the new one, otherwise you risk data inconsistency or a broken installation.
## [2.0.30](https://github.com/kimai/kimai/releases/tag/2.0.30)
The `DATABASE_URL` in your environment settings (e.g. [.env](https://github.com/kimai/kimai/issues/4246), [docker-compose.yaml](https://github.com/tobybatch/kimai2/issues/531) or webserver config)
now requires the `charset` and `serverVersion` params, e.g.: `DATABASE_URL=mysql://user:password@127.0.0.1:3306/database?charset=utf8mb4&serverVersion=10.5.8-MariaDB` (examples in `.env`).
## [2.0](https://github.com/kimai/kimai/releases/tag/2.0)
**!! This release requires minimum PHP version to 8.1 !!**
### Breaking changes
- All plugins need to be updated: delete all previous version from your installation (`rm -r var/plugins/*`) before updating!
- The `local.yaml` is not compatible with old version, remove it before the update and then re-create it after everything works
- removed: configuring the `dashboard` is not supported any longer
- removed: custom translation files via `theme.branding.translation`
- removed: changing the plugin directory via `kimai.plugin_dir`
### Developer
Developer read the full documentation at [https://www.kimai.org/documentation/migration-v2.html](https://www.kimai.org/documentation/migration-v2.html).
- Invoice renderer and templates for XML, JSON and TEXT were moved to the [Extended invoicing plugin](https://www.kimai.org/store/invoice-bundle.html) (install if you use one of those)
- Moved `company.docx` to [external repo](https://github.com/kimai/invoice-templates/tree/main/docx-company) (needs to be re-uploaded if you want to keep on using it!)
- Role names are forced to be uppercase
- Removed unused `public/avatars/` directory
- Time-tracking mode `duration_only` was removed, existing installations will be switched to `duration_fixed_begin`
- Removed Twig filters. You might have to replace them in your custom export/invoice templates:
- `date_full` => `date_time`
- `duration_decimal` => `duration(true)`
- `currency` => `currency_name`
- `country` => `country_name`
- `language` => `language_name`
- Removed support for custom translation files (use [TranslationBundle](https://www.kimai.org/store/translation-bundle.html) instead or write your own plugin)
- Removed all 3rd party mailer packages, you need to install them manually (ONLY if you used a short syntax to configure the `MAILER_URL` in `.env`):
- `composer require symfony/amazon-mailer`
- `composer require symfony/google-mailer`
- `composer require symfony/mailchimp-mailer`
- `composer require symfony/mailgun-mailer`
- `composer require symfony/postmark-mailer`
- `composer require symfony/sendgrid-mailer`

View File

@@ -1,26 +0,0 @@
{
"name": "Kimai v2",
"description": "The reloaded Kimai Time-tracking application",
"keywords": [
"php",
"kimai"
],
"website": "https://www.kimai.org.com/",
"repository": "https://github.com/kevinpapst/kimai2",
"logo": "",
"success_url": "/",
"scripts": {
"postdeploy": "php bin/console doctrine:schema:create && php bin/console doctrine:fixtures:load -n"
},
"env": {
"SYMFONY_ENV": "prod",
"SYMFONY_SECRET": {
"description": "Extra entropy for %kernel.secret%; used for CSRF tokens, cookies and signed URLs.",
"generator": "secret"
}
},
"addons": [
"heroku-postgresql"
],
"image": "heroku/php"
}

View File

@@ -1,7 +0,0 @@
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>

View File

@@ -1,21 +0,0 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
/**
* Class AppCache
*
* @author Kevin Papst <kevin@kevinpapst.de>
*/
class AppCache extends HttpCache
{
}

View File

@@ -1,71 +0,0 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
/**
* Class AppKernel
*
* @author Kevin Papst <kevin@kevinpapst.de>
*/
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = [
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(),
new Avanzu\AdminThemeBundle\AvanzuAdminThemeBundle(),
new AppBundle\AppBundle(),
new TimesheetBundle\TimesheetBundle(),
];
// Bundles only used for development or unit and functional tests
if (in_array($this->getEnvironment(), ['dev', 'test'])) {
//$bundles[] = new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle();
$bundles[] = new Symfony\Bundle\AsseticBundle\AsseticBundle();
$bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle();
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
$bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
$bundles[] = new Symfony\Bundle\WebServerBundle\WebServerBundle();
}
return $bundles;
}
public function getRootDir()
{
return __DIR__;
}
public function getCacheDir()
{
return dirname(__DIR__).'/var/cache/'.$this->getEnvironment();
}
public function getLogDir()
{
return dirname(__DIR__).'/var/logs';
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
}
}

View File

@@ -1,38 +0,0 @@
{# User Account: style can be found in dropdown.less #}
{% import "AvanzuAdminThemeBundle:layout:macros.html.twig" as macro %}
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
{{ macro.avatar(user.avatar, user.username, 'user-image') }}
<span class="hidden-xs">{{ user.name }}</span>
</a>
<ul class="dropdown-menu">
<!-- User image -->
<li class="user-header">
{{ macro.avatar(user.avatar, user.username) }}
<p>
{{user.name}}
<small>{{user.title}}</small>
</p>
</li>
{#
<!-- Menu Body -->
<li class="user-body">
<div class="col-xs-4 text-center">
</div>
<div class="col-xs-4 text-center">
</div>
<div class="col-xs-4 text-center">
</div>
</li>
#}
<!-- Menu Footer-->
<li class="user-footer">
<div class="pull-left">
<a href="{{ path('user_profile', {'username' : user.username}) }}" class="btn btn-default btn-flat">{{ 'label.user_profile'|trans }}</a>
</div>
<div class="pull-right">
<a href="{{ logout_path() }}" class="btn btn-default btn-flat">{{ 'label.logout'|trans }}</a>
</div>
</li>
</ul>
</li>

View File

@@ -1,12 +0,0 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="{{ asset('theme/bootstrap/css/bootstrap.min.css') }}">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
{#<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">#}
<link rel="stylesheet" href="{{ asset('theme/dist/css/AdminLTE.min.css') }}">
<link rel="stylesheet" href="{{ asset("theme/dist/css/skins/" ~ avanzu_admin_context.skin|default('skin-blue-light') ~ ".min.css") }}">
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->

View File

@@ -1,28 +0,0 @@
{#
This template is used to render any error different from 403, 404 and 500.
This is the simplest way to customize error pages in Symfony applications.
In case you need it, you can also hook into the internal exception handling
made by Symfony. This allows you to perform advanced tasks and even recover
your application from some errors.
See http://symfony.com/doc/current/cookbook/controller/error_pages.html
#}
{% extends 'base.html.twig' %}
{% block body_id 'error' %}
{% block main %}
<h1 class="text-danger">{{ 'http_error.name'|trans({ '%status_code%': status_code }) }}</h1>
<p class="lead">
{{ 'http_error.description'|trans({ '%status_code%': status_code }) }}
</p>
<p>
{{ 'http_error.suggestion'|trans({ '%url%': path('homepage') })|raw }}
</p>
{% endblock %}
{% block sidebar %}
{{ parent() }}
{% endblock %}

View File

@@ -1,28 +0,0 @@
{#
This template is used to render errors of type HTTP 403 (Forbidden)
This is the simplest way to customize error pages in Symfony applications.
In case you need it, you can also hook into the internal exception handling
made by Symfony. This allows you to perform advanced tasks and even recover
your application from some errors.
See http://symfony.com/doc/current/cookbook/controller/error_pages.html
#}
{% extends 'base.html.twig' %}
{% block body_id 'error' %}
{% block main %}
<h1 class="text-danger"><i class="fa fa-unlock-alt"></i> {{ 'http_error.name'|trans({ '%status_code%': 403 }) }}</h1>
<p class="lead">
{{ 'http_error_403.description'|trans }}
</p>
<p>
{{ 'http_error_403.suggestion'|trans }}
</p>
{% endblock %}
{% block sidebar %}
{{ parent() }}
{% endblock %}

View File

@@ -1,28 +0,0 @@
{#
This template is used to render errors of type HTTP 404 (Not Found)
This is the simplest way to customize error pages in Symfony applications.
In case you need it, you can also hook into the internal exception handling
made by Symfony. This allows you to perform advanced tasks and even recover
your application from some errors.
See http://symfony.com/doc/current/cookbook/controller/error_pages.html
#}
{% extends 'base.html.twig' %}
{% block body_id 'error' %}
{% block main %}
<h1 class="text-danger">{{ 'http_error.name'|trans({ '%status_code%': 404 }) }}</h1>
<p class="lead">
{{ 'http_error_404.description'|trans }}
</p>
<p>
{{ 'http_error_404.suggestion'|trans({ '%url%': path('homepage') })|raw }}
</p>
{% endblock %}
{% block sidebar %}
{{ parent() }}
{% endblock %}

View File

@@ -1,28 +0,0 @@
{#
This template is used to render errors of type HTTP 500 (Internal Server Error)
This is the simplest way to customize error pages in Symfony applications.
In case you need it, you can also hook into the internal exception handling
made by Symfony. This allows you to perform advanced tasks and even recover
your application from some errors.
See http://symfony.com/doc/current/cookbook/controller/error_pages.html
#}
{% extends 'base.html.twig' %}
{% block body_id 'error' %}
{% block main %}
<h1 class="text-danger">{{ 'http_error.name'|trans({ '%status_code%': 500 }) }}</h1>
<p class="lead">
{{ 'http_error_500.description'|trans }}
</p>
<p>
{{ 'http_error_500.suggestion'|trans({ '%url%': path('homepage') })|raw }}
</p>
{% endblock %}
{% block sidebar %}
{{ parent() }}
{% endblock %}

View File

@@ -1,14 +0,0 @@
# Users
There are multiple pre-defined roles in Kimai, which define the ACLs. A user can only inherit one role, where the roles extend each user.
## Roles
| Role name | extends | Gives permission for |
|---|---|---|
| ROLE_CUSTOMER | - | Currently has no permissions, but was reserved for future functionality |
| ROLE_USER | ROLE_CUSTOMER | Time-tracking |
| ROLE_TEAMLEAD | ROLE_USER | All of the above, plus: editing other users timesheets |
| ROLE_ADMIN | ROLE_TEAMLEAD | All of the above, plus: editing customers, editing projects, editing activities |
| ROLE_SUPER_ADMIN | ROLE_ADMIN | All of the above, plus: editing users |

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2016-10-19T21:46:45Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<body>
<trans-unit id="Toggle navigation">
<source>Toggle navigation</source>
<target>Ansicht der Seitenleiste umschalten</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2016-10-19T21:46:45Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<body>
<trans-unit id="access.denied">
<source>access.denied</source>
<target>Der Zugriff wurde verweigert</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2016-10-19T21:46:45Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<body>
<trans-unit id="timesheet.stop.success">
<source>timesheet.stop.success</source>
<target>Zeitmessung wurde gestoppt</target>
</trans-unit>
<trans-unit id="timesheet.stop.error">
<source>timesheet.stop.error</source>
<target>Zeitmessung konnte nicht gestoppt werden: %reason%</target>
</trans-unit>
<trans-unit id="timesheet.start.success">
<source>timesheet.start.success</source>
<target>Zeitmessung wurde gestartet</target>
</trans-unit>
<trans-unit id="timesheet.start.error">
<source>timesheet.start.error</source>
<target>Zeitmessung konnte nicht gestartet werden: %reason%</target>
</trans-unit>
<trans-unit id="action.updated_successfully">
<source>action.updated_successfully</source>
<target>Änderungen erfolgreich gespeichert</target>
</trans-unit>
<trans-unit id="action.deleted_successfully">
<source>action.deleted_successfully</source>
<target>Eintrag wurde erfolgreich gelöscht</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -1,712 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2016-10-19T21:46:45Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<body>
<!--
Global template keys
-->
<trans-unit id="browser.title">
<source>browser.title</source>
<target>Kimai - Time Tracking</target>
</trans-unit>
<trans-unit id="yes">
<source>yes</source>
<target>Ja</target>
</trans-unit>
<trans-unit id="no">
<source>no</source>
<target>Nein</target>
</trans-unit>
<trans-unit id="subtitle.amount">
<source>subtitle.amount</source>
<target> (insgesamt %count%)</target>
</trans-unit>
<trans-unit id="This is a mandatory field">
<source>This is a mandatory field</source>
<target>Pflichtfeld</target>
</trans-unit>
<trans-unit id="create">
<source>create</source>
<target>Erstellen</target>
</trans-unit>
<trans-unit id="confirm.delete">
<source>confirm.delete</source>
<target>Wollen Sie das wirklich löschen?</target>
</trans-unit>
<trans-unit id="confirm.delete_message">
<source>confirm.delete_message</source>
<target>Sie müssen das Löschen erneut bestätigen, da verknüpfte Objekte existieren welche ebenfalls mit gelöscht werden.</target>
</trans-unit>
<!--
Login / Security
-->
<trans-unit id="security.title.login">
<source>security.title.login</source>
<target>Anmelden</target>
</trans-unit>
<trans-unit id="security.label.username">
<source>security.label.username</source>
<target>Benutzername</target>
</trans-unit>
<trans-unit id="security.label.password">
<source>security.label.password</source>
<target>Passwort</target>
</trans-unit>
<trans-unit id="security.label.password_repeat">
<source>security.label.password_repeat</source>
<target>Passwort wiederholen</target>
</trans-unit>
<trans-unit id="security.action.sign_in">
<source>security.action.sign_in</source>
<target>Los geht's</target>
</trans-unit>
<trans-unit id="label.logout">
<source>label.logout</source>
<target>Abmelden</target>
</trans-unit>
<trans-unit id="label.user_profile">
<source>label.user_profile</source>
<target>Mein Profil</target>
</trans-unit>
<!--
Menu / Navbar items
-->
<trans-unit id="menu.homepage">
<source>menu.homepage</source>
<target>Dashboard</target>
</trans-unit>
<trans-unit id="menu.admin">
<source>menu.admin</source>
<target>Administration</target>
</trans-unit>
<trans-unit id="menu.logout">
<source>menu.logout</source>
<target>Abmelden</target>
</trans-unit>
<trans-unit id="menu.timesheet">
<source>menu.timesheet</source>
<target>Zeiterfassung</target>
</trans-unit>
<trans-unit id="menu.admin_timesheet">
<source>menu.admin_timesheet</source>
<target>Mitarbeiter Zeiten</target>
</trans-unit>
<trans-unit id="menu.admin_customer">
<source>menu.admin_customer</source>
<target>Kunden</target>
</trans-unit>
<trans-unit id="menu.admin_project">
<source>menu.admin_project</source>
<target>Projekte</target>
</trans-unit>
<trans-unit id="menu.admin_activity">
<source>menu.admin_activity</source>
<target>Aktivitäten</target>
</trans-unit>
<trans-unit id="menu.admin_user">
<source>menu.admin_user</source>
<target>Benutzer</target>
</trans-unit>
<!--
Footer
-->
<trans-unit id="footer.license">
<source>footer.license</source>
<target>Alle Rechte vorbehalten.</target>
</trans-unit>
<!--
Error templates
-->
<trans-unit id="http_error.name">
<source>http_error.name</source>
<target>Error</target>
</trans-unit>
<trans-unit id="http_error.description">
<source>http_error.description</source>
<target>Error</target>
</trans-unit>
<trans-unit id="http_error.suggestion">
<source>http_error.suggestion</source>
<target>Error</target>
</trans-unit>
<trans-unit id="http_error_403.description">
<source>http_error_403.description</source>
<target>Error</target>
</trans-unit>
<trans-unit id="http_error_403.suggestion">
<source>http_error_403.suggestion</source>
<target>Error</target>
</trans-unit>
<trans-unit id="http_error_404.description">
<source>http_error_404.description</source>
<target>Error</target>
</trans-unit>
<trans-unit id="http_error_404.suggestion">
<source>http_error_404.suggestion</source>
<target>Error</target>
</trans-unit>
<trans-unit id="http_error_405.description">
<source>http_error_405.description</source>
<target>Error</target>
</trans-unit>
<trans-unit id="http_error_405.suggestion">
<source>http_error_405.suggestion</source>
<target>Error</target>
</trans-unit>
<trans-unit id="error.no_entries_found">
<source>error.no_entries_found</source>
<target>Keine Einträge vorhanden</target>
</trans-unit>
<!--
General labels
-->
<trans-unit id="label.date">
<source>label.date</source>
<target>Datum</target>
</trans-unit>
<trans-unit id="label.starttime">
<source>label.starttime</source>
<target>Begin</target>
</trans-unit>
<trans-unit id="label.endtime">
<source>label.endtime</source>
<target>Ende</target>
</trans-unit>
<trans-unit id="label.duration">
<source>label.duration</source>
<target>Dauer</target>
</trans-unit>
<trans-unit id="label.username">
<source>label.username</source>
<target>Benutzer</target>
</trans-unit>
<trans-unit id="label.description">
<source>label.description</source>
<target>Beschreibung</target>
</trans-unit>
<trans-unit id="label.name">
<source>label.name</source>
<target>Name</target>
</trans-unit>
<trans-unit id="label.comment">
<source>label.comment</source>
<target>Kommentar</target>
</trans-unit>
<trans-unit id="label.id">
<source>label.id</source>
<target>ID</target>
</trans-unit>
<trans-unit id="label.visible">
<source>label.visible</source>
<target>Sichtbar</target>
</trans-unit>
<trans-unit id="label.budget">
<source>label.budget</source>
<target>Budget</target>
</trans-unit>
<trans-unit id="label.activity">
<source>label.activity</source>
<target>Aktivität</target>
</trans-unit>
<trans-unit id="label.project">
<source>label.project</source>
<target>Projekt</target>
</trans-unit>
<trans-unit id="label.hourly_rate">
<source>label.hourly_rate</source>
<target>Stundenlohn</target>
</trans-unit>
<trans-unit id="label.hours">
<source>label.hours</source>
<target>Stunden</target>
</trans-unit>
<trans-unit id="label.rate">
<source>label.rate</source>
<target>Lohn</target>
</trans-unit>
<trans-unit id="label.language">
<source>label.language</source>
<target>Sprache</target>
</trans-unit>
<trans-unit id="label.customer">
<source>label.customer</source>
<target>Kunde</target>
</trans-unit>
<trans-unit id="label.email">
<source>label.email</source>
<target>Email</target>
</trans-unit>
<!--
Buttons & Actions
-->
<trans-unit id="label.actions">
<source>label.actions</source>
<target>Aktionen</target>
</trans-unit>
<trans-unit id="action.edit">
<source>action.edit</source>
<target>Bearbeiten</target>
</trans-unit>
<trans-unit id="action.delete">
<source>action.delete</source>
<target>Löschen</target>
</trans-unit>
<trans-unit id="action.save">
<source>action.save</source>
<target>Speichern</target>
</trans-unit>
<trans-unit id="action.back">
<source>action.back</source>
<target>Zurück</target>
</trans-unit>
<!--
Dashboard
-->
<trans-unit id="dashboard.title">
<source>dashboard.title</source>
<target>Dashboard</target>
</trans-unit>
<trans-unit id="dashboard.subtitle">
<source>dashboard.subtitle</source>
<target>Willkommen!</target>
</trans-unit>
<trans-unit id="dashboard.you">
<source>dashboard.you</source>
<target>Deine Statistiken</target>
</trans-unit>
<trans-unit id="dashboard.all">
<source>dashboard.all</source>
<target>Alle Benutzer</target>
</trans-unit>
<trans-unit id="dashboard.admin">
<source>dashboard.admin</source>
<target>Administrator</target>
</trans-unit>
<!--
Widgets
-->
<trans-unit id="more.info.link">
<source>more.info.link</source>
<target>Mehr Infos</target>
</trans-unit>
<trans-unit id="badge.visible">
<source>badge.visible</source>
<target>Ja</target>
</trans-unit>
<trans-unit id="badge.invisible">
<source>badge.invisible</source>
<target>Nein</target>
</trans-unit>
<trans-unit id="label.toggle_dropdown">
<source>label.toggle_dropdown</source>
<target>Menü anzeigen</target>
</trans-unit>
<!--
Timesheet
-->
<trans-unit id="timesheet.title">
<source>timesheet.title</source>
<target>Zeiterfassung</target>
</trans-unit>
<trans-unit id="timesheet.subtitle">
<source>timesheet.subtitle</source>
<target>Verwalten Sie Ihre Zeiteinträge</target>
</trans-unit>
<trans-unit id="timesheet.edit">
<source>timesheet.edit</source>
<target>Eintrag bearbeiten</target>
</trans-unit>
<trans-unit id="label.begin">
<source>label.begin</source>
<target>Von</target>
</trans-unit>
<trans-unit id="label.end">
<source>label.end</source>
<target>Bis</target>
</trans-unit>
<!--
User profile
-->
<trans-unit id="profile.title">
<source>profile.title</source>
<target>Benutzerprofil</target>
</trans-unit>
<trans-unit id="profile.subtitle">
<source>profile.subtitle</source>
<target>Verwalte Deine Einstellungen</target>
</trans-unit>
<trans-unit id="profile.about_me">
<source>profile.about_me</source>
<target>Über mich</target>
</trans-unit>
<trans-unit id="profile.first_entry">
<source>profile.first_entry</source>
<target>Arbeitet seit</target>
</trans-unit>
<trans-unit id="profile.tab_monthly">
<source>profile.tab_monthly</source>
<target>Jahresstatistik</target>
</trans-unit>
<trans-unit id="profile.settings">
<source>profile.settings</source>
<target>Einstellungen</target>
</trans-unit>
<trans-unit id="profile.password">
<source>profile.password</source>
<target>Passwort</target>
</trans-unit>
<trans-unit id="profile.roles">
<source>profile.roles</source>
<target>Rollen</target>
</trans-unit>
<!--
Admin: Timesheet
-->
<trans-unit id="admin_timesheet.title">
<source>admin_timesheet.title</source>
<target>Mitarbeiter Zeiterfassung</target>
</trans-unit>
<trans-unit id="admin_timesheet.subtitle">
<source>admin_timesheet.subtitle</source>
<target>Zeiten aller Benutzer</target>
</trans-unit>
<!--
Admin: Projects
-->
<trans-unit id="admin_project.title">
<source>admin_project.title</source>
<target>Projekte</target>
</trans-unit>
<trans-unit id="admin_project.subtitle">
<source>admin_project.subtitle</source>
<target>Ein Projekt fasst Tätigkeiten für jeweils einen Kunden in einer Gruppe zusammen</target>
</trans-unit>
<trans-unit id="admin_project.delete_confirm">
<source>admin_project.delete_confirm</source>
<target>Momentan existieren für das Projekt %project% des Kunden %customer% insgesamt %activities% Aktivitäten und %records% Zeiteinträge, welche sich auf eine Gesamtdauer von %duration% belaufen. Diese Aktivitäten und Zeiteinträge werden ebenfalls mit gelöscht!</target>
</trans-unit>
<!--
Admin: Activity
-->
<trans-unit id="admin_activity.title">
<source>admin_activity.title</source>
<target>Aktivitäten</target>
</trans-unit>
<trans-unit id="admin_activity.subtitle">
<source>admin_activity.subtitle</source>
<target>Aufgaben die zur Zeiterfassung genutzt werden können</target>
</trans-unit>
<trans-unit id="admin_activity.delete_confirm">
<source>admin_activity.delete_confirm</source>
<target>Momentan existieren für die Aktivität %activity% im Projekt %project% für den Kunden %customer% insgesamt %records% Zeiteinträge, welche sich auf eine Gesamtdauer von %duration% belaufen. Diese Zeiteinträge werden ebenfalls mit gelöscht!</target>
</trans-unit>
<!--
Admin: Customer
-->
<trans-unit id="admin_customer.title">
<source>admin_customer.title</source>
<target>Kunden</target>
</trans-unit>
<trans-unit id="admin_customer.subtitle">
<source>admin_customer.subtitle</source>
<target>Ihre Kunden stellen die Basis dar, auf der Sie Projekte und Tätigkeiten anlegen können</target>
</trans-unit>
<trans-unit id="label.company">
<source>label.company</source>
<target>Unternehmensbezeichnung</target>
</trans-unit>
<trans-unit id="label.vat">
<source>label.vat</source>
<target>Umsatzsteuer</target>
</trans-unit>
<trans-unit id="label.contact">
<source>label.contact</source>
<target>Kontakt</target>
</trans-unit>
<trans-unit id="label.address">
<source>label.address</source>
<target>Adresse</target>
</trans-unit>
<trans-unit id="label.country">
<source>label.country</source>
<target>Land</target>
</trans-unit>
<trans-unit id="label.phone">
<source>label.phone</source>
<target>Telefon</target>
</trans-unit>
<trans-unit id="label.fax">
<source>label.fax</source>
<target>Fax</target>
</trans-unit>
<trans-unit id="label.mobile">
<source>label.mobile</source>
<target>Handy</target>
</trans-unit>
<trans-unit id="label.homepage">
<source>label.homepage</source>
<target>Homepage</target>
</trans-unit>
<trans-unit id="label.timezone">
<source>label.timezone</source>
<target>Zeitzone</target>
</trans-unit>
<trans-unit id="label.currency">
<source>label.currency</source>
<target>Währung</target>
</trans-unit>
<trans-unit id="admin_customer.delete_confirm">
<source>admin_customer.delete_confirm</source>
<target>Momentan existieren für den Kunden %customer% insgesamt %project% Projekte mit %activity% Aktivitäten, die sich in %records% Zeiteinträgen auf eine Gesamtdauer von %duration% belaufen. Diese Projekte, Aktivitäten und Zeiteinträge werden ebenfalls mit gelöscht!</target>
</trans-unit>
<!--
Admin: User
-->
<trans-unit id="admin_user.title">
<source>admin_user.title</source>
<target>Benutzer</target>
</trans-unit>
<trans-unit id="admin_user.subtitle">
<source>admin_user.subtitle</source>
<target>Alle registrierten Benutzer der Zeitverwaltung</target>
</trans-unit>
<trans-unit id="label.alias">
<source>label.alias</source>
<target>Name</target>
</trans-unit>
<trans-unit id="label.title">
<source>label.title</source>
<target>Titel</target>
</trans-unit>
<trans-unit id="label.avatar">
<source>label.avatar</source>
<target>Profilbild</target>
</trans-unit>
<trans-unit id="label.active">
<source>label.active</source>
<target>Aktiv</target>
</trans-unit>
<trans-unit id="label.roles">
<source>label.roles</source>
<target>Rolle</target>
</trans-unit>
<!--
ROLES
-->
<trans-unit id="ROLE_SUPER_ADMIN">
<source>ROLE_SUPER_ADMIN</source>
<target>System-Admin</target>
</trans-unit>
<trans-unit id="ROLE_ADMIN">
<source>ROLE_ADMIN</source>
<target>Administrator</target>
</trans-unit>
<trans-unit id="ROLE_TEAMLEAD">
<source>ROLE_TEAMLEAD</source>
<target>Teamleiter</target>
</trans-unit>
<trans-unit id="ROLE_USER">
<source>ROLE_USER</source>
<target>Benutzer</target>
</trans-unit>
<trans-unit id="ROLE_CUSTOMER">
<source>ROLE_CUSTOMER</source>
<target>Kunde</target>
</trans-unit>
<!--
Statistics
-->
<trans-unit id="stats.durationThisMonth">
<source>stats.durationThisMonth</source>
<target>Arbeitszeit diesen Monat</target>
</trans-unit>
<trans-unit id="stats.amountThisMonth">
<source>stats.amountThisMonth</source>
<target>Umsatz diesen Monat</target>
</trans-unit>
<trans-unit id="stats.durationTotal">
<source>stats.durationTotal</source>
<target>Arbeitszeit total</target>
</trans-unit>
<trans-unit id="stats.amountTotal">
<source>stats.amountTotal</source>
<target>Umsatz total</target>
</trans-unit>
<!--
Dashboard
-->
<trans-unit id="stats.userTotal">
<source>stats.userTotal</source>
<target>Anzahl Benutzer</target>
</trans-unit>
<trans-unit id="stats.userActiveThisMoth">
<source>stats.userActiveThisMoth</source>
<target>Aktive Benutzer diesen Monat</target>
</trans-unit>
<trans-unit id="stats.userActiveEver">
<source>stats.userActiveEver</source>
<target>Aktive Benutzer jemals</target>
</trans-unit>
<trans-unit id="stats.activeRecordings">
<source>stats.activeRecordings</source>
<target>Momentan aktive Zeitmessungen</target>
</trans-unit>
<trans-unit id="stats.activitiesTotal">
<source>stats.activitiesTotal</source>
<target>Anzahl Aktivitäten</target>
</trans-unit>
<trans-unit id="stats.projectsTotal">
<source>stats.projectsTotal</source>
<target>Anzahl Projekte</target>
</trans-unit>
<trans-unit id="stats.customerTotal">
<source>stats.customerTotal</source>
<target>Anzahl Kunden</target>
</trans-unit>
<!--
Month names
-->
<trans-unit id="month.1">
<source>month.1</source>
<target>Januar</target>
</trans-unit>
<trans-unit id="month.2">
<source>month.2</source>
<target>Februar</target>
</trans-unit>
<trans-unit id="month.3">
<source>month.3</source>
<target>März</target>
</trans-unit>
<trans-unit id="month.4">
<source>month.4</source>
<target>April</target>
</trans-unit>
<trans-unit id="month.5">
<source>month.5</source>
<target>Mai</target>
</trans-unit>
<trans-unit id="month.6">
<source>month.6</source>
<target>Juni</target>
</trans-unit>
<trans-unit id="month.7">
<source>month.7</source>
<target>Juli</target>
</trans-unit>
<trans-unit id="month.8">
<source>month.8</source>
<target>August</target>
</trans-unit>
<trans-unit id="month.9">
<source>month.9</source>
<target>September</target>
</trans-unit>
<trans-unit id="month.10">
<source>month.10</source>
<target>Oktober</target>
</trans-unit>
<trans-unit id="month.11">
<source>month.11</source>
<target>November</target>
</trans-unit>
<trans-unit id="month.12">
<source>month.12</source>
<target>Dezember</target>
</trans-unit>
<!--
Navbar - recent entries and activities
-->
<trans-unit id="active.entries">
<source>active.entries</source>
<target>Sie haben %count% aktiven Eintrag|Sie haben %count% aktive Einträge</target>
</trans-unit>
<trans-unit id="timesheet.all">
<source>timesheet.all</source>
<target>Alle Einträge anzeigen</target>
</trans-unit>
<trans-unit id="recent.activities">
<source>recent.activities</source>
<target>Ihr %count% zuletzt bearbeitete Aktivität|Eine ihrer %count% letzten Aktivitäten neustarten</target>
</trans-unit>
<trans-unit id="recent.activities.format">
<source>recent.activities.format</source>
<target>%activity% in %project% für %customer%</target>
</trans-unit>
<trans-unit id="timesheet.start">
<source>timesheet.start</source>
<target>Neue Zeitmessung starten</target>
</trans-unit>
<!--
TOOLBARS
-->
<trans-unit id="label.pageSize">
<source>label.pageSize</source>
<target>Anzahl Einträge</target>
</trans-unit>
<trans-unit id="label.entryState">
<source>label.entryState</source>
<target>Zeiten</target>
</trans-unit>
<trans-unit id="entryState.all">
<source>entryState.all</source>
<target>Alle</target>
</trans-unit>
<trans-unit id="entryState.running">
<source>entryState.running</source>
<target>Laufende</target>
</trans-unit>
<trans-unit id="entryState.stopped">
<source>entryState.stopped</source>
<target>Beendete</target>
</trans-unit>
<trans-unit id="0">
<source>0</source>
<target>0</target>
</trans-unit>
<trans-unit id="10">
<source>10</source>
<target>10</target>
</trans-unit>
<trans-unit id="25">
<source>25</source>
<target>25</target>
</trans-unit>
<trans-unit id="50">
<source>50</source>
<target>50</target>
</trans-unit>
<trans-unit id="75">
<source>75</source>
<target>75</target>
</trans-unit>
<trans-unit id="100">
<source>100</source>
<target>100</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2016-10-19T21:46:45Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<body>
<trans-unit id="previous">
<source>previous</source>
<target>Vorherige</target>
</trans-unit>
<trans-unit id="next">
<source>next</source>
<target>Nächste</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" target-language="de" datatype="plaintext" original="not.available">
<body>
<trans-unit id="This value is not a valid role.">
<source>This value is not a valid role.</source>
<target>Dieser Wert ist keine gültige Rolle.</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -1,52 +0,0 @@
{% extends 'base.html.twig' %}
{% import "macros/datatables.html.twig" as tables %}
{% import "macros/widgets.html.twig" as widgets %}
{% block page_title %}{{ 'admin_user.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_user.subtitle'|trans }} {{ 'subtitle.amount'|trans({'%count%': entries.count}) }}{% endblock %}
{% block javascript_imports %}<script src="{{ asset('js/toolbar.js') }}"></script>{% endblock %}
{% block main %}
{% if entries.count == 0 %}
{{ widgets.callout('warning', 'error.no_entries_found') }}
{% endif %}
{{ tables.data_table_header({
'label.id': 'hidden-xs',
'label.alias': '',
'label.username': 'hidden-xs',
'label.email': 'hidden-xs hidden-sm',
'label.title': 'hidden-xs',
'label.active': '',
'label.roles': '',
'label.actions': '',
}, toolbarForm, {'plus-square': path('admin_user_create')}) }}
{% for entry in entries %}
<tr>
<td class="hidden-xs">{{ entry.id }}</td>
<td>{{ widgets.username(entry) }}</td>
<td class="hidden-xs">{{ entry.username }}</td>
<td class="hidden-xs hidden-sm">{{ entry.email }}</td>
<td class="hidden-xs">{{ entry.title }}</td>
<td>{{ widgets.label_visible(entry.active) }}</td>
<td>
{% for role in entry.roles %}
{{ widgets.label_role(role) }}
{% endfor %}
</td>
<td>
{% set actionButtons = {} %}
{% if is_granted('edit', entry) %}
{% set actionButtons = {'edit': path('user_profile', {'username' : entry.username})}|merge(actionButtons) %}
{% endif %}
{% if is_granted('delete', entry) %}
{% set actionButtons = actionButtons|merge({'trash': '#'}) %}
{% endif %}
{{ widgets.button_group(actionButtons) }}
</td>
</tr>
{% endfor %}
{{ tables.data_table_footer(entries, 'admin_user_paginated') }}
{% endblock %}

View File

@@ -1,12 +0,0 @@
{% extends 'base.html.twig' %}
{% block page_title %}{{ 'admin_user.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_user.subtitle'|trans }}{% endblock %}
{% block main %}
{{ include('default/_form.html.twig', {
'title': 'create'|trans,
'form': form,
'back': path('admin_user')
}) }}
{% endblock %}

View File

@@ -1,100 +0,0 @@
{% extends 'AvanzuAdminThemeBundle:layout:default-layout.html.twig' %}
{% block avanzu_page_content %}
{{ include('default/_flash_messages.html.twig') }}
{% block main %}{% endblock %}
{% endblock %}
{% block avanzu_document_title %}
{% block title %}{{ 'browser.title'|trans }}{% endblock %}
{% endblock %}
{% block avanzu_page_title %}
{% block page_title %}{% endblock %}
{% endblock %}
{% block avanzu_page_subtitle %}
{% block page_subtitle %}{% endblock %}
{% endblock %}
{% block avanzu_logo_path %}
{{ path('dashboard') }}
{% endblock %}
{% block avanzu_logo_mini %}
<b>K</b>TT
{% endblock %}
{% block avanzu_logo_lg %}
<b>Kimai</b> - Time Tracking
{% endblock %}
{% block avanzu_head %}
<link rel="stylesheet" href="{{ asset('css/kimai.css') }}">
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
{% endblock %}
{% block avanzu_footer %}
{% block footer %}
<footer class="main-footer">
<div class="pull-right hidden-xs">
<b>Version</b> 2.0
</div>
<strong>Copyright &copy; {{ 'now'|date('Y') }} - <a href="http://www.kevinpapst.de">Kevin Papst</a></strong>.
{{ 'footer.license'|trans }}
</footer>
<!-- Page rendered on {{ 'now'|localizeddate('long', 'long', null, 'UTC') }} -->
{% endblock %}
{% endblock %}
{% block avanzu_navbar_messages %}
{% if app.user is not null and is_granted('IS_AUTHENTICATED_FULLY') %}
{{ render(controller('TimesheetBundle:Timesheet:activeEntries')) }}
{% endif %}
{% endblock %}
{% block avanzu_navbar_notifications %}
{% if app.user is not null and is_granted('IS_AUTHENTICATED_FULLY') %}
{{ render(controller('TimesheetBundle:Activity:recentActivities')) }}
{% endif %}
{#
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-globe"></i> <span class="caret"></span></a>
<ul class="dropdown-menu locales" role="menu">
{% for locale in locales() %}
<li {% if app.request.locale == locale.code %}class="active"{% endif %}><a href="{{ path(app.request.get('_route', 'homepage'), app.request.get('_route_params', [])|merge({ _locale: locale.code })) }}">{{ locale.name|capitalize }}</a></li>
{% endfor %}
</ul>
</li>
#}
{% endblock %}
{% block avanzu_navbar_toggle %}{{ parent() }}{% endblock %}
{% block avanzu_navbar_tasks %}{{ parent() }}{% endblock %}
{% block avanzu_navbar_user %}{{ parent() }}{% endblock %}
{% block avanzu_navbar_control_sidebar_toggle %}{{ parent() }}{% endblock %}
{% block avanzu_sidebar_user %}{# right now we simply deactivate that box #}{% endblock %}
{% block avanzu_sidebar_search %}{# right now we simply deactivate that box #}{% endblock %}
{% block avanzu_sidebar_nav %}{{ parent() }}{% endblock %}
{% block avanzu_breadcrumb %}{{ parent() }}{% endblock %}
{% block avanzu_control_sidebar %}{{ parent() }}{% endblock %}
{% block avanzu_javascripts %}
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="{{ asset('theme/bootstrap/js/bootstrap.min.js') }}"></script>
<script src="{{ asset('js/kimai.js') }}"></script>
<script src="{{ asset('js/Chart.min.js') }}"></script>
{% block javascript_imports %}{% endblock %}
{% endblock %}
{% block avanzu_javascripts_inline %}
<script type="text/javascript">
$(document).ready(function () {
$('.dropdown-toggle').dropdown();
$(document).kimai({imagePath: '{{ asset('images') }}', confirmDelete: '{{ 'confirm.delete'|trans }}'});
//$(document).kimai('pauseRecord', 'li.messages-menu ul.menu li');
});
</script>
{% endblock %}

View File

@@ -1,27 +0,0 @@
{% extends 'base.html.twig' %}
{% import "macros/widgets.html.twig" as widgets %}
{% block page_title %}{{ 'dashboard.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'dashboard.subtitle'|trans }}{% endblock %}
{% block main %}
{% for settings in dashboard_widgets %}
{% if settings.header %}
{{ widgets.page_header(settings.header) }}
{% endif %}
{% set width = settings.widgets|length %}
{% set rawWidth = 12 / width %}
{% set columnWidth = rawWidth|round(0, 'floor') %}
<div class="row">
{% for widgetTemplate in settings.widgets %}
<div class="col-md-{{ columnWidth }} col-sm-{{ columnWidth * 2 }} col-xs-{{ columnWidth * 4 }}">
{% set widgetString = '{% import "macros/widgets.html.twig" as widgets %}' ~ widgetTemplate %}
{{ include(template_from_string(widgetString)) }}
</div>
{% endfor %}
</div>
{% endfor %}
{% endblock %}

View File

@@ -1,9 +0,0 @@
{% import "AvanzuAdminThemeBundle:layout:macros.html.twig" as macro %}
{% if app.session.started and app.session.flashbag.peekAll|length > 0 %}
<div class="row">
<div class="col-sm-12">
{{ macro.session_flash(avanzu_adminlte_close_alert|default(true), false, '', 'flashmessages') }}
</div>
</div>
{% endif %}

View File

@@ -1,16 +0,0 @@
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ title }}</h3>
</div>
{{ form_start(form) }}
<div class="box-body">
{{ form_widget(form) }}
</div>
<div class="box-footer">
<input type="submit" value="{{ 'action.save'|trans }}" class="btn btn-primary" />
{% if back %}
<a href="{{ back }}" class="btn btn-warning">{{ 'action.back'|trans }}</a>
{% endif %}
</div>
{{ form_end(form) }}
</div>

View File

@@ -1,20 +0,0 @@
<div class="box box-solid box-danger">
<div class="box-header">
<h3 class="box-title">{{ title|default('confirm.delete'|trans) }}</h3>
</div>
<div class="box-body">
{{ message|default('confirm.delete_message'|trans)|raw }}
</div>
{{ form_start(form) }}
<div class="box-body">
{{ form_widget(form) }}
</div>
<div class="box-footer">
<input type="submit" value="{{ 'action.delete'|trans }}" class="btn btn-danger" />
{% if back %}
<a href="{{ back }}" class="btn btn-primary">{{ 'action.back'|trans }}</a>
{% endif %}
</div>
{{ form_end(form) }}
</div>

View File

@@ -1,19 +0,0 @@
{#
Each field type is rendered by a template fragment, which is determined
by the name of your form type class (DateTimePickerType -> date_time_picker)
and the suffix "_widget". This can be controlled by overriding getBlockPrefix()
in DateTimePickerType.
See http://symfony.com/doc/current/cookbook/form/create_custom_field_type.html#creating-a-template-for-the-field
#}
{% block date_time_picker_widget %}
{% spaceless %}
<div class="input-group date" data-toggle="datetimepicker">
{{ block('datetime_widget') }}
<span class="input-group-addon">
<span class="fa fa-calendar"></span>
</span>
</div>
{% endspaceless %}
{% endblock %}

View File

@@ -1,78 +0,0 @@
{% macro data_table_header(entries, form, tools, toolsRight) %}
<div class="box data_table">
{% if form or tools or toolsRight %}
<div class="box-header with-border">
{% if tools %}
<div class="btn-group tools-left">
{% for icon,url in tools %}
<a class="btn btn-default" href="{{ url }}"><i class="fa fa-{{ icon }}"></i></a>
{% endfor %}
</div>
{% endif %}
{% if form %}
<div class="box-title toolbar">
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</div>
{% endif %}
{% if toolsRight %}
<div class="box-tools">
<div class="btn-group">
{% for icon,url in tools %}
<a class="btn btn-default" href="{{ url }}"><i class="fa fa-{{ icon }}"></i></a>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% endif %}
<div class="box-body no-padding">
<div class="dataTables_wrapper form-inline dt-bootstrap">
<div class="row">
<div class="col-sm-6"></div>
<div class="col-sm-6"></div>
</div>
<div class="row">
<div class="col-sm-12">
<table class="table table-striped table-hover dataTable" role="grid">
<thead>
<tr>
{% for title, class in entries %}
<th{% if class %} class="{{ class }}"{% endif %}>
{{ title|trans }}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% endmacro %}
{% macro data_table_footer(entries, route) %}
</tbody>
</table>
</div>
</div>
{#<div class="row">
<div class="col-sm-5">
{#<div class="dataTables_info" id="example2_info" role="status" aria-live="polite">
{{ 'datatables.entry_counter'|trans({'%from%': '1', '%to%': '10', '%total%': entries.count}) }}
</div># }
</div>
<div class="col-sm-7">
<div class="dataTables_paginate paging_simple_numbers">
{{ pagerfanta(entries, 'twitter_bootstrap3_translated', { routeName: route }) }}
</div>
</div>
</div>#}
</div>
</div>
</div>
<div class="navigation text-center">
{{ pagerfanta(entries, 'twitter_bootstrap3_translated', { routeName: route }) }}
</div>
{% endmacro %}

View File

@@ -1,173 +0,0 @@
{% macro page_header(title) %}
<h2 class="page-header">{{ title|trans }}</h2>
{% endmacro %}
{% macro label_visible(visible) %}
{% import _self as macro %}
{% if visible %}
{{ macro.label('badge.visible', 'success') }}
{% else %}
{{ macro.label('badge.invisible', 'warning') }}
{% endif %}
{% endmacro %}
{% macro label_role(role) %}
{% import _self as macro %}
{% if role == 'ROLE_SUPER_ADMIN' %}
{{ macro.label(role, 'danger') }}
{% else %}
{{ macro.label(role, 'primary') }}
{% endif %}
{% endmacro %}
{% macro username(user) %}
{{ user.alias|default(user.username) }}
{% endmacro %}
{% macro label_user(user) %}
{% import _self as macro %}
{{ macro.label(macro.username(user), 'primary') }}
{% endmacro %}
{% macro label_activity(activity) %}
{% import _self as macro %}
{% if activity.visible and activity.project.visible and activity.project.customer.visible %}
{{ macro.label(activity.name, 'primary', activity.project.customer.name ~ ': ' ~ activity.project.name) }}
{% else %}
{{ macro.label(activity.name, 'warning', activity.project.customer.name ~ ': ' ~ activity.project.name) }}
{% endif %}
{% endmacro %}
{% macro label_project(project) %}
{% import _self as macro %}
{% if project.visible and project.customer.visible %}
{{ macro.label(project.name, 'primary', project.customer.name) }}
{% else %}
{{ macro.label(project.name, 'warning', project.customer.name) }}
{% endif %}
{% endmacro %}
{% macro label_customer(customer) %}
{% import _self as macro %}
{% if customer.visible %}
{{ macro.label(customer.name, 'primary') }}
{% else %}
{{ macro.label(customer.name, 'warning') }}
{% endif %}
{% endmacro %}
{% macro badge_counter(count, url) %}
{% if url %}
<a href="{{ url }}"><span class="badge bg-blue">{{ count }}</span></a>
{% else %}
<span class="badge bg-blue">{{ count }}</span>
{% endif %}
{% endmacro %}
{% macro label(title, type, tooltip) %}
{# success, warning, danger, primary #}
<span {% if tooltip %}title="{{ tooltip }}" {% endif %}class="label label-{{ type|default('success') }}">{{ title|trans }}</span>
{% endmacro %}
{% macro badge(title, color) %}
{# black, green, blue, yellow #}
<span class="badge bg-{{ color|default('red') }}">{{ title|trans }}</span>
{% endmacro %}
{% macro alert(type, description, title, icon) %}
<div class="alert alert-{{ type|default('danger') }} alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
{% if title %}<h4><i class="icon fa fa-{{ icon|default('ban') }}"></i> {{ title|trans }}</h4>{% endif %}
{{ description|trans }}
</div>
{% endmacro %}
{% macro callout(type, description, title) %}
<div class="callout callout-{{ type|default('danger') }} lead">
{% if title %}<h4>{{ title|trans }}</h4>{% endif %}
<p>{{ description|trans }}</p>
</div>
{% endmacro %}
{% macro info_box_counter(title, amount, icon, color, url) %}
<div class="info-box">
<span class="info-box-icon bg-{{ color|default(kimai_context.box_color) }}"><i class="fa fa-{{ icon|default('flag-o') }}"></i></span>
<div class="info-box-content">
{# this is a ugly hack, make me look nicely (dashboard widget with link) #}
{% if url %}
<a href="{{ url }}" class="small-box-footer">
{% endif %}
<span class="info-box-text">{{ title|trans }}</span>
<span class="info-box-number">{{ amount }}</span>
{% if url %}
</a>
{% endif %}
</div>
</div>
{% endmacro %}
{% macro info_box_progress(title, description, amount, percentage, icon, color) %}
<div class="info-box bg-{{ color|default(kimai_context.box_color) }}">
<span class="info-box-icon"><i class="fa fa-{{ icon|default('thumbs-o-up') }}"></i></span>
<div class="info-box-content">
<span class="info-box-text">{{ title|trans }}</span>
<span class="info-box-number">{{ amount }}</span>
<div class="progress">
<div class="progress-bar" style="width: {{ percentage }}%"></div>
</div>
<span class="progress-description">
{{ description }}
</span>
</div>
<!-- /.info-box-content -->
</div>
{% endmacro %}
{% macro info_box_more(title, amount, unit, url, icon, color) %}
<div class="small-box bg-{{ color|default(kimai_context.box_color) }}">
<div class="inner">
<h3>{{ amount }}<sup style="font-size: 20px">{{ unit|default('') }}</sup></h3>
<p>{{ title|trans }}</p>
</div>
<div class="icon">
<i class="fa fa-{{ icon|default('bar-chart') }}"></i>
</div>
<a href="{{ url }}" class="small-box-footer">
{{ 'more.info.link'|trans }} <i class="fa fa-arrow-circle-right"></i>
</a>
</div>
{% endmacro %}
{% macro button_group_dropdown(title, actions) %}
<div class="btn-group">
<button type="button" class="btn btn-default">{{ title|trans }}</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">{{ 'label.toggle_dropdown'|trans }}</span>
</button>
<ul class="dropdown-menu" role="menu">
{% for url, entry in actions %}
<li><a href="{{ url }}">{{ entry|trans }}</a></li>
{% endfor %}
</ul>
</div>
{% endmacro %}
{% macro button_group(actions) %}
{% import _self as macro %}
<div class="btn-group">
{% for icon, url in actions %}
{{ macro.button_action(icon, url) }}
{% endfor %}
</div>
{% endmacro %}
{% macro button_action(icon, url) %}
<a href="{{ url }}" class="btn btn-default btn-{{ icon }}">
<i class="fa fa-{{ icon }}"></i>
</a>
{% endmacro %}

View File

@@ -1,40 +0,0 @@
{% extends 'AvanzuAdminThemeBundle:layout:login-layout.html.twig' %}
{% block avanzu_login_title %}{{ 'browser.title'|trans }}{% endblock %}
{% block avanzu_logo_login %}<b>Kimai</b><br>TimeTracking{% endblock %}
{% block avanzu_login_box_msg %}
{{ 'security.title.login'|trans }}
{% if error|default(false) %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
{% endblock %}
{% block avanzu_login_form %}
<form action="{{ path('security_login') }}" method="post">
<div class="form-group has-feedback">
<input type="text" name="_username" class="form-control" placeholder="{{ 'security.label.username'|trans }}" value="{{ last_username }}">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input name="_password" type="password" class="form-control" placeholder="{{ 'security.label.password'|trans }}">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="row">
<div class="col-xs-8">
{#
<div class="checkbox icheck">
<label>
<input type="checkbox"> {{ 'Remember Me'|trans({}, 'AvanzuAdminTheme') }}
</label>
</div>
#}
</div>
<div class="col-xs-4">
<button type="submit" class="btn btn-primary btn-block btn-flat">{{ 'security.action.sign_in'|trans }}</button>
</div>
</div>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}"/>
</form>
{% endblock %}
{% block avanzu_login_social_auth %}{% endblock %}
{% block avanzu_login_actions %}{% endblock %}

View File

@@ -1,254 +0,0 @@
{% extends 'base.html.twig' %}
{% block page_title %}{{ 'profile.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'profile.subtitle'|trans }}{% endblock %}
{% block main %}
{% import _self as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="row">
<div class="col-md-3">
{{ macro.profile_box(user, stats) }}
{{ macro.profile_infos(user, stats) }}
</div>
<div class="col-md-9">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li {% if tab == "charts" %}class="active"{% endif %}><a href="#charts" data-toggle="tab" aria-expanded="true">{{ 'profile.tab_monthly'|trans }}</a></li>
{% if form %}
<li {% if tab == "profile" %}class="active"{% endif %}><a href="#profile" data-toggle="tab" aria-expanded="false">{{ 'profile.settings'|trans }}</a></li>
{% endif %}
{% if form_password %}
<li {% if tab == "password" %}class="active"{% endif %}><a href="#password" data-toggle="tab" aria-expanded="false">{{ 'profile.password'|trans }}</a></li>
{% endif %}
{% if form_roles %}
<li {% if tab == "roles" %}class="active"{% endif %}><a href="#roles" data-toggle="tab" aria-expanded="false">{{ 'profile.roles'|trans }}</a></li>
{% endif %}
</ul>
<div class="tab-content">
<div class="tab-pane {% if tab == "charts" %}active{% endif %}" id="charts">
{% if years is empty %}
{{ widgets.callout('warning', 'error.no_entries_found') }}
{% endif %}
<script type="text/javascript">
var barChartOptions = {
scaleBeginAtZero: true,
scaleShowGridLines: true,
scaleGridLineColor: "rgba(0,0,0,.05)",
scaleGridLineWidth: 1,
scaleShowHorizontalLines: true,
scaleShowVerticalLines: true,
barShowStroke: true,
barStrokeWidth: 2,
barValueSpacing: 5,
barDatasetSpacing: 1,
responsive: true,
maintainAspectRatio: true,
tooltipTemplate: "<%= value %> {{ 'label.hours'|trans }}",
};
var barChartLabels = [
{% for i in 1..11 %}
"{{ ('month.' ~i)|trans }}",
{% endfor %}
"{{ 'month.12'|trans }}"
];
</script>
{% for year,yearStat in years %}
<h2>{{ year }}</h2>
<div class="chart">
<canvas id="barChart{{ year }}" style="height: 230px;"></canvas>
</div>
<script type="text/javascript">
var barChartData{{ year }} = {
labels: barChartLabels,
datasets: [
{
{# label: '# hours',#}
fillColor: "#00a65a",
strokeColor: "#00a65a",
pointColor: "#00a65a",
pointStrokeColor: "#c1c7d1",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [
{% for i in 1..11 %}
{{ (yearStat.month(i).totalDuration / 3600)|round }},
{% endfor %}
{{ (yearStat.month(12).totalDuration / 3600)|round }}
]
}
]
};
{% if tab == "charts" %}
$(function () {
var barChartCanvas{{ year }} = $("#barChart{{ year }}").get(0).getContext("2d");
var barChart = new Chart(barChartCanvas{{ year }});
barChart.Bar(barChartData{{ year }}, barChartOptions);
});
{% endif %}
$('a[href="#charts"]').on('shown.bs.tab', function(e){
var barChartCanvas{{ year }} = $("#barChart{{ year }}").get(0).getContext("2d");
var barChart = new Chart(barChartCanvas{{ year }});
barChart.Bar(barChartData{{ year }}, barChartOptions);
});
</script>
{% endfor %}
</div>
{% if form %}
<div class="tab-pane {% if tab == "profile" %}active{% endif %}" id="profile">
{{ form_start(form) }}
{{ form_widget(form) }}
<input type="submit" value="{{ 'action.save'|trans }}" class="btn btn-primary" />
{{ form_end(form) }}
</div>
{% endif %}
{% if form_password %}
<div class="tab-pane {% if tab == "password" %}active{% endif %}" id="password">
{{ form_start(form_password) }}
{{ form_widget(form_password) }}
<input type="submit" value="{{ 'action.save'|trans }}" class="btn btn-primary" />
{{ form_end(form_password) }}
</div>
{% endif %}
{% if form_roles %}
<div class="tab-pane {% if tab == "roles" %}active{% endif %}" id="roles">
{{ form_start(form_roles) }}
{{ form_widget(form_roles) }}
<input type="submit" value="{{ 'action.save'|trans }}" class="btn btn-primary" />
{{ form_end(form_roles) }}
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}
{% macro profile_infos(user, stats) %}
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'profile.about_me'|trans }}</h3>
</div>
<div class="box-body">
<ul class="nav nav-stacked">
{# colors = purple, blue, aqua, red, green #}
{# FIXME hourly rate must be dynamic <li><a href="#">{{ 'label.hourly_rate'|trans }} <span class="pull-right badge bg-blue">70</span></a></li> #}
<li><a href="#">{{ 'label.id'|trans }} <span class="pull-right badge bg-aqua">{{ user.id }}</span></a></li>
<li><a href="#">{{ 'label.username'|trans }} <span class="pull-right badge bg-blue">{{ user.username }}</span></a></li>
<li><a href="#">{{ 'label.language'|trans }} <span class="pull-right badge bg-green">{{ user.language }}</span></a></li>
<li><a href="#">{{ 'profile.first_entry'|trans }} <span class="pull-right badge bg-purple">{{ stats.firstEntry|date }}</span></a></li>
</ul>
</div>
</div>
{% endmacro %}
{% macro profile_box(user, stats) %}
{% import "AvanzuAdminThemeBundle:layout:macros.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="box box-primary">
<div class="box-body box-profile">
{{ macro.avatar(user.avatar, user.username, 'profile-user-img img-responsive img-circle') }}
<h3 class="profile-username text-center">{{ widgets.username(user) }}</h3>
<p class="text-muted text-center">{{ user.title }}</p>
<ul class="list-group list-group-unbordered">
<li class="list-group-item">
<b>{{ 'stats.durationThisMonth'|trans }}</b> <a class="pull-right">{{ stats.durationThisMonth|duration }}</a>
</li>
<li class="list-group-item">
<b>{{ 'stats.amountThisMonth'|trans }}</b> <a class="pull-right">{{ stats.amountThisMonth|money }}</a>
</li>
<li class="list-group-item">
<b>{{ 'stats.durationTotal'|trans }}</b> <a class="pull-right">{{ stats.durationTotal|duration }}</a>
</li>
<li class="list-group-item">
<b>{{ 'stats.amountTotal'|trans }}</b> <a class="pull-right">{{ stats.amountTotal|money }}</a>
</li>
</ul>
{# <a href="#" class="btn btn-primary btn-block"><b>Follow</b></a> #}
</div>
<!-- /.box-body -->
</div>
{% endmacro %}
{# -------------------------------- UNUSED FOR NOW -------------------------------- #}
{% macro profile_list_unused(user, items, color) %}
{% import "AvanzuAdminThemeBundle:layout:macros.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="box box-widget widget-user-2">
<!-- Add the bg color to the header using any of the bg-* classes -->
<div class="widget-user-header bg-{{ color|default(kimai_context.box_color) }}">
<div class="widget-user-image">
{{ macro.avatar(user.avatar, user.username) }}
</div>
<!-- /.widget-user-image -->
<h3 class="widget-user-username">{{ widgets.username(user) }}</h3>
<h5 class="widget-user-desc">{{ user.title }}</h5>
</div>
<div class="box-footer no-padding">
<ul class="nav nav-stacked">
{% for entry in items %}
<li><a href="{{ entry.url }}">{{ entry.title|trans }} <span class="pull-right badge bg-{{ entry.color }}">{{ entry.value }}</span></a></li>
{% endfor %}
</ul>
</div>
</div>
{% endmacro %}
{# -------------------------------- UNUSED FOR NOW -------------------------------- #}
{% macro profile_box_unused(user, stats, color) %}
{% import "AvanzuAdminThemeBundle:layout:macros.html.twig" as macro %}
{% import "macros/widgets.html.twig" as widgets %}
<div class="box box-widget widget-user">
<div class="widget-user-header bg-{{ color|default(kimai_context.box_color) }}">
<h3 class="widget-user-username">{{ widgets.username(user) }}</h3>
<h5 class="widget-user-desc">{{ user.title }}</h5>
</div>
<div class="widget-user-image">
{{ macro.avatar(user.avatar, user.username) }}
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-3 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.durationTotal|duration }}</h5>
<span class="description-text">{{ 'stats.durationTotal'|trans }}</span>
</div>
</div>
<div class="col-sm-3 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.amountTotal|money }}</h5>
<span class="description-text">{{ 'stats.amountTotal'|trans }}</span>
</div>
</div>
<div class="col-sm-3 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.durationThisMonth|duration }}</h5>
<span class="description-text">{{ 'stats.durationThisMonth'|trans }}</span>
</div>
</div>
<div class="col-sm-3 border-right">
<div class="description-block">
<h5 class="description-header">{{ stats.amountThisMonth|money }}</h5>
<span class="description-text">{{ 'stats.amountThisMonth'|trans }}</span>
</div>
</div>
</div>
</div>
</div>
{% endmacro %}

View File

@@ -1,13 +0,0 @@
<?php
use Doctrine\Common\Annotations\AnnotationRegistry;
use Composer\Autoload\ClassLoader;
/**
* @var ClassLoader $loader
*/
$loader = require __DIR__.'/../vendor/autoload.php';
AnnotationRegistry::registerLoader([$loader, 'loadClass']);
return $loader;

View File

@@ -1,105 +0,0 @@
# This is the main configuration file of your application. It stores all the
# common options for every execution environment ('prod', 'dev', 'test').
# To avoid creating configuration files that are too long, we first import some
# files that define the values for important parts of the application,
# such as the security component and the dependency injection services
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
# These are the configuration parameters that define the application's behavior
# and which are independent from the underlying technical infrastructure
# See http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
# This parameter defines the codes of the locales (languages) enabled in the application
app_locales: en|de
app.notifications.email_sender: "%mailer_from%"
# Basic configuration for the Symfony framework features
framework:
# Uncomment the 'ide' option to turn all of the file paths in an exception
# page into clickable links that open the given file using your favorite IDE.
# Supported values are 'textmate', 'macvim', 'emacs' and 'sublime' shortcuts
# and any custom configuration string, such as: "phpstorm://open?file=%%f&line=%%l"
# See http://symfony.com/doc/current/reference/configuration/framework.html#ide
#ide: sublime
# When using the HTTP Cache, ESI allows to render page fragments separately
# and with different cache configurations for each fragment
# http://symfony.com/doc/current/book/http_cache.html#edge-side-includes
esi: { enabled: true }
translator: { fallback: "%locale%" }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
templating:
engines: ['twig']
default_locale: "%locale%"
trusted_hosts: ~
session:
handler_id: session.handler.native_file
save_path: "%kernel.root_dir%/../var/sessions/%kernel.environment%"
fragments: ~
http_method_override: true
assets: ~
# Twig Configuration (used for rendering application templates)
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
# form_themes:
# - "bootstrap_3_layout.html.twig"
# - "form/fields.html.twig"
globals:
kimai_context:
date_1: "d.m.Y" # used for display in timesheets
box_color: "green" # a color for ???
active_warning: 3 # display a warning color if the user has at least X active recordings
# Assetic Configuration (used for managing web assets: CSS, JavaScript, Sass, etc.)
#assetic:
# debug: "%kernel.debug%"
# use_controller: false
# bundles: [ ]
# filters:
# cssrewrite: ~
# jsqueeze: ~
# scssphp:
# # the formatter must be the FQCN (don't use the 'compressed' value)
# formatter: "Leafo\\ScssPhp\\Formatter\\Compressed"
# Doctrine Configuration (used to access databases and manipulate their information)
doctrine:
dbal:
url: "%database_url%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
# Swiftmailer Configuration (used to send emails)
#swiftmailer:
# transport: "%mailer_transport%"
# host: "%mailer_host%"
# username: "%mailer_user%"
# password: "%mailer_password%"
# spool: { type: memory }
avanzu_admin_theme:
use_twig: true
use_assetic: true
bower_bin: "/usr/local/bin/bower"
options:
default_avatar: avatars/default.png
skin: skin-green-light
fixed_layout: false
boxed_layout: false
collapsed_sidebar: true
mini_sidebar: true
control_sidebar: false

View File

@@ -1,47 +0,0 @@
imports:
- { resource: config.yml }
- { resource: services_dev.yml }
framework:
router:
resource: "%kernel.root_dir%/config/routing_dev.yml"
strict_requirements: true
profiler: { only_exceptions: false }
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: info
console:
type: console
bubble: false
# uncomment to get logging in your browser
# you may have to allow bigger header sizes in your Web server configuration
#firephp:
# type: firephp
# level: info
#chromephp:
# type: chromephp
# level: info
#assetic:
# use_controller: true
#swiftmailer:
# delivery_address: me@example.com
services:
twig.text_extension:
class: Twig_Extensions_Extension_Text
tags:
- name: twig.extension
web_profiler:
toolbar: '%kernel.debug%'
intercept_redirects: false
# See routing_dev.yml
#avanzu_admin_theme:
# enable_demo: false

View File

@@ -1,25 +0,0 @@
imports:
- { resource: config.yml }
#framework:
# cache:
# system: cache.adapter.apcu
#doctrine:
# orm:
# metadata_cache_driver: apc
# result_cache_driver: apc
# query_cache_driver: apc
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console

View File

@@ -1,31 +0,0 @@
imports:
- { resource: config_dev.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
profiler:
collect: false
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
disable_delivery: true
# It's recommended to use a separate database for tests. This allows to have a
# fixed and known set of data fixtures, it simplifies the code of tests and it
# makes them more robust.
# In this case we just need to define a different path for the application database.
doctrine:
dbal:
database_url: 'sqlite:///%kernel.root_dir%/data/timesheet_test.sqlite'
# this configuration simplifies testing URLs protected by the security mechanism
# See http://symfony.com/doc/current/cookbook/testing/http_authentication.html
security:
firewalls:
secured_area:
http_basic: ~

View File

@@ -1,86 +0,0 @@
doctrine:
orm:
dql:
datetime_functions:
convert_tz: DoctrineExtensions\Query\Mysql\ConvertTz
date: DoctrineExtensions\Query\Mysql\Date
date_format: DoctrineExtensions\Query\Mysql\DateFormat
dateadd: DoctrineExtensions\Query\Mysql\DateAdd
datesub: DoctrineExtensions\Query\Mysql\DateSub
datediff: DoctrineExtensions\Query\Mysql\DateDiff
day: DoctrineExtensions\Query\Mysql\Day
dayname: DoctrineExtensions\Query\Mysql\DayName
dayofweek: DoctrineExtensions\Query\Mysql\DayOfWeek
dayofyear: DoctrineExtensions\Query\Mysql\DayOfYear
div: DoctrineExtensions\Query\Mysql\Div
from_unixtime: DoctrineExtensions\Query\Mysql\FromUnixtime
last_day: DoctrineExtensions\Query\Mysql\LastDay
minute: DoctrineExtensions\Query\Mysql\Minute
now: DoctrineExtensions\Query\Mysql\Now
month: DoctrineExtensions\Query\Mysql\Month
monthname: DoctrineExtensions\Query\Mysql\MonthName
second: DoctrineExtensions\Query\Mysql\Second
strtodate: DoctrineExtensions\Query\Mysql\StrToDate
time: DoctrineExtensions\Query\Mysql\Time
timediff: DoctrineExtensions\Query\Mysql\TimeDiff
timestampadd: DoctrineExtensions\Query\Mysql\TimestampAdd
timestampdiff: DoctrineExtensions\Query\Mysql\TimestampDiff
timetosec: DoctrineExtensions\Query\Mysql\TimeToSec
week: DoctrineExtensions\Query\Mysql\Week
weekday: DoctrineExtensions\Query\Mysql\WeekDay
year: DoctrineExtensions\Query\Mysql\Year
yearweek: DoctrineExtensions\Query\Mysql\YearWeek
unix_timestamp: DoctrineExtensions\Query\Mysql\UnixTimestamp
numeric_functions:
acos: DoctrineExtensions\Query\Mysql\Acos
asin: DoctrineExtensions\Query\Mysql\Asin
atan2: DoctrineExtensions\Query\Mysql\Atan2
atan: DoctrineExtensions\Query\Mysql\Atan
bit_count: DoctrineExtensions\Query\Mysql\BitCount
bit_xor: DoctrineExtensions\Query\Mysql\BitXor
ceil: DoctrineExtensions\Query\Mysql\Ceil
cos: DoctrineExtensions\Query\Mysql\Cos
cot: DoctrineExtensions\Query\Mysql\Cot
floor: DoctrineExtensions\Query\Mysql\Floor
hour: DoctrineExtensions\Query\Mysql\Hour
pi: DoctrineExtensions\Query\Mysql\Pi
power: DoctrineExtensions\Query\Mysql\Power
quarter: DoctrineExtensions\Query\Mysql\Quarter
rand: DoctrineExtensions\Query\Mysql\Rand
round: DoctrineExtensions\Query\Mysql\Round
stddev: DoctrineExtensions\Query\Mysql\StdDev
sin: DoctrineExtensions\Query\Mysql\Sin
std: DoctrineExtensions\Query\Mysql\Std
tan: DoctrineExtensions\Query\Mysql\Tan
string_functions:
ascii: DoctrineExtensions\Query\Mysql\Ascii
binary: DoctrineExtensions\Query\Mysql\Binary
char_length: DoctrineExtensions\Query\Mysql\CharLength
concat_ws: DoctrineExtensions\Query\Mysql\ConcatWs
countif: DoctrineExtensions\Query\Mysql\CountIf
crc32: DoctrineExtensions\Query\Mysql\Crc32
degrees: DoctrineExtensions\Query\Mysql\Degrees
field: DoctrineExtensions\Query\Mysql\Field
find_in_set: DoctrineExtensions\Query\Mysql\FindInSet
greatest: DoctrineExtensions\Query\Mysql\Greatest
group_concat: DoctrineExtensions\Query\Mysql\GroupConcat
ifelse: DoctrineExtensions\Query\Mysql\IfElse
ifnull: DoctrineExtensions\Query\Mysql\IfNull
least: DoctrineExtensions\Query\Mysql\Least
lpad: DoctrineExtensions\Query\Mysql\Lpad
match_against: DoctrineExtensions\Query\Mysql\MatchAgainst
md5: DoctrineExtensions\Query\Mysql\Md5
nullif: DoctrineExtensions\Query\Mysql\NullIf
radians: DoctrineExtensions\Query\Mysql\Radians
regexp: DoctrineExtensions\Query\Mysql\Regexp
replace: DoctrineExtensions\Query\Mysql\Replace
rpad: DoctrineExtensions\Query\Mysql\Rpad
sha1: DoctrineExtensions\Query\Mysql\Sha1
sha2: DoctrineExtensions\Query\Mysql\Sha2
soundex: DoctrineExtensions\Query\Mysql\Soundex
substring_index: DoctrineExtensions\Query\Mysql\SubstringIndex
uuid_short: DoctrineExtensions\Query\Mysql\UuidShort
hex: DoctrineExtensions\Query\Mysql\Hex
unhex: DoctrineExtensions\Query\Mysql\Unhex

View File

@@ -1,37 +0,0 @@
# This file defines the canonical configuration parameters of the application.
# Symfony uses this file as a template to generate the real app/config/parameters.yml used by the application.
# See http://symfony.com/doc/current/best_practices/configuration.html#canonical-parameters
parameters:
# used to load additional doctrine functions (possible values: mysql, sqlite)
database_engine: sqlite
# Define the database connection string
database_url: 'sqlite:///%kernel.root_dir%/data/timesheet.sqlite'
# database_url: 'mysql://root:pass@127.0.0.1:3306/timesheet'
# You can prefix all your tables to pevent collision with other software
database_prefix: kimai2_
# You can create the database and load the sample data from the command line:
#
# php bin/console doctrine:database:create
# php bin/console doctrine:schema:create
# php bin/console doctrine:fixtures:load
# If you don't use a real mail server, you can send emails via your Gmail account.
# see http://symfony.com/doc/current/cookbook/email/gmail.html
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: ~
mailer_password: ~
mailer_from: anonymous@example.com
# The code of the default language used by the application ('en' = English, 'de' = German)
locale: de
# The 'secret' value is a random string of characters, numbers and symbols
# used internally by Symfony in several places (CSRF tokens, URI signing,
# 'Remember Me' functionality, etc.)
# see: http://symfony.com/doc/current/reference/configuration/framework.html#secret
secret: 'please_change_this_secret_to_something_unique'

View File

@@ -1,39 +0,0 @@
# These first lines load the all routes defined as @Route() annotations in any
# controller defined inside the src/AppBundle/Controller/ directory. Controllers
# are loaded recursively, so you can separate them into subdirectories.
# If you don't like to add annotations in your applications, you can also define
# the routes in YAML, XML or PHP files.
# See http://symfony.com/doc/current/book/routing.html
app:
resource: '@AppBundle/Controller/'
type: annotation
prefix: /{_locale}
requirements:
_locale: '%app_locales%'
defaults:
_locale: '%locale%'
timesheet:
resource: '@TimesheetBundle/Controller/'
type: annotation
prefix: /{_locale}
requirements:
_locale: '%app_locales%'
defaults:
_locale: '%locale%'
# These lines define a route using YAML configuration. The controller used by
# the route (FrameworkBundle:Template:template) is a convenient shortcut when
# the template can be rendered without executing any logic in your own controller.
# See http://symfony.com/doc/current/cookbook/templating/render_without_controller.html
homepage:
path: /{_locale}
defaults:
_controller: FrameworkBundle:Redirect:redirect
route: timesheet
permanent: true
avanzu_admin_profile:
path: /{_locale}/profile/{username}
options:
avanzu_admin_route: profile

View File

@@ -1,35 +0,0 @@
# this imports the routes used to display the web debug toolbar at the bottom of each page
_wdt:
resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml"
prefix: /_wdt
# this imports the routes needed to display the Symfony Profiler information
_profiler:
resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml"
prefix: /_profiler
# this imports the route used to test error pages. Just browse the following URL:
# /{_locale}/_error/{status_code}.{format}
# (e.g. /en/_error/404, /en/_error/403.json, /fr/_error/500.xml)
# See http://symfony.com/doc/current/cookbook/controller/error_pages.html#testing-error-pages-during-development
_errors:
resource: "@TwigBundle/Resources/config/routing/errors.xml"
prefix: /{_locale}/_error
requirements:
_locale: '%app_locales%'
defaults:
_locale: '%locale%'
# this loads the main routing file, which usually defines the routes available
# in any environment (production, development, etc.)
_main:
resource: routing.yml
# ========================================================================
# Demo routes, only work with "avanzu_admin_theme/enable_demo: true"
# ========================================================================
#avanzu_admin:
# prefix: /admin
# resource: "@AvanzuAdminThemeBundle/Resources/config/routes.yml"

View File

@@ -1,55 +0,0 @@
security:
encoders:
# Our user class and the algorithm we'll use to encode passwords
# http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password
AppBundle\Entity\User: bcrypt
providers:
# in this example, users are stored via Doctrine in the database
# demo users can be found at src/AppBundle/DataFixtures/ORM/LoadFixtures.php
database_users:
entity: { class: AppBundle:User, property: username }
# http://symfony.com/doc/current/book/security.html#firewalls-authentication
firewalls:
secured_area:
# does what it says
logout_on_user_change: true
# this firewall applies to all URLs
pattern: ^/
# but the firewall does not require login on every page
# denying access is done in access_control or in your controllers
anonymous: ~
# This allows the user to login by submitting a username and password
# Reference: http://symfony.com/doc/current/cookbook/security/form_login_setup.html
form_login:
# The route name that the login form submits to
check_path: security_login
# The name of the route where the login form lives
# When the user tries to access a protected page, they are redirected here
login_path: security_login
# Secure the login form against CSRF
# Reference: http://symfony.com/doc/current/cookbook/security/csrf_in_login_form.html
csrf_token_generator: security.csrf.token_manager
logout:
# The route name the user can go to in order to logout
path: security_logout
# The name of the route to redirect to after logging out
target: homepage
role_hierarchy:
ROLE_USER: ROLE_CUSTOMER
ROLE_TEAMLEAD: ROLE_USER
ROLE_ADMIN: ROLE_TEAMLEAD
ROLE_SUPER_ADMIN: ROLE_ADMIN
access_control:
# this is a catch-all for the admin area
# additional security lives in the controllers
- { path: '^/(%app_locales%)$', role: IS_AUTHENTICATED_FULLY }
- { path: '^/(%app_locales%)/login', role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: '^/(%app_locales%)/admin', roles: ROLE_ADMIN }

View File

@@ -1,177 +0,0 @@
services:
# ================================================================================
# TWIG
# ================================================================================
markdown:
class: AppBundle\Utils\Markdown
app.twig.app_extension:
public: false
class: AppBundle\Twig\Extensions
arguments: ['@markdown', '%app_locales%']
tags:
- { name: twig.extension }
# twig function: template_from_string()
app.twig.loader_extension:
class: Twig_Extension_StringLoader
tags:
- { name: 'twig.extension' }
app.twig.intl_extension:
public: false
class: Twig_Extensions_Extension_Intl
tags:
- { name: twig.extension }
# ================================================================================
# SECURITY
# ================================================================================
# security voter to check user-profile access
app.voter.user:
class: AppBundle\Voter\UserVoter
arguments: ["@security.access.decision_manager"]
tags:
- { name: security.voter }
# security voter to check customer access
timesheet.voter.customer:
class: TimesheetBundle\Voter\CustomerVoter
arguments: ["@security.access.decision_manager"]
tags:
- { name: security.voter }
# security voter to check project access
timesheet.voter.project:
class: TimesheetBundle\Voter\ProjectVoter
arguments: ["@security.access.decision_manager"]
tags:
- { name: security.voter }
# security voter to check activity access
timesheet.voter.activity:
class: TimesheetBundle\Voter\ActivityVoter
arguments: ["@security.access.decision_manager"]
tags:
- { name: security.voter }
# security voter to check activity access
timesheet.voter.timesheet:
class: TimesheetBundle\Voter\TimesheetVoter
arguments: ["@security.access.decision_manager"]
tags:
- { name: security.voter }
# ================================================================================
# FORMS
# ================================================================================
# form to edit user roles
app.admin.user_role:
class: AppBundle\Form\Type\UserRoleType
arguments: ["%security.role_hierarchy.roles%"]
tags:
- { name: form.type }
# event-listener to populate the navigation
app.menu_builder:
class: AppBundle\EventListener\MenuBuilder
arguments: ["@event_dispatcher", "@security.authorization_checker"]
tags:
- { name: kernel.event_listener, event: theme.sidebar_setup_menu, method: onSetupNavbar }
# ================================================================================
# DATABASE
# ================================================================================
# service that prefixes every database table
app.tableprefix_subscriber:
class: AppBundle\Doctrine\TablePrefixSubscriber
arguments: ["%database_prefix%"]
tags:
- { name: doctrine.event_subscriber }
app.database_listener.timesheet:
class: TimesheetBundle\EventListener\TimesheetListener
tags:
- { name: doctrine.event_listener, event: prePersist, lazy: true }
- { name: doctrine.event_listener, event: preUpdate, lazy: true }
# Uncomment the following lines to define a service for the Post Doctrine repository.
# It's not mandatory to create these services, but if you use repositories a lot,
# these services simplify your code:
#
# app.post_repository:
# class: Doctrine\ORM\EntityRepository
# factory: ['@doctrine.orm.entity_manager', getRepository]
# arguments: [AppBundle\Entity\User]
#
# // traditional code inside a controller
# $entityManager = $this->getDoctrine()->getManager();
# $posts = $entityManager->getRepository('AppBundle:User')->findAll();
#
# // same code using repository services
# $posts = $this->get('app.user_repository')->findAll();
# ================================================================================
# THEME
# ================================================================================
avanzu_admin_theme.navbar_user_listener:
class: AppBundle\EventListener\NavbarShowUserListener
arguments: ["@security.token_storage"]
tags:
- { name: kernel.event_listener, event: theme.navbar_user, method: onShowUser }
- { name: kernel.event_listener, event: theme.sidebar_user, method: onShowUser }
# avanzu_admin_theme.navbar_task_listener:
# class: "%avanzu_admin_theme.navbar_task_listener.class%"
# tags:
# - { name: kernel.event_listener, event: theme.tasks, method: onListTasks }
#
# avanzu_admin_theme.navbar_notify_listener:
# class: "%avanzu_admin_theme.navbar_notify_listener.class%"
# tags:
# - { name: kernel.event_listener, event: theme.notifications, method: onListNotifications }
#
# avanzu_admin_theme.navbar_msg_listener:
# class: "%avanzu_admin_theme.navbar_msg_listener.class%"
# tags:
# - { name: kernel.event_listener, event: theme.messages, method: onListMessages }
#
# avanzu_admin_theme.setup_menu_listener:
# class: "%avanzu_admin_theme.setup_menu_listener.class%"
# tags:
# - { name: kernel.event_listener, event: theme.sidebar_setup_menu, method: onSetupMenu }
# - { name: kernel.event_listener, event: theme.breadcrumb, method: onSetupMenu }
# ================================================================================
# APPLICATION CORE
# ================================================================================
# a route listener, that injects the locale through a URL directory
app.redirect_to_preferred_locale_listener:
class: AppBundle\EventListener\RedirectToPreferredLocaleListener
arguments: ['@router', '%app_locales%', '%locale%']
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
# additional menu entries for the timesheet bundle
timesheet.configure_menu_listener:
class: TimesheetBundle\EventListener\Menu
tags:
- { name: kernel.event_listener, event: app.main_menu_configure, method: onMainMenuConfigure }
- { name: kernel.event_listener, event: app.admin_menu_configure, method: onAdminMenuConfigure }
# ================================================================================
# CONSOLE COMMANDS
# ================================================================================
app.command.create_user:
class: AppBundle\Command\CreateUserCommand
arguments: ["@security.password_encoder", "@doctrine", "@validator"]
tags:
- { name: console.command, command: kimai:create-user }

View File

@@ -1,32 +0,0 @@
imports:
- { resource: services.yml }
services:
# ================================================================================
# CONSOLE COMMANDS
# ================================================================================
app.command.run_phpcs:
class: AppBundle\Command\RunCodeSnifferCommand
arguments: ["%kernel.root_dir%"]
tags:
- { name: console.command, command: kimai:dev:phpcs }
app.command.run_unit_tests:
class: AppBundle\Command\RunUnitTestsCommand
arguments: ["%kernel.root_dir%"]
tags:
- { name: console.command, command: kimai:dev:test-unit }
app.command.run_integration_tests:
class: AppBundle\Command\RunIntegrationTestsCommand
arguments: ["%kernel.root_dir%"]
tags:
- { name: console.command, command: kimai:dev:test-integration }
app.command.dev_reset:
class: AppBundle\Command\DevResetCommand
arguments: ["%kernel.root_dir%"]
tags:
- { name: console.command, command: kimai:dev:reset }

View File

@@ -1,50 +0,0 @@
doctrine:
orm:
dql:
datetime_functions:
date: DoctrineExtensions\Query\Sqlite\Date
date_format: DoctrineExtensions\Query\Sqlite\DateFormat
#dateadd: DoctrineExtensions\Query\Sqlite\DateAdd
#datediff: DoctrineExtensions\Query\Sqlite\DateDiff
day: DoctrineExtensions\Query\Sqlite\Day
dayname: DoctrineExtensions\Query\Sqlite\DayName
minute: DoctrineExtensions\Query\Sqlite\Minute
#month: DoctrineExtensions\Query\Sqlite\Month
#monthname: DoctrineExtensions\Query\Sqlite\MonthName
second: DoctrineExtensions\Query\Sqlite\Second
month: DoctrineExtensions\Query\Sqlite\Month
strftime: DoctrineExtensions\Query\Sqlite\StrfTime
#strtodate: DoctrineExtensions\Query\Sqlite\StrToDate
#time: DoctrineExtensions\Query\Sqlite\Time
#timestampadd: DoctrineExtensions\Query\Sqlite\TimestampAdd
#timestampdiff: DoctrineExtensions\Query\Sqlite\TimestampDiff
week: DoctrineExtensions\Query\Sqlite\Week
weekday: DoctrineExtensions\Query\Sqlite\WeekDay
year: DoctrineExtensions\Query\Sqlite\Year
string_functions:
# binary: DoctrineExtensions\Query\Sqlite\Binary
# char_length: DoctrineExtensions\Query\Sqlite\CharLength
concat_ws: DoctrineExtensions\Query\Sqlite\ConcatWs
# countif: DoctrineExtensions\Query\Sqlite\CountIf
# crc32: DoctrineExtensions\Query\Sqlite\Crc32
# degrees: DoctrineExtensions\Query\Sqlite\Degrees
# field: DoctrineExtensions\Query\Sqlite\Field
# find_in_set: DoctrineExtensions\Query\Sqlite\FindInSet
# group_concat: DoctrineExtensions\Query\Sqlite\GroupConcat
# ifelse: DoctrineExtensions\Query\Sqlite\IfElse
ifnull: DoctrineExtensions\Query\Sqlite\IfNull
# match_against: DoctrineExtensions\Query\Sqlite\MatchAgainst
# md5: DoctrineExtensions\Query\Sqlite\Md5
# nullif: DoctrineExtensions\Query\Sqlite\NullIf
# radians: DoctrineExtensions\Query\Sqlite\Radians
# regexp: DoctrineExtensions\Query\Sqlite\Regexp
replace: DoctrineExtensions\Query\Sqlite\Replace
# sha1: DoctrineExtensions\Query\Sqlite\Sha1
# sha2: DoctrineExtensions\Query\Sqlite\Sha2
# soundex: DoctrineExtensions\Query\Sqlite\Soundex
# uuid_short: DoctrineExtensions\Query\Sqlite\UuidShort
numeric_functions:
round: DoctrineExtensions\Query\Sqlite\Round

1
assets/app-rtl.js Normal file
View File

@@ -0,0 +1 @@
require('./sass/_app-rtl.scss');

9
assets/app.js Normal file
View File

@@ -0,0 +1,9 @@
require('./sass/_app.scss');
// ------ Kimai itself ------
require('./js/KimaiWebLoader.js');
global.KimaiPaginatedBoxWidget = require('./js/widgets/KimaiPaginatedBoxWidget').default;
global.KimaiReloadPageWidget = require('./js/widgets/KimaiReloadPageWidget').default;
global.KimaiColor = require('./js/widgets/KimaiColor').default;
global.KimaiStorage = require('./js/widgets/KimaiStorage').default;

2
assets/calendar.js Normal file
View File

@@ -0,0 +1,2 @@
global.KimaiCalendar = require('./js/widgets/KimaiCalendar').default;

58
assets/chart.js Normal file
View File

@@ -0,0 +1,58 @@
import {
Chart,
ArcElement,
LineElement,
BarElement,
PointElement,
BarController,
// BubbleController,
DoughnutController,
LineController,
PieController,
// PolarAreaController,
// RadarController,
// ScatterController,
CategoryScale,
LinearScale,
// LogarithmicScale,
// RadialLinearScale,
// TimeScale,
// TimeSeriesScale,
// Decimation,
// Filler,
Legend,
Title,
Tooltip,
Colors,
// SubTitle
} from 'chart.js';
Chart.register(
ArcElement,
LineElement,
BarElement,
PointElement,
BarController,
// BubbleController,
DoughnutController,
LineController,
PieController,
// PolarAreaController,
// RadarController,
// ScatterController,
CategoryScale,
LinearScale,
// LogarithmicScale,
// RadialLinearScale,
// TimeScale,
// TimeSeriesScale,
// Decimation,
// Filler,
Legend,
Title,
Tooltip,
Colors
// SubTitle
);
global.Chart = Chart;

8
assets/dashboard.js Normal file
View File

@@ -0,0 +1,8 @@
/**
* https://gridstackjs.com
* https://github.com/gridstack/gridstack.js/tree/master/doc
*/
require('gridstack/dist/gridstack.min.css');
require('gridstack/dist/gridstack-extra.min.css');
import { GridStack } from 'gridstack';
global.GridStack = GridStack;

2
assets/export-pdf.js Normal file
View File

@@ -0,0 +1,2 @@
require('./sass/_export-pdf.scss');

5
assets/highlight.js Normal file
View File

@@ -0,0 +1,5 @@
require('highlight.js/styles/github-dark.css');
const hljs = require('highlight.js/lib/common');
global.hljs = hljs;

2
assets/invoice-pdf.js Normal file
View File

@@ -0,0 +1,2 @@
require('./sass/_invoice-pdf.scss');

2
assets/invoice.js Normal file
View File

@@ -0,0 +1,2 @@
require('./sass/_invoice.scss');

View File

@@ -0,0 +1,53 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiConfiguration: handling all configuration and runtime settings
*/
export default class KimaiConfiguration {
constructor(configurations) {
this._configurations = configurations;
}
get(name) {
return this._configurations[name];
}
has(name) {
return name in this._configurations;
}
isRTL() {
return this.get('direction') === 'rtl';
}
getLanguage() {
return this.get('locale').replace('_', '-');
}
is24Hours() {
return !!this.get('twentyFourHours');
}
/**
* @param {boolean} iso
* @return {number}
*/
getFirstDayOfWeek(iso = true) {
if (iso === undefined) {
iso = true;
}
let config = this.get('first_dow_iso');
if (!iso) {
config = config % 7;
}
return config;
}
}

View File

@@ -0,0 +1,98 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiContainer
*
* ServiceContainer for Kimai
*/
import KimaiConfiguration from './KimaiConfiguration';
import KimaiTranslation from './KimaiTranslation';
import KimaiPlugin from './KimaiPlugin';
export default class KimaiContainer {
/**
* Create a new Container with the given configurations and translations.
*
* @param {KimaiConfiguration} configuration
* @param {KimaiTranslation} translation
*/
constructor(configuration, translation) {
if (!(configuration instanceof KimaiConfiguration)) {
throw new Error('Configuration needs to a KimaiConfiguration instance');
}
this._configuration = configuration;
if (!(translation instanceof KimaiTranslation)) {
throw new Error('Configuration needs to a KimaiTranslation instance');
}
this._translation = translation;
this._plugins = [];
}
/**
* Register a new Plugin.
*
* @param {KimaiPlugin} plugin
* @returns {KimaiPlugin}
*/
registerPlugin(plugin) {
if (!(plugin instanceof KimaiPlugin)) {
throw new Error('Invalid plugin given, needs to be a KimaiPlugin instance');
}
plugin.setContainer(this);
this._plugins.push(plugin);
return plugin;
}
/**
* @param {string} name
* @returns {KimaiPlugin}
*/
getPlugin(name) {
for (let plugin of this._plugins) {
if (plugin.getId() !== null && plugin.getId() === name) {
return plugin;
}
}
throw new Error('Unknown plugin: ' + name);
}
/**
* @returns {Array<KimaiPlugin>}
*/
getPlugins() {
return this._plugins;
}
/**
* @returns {KimaiTranslation}
*/
getTranslation() {
return this._translation;
}
/**
* @returns {KimaiConfiguration}
*/
getConfiguration() {
return this._configuration;
}
/**
* @returns {KimaiUser}
*/
getUser() {
return this.getPlugin('user');
}
}

111
assets/js/KimaiLoader.js Normal file
View File

@@ -0,0 +1,111 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiLoader: bootstrap the application and all plugins
*/
import { Settings } from 'luxon';
import KimaiTranslation from "./KimaiTranslation";
import KimaiConfiguration from "./KimaiConfiguration";
import KimaiContainer from "./KimaiContainer";
import KimaiDatatableColumnView from './plugins/KimaiDatatableColumnView.js';
import KimaiThemeInitializer from "./plugins/KimaiThemeInitializer";
import KimaiDateRangePicker from "./forms/KimaiDateRangePicker";
import KimaiDatatable from "./plugins/KimaiDatatable";
import KimaiToolbar from "./plugins/KimaiToolbar";
import KimaiAPI from "./plugins/KimaiAPI";
import KimaiAlternativeLinks from "./plugins/KimaiAlternativeLinks";
import KimaiAjaxModalForm from "./plugins/KimaiAjaxModalForm";
import KimaiActiveRecords from "./plugins/KimaiActiveRecords";
import KimaiEvent from "./plugins/KimaiEvent";
import KimaiAPILink from "./plugins/KimaiAPILink";
import KimaiAlert from "./plugins/KimaiAlert";
import KimaiAutocomplete from "./forms/KimaiAutocomplete";
import KimaiFormSelect from "./forms/KimaiFormSelect";
import KimaiForm from "./plugins/KimaiForm";
import KimaiDatePicker from "./forms/KimaiDatePicker";
import KimaiConfirmationLink from "./plugins/KimaiConfirmationLink";
import KimaiMultiUpdateTable from "./plugins/KimaiMultiUpdateTable";
import KimaiDateUtils from "./plugins/KimaiDateUtils";
import KimaiEscape from "./plugins/KimaiEscape";
import KimaiFetch from "./plugins/KimaiFetch";
import KimaiTimesheetForm from "./forms/KimaiTimesheetForm";
import KimaiTeamForm from "./forms/KimaiTeamForm";
import KimaiCopyDataForm from "./forms/KimaiCopyDataForm";
import KimaiDateNowForm from "./forms/KimaiDateNowForm";
import KimaiNotification from "./plugins/KimaiNotification";
import KimaiHotkeys from "./plugins/KimaiHotkeys";
import KimaiRemoteModal from "./plugins/KimaiRemoteModal";
import KimaiUser from "./plugins/KimaiUser";
import KimaiAutocompleteTags from "./forms/KimaiAutocompleteTags";
export default class KimaiLoader {
constructor(configurations, translations) {
// set the current locale for all javascript components
Settings.defaultLocale = configurations['locale'].replace('_', '-').toLowerCase();
Settings.defaultZone = configurations['timezone'];
const kimai = new KimaiContainer(
new KimaiConfiguration(configurations),
new KimaiTranslation(translations)
);
// GLOBAL HELPER PLUGINS
kimai.registerPlugin(new KimaiUser());
kimai.registerPlugin(new KimaiEscape());
kimai.registerPlugin(new KimaiEvent());
kimai.registerPlugin(new KimaiAPI());
kimai.registerPlugin(new KimaiAlert());
kimai.registerPlugin(new KimaiFetch());
kimai.registerPlugin(new KimaiDateUtils());
kimai.registerPlugin(new KimaiNotification());
// FORM PLUGINS
kimai.registerPlugin(new KimaiFormSelect('.selectpicker', 'select[data-related-select]'));
kimai.registerPlugin(new KimaiDateRangePicker('input[data-daterangepicker="on"]'));
kimai.registerPlugin(new KimaiDatePicker('input[data-datepicker="on"]'));
kimai.registerPlugin(new KimaiAutocomplete());
kimai.registerPlugin(new KimaiAutocompleteTags());
kimai.registerPlugin(new KimaiTimesheetForm());
kimai.registerPlugin(new KimaiTeamForm());
kimai.registerPlugin(new KimaiCopyDataForm());
kimai.registerPlugin(new KimaiDateNowForm());
kimai.registerPlugin(new KimaiForm());
kimai.registerPlugin(new KimaiHotkeys());
// SPECIAL FEATURES
kimai.registerPlugin(new KimaiConfirmationLink('confirmation-link'));
kimai.registerPlugin(new KimaiDatatableColumnView('data-column-visibility'));
kimai.registerPlugin(new KimaiDatatable('section.content', 'table.dataTable'));
kimai.registerPlugin(new KimaiToolbar('form.searchform', 'toolbar-action'));
kimai.registerPlugin(new KimaiAlternativeLinks('.alternative-link'));
kimai.registerPlugin(new KimaiAjaxModalForm('.modal-ajax-form', ['td.multiCheckbox', 'td.actions']));
kimai.registerPlugin(new KimaiRemoteModal());
kimai.registerPlugin(new KimaiActiveRecords());
kimai.registerPlugin(new KimaiAPILink('api-link'));
kimai.registerPlugin(new KimaiMultiUpdateTable());
kimai.registerPlugin(new KimaiThemeInitializer());
// notify all listeners that Kimai plugins can now be registered
document.dispatchEvent(new CustomEvent('kimai.pluginRegister', {detail: {'kimai': kimai}}));
// initialize all plugins
kimai.getPlugins().map(plugin => { plugin.init(); });
// notify all listeners that Kimai is now ready to be used
document.dispatchEvent(new CustomEvent('kimai.initialized', {detail: {'kimai': kimai}}));
this.kimai = kimai;
}
getKimai() {
return this.kimai;
}
}

161
assets/js/KimaiPlugin.js Normal file
View File

@@ -0,0 +1,161 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiPlugin: base class for all plugins
*/
import KimaiContainer from "./KimaiContainer";
export default class KimaiPlugin {
/**
* Overwrite this method to initialize your plugin.
*
* It is called AFTER setContainer() and AFTER DOMContentLoaded was fired.
* You don't have access to the container before this method!
*/
init() {
}
/**
* If you return an ID, you indicate that your plugin can be used by other plugins.
*
* @returns {string|null}
*/
getId() {
return null;
}
/**
* @param {KimaiContainer} core
*/
setContainer(core) {
if (!(core instanceof KimaiContainer)) {
throw new Error('Plugin was given an invalid KimaiContainer');
}
this._core = core;
}
/**
* This function returns null, if you call it BEFORE init().
*
* @returns {KimaiContainer}
*/
getContainer() {
return this._core;
}
/**
* @param {string} name
* @returns {(string|number|boolean)}
*/
getConfiguration(name) {
return this.getContainer().getConfiguration().get(name);
}
/**
* @return {KimaiConfiguration}
*/
getConfigurations() {
return this.getContainer().getConfiguration();
}
/**
* @returns {KimaiDateUtils}
*/
getDateUtils() {
return this.getPlugin('date');
}
/**
* @param {string} name
* @returns {KimaiPlugin}
*/
getPlugin(name) {
return this.getContainer().getPlugin(name);
}
/**
* @returns {KimaiTranslation}
*/
getTranslation() {
return this.getContainer().getTranslation();
}
/**
* @param {string} name
* @returns {string}
*/
translate(name) {
return this.getTranslation().get(name);
}
/**
* @param {string} title
* @returns {string}
*/
escape(title) {
return this.getPlugin('escape').escapeForHtml(title);
}
/**
* @param {string} name
* @param {string|null} details
*/
trigger(name, details = null) {
this.getPlugin('event').trigger(name, details);
}
/**
* @param {string} url
* @param {object} options
* @returns {Promise<Response>}
*/
fetch(url, options = {}) {
return this.getPlugin('fetch').fetch(url, options);
}
/**
* @param {HTMLFormElement} form
* @param {object} options
* @param {string|null} url
* @returns {Promise<Response>}
*/
fetchForm(form, options = {}, url = null) {
url = url || form.getAttribute('action');
const method = form.getAttribute('method').toUpperCase();
if (method === 'GET') {
const data = this.getPlugin('form').convertFormDataToQueryString(form, {}, true);
// TODO const data = new URLSearchParams(new FormData(form)).toString();
url = url + (url.includes('?') ? '&' : '?') + data;
options = {...{method: 'GET'}, ...options};
} else if (method === 'POST') {
options = {...{
method: 'POST',
body: new FormData(form)
}, ...options};
}
return this.fetch(url, options);
}
/**
* Check if the current device is a mobile device (targeting the bootstrip xs breakpoint size).
*
* @returns {boolean}
*/
isMobile() {
const width = Math.max(
document.documentElement.clientWidth,
window.innerWidth || 0
);
return width < 576;
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiTranslation: handling translation strings
*/
export default class KimaiTranslation {
/**
* @param {Array<string, string>} translations
*/
constructor(translations) {
this._translations = translations;
}
/**
* @param {string} name
* @returns {string}
*/
get(name) {
return this._translations[name];
}
/**
* @param {string} name
* @returns {boolean}
*/
has(name) {
return name in this._translations;
}
}

View File

@@ -0,0 +1,33 @@
/*
* This file is part of the Kimai time-tracking app.
*
* Main JS application file for Kimai 2. This file should be included in all pages.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/*!
* [KIMAI] Wrapper class for loading Kimai app in browser script scope
*/
import KimaiLoader from "./KimaiLoader";
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define([], function () {
return (root.KimaiWebLoader = factory());
});
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.KimaiWebLoader = factory();
}
}(typeof self !== 'undefined' ? self : this, function () {
class KimaiWebLoader extends KimaiLoader {
}
return KimaiWebLoader;
}));

View File

@@ -0,0 +1,98 @@
/*
* 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.
*/
import TomSelect from 'tom-select';
import KimaiFormTomselectPlugin from "./KimaiFormTomselectPlugin";
/**
* Supporting auto-complete fields via API.
*/
export default class KimaiAutocomplete extends KimaiFormTomselectPlugin {
init()
{
this.selector = '[data-form-widget="autocomplete"]';
}
/**
* @param {HTMLFormElement} form
* @return boolean
*/
supportsForm(form) // eslint-disable-line no-unused-vars
{
return true;
}
loadData(apiUrl, query, callback) {
/** @type {KimaiAPI} API */
const API = this.getContainer().getPlugin('api');
API.get(apiUrl, {'name': query}, (data) => {
let results = [];
for (let item of data) {
results.push({text: item.name, value: item.name});
}
callback(results);
}, () => {
callback();
});
}
activateForm(form)
{
[].slice.call(form.querySelectorAll(this.selector)).map((node) => {
const apiUrl = node.dataset['autocompleteUrl'];
let minChars = 3;
if (node.dataset['minimumCharacter'] !== undefined) {
minChars = parseInt(node.dataset['minimumCharacter']);
}
let options = {
// see https://github.com/orchidjs/tom-select/issues/543#issuecomment-1664342257
onItemAdd: function(){
// remove remaining characters from input after selecting an item
this.setTextboxValue('');
},
// if there are more than 500, they need to be found by "typing"
maxOptions: 500,
// the autocomplete is ONLY used, when the user can create tags
create: node.dataset['create'] !== undefined,
onOptionAdd: (value) => {
node.dispatchEvent(new CustomEvent('create', {detail: {'value': value}}));
},
plugins: ['remove_button'],
shouldLoad: function(query) {
return query.length >= minChars;
},
load: (query, callback) => {
this.loadData(apiUrl, query, callback);
},
};
let render = {
// eslint-disable-next-line
not_loading: (data, escape) => {
// no default content
},
};
const rendererType = (node.dataset['renderer'] !== undefined) ? node.dataset['renderer'] : 'default';
options.render = {...render, ...this.getRenderer(rendererType)};
new TomSelect(node, options);
});
}
destroyForm(form) {
[].slice.call(form.querySelectorAll(this.selector)).map((node) => {
if (node.tomselect) {
node.tomselect.destroy();
}
});
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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.
*/
import KimaiAutocomplete from "./KimaiAutocomplete";
/**
* Used for timesheet tagging in toolbar and edit dialogs.
*/
export default class KimaiAutocompleteTags extends KimaiAutocomplete {
init()
{
this.selector = '[data-form-widget="tags"]';
}
loadData(apiUrl, query, callback) {
/** @type {KimaiAPI} API */
const API = this.getContainer().getPlugin('api');
API.get(apiUrl, {'name': query}, (data) => {
let results = [];
for (let item of data) {
results.push({text: item.name, value: item.name, color: item.color});
}
callback(results);
}, () => {
callback();
});
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiEditTimesheetForm: responsible for the most important form in the application
*/
import KimaiFormPlugin from "./KimaiFormPlugin";
/**
* Used for simple copy from link to input action, e.g. the time and duration dropdowns
* copy the selected values into their corresponding input.
*/
export default class KimaiCopyDataForm extends KimaiFormPlugin {
/**
* @param {HTMLFormElement} form
* @return boolean
*/
supportsForm(form) // eslint-disable-line no-unused-vars
{
return true;
}
/**
* @param {HTMLFormElement} form
*/
activateForm(form)
{
if (this._eventHandler === undefined) {
this._eventHandler = (event) => {
let element = event.target;
if (!element.matches('a[data-form-widget="copy-data"]')) {
element = element.parentNode; // mostly for icons
}
if (!element.matches('a[data-form-widget="copy-data"]') || element.dataset.target === undefined) {
return;
}
const target = document.querySelector(element.dataset.target);
if (target === null) {
return;
}
target.value = element.dataset.value;
if (element.dataset.event !== undefined) {
for (const event of element.dataset.event.split(' ')) {
target.dispatchEvent(new Event(event));
const form = target.closest('form');
if (form !== null) {
form.dispatchEvent(new Event(event));
}
}
}
event.preventDefault();
};
}
form.addEventListener('click', this._eventHandler);
}
/**
* @param {HTMLFormElement} form
*/
destroyForm(form)
{
form.removeEventListener('click', this._eventHandler);
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiEditTimesheetForm: responsible for the most important form in the application
*/
import KimaiFormPlugin from "./KimaiFormPlugin";
/**
*/
export default class KimaiDateNowForm extends KimaiFormPlugin {
init()
{
this.selector = 'a[data-form-widget="date-now"]';
}
/**
* @param {HTMLFormElement} form
* @return boolean
*/
supportsForm(form) // eslint-disable-line no-unused-vars
{
return true;
}
/**
* @param {HTMLFormElement} form
*/
activateForm(form)
{
[].slice.call(form.querySelectorAll(this.selector)).map((element) => {
if (element.dataset.format !== undefined && element.dataset.target !== undefined) {
if (this._eventHandler === undefined) {
this._eventHandler = (event) => {
const linkTarget = event.currentTarget;
const formElement = document.getElementById(linkTarget.dataset.target);
if (!formElement.disabled) {
formElement.value = this.getDateUtils().format(linkTarget.dataset.format, null);
// this should usually work
formElement.dispatchEvent(new Event('change', {bubbles: true}));
// this is required for Litepicker to pick the new date (with autoRefresh option)
formElement.dispatchEvent(new Event('keyup', {bubbles: true}));
}
event.preventDefault();
};
}
element.addEventListener('click', this._eventHandler);
}
});
}
/**
* @param {HTMLFormElement} form
*/
destroyForm(form)
{
[].slice.call(form.querySelectorAll(this.selector)).map((element) => {
if (element.dataset.format !== undefined && element.dataset.target !== undefined) {
element.removeEventListener('click', this._eventHandler);
}
});
}
}

View File

@@ -0,0 +1,129 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiDatePicker: single date selects (currently unused)
*/
import { Litepicker } from 'litepicker';
import 'litepicker/dist/plugins/mobilefriendly';
import KimaiFormPlugin from "./KimaiFormPlugin";
export default class KimaiDatePicker extends KimaiFormPlugin {
constructor(selector)
{
super();
this._selector = selector;
}
init()
{
window.disableLitepickerStyles = true;
this._pickers = [];
}
/**
* @param {HTMLFormElement} form
* @return boolean
*/
supportsForm(form) // eslint-disable-line no-unused-vars
{
return true;
}
/**
* @param {HTMLFormElement} form
*/
activateForm(form)
{
const FIRST_DOW = this.getConfigurations().getFirstDayOfWeek(false);
const LANGUAGE = this.getConfigurations().getLanguage();
let options = {
buttonText: {
previousMonth: `<i class="fas fa-chevron-left"></i>`,
nextMonth: `<i class="fas fa-chevron-right"></i>`,
apply: this.translate('confirm'),
cancel: this.translate('cancel'),
},
};
const newPickers = [].slice.call(form.querySelectorAll(this._selector)).map((element) => {
if (element.dataset.format === undefined) {
console.log('Trying to bind litepicker to an element without data-format attribute');
}
if (element.hasAttribute('min') !== undefined) {
options = {...options, ...{
'minDate': element.getAttribute('min'),
}};
}
if (element.hasAttribute('max') !== undefined) {
options = {...options, ...{
'maxDate': element.getAttribute('max'),
}};
}
options = {...options, ...{
format: element.dataset.format,
showTooltip: false,
element: element,
lang: LANGUAGE,
autoRefresh: true,
firstDay: FIRST_DOW, // Litepicker: 0 = Sunday, 1 = Monday
setup: (picker) => {
// nasty hack, because litepicker does not trigger change event on the input and the available
// event "selected" is triggered way to often, even when moving the cursor inside the input
// element (not even typing is necessary) and so we have to make sure that the manual "click" event
// (works for touch as well) happened before we actually dispatch the change event manually ...
// what? report forms would be submitted upon cursor move without the "preselect” check
picker.on('preselect', (date1, date2) => { // eslint-disable-line no-unused-vars
picker._wasPreselected = true;
});
picker.on('selected', (date1, date2) => { // eslint-disable-line no-unused-vars
if (picker._wasPreselected !== undefined) {
element.dispatchEvent(new Event('change', {bubbles: true}));
delete picker._wasPreselected;
}
});
// only if mobile.friendly plugin is activated
if (picker.backdrop !== undefined) {
// the node needs to be moved, so the flat form layout works properly (e.g. for date types)
document.body.appendChild(picker.backdrop);
}
},
}};
return [element, new Litepicker(this.prepareOptions(options))];
});
this._pickers = this._pickers.concat(newPickers);
}
prepareOptions(options)
{
return {...options, ...{
plugins: ['mobilefriendly'],
}};
}
/**
* @param {HTMLFormElement} form
*/
destroyForm(form)
{
[].slice.call(form.querySelectorAll(this._selector)).map((element) => {
for (let i = 0; i < this._pickers.length; i++) {
if (this._pickers[i][0] === element) {
this._pickers[i][1].destroy();
this._pickers.splice(i, 1);
}
}
});
}
}

View File

@@ -0,0 +1,25 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiDateRangePicker: activate the (daterange picker) compound field in toolbar
*/
import KimaiDatePicker from "./KimaiDatePicker";
export default class KimaiDateRangePicker extends KimaiDatePicker {
prepareOptions(options)
{
return {...options, ...{
plugins: ['mobilefriendly'],
singleMode: false,
autoRefresh: true,
}};
}
}

View File

@@ -0,0 +1,39 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiFormPlugin: base class for all none ID plugin that handle forms
*/
import KimaiPlugin from '../KimaiPlugin';
export default class KimaiFormPlugin extends KimaiPlugin {
/**
* @param {HTMLFormElement} form
* @return boolean
*/
supportsForm(form) // eslint-disable-line no-unused-vars
{
return false;
}
/**
* @param {HTMLFormElement} form
*/
activateForm(form) // eslint-disable-line no-unused-vars
{
}
/**
* @param {HTMLFormElement} form
*/
destroyForm(form) // eslint-disable-line no-unused-vars
{
}
}

View File

@@ -0,0 +1,564 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiFormSelect: enhanced functionality for HTMLSelectElement
*/
import TomSelect from 'tom-select';
import KimaiFormTomselectPlugin from "./KimaiFormTomselectPlugin";
export default class KimaiFormSelect extends KimaiFormTomselectPlugin {
constructor(selector, apiSelects)
{
super();
this._selector = selector;
this._apiSelects = apiSelects;
}
getId()
{
return 'form-select';
}
init()
{
// selects the original value inside dropdowns, as the "reset" event (the updated option)
// is not automatically propagated to the JS element
document.addEventListener('reset', (event) => {
if (event.target.tagName.toUpperCase() === 'FORM') {
setTimeout(() => {
const fields = event.target.querySelectorAll(this._selector);
for (let field of fields) {
if (field.tagName.toUpperCase() === 'SELECT') {
field.dispatchEvent(new Event('data-reloaded'));
}
}
}, 10);
}
});
}
/**
* @param {HTMLFormElement} node
*/
activateSelectPickerByElement(node)
{
let plugins = ['change_listener'];
const isMultiple = node.multiple !== undefined && node.multiple === true;
const isRequired = node.required !== undefined && node.required === true;
if (isRequired) {
plugins.push('no_backspace_delete');
}
if (isMultiple) {
plugins.push('remove_button');
}
if (node.dataset['order'] !== undefined && node.dataset['order'] === '1') {
//plugins.push('caret_position');
plugins.push('drag_drop');
}
let options = {
// see https://github.com/orchidjs/tom-select/issues/543#issuecomment-1664342257
onItemAdd: function(){
// remove remaining characters from input after selecting an item
this.setTextboxValue('');
},
lockOptgroupOrder: true,
allowEmptyOption: !isRequired,
hidePlaceholder: false,
plugins: plugins,
// if there are more than X entries, the other ones are hidden and can only be found
// by typing some characters to trigger the internal option search
// see App\Form\Type\TagsType::MAX_AMOUNT_SELECT
// TODO make this value configurable with a data attribute
maxOptions: 500,
sortField:[{field: '$order'}, {field: '$score'}],
// required so it works in table.responsive, but requires z-index 1056, because bootstrap modal would otherwise hide it
dropdownParent: 'body',
};
let render = {
onOptionAdd: (value) => {
node.dispatchEvent(new CustomEvent('create', {detail: {'value': value}}));
},
};
const rendererType = (node.dataset['renderer'] !== undefined) ? node.dataset['renderer'] : 'default';
options.render = {...render, ...this.getRenderer(rendererType)};
if (node.dataset['create'] !== undefined) {
options = {...options, ...{
persist: true,
create: true,
}};
} else {
options = {...options, ...{
persist: false,
create: false,
}};
}
if (node.dataset.disableSearch !== undefined) {
options = {...options, ...{
controlInput: null,
}};
}
const select = new TomSelect(node, options);
node.addEventListener('data-reloaded', (event) => {
select.clear(true);
select.clearOptionGroups();
select.clearOptions();
select.sync();
select.setValue(event.detail);
select.refreshItems();
select.refreshOptions(false);
});
// support reloading the list upon external event
if (node.dataset['reload'] !== undefined) {
node.addEventListener('reload', () => {
select.disable();
node.disabled = true;
/** @type {KimaiAPI} API */
const API = this.getContainer().getPlugin('api');
API.get(node.dataset['reload'], {}, (data) => {
this._updateSelect(node, data);
select.enable();
node.disabled = false;
});
node.dispatchEvent(new Event('change'));
});
}
}
/**
* @param {HTMLFormElement} form
* @return boolean
*/
supportsForm(form) // eslint-disable-line no-unused-vars
{
return true;
}
/**
* @param {HTMLFormElement} form
*/
activateForm(form)
{
[].slice.call(form.querySelectorAll(this._selector)).map((node) => {
this.activateSelectPickerByElement(node);
});
this._activateApiSelects(this._apiSelects);
}
/**
* @param {HTMLFormElement} form
*/
destroyForm(form)
{
[].slice.call(form.querySelectorAll(this._selector)).map((node) => {
if (node.tomselect) {
node.tomselect.destroy();
}
});
}
/**
* @param {string|Element} selectIdentifier
* @param {object} data
* @private
*/
_updateOptions(selectIdentifier, data)
{
let emptyOption = null;
let node = null;
if (selectIdentifier instanceof Element) {
node = selectIdentifier;
} else {
node = document.querySelector(selectIdentifier);
}
if (node === null) {
console.log('Missing select: ' + selectIdentifier);
return;
}
const selectedValue = node.value;
for (let i = 0; i < node.options.length; i++) {
if (node.options[i].value === '') {
emptyOption = node.options[i];
}
}
node.options.length = 0;
if (emptyOption !== null) {
node.appendChild(this._createOption(emptyOption.text, ''));
}
let emptyOpts = [];
let options = [];
/** @type {string|null} titlePattern */
let titlePattern = null;
if (node.dataset !== undefined && node.dataset['optionPattern'] !== undefined) {
titlePattern = node.dataset['optionPattern'];
}
if (titlePattern === null || titlePattern === '') {
titlePattern = '{name}';
}
for (const [key, value] of Object.entries(data)) {
if (key === '__empty__') {
for (const entity of value) {
emptyOpts.push(this._createOption(this._getTitleFromPattern(titlePattern, entity), entity.id));
}
continue;
}
let optGroup = this._createOptgroup(key);
for (const entity of value) {
optGroup.appendChild(this._createOption(this._getTitleFromPattern(titlePattern, entity), entity.id));
}
options.push(optGroup);
}
// log the one with a group name first (e.g. non-global activities)
options.forEach(child => node.appendChild(child));
// append the ones with no parent at the end (e.g. global activities)
const optGroupEmpty = this._createOptgroup('');
emptyOpts.forEach(child => optGroupEmpty.appendChild(child));
node.appendChild(optGroupEmpty);
// if available, re-select the previous selected option (mostly usable for global activities)
node.value = selectedValue;
// pre-select an option if it is the only available one
if (node.value === '' || node.value === null) {
const allOptions = node.options;
const optionLength = allOptions.length;
let selectOption = '';
if (optionLength === 1 && node.dataset['autoselect'] === undefined) {
selectOption = allOptions[0].value;
} else if (optionLength === 2 && emptyOption !== null) {
selectOption = allOptions[1].value;
}
if (selectOption !== '') {
node.value = selectOption;
}
}
// this will update the attached javascript component
node.dispatchEvent(new CustomEvent('data-reloaded', {detail: node.value}));
// if we don't trigger the change, the other selects won't reset
node.dispatchEvent(new Event('change'));
}
/**
* @param {string} pattern
* @param {array} entity
* @private
*/
_getTitleFromPattern(pattern, entity)
{
const DATE_UTILS = this.getDateUtils();
const regexp = new RegExp('{[^}]*?}','g');
let title = pattern;
let match = null;
while ((match = regexp.exec(pattern)) !== null) {
// cutting a string like "{name}" into "name"
const field = match[0].slice(1, -1);
let value = entity[field] === undefined ? null : entity[field];
if ((field === 'start' || field === 'end')) {
if (value === null) {
value = '?';
} else {
value = DATE_UTILS.getFormattedDate(value);
}
}
title = title.replace(new RegExp('{' + field + '}', 'g'), value ?? '');
}
title = title.replace(/- \?-\?/, '');
title = title.replace(/\r\n|\r|\n/g, ' ');
title = title.substring(0, 110);
const chars = '- ';
let start = 0, end = title.length;
while (start < end && chars.indexOf(title[start]) >= 0) {
++start;
}
while (end > start && chars.indexOf(title[end - 1]) >= 0) {
--end;
}
let result = (start > 0 || end < title.length) ? title.substring(start, end) : title;
if (result === '' && entity['name'] !== undefined) {
return entity['name'];
}
return result;
}
/**
* @param {HTMLSelectElement} select
* @param {string} label
* @param {string} value
* @param {object} dataset
*/
addOption(select, label, value, dataset)
{
const option = this._createOption(label, value);
for (const key in dataset) {
option.dataset[key] = dataset[key];
}
select.options.add(option);
if (select.tomselect !== undefined) {
select.tomselect.sync();
}
}
/**
*
* @param {HTMLSelectElement} select
* @param {HTMLOptionElement} option
*/
removeOption(select, option)
{
option.remove();
if (select.tomselect !== undefined) {
select.tomselect.removeOption(option.value, true);
select.tomselect.clear(true);
}
}
/**
* @param {string} label
* @param {string} value
* @returns {HTMLElement}
* @private
*/
_createOption(label, value)
{
let option = document.createElement('option');
option.innerText = label;
option.value = value;
return option;
}
/**
* @param {string} label
* @returns {HTMLElement}
* @private
*/
_createOptgroup(label)
{
let optGroup = document.createElement('optgroup');
optGroup.label = label;
return optGroup;
}
/**
* @param {string} selector
* @private
*/
_activateApiSelects(selector)
{
if (this._eventHandlerApiSelects === undefined) {
this._eventHandlerApiSelects = (event) => {
if (event.target === null || !event.target.matches(selector)) {
return;
}
const apiSelect = event.target;
const targetSelectId = '#' + apiSelect.dataset['relatedSelect'];
/** @type {HTMLSelectElement} targetSelect */
const targetSelect = document.getElementById(apiSelect.dataset['relatedSelect']);
// if the related target select does not exist, we do not need to load the related data
if (targetSelect === null || targetSelect.dataset['reloading'] === '1') {
return;
}
targetSelect.dataset['reloading'] = '1';
if (targetSelect.tomselect !== undefined) {
targetSelect.tomselect.disable();
}
targetSelect.disabled = true;
let formPrefix = apiSelect.dataset['formPrefix'];
if (formPrefix === undefined || formPrefix === null) {
formPrefix = '';
} else if (formPrefix.length > 0) {
formPrefix += '_';
}
let newApiUrl = this._buildUrlWithFormFields(apiSelect.dataset['apiUrl'], formPrefix);
const selectValue = apiSelect.value;
// Problem: select a project with activities and then select a customer that has no project
// results in a wrong URL, it triggers "activities?project=" instead of using the "emptyUrl"
if (selectValue === undefined || selectValue === null || selectValue === '' || (Array.isArray(selectValue) && selectValue.length === 0)) {
if (apiSelect.dataset['emptyUrl'] === undefined) {
this._updateSelect(targetSelectId, {});
targetSelect.dataset['reloading'] = '0';
return;
}
newApiUrl = this._buildUrlWithFormFields(apiSelect.dataset['emptyUrl'], formPrefix);
}
/** @type {KimaiAPI} API */
const API = this.getContainer().getPlugin('api');
API.get(newApiUrl, {}, (data) => {
this._updateSelect(targetSelectId, data);
if (targetSelect.tomselect !== undefined) {
targetSelect.tomselect.enable();
}
targetSelect.dataset['reloading'] = '0';
targetSelect.disabled = false;
});
};
document.addEventListener('change', this._eventHandlerApiSelects);
}
}
/**
* @param {string} apiUrl
* @param {string} formPrefix
* @return {string}
* @private
*/
_buildUrlWithFormFields(apiUrl, formPrefix)
{
let newApiUrl = apiUrl;
apiUrl.split('?')[1].split('&').forEach(item => {
const [key, value] = item.split('='); // eslint-disable-line no-unused-vars
const decoded = decodeURIComponent(value);
const test = decoded.match(/%(.*)%/);
if (test !== null) {
const originalFieldName = test[1];
const targetFieldName = (formPrefix + originalFieldName).replace(/\[/, '').replace(/]/, '');
const targetField = document.getElementById(targetFieldName);
let newValue = '';
if (targetField === null) {
// happens for example:
// - in duration only mode, when the end field is not found
// console.log('ERROR: Cannot find field with name "' + test[1] + '" by selector: #' + formPrefix + test[1]);
} else {
if (targetField.value !== null) {
newValue = targetField.value;
if (targetField.tagName === 'SELECT' && targetField.multiple) {
newValue = [...targetField.selectedOptions].map(o => o.value);
} else if (newValue !== '') {
if (targetField.type === 'date') {
const timeId = targetField.id.replace('_date', '_time');
const timeElement = document.getElementById(timeId);
const time = timeElement === null ? '12:00:00' : timeElement.value;
// using 12:00 as fallback, because timezone handling might change the date if we use 00:00
const newDate = this.getDateUtils().fromHtml5Input(newValue, time);
newValue = this.getDateUtils().formatForAPI(newDate, false);
} else if (targetField.type === 'text' && targetField.name.includes('date')) {
const timeId = targetField.id.replace('_date', '_time');
const timeElement = document.getElementById(timeId);
// using 12:00 as fallback, because timezone handling might change the date if we use 00:00
let time = '12:00:00';
let timeFormat = 'HH:mm';
if (timeElement !== null) {
time = timeElement.value;
timeFormat = timeElement.dataset['format'];
}
const newDate = this.getDateUtils().fromFormat(newValue.trim() + ' ' + time.trim(), targetField.dataset['format'] + ' ' + timeFormat);
newValue = this.getDateUtils().formatForAPI(newDate, false);
} else if (targetField.dataset['format'] !== undefined) {
// find out when this else branch is triggered and document!
if (this.getDateUtils().isValidDateTime(newValue, targetField.dataset['format'])) {
newValue = this.getDateUtils().format(targetField.dataset['format'], newValue);
}
}
} else {
// happens for example:
// - when the end date is not set on a timesheet record and the project list is loaded (as the URL contains the %end% replacer)
// console.log('Empty value found for field with name "' + test[1] + '" by selector: #' + formPrefix + test[1]);
}
} else {
// happens for example:
// - when a customer without projects is selected
// console.log('ERROR: Empty field with name "' + test[1] + '" by selector: #' + formPrefix + test[1]);
}
}
if (Array.isArray(newValue)) {
let urlParams = [];
for (let tmpValue of newValue) {
if (tmpValue === null) {
tmpValue = '';
}
urlParams.push(originalFieldName + '=' + tmpValue);
}
newApiUrl = newApiUrl.replace(item, urlParams.join('&'));
} else {
if (newValue === null) {
newValue = '';
}
newApiUrl = newApiUrl.replace(value, newValue);
}
}
});
return newApiUrl;
}
/**
* @param {string|Element} select
* @param {object} data
* @private
*/
_updateSelect(select, data)
{
const options = {};
for (const apiData of data) {
let title = '__empty__';
if (apiData['parentTitle'] !== undefined && apiData['parentTitle'] !== null) {
title = apiData['parentTitle'];
}
if (options[title] === undefined) {
options[title] = [];
}
options[title].push(apiData);
}
const ordered = {};
Object.keys(options).sort().forEach(function(key) {
ordered[key] = options[key];
});
this._updateOptions(select, ordered);
}
}

View File

@@ -0,0 +1,80 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiFormTomselectPlugin: base form plugin for everyone using tomselect
*/
import KimaiFormPlugin from './KimaiFormPlugin';
export default class KimaiFormTomselectPlugin extends KimaiFormPlugin {
/**
* @param {string} rendererType
* @return array
*/
getRenderer(rendererType)
{
// default renderer
let render = {
option_create: (data, escape) => {
const name = escape(data.input);
if (name.length < 3) {
return null;
}
const tpl = this.translate('select.search.create');
const tplReplaced = tpl.replace('%input%', '<strong>' + name + '</strong>');
return '<div class="create">' + tplReplaced + '</div>';
},
no_results: (data, escape) => {
const tpl = this.translate('select.search.notfound');
const tplReplaced = tpl.replace('%input%', '<strong>' + escape(data.input) + '</strong>');
return '<div class="no-results">' + tplReplaced + '</div>';
},
};
if (rendererType === 'color') {
render = {...render, ...{
option: function(data, escape) {
let item = '<div class="list-group-item border-0 p-1 ps-2 text-nowrap">';
// if no color is set, do NOT add an empty placeholder
if (data.color !== undefined) {
item += '<span style="background-color:' + data.color + '" class="color-choice-item me-2">&nbsp;</span>';
}
item += escape(data.text) + '</div>';
return item;
},
item: function(data, escape) {
let item = '<div class="text-nowrap">';
// if no color is set, do NOT add an empty placeholder
if (data.color !== undefined) {
item += '<span style="background-color:' + data.color + '" class="color-choice-item me-2">&nbsp;</span>';
}
item += escape(data.text) + '</div>';
return item;
}
}};
} else {
render = {...render, ...{
// the empty entry would collapse and only show as a tiny 5px line if there is no content inside
option: function(data, escape) {
let text = data.text;
if (text === null || text.trim() === '') {
text = '&nbsp;';
} else {
text = escape(text);
}
return '<div>' + text + '</div>';
}
}};
}
return render;
}
}

View File

@@ -0,0 +1,147 @@
/*
* 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.
*/
/*!
* [KIMAI] KimaiEditTimesheetForm: responsible for the most important form in the application
*/
import KimaiFormPlugin from "./KimaiFormPlugin";
import KimaiColor from "../widgets/KimaiColor";
export default class KimaiTeamForm extends KimaiFormPlugin {
init()
{
this.usersId = 'team_edit_form_users';
}
/**
* @param {HTMLFormElement} form
* @return boolean
*/
supportsForm(form)
{
return form.name === 'team_edit_form';
}
/**
* @return {HTMLElement}
* @private
*/
_getPrototype()
{
return document.getElementById('team_edit_form_members');
}
/**
* @param {HTMLFormElement} form
*/
activateForm(form)
{
if (!this.supportsForm(form)) {
return;
}
// must be attached to the form, because the button is added dynamically
form.addEventListener('click', event => this._removeMember(event));
document.getElementById(this.usersId).addEventListener('change', event => {
const select = event.target;
const option = select.options[select.selectedIndex];
const member = this._createMember(option);
this._getPrototype().append(member);
this.getPlugin('form-select').removeOption(select, option);
});
}
/**
* @param {HTMLOptionElement} option
* @returns {Element}
* @private
*/
_createMember(option)
{
/** @type {KimaiEscape} ESCAPER */
const ESCAPER = this.getPlugin('escape');
const prototype = this._getPrototype();
let counter = prototype.dataset['widgetCounter'] || prototype.childNodes.length;
let newWidget = prototype.dataset['prototype'];
newWidget = newWidget.replace(/__name__/g, counter);
newWidget = newWidget.replace(/#000000/g, KimaiColor.calculateContrastColor(option.dataset.color));
newWidget = newWidget.replace(/__DISPLAY__/g, ESCAPER.escapeForHtml(option.dataset.display));
newWidget = newWidget.replace(/__COLOR__/g, option.dataset.color);
newWidget = newWidget.replace(/__INITIALS__/g, ESCAPER.escapeForHtml(option.dataset.initials));
newWidget = newWidget.replace(/__TITLE__/g, ESCAPER.escapeForHtml(option.dataset.title));
newWidget = newWidget.replace(/__USERNAME__/g, ESCAPER.escapeForHtml(option.text));
prototype.dataset['widgetCounter'] = (++counter).toString();
const temp = document.createElement('div');
temp.innerHTML = newWidget;
temp.querySelector('input[type=hidden]').value = option.value;
const newNode = temp.firstElementChild;
// copy over all initial settings, so we are able to rebuild the original option if the
// member is removed from the list later on
for (const key in option.dataset) {
newNode.dataset[key] = option.dataset[key];
}
return newNode;
}
/**
* @param {Event} event
* @private
*/
_removeMember(event)
{
let button = event.target;
if (button.parentNode.matches('.remove-member')) {
button = button.parentNode;
}
if (button.matches('.remove-member')) {
// see blocks.html.twig => block team_member_widget
const element = button.parentNode.parentNode.parentNode.parentNode.parentNode;
// re-adding the option to the select makes up for form validation errors
// because the list would have to be re-ordered and indices need to be changed ...
/*
this.getPlugin('form-select').addOption(
document.getElementById(this.usersId),
element.dataset['display'],
element.dataset['id'],
element.dataset
);
const prototype = this._getPrototype();
prototype.dataset['widgetCounter'] = (prototype.dataset['widgetCounter'] - 1).toString();
*/
element.remove();
event.stopPropagation();
event.preventDefault();
}
}
/**
* @param {HTMLFormElement} form
*/
destroyForm(form)
{
if (!this.supportsForm(form)) {
return;
}
form.removeEventListener('click', this._removeMember);
}
}

Some files were not shown because too many files have changed in this diff Show More