Merge branch 'dev' of https://git.odit.services/lfk/frontend into dev
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
commit
3837c5673a
|
@ -54,7 +54,7 @@ steps:
|
|||
tags:
|
||||
- dev
|
||||
registry: registry.odit.services
|
||||
|
||||
mtu: 1000
|
||||
trigger:
|
||||
branch:
|
||||
- dev
|
||||
|
|
363
CHANGELOG.md
363
CHANGELOG.md
|
@ -2,8 +2,370 @@
|
|||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [0.8.0](https://git.odit.services/lfk/frontend/compare/0.7.0...0.8.0)
|
||||
|
||||
- new license file version [CI SKIP] [`579ece6`](https://git.odit.services/lfk/frontend/commit/579ece625651c8bf37b5704e82264a8833811f68)
|
||||
- Merge pull request 'User settings feature/103-settings_page' (#104) from feature/103-settings_page into dev [`822e97d`](https://git.odit.services/lfk/frontend/commit/822e97d3c35be57ecf9ed6bd6af474fd89e7d8d8)
|
||||
- Sorted translations🌍 [`120d3c9`](https://git.odit.services/lfk/frontend/commit/120d3c9dc81a0878d0dd64b66caadc6201651bda)
|
||||
- Translated headers [`01eba88`](https://git.odit.services/lfk/frontend/commit/01eba88adfd7cced75e828427494cb99fdf01d70)
|
||||
- Implemented change detection [`37bc5ff`](https://git.odit.services/lfk/frontend/commit/37bc5ff17b8f97dfc76962435f9cb64156848c82)
|
||||
- Added new profile deletion modal [`13b557a`](https://git.odit.services/lfk/frontend/commit/13b557aba89378af40e2f9feb5f90a1c582aea91)
|
||||
- Implemented the password change logic [`24b9898`](https://git.odit.services/lfk/frontend/commit/24b98983cf964fe2b5594e20b22c63e97ada3166)
|
||||
- The settings page now boasts your profile picture [`e459bb0`](https://git.odit.services/lfk/frontend/commit/e459bb04cc3fcdc5d176e53b764ad3e995d66762)
|
||||
- Added inputs for password update [`5d7eb69`](https://git.odit.services/lfk/frontend/commit/5d7eb690e4f2be0d389c785abe73c137cf25c29c)
|
||||
- Added delete Profile button [`418f9c2`](https://git.odit.services/lfk/frontend/commit/418f9c2662531b997699e8db05e21da394025688)
|
||||
- Implemented profile updates [`3a4575f`](https://git.odit.services/lfk/frontend/commit/3a4575f25148c74878c978e5cf9885ad12101f00)
|
||||
- Added translations 🌍 [`3945f3c`](https://git.odit.services/lfk/frontend/commit/3945f3cf3862369ff179379d76090b1e2d78b417)
|
||||
- Its translation time 🌍 [`5de0fd7`](https://git.odit.services/lfk/frontend/commit/5de0fd792f15241a4a49eda575bc8f23ba6c6974)
|
||||
- Fixed delete_triggered not getting reset [`e76e5ab`](https://git.odit.services/lfk/frontend/commit/e76e5abcf87883602002fb5687a3fd7b95f24793)
|
||||
- Added deletion confirmation modal [`716b728`](https://git.odit.services/lfk/frontend/commit/716b72880ad7468694affaf5549b2d34186294b6)
|
||||
- Added translations [`e76854c`](https://git.odit.services/lfk/frontend/commit/e76854c23be9d909c35a61f8f8e65f743ccf3ec4)
|
||||
- Added translations🌍 [`34dfc9a`](https://git.odit.services/lfk/frontend/commit/34dfc9add670040e2308964ed8c81d3a99f11f0d)
|
||||
- Added hint to the logout after password update [`0b6134d`](https://git.odit.services/lfk/frontend/commit/0b6134dd8093427ec15e55d805dae3b18dc55c6d)
|
||||
- Added missing translation [`44d6cba`](https://git.odit.services/lfk/frontend/commit/44d6cba403c117b1b76ecad32fbc4c2bd02a8cc3)
|
||||
- Updated old endpoints [`178c257`](https://git.odit.services/lfk/frontend/commit/178c2579d56c3e78e947e658a5c3afe367c3e8ce)
|
||||
- Settings - rouded corners on password change [`e0ae2ec`](https://git.odit.services/lfk/frontend/commit/e0ae2ec42b89271282e3e96e41de38afd08aa229)
|
||||
- Now force reloading to log out [`342a95d`](https://git.odit.services/lfk/frontend/commit/342a95ddbeceac2cf3547462a9b1996ecd7dba61)
|
||||
- Removed useless debug info 🐞 [`bef180f`](https://git.odit.services/lfk/frontend/commit/bef180f4ba7aaf252d87efc789eb53fb75abbdf1)
|
||||
- Bumped lfk client js version [`50be992`](https://git.odit.services/lfk/frontend/commit/50be992b72dd71eb2c756b1bf6f2d606344fe7ca)
|
||||
- Now showing logo as default profile pic [`d00f46e`](https://git.odit.services/lfk/frontend/commit/d00f46eee1fd28095064f50620c15ac648f331b9)
|
||||
- Moved settings to their own folder [`016fba5`](https://git.odit.services/lfk/frontend/commit/016fba527910b95eb2690207bbede91004d2f2d9)
|
||||
- Now also resetting postdata (prevent against password leaks) [`859f6e2`](https://git.odit.services/lfk/frontend/commit/859f6e25675362ee2ef5553255e3dc9e3040672c)
|
||||
|
||||
#### [0.7.0](https://git.odit.services/lfk/frontend/compare/0.6.0...0.7.0)
|
||||
|
||||
> 19 March 2021
|
||||
|
||||
- Merge pull request 'feature/62-contract-generation' (#76) from feature/62-contract-generation into dev [`#62`](https://git.odit.services/lfk/frontend/issues/62)
|
||||
- Merge pull request 'Small bugfixes - feature/64-dialog_clearing_bug' (#75) from feature/64-dialog_clearing_bug into dev [`#64`](https://git.odit.services/lfk/frontend/issues/64)
|
||||
- Fixed non-automatic logout [`#38`](https://git.odit.services/lfk/frontend/issues/38)
|
||||
- Merge pull request 'feature/69-translation-keys' (#74) from feature/69-translation-keys into dev [`#69`](https://git.odit.services/lfk/frontend/issues/69)
|
||||
- Merge pull request 'feature/50-contact-management' (#67) from feature/50-contact-management into dev [`#50`](https://git.odit.services/lfk/frontend/issues/50)
|
||||
- 🚀RELEASE v0.7.0 [`da5d62a`](https://git.odit.services/lfk/frontend/commit/da5d62ae03bbd057f52473ec047e09067e3715a3)
|
||||
- Ordered locales [`0f93feb`](https://git.odit.services/lfk/frontend/commit/0f93febd866b0117d7bdf6149c2e8b94f801b1b5)
|
||||
- Added missing translation [`918bb94`](https://git.odit.services/lfk/frontend/commit/918bb946446608ecebf3e388607068f7aa48e105)
|
||||
- Sorted translations [`eff2050`](https://git.odit.services/lfk/frontend/commit/eff205095915e3f9bf9dd2f746e5245015740ca5)
|
||||
- Sorted translations 🌎🌍 [`5f6ee33`](https://git.odit.services/lfk/frontend/commit/5f6ee33e2bcabc007bba340ef51bc28f707aa58d)
|
||||
- Added language keys🌎 [`60aa919`](https://git.odit.services/lfk/frontend/commit/60aa919b141d26853300db28ab20a6fe41c3f0b6)
|
||||
- Sorted translations 🌎 [`16d0dba`](https://git.odit.services/lfk/frontend/commit/16d0dbab5bb587cb859c30e04321fb5758455f80)
|
||||
- Translated missing german stuff 🌍 [`e4b80c9`](https://git.odit.services/lfk/frontend/commit/e4b80c9ab34d31ec31df55904eacfac2c8728b10)
|
||||
- Added translation keys [`880d722`](https://git.odit.services/lfk/frontend/commit/880d722912fbb8aa7b383f3a7f4e04b639287c3f)
|
||||
- Added german translations [`d4d8470`](https://git.odit.services/lfk/frontend/commit/d4d847059af0a02a67e1759812b420f92609f517)
|
||||
- Working add fixed/normal switch [`5d2025a`](https://git.odit.services/lfk/frontend/commit/5d2025aa43f6c4bc4c8f792be22fcec07edd37b9)
|
||||
- Added basic donation detail [`88ade26`](https://git.odit.services/lfk/frontend/commit/88ade26ef7b112a777af2c7efc10088f79b8f04e)
|
||||
- Added basic overview with emptystate [`f1ceef0`](https://git.odit.services/lfk/frontend/commit/f1ceef05fca603f76480df47623941a4ec6a18d1)
|
||||
- Finished group creation modal [`d2193bf`](https://git.odit.services/lfk/frontend/commit/d2193bf428d021328f407e6be1e661b582fd2a1d)
|
||||
- Added basic donation overview [`8d89d15`](https://git.odit.services/lfk/frontend/commit/8d89d158d11874369265ba668967762d4ee20dd8)
|
||||
- Donors now get their donations linked in the donor detail [`3aea259`](https://git.odit.services/lfk/frontend/commit/3aea259e415e21f99602bc4e4bfc8cb633d68ab9)
|
||||
- Fixed text size mismatch [`3d51ba0`](https://git.odit.services/lfk/frontend/commit/3d51ba0dc2da65e826bdbb29a6da11ba07078139)
|
||||
- Applied the select fix to all things runner 🏃♀️🏃♂️ [`0386d4e`](https://git.odit.services/lfk/frontend/commit/0386d4e88ab57457fa981399627b2b61f38bb1ae)
|
||||
- Now the saveing button even worx :O [`63e0249`](https://git.odit.services/lfk/frontend/commit/63e02492e81e3ee02386d3e4363d3ae20125aa8b)
|
||||
- Switched import modal over to svelte select [`bd3ea72`](https://git.odit.services/lfk/frontend/commit/bd3ea721c301bf6ef67ef4e1e27ca73e799e1a35)
|
||||
- Switched the scanstation detail over to svelte select👀👀 [`b1031e3`](https://git.odit.services/lfk/frontend/commit/b1031e3115ce03ee68e10f3240f8e829f3f7cfde)
|
||||
- Switched the scanstation modal over to svelte select👀👀 [`64c96f2`](https://git.odit.services/lfk/frontend/commit/64c96f25d4a9277df431011f4660b59a2eb0a9da)
|
||||
- Fixed select bug for sponsoring detail 🛠 [`64311e9`](https://git.odit.services/lfk/frontend/commit/64311e96528e0b023892170b5541652cc22f176b)
|
||||
- Added missing translation keys [`c96a21c`](https://git.odit.services/lfk/frontend/commit/c96a21cf9990a80ec2571366a40116a9d5d64549)
|
||||
- Fixed runner group update recognition being weired [`b009501`](https://git.odit.services/lfk/frontend/commit/b009501a533e6ebfa79dde4c48554c99ee53c9c2)
|
||||
- Fixed runner group update recognition being weired [`ee49e78`](https://git.odit.services/lfk/frontend/commit/ee49e78dcd34b0d22c3e3c16ed8e0eb8805ea4c8)
|
||||
- Donors now get their donations linked in the donor overview [`0f64767`](https://git.odit.services/lfk/frontend/commit/0f64767437626e90adaa931cb15c491e5bfa76c9)
|
||||
- Fixed load order bug [`c575c73`](https://git.odit.services/lfk/frontend/commit/c575c7376499be07980cb4dbdb7a177e0a18e29c)
|
||||
- Fixed select bug for sponsoring modal 🐞 [`77662b9`](https://git.odit.services/lfk/frontend/commit/77662b9c19bbef57c49471d9326b48656aebf1ff)
|
||||
- Fixed select bug for org detail 🏠 [`82423ec`](https://git.odit.services/lfk/frontend/commit/82423ec46798a354e6f3208b67eac3723f874a4d)
|
||||
- Added new icon for donations [`fa522a8`](https://git.odit.services/lfk/frontend/commit/fa522a85d6215d3f6dd9af05f18dd75fbfb5e0c4)
|
||||
- Formatting [`f09e58c`](https://git.odit.services/lfk/frontend/commit/f09e58c69c4d279f825f756c789db08980be9435)
|
||||
- Bumped non-svelte dev dependencies🔝 [`629aabd`](https://git.odit.services/lfk/frontend/commit/629aabd3a35766b181bebe28a31d531362c0a400)
|
||||
- Added missing language keys [`6109996`](https://git.odit.services/lfk/frontend/commit/6109996adeec808847a72691a9cc3f174285612e)
|
||||
- Added groupoverview to router [`d9eab9f`](https://git.odit.services/lfk/frontend/commit/d9eab9f2547744ae018f6bd20c730ffd289db4c0)
|
||||
- Added the new, shiny badges to donor overview [`b0aca9d`](https://git.odit.services/lfk/frontend/commit/b0aca9de13b5dcfc082a0bd27bfec4a2ef4402cf)
|
||||
- Fixed missing inversion [`a8774fa`](https://git.odit.services/lfk/frontend/commit/a8774fa5242a64783c7fcce476c99e7e82a3d158)
|
||||
- New folder structure [`4dbca60`](https://git.odit.services/lfk/frontend/commit/4dbca6096fa6e0aa6ff3f1a310280cf4e56163b1)
|
||||
- Fixed missing middlename action [`d6c96b7`](https://git.odit.services/lfk/frontend/commit/d6c96b781f33600fd61057e3ddb0cb0b6313a6ee)
|
||||
- Formatting [`a79a87d`](https://git.odit.services/lfk/frontend/commit/a79a87de4c04f685d1209a38cab0a590274c6ded)
|
||||
- Fixed donation badges now show their amount [`fb5a64c`](https://git.odit.services/lfk/frontend/commit/fb5a64c25188cd577196a80613c7aa4851d74bd5)
|
||||
- Added donation route [`ccacdf2`](https://git.odit.services/lfk/frontend/commit/ccacdf274bcd55c3333e56e83081a4957b8f27db)
|
||||
- Formatting [`cd9a546`](https://git.odit.services/lfk/frontend/commit/cd9a5469fd085b1204e9a513bc7e22c6f54532b8)
|
||||
- Enabled add modal [`8042bca`](https://git.odit.services/lfk/frontend/commit/8042bca7ccbfe0782bf875c8dd730d0c8653ff66)
|
||||
- Added custom i18n ally insert format [`1ef1053`](https://git.odit.services/lfk/frontend/commit/1ef1053d3f96a3b2cd584d27781575e329925613)
|
||||
- Now routing stuff to the donation detail [`fd406eb`](https://git.odit.services/lfk/frontend/commit/fd406eb3e6ac6ee41884f7f902895756367bd3b9)
|
||||
- Adjusted togle label font size [`a880ed2`](https://git.odit.services/lfk/frontend/commit/a880ed2b18a1a6ff71f9a95dc1d06242fa4bd613)
|
||||
- DonorDetail accessibility improvements 👀 [`019a029`](https://git.odit.services/lfk/frontend/commit/019a0297a90695fcf1887c4bbf0310d2a81114bd)
|
||||
- Updated donor badege styleing [`247ba40`](https://git.odit.services/lfk/frontend/commit/247ba4030928bcf49e15ee2e7383026c019751e9)
|
||||
- Updated donor badege styleing [`fcf01ba`](https://git.odit.services/lfk/frontend/commit/fcf01ba6772340a82d7f2a703a4e66111e9f13e8)
|
||||
- Removed useless style [`07636f5`](https://git.odit.services/lfk/frontend/commit/07636f51c426121d56ef27309b5f069b39843393)
|
||||
- Renamed button [`1124f25`](https://git.odit.services/lfk/frontend/commit/1124f25ea3b1a2c052e2bd9c4c3480d579a8fc74)
|
||||
- Amount now also self-resetts [`d2430ba`](https://git.odit.services/lfk/frontend/commit/d2430badbe8e07dc0ae0998c9595784be5d1d79e)
|
||||
- Renamed folder [`7d08ea8`](https://git.odit.services/lfk/frontend/commit/7d08ea84660e735031a0511a2862429bb5222b3a)
|
||||
- Merge pull request 'Donation management feature/79-donation_management' (#87) from feature/79-donation_management into dev [`03be2d0`](https://git.odit.services/lfk/frontend/commit/03be2d04923970ecb5b05f5de645a446afe3a245)
|
||||
- Merge pull request 'i18n fix run no.1 feature/69-i18n_fixes' (#85) from feature/69-i18n_fixes into dev [`8b7f5a7`](https://git.odit.services/lfk/frontend/commit/8b7f5a765bcd91207957754747221f05ffdaff4b)
|
||||
- Merge pull request 'Fixed refresh page reload bug' (#86) from feature/82-auth_refresh_bug into dev [`9cd9400`](https://git.odit.services/lfk/frontend/commit/9cd94004fce1847d8adb028bef36b6fb49ff144d)
|
||||
- Sorted translations [`8b70882`](https://git.odit.services/lfk/frontend/commit/8b70882fecd2a0830176074dec504e417923fa50)
|
||||
- Implmented donor deletion confirmation [`264868b`](https://git.odit.services/lfk/frontend/commit/264868bb6afe2066417f9a98091230cadb54ee63)
|
||||
- Error message on pdf generation fail ❌ [`12bcbd2`](https://git.odit.services/lfk/frontend/commit/12bcbd28f3e5672dfb1d34d6eacfd2cc144dd4d1)
|
||||
- i18n translation spree 🌍 [`7fb7ba0`](https://git.odit.services/lfk/frontend/commit/7fb7ba0d2b78065d3d6f1c407b91a0bb9fb832cd)
|
||||
- Added missing translations 🌍 [`a99c022`](https://git.odit.services/lfk/frontend/commit/a99c0226084ceaea1da7a110edf2ab546b797c71)
|
||||
- Implemented donor creation modal [`1b6f866`](https://git.odit.services/lfk/frontend/commit/1b6f86669c01f556e720ab5ba42b57e67a5a963d)
|
||||
- Added donor detail [`cb704c4`](https://git.odit.services/lfk/frontend/commit/cb704c4551bdb46685859ec7901041900acf4c52)
|
||||
- Implemented donor overview and deletion [`02087a5`](https://git.odit.services/lfk/frontend/commit/02087a541e938bfb5286290e12c5557b6b173460)
|
||||
- Some i18n 🌍 [`ca8f978`](https://git.odit.services/lfk/frontend/commit/ca8f9786675952af47f663ac4593f33d35924a1a)
|
||||
- Updated sponsoring logo [`3a57e1c`](https://git.odit.services/lfk/frontend/commit/3a57e1c76624c8ee41757771714970d91db0dddc)
|
||||
- ✨ PDF download from TeamDetail + TeamsOverview [`dbc0ab7`](https://git.odit.services/lfk/frontend/commit/dbc0ab76af0934d3603509e218465378b99cdf63)
|
||||
- basic progress toasts [`a7642c2`](https://git.odit.services/lfk/frontend/commit/a7642c2da410caf662e788951149169af2668afd)
|
||||
- i18n run [`1939300`](https://git.odit.services/lfk/frontend/commit/19393006efd841220295ae588a5dbb67408261ee)
|
||||
- ✨ PDF generation from OrgDetail [`0a55d73`](https://git.odit.services/lfk/frontend/commit/0a55d7314636c1041b63c5a065a69d115890b4b9)
|
||||
- Now the toast hides the generation toast [`ed13a0d`](https://git.odit.services/lfk/frontend/commit/ed13a0d14b42de646e2b9e2c1566ac9c256cc1d3)
|
||||
- Now using translations in org/add/address [`b7d38dd`](https://git.odit.services/lfk/frontend/commit/b7d38dd8493833322f6f1e6634ea2f08a5666fd2)
|
||||
- Now the toast hides the generation toast [`8fa0be7`](https://git.odit.services/lfk/frontend/commit/8fa0be7633f41974e7e2c5e0927449717b88007a)
|
||||
- Added donors to sidebar [`0cc91ac`](https://git.odit.services/lfk/frontend/commit/0cc91ac0373ec1ff1229408a6a0beb43df07244e)
|
||||
- More missing translations 🌍 [`d0a48ab`](https://git.odit.services/lfk/frontend/commit/d0a48ab94b5c281692a7bd935a4eaf11d3b32eb5)
|
||||
- Added missing translations [`2b037d4`](https://git.odit.services/lfk/frontend/commit/2b037d41ac0b972190c9b2c853b42c41f4148c60)
|
||||
- ✨ progress toast in RunnersOverview [`4ece21c`](https://git.odit.services/lfk/frontend/commit/4ece21cdf240f203b710410b3ce9fb716ad12fef)
|
||||
- Fixed missing icon [`bca9605`](https://git.odit.services/lfk/frontend/commit/bca9605d4a0ba56468d91cc4165fe15171e90c9b)
|
||||
- Updated icons [`0321f0e`](https://git.odit.services/lfk/frontend/commit/0321f0e979af8336ab26563f662357e62812a4c7)
|
||||
- ✒ change "Edit" table actions to "Detail" [`289a8c1`](https://git.odit.services/lfk/frontend/commit/289a8c14d335a3cb3c4333725c14c497dc6944a9)
|
||||
- Fixed orgs/teams not being marked as selected on initial modal opening [`44ed633`](https://git.odit.services/lfk/frontend/commit/44ed633cbfee880b0bf7056388d04ede5f50fa47)
|
||||
- Mitigated null error [`396bd22`](https://git.odit.services/lfk/frontend/commit/396bd221996bd21acafddbf1ab87fbf9b378e306)
|
||||
- Fixed known translation mishaps [`02d2413`](https://git.odit.services/lfk/frontend/commit/02d24139e9974f4a8a8a62fd906efac9cabb2459)
|
||||
- Added total dontaion amount to donor detail [`5d945f5`](https://git.odit.services/lfk/frontend/commit/5d945f5bc5bc5c4426da71a18c88a82ce4083f30)
|
||||
- Fixed refresh page reload bug [`c569724`](https://git.odit.services/lfk/frontend/commit/c5697242ee7cef2cb9d2949a10d4efc533684401)
|
||||
- Merge pull request 'Donor management feature/78-donor_mgnt' (#80) from feature/78-donor_mgnt into dev [`ad638e8`](https://git.odit.services/lfk/frontend/commit/ad638e8bc8b3f2179526d6fbd6cdf18ee2524054)
|
||||
- 🖼 new donor empty image [`aec8bf5`](https://git.odit.services/lfk/frontend/commit/aec8bf56a2c03364a353e64a640bae3e8d4540a0)
|
||||
- Formatting [`3e9383e`](https://git.odit.services/lfk/frontend/commit/3e9383e6d9afab2ea06cd8feaff6d52f53e161b9)
|
||||
- Normalized svg [`18335e3`](https://git.odit.services/lfk/frontend/commit/18335e3325ab41caa54f1ff53bfd09bd0f590c2e)
|
||||
- Fixed deletion in detail bug [`f97c2a3`](https://git.odit.services/lfk/frontend/commit/f97c2a36f69d431293ed21d20ff2e8e0782bd53d)
|
||||
- Implemented currency formatting [`1c49755`](https://git.odit.services/lfk/frontend/commit/1c4975589f8ac1c5cd13b7935fb5663adde52615)
|
||||
- Updated donot empty logo [`fffe5c2`](https://git.odit.services/lfk/frontend/commit/fffe5c2c4b384e3626b140a6c807b505b3dd4ae2)
|
||||
- Converted total donation amount to € [`04a09c3`](https://git.odit.services/lfk/frontend/commit/04a09c3ce5e990a50e77ba235dce830983e0ff2d)
|
||||
- Fixed typo [`f63e177`](https://git.odit.services/lfk/frontend/commit/f63e17775c261c994f289f9d0797be3a2c3a6a3e)
|
||||
- Implemented receipt needed [`78514c6`](https://git.odit.services/lfk/frontend/commit/78514c6572793422bfaed0d9b9ee4516a30f7fe7)
|
||||
- Merge pull request 'Mitigated null error' (#77) from feature/64-dialog_clearing_bug into dev [`32024cf`](https://git.odit.services/lfk/frontend/commit/32024cf2c5ade31ec0edd8150ab10e801a70dc44)
|
||||
- 🐞 fixed translation keys [`d67dfdf`](https://git.odit.services/lfk/frontend/commit/d67dfdf2e7ca8f88113377690f794f440d07dd14)
|
||||
- Removed key duplicate from last merge [`5b3e66c`](https://git.odit.services/lfk/frontend/commit/5b3e66c4f6f30d5ea92ac7281cd2c3a17081c9fa)
|
||||
- ✨ translation keys [`a588bc4`](https://git.odit.services/lfk/frontend/commit/a588bc46319a387690a284a2dccca718f194b80b)
|
||||
- ✨ basic select boxes in table [`e8f7c1c`](https://git.odit.services/lfk/frontend/commit/e8f7c1c832037af251d2e3c41600b7c7109fdaa2)
|
||||
- First part of org detail address edit [`e5c31c9`](https://git.odit.services/lfk/frontend/commit/e5c31c9dd43c36d81205e100ded030309296fb5d)
|
||||
- Added address to org creation dialog (styleing only) [`6d2431b`](https://git.odit.services/lfk/frontend/commit/6d2431b683b36a2595a259e69339b8b9fd0c9bdc)
|
||||
- 🐞 fixed bug in OrgDetail address reactivity [`616990b`](https://git.odit.services/lfk/frontend/commit/616990b930cafe4eac57cf771b8b5d722b281218)
|
||||
- Removed unused locales [`722feac`](https://git.odit.services/lfk/frontend/commit/722feac8bd0a4be5214268c0bdb321243a4d602d)
|
||||
- ✨ OrgOverview - multiple pdf download [`40dda11`](https://git.odit.services/lfk/frontend/commit/40dda1150ca8ddc17b1bb64649becab3440bdfad)
|
||||
- Removed unused locales [`4be87a6`](https://git.odit.services/lfk/frontend/commit/4be87a64b9df5a722b3a03893eff64f140f2dc28)
|
||||
- Translated all missing translations 🌍 [`2e3750c`](https://git.odit.services/lfk/frontend/commit/2e3750c87c882c562822cee1615e74b6e84857d9)
|
||||
- ✨ PDF from RunnerDetail [`3b18be5`](https://git.odit.services/lfk/frontend/commit/3b18be58747f204908e0d1065abe66e78d156da6)
|
||||
- 🇩🇪 more german translations [`377d691`](https://git.odit.services/lfk/frontend/commit/377d691053966410da6dfdeb1bf2cb10009a0c0a)
|
||||
- 🐞 fixed bug in Tracks datatable translation keys [`30867b4`](https://git.odit.services/lfk/frontend/commit/30867b4ba1328a405aa3ea20c1043d066f774ee0)
|
||||
- 📃 pdf generation in RunnersOverview [`fa3dc87`](https://git.odit.services/lfk/frontend/commit/fa3dc870d3e114ddca472197d30e1f4178030568)
|
||||
- some more translation keys [`9b0252f`](https://git.odit.services/lfk/frontend/commit/9b0252fb754cceb2c2dd374c0e4f465d6ea67f92)
|
||||
- drop filepond keys [`e90fe73`](https://git.odit.services/lfk/frontend/commit/e90fe73aa25cdc077bed4446a088583126b5bd20)
|
||||
- Implemented detail address add fix [`ec8d946`](https://git.odit.services/lfk/frontend/commit/ec8d946a41c8196bce8556179fa93f0ec47a7507)
|
||||
- reactive button for checkboxes in table [`5e6ada1`](https://git.odit.services/lfk/frontend/commit/5e6ada140ce2722bc67f4c7c10fe95138d7d27f0)
|
||||
- Genered soem runner related keys [`3c541ad`](https://git.odit.services/lfk/frontend/commit/3c541ada89aa9acee805ab0d31f7a68078bc2a69)
|
||||
- Added address to org overview [`bcc7d77`](https://git.odit.services/lfk/frontend/commit/bcc7d7770ebcee95cbc6cfa69841ac15d12bc1a6)
|
||||
- Runner Contact information column npow features address [`57e17f2`](https://git.odit.services/lfk/frontend/commit/57e17f2864765c13ab6cce84ede92a3be8e524fc)
|
||||
- 🌎 i18n [`ff15308`](https://git.odit.services/lfk/frontend/commit/ff15308c037e6800c1bbd43d01617554e98bf2d1)
|
||||
- Fixed privacy/imprint fallback bug [`b195c70`](https://git.odit.services/lfk/frontend/commit/b195c707b05ffa415b50afdf4a532e03340e1ebf)
|
||||
- Formatting [`25ac84e`](https://git.odit.services/lfk/frontend/commit/25ac84e5fddd0927dc4283836a36e0f15615609f)
|
||||
- Fixed clear on import bug [`e53467d`](https://git.odit.services/lfk/frontend/commit/e53467da22dee965f753500c4807fd54b02ec4be)
|
||||
- Fixed clear on import bug [`09d27c0`](https://git.odit.services/lfk/frontend/commit/09d27c0b05634e7e8eefd79fa048c2cb53082abf)
|
||||
- Merge commit 'b337873ca214682487844973104772539956c09a' into feature/48-usergroup-management [`266a11f`](https://git.odit.services/lfk/frontend/commit/266a11f64f073b917ebc7a0c1496d0a48a657e8a)
|
||||
- Merge commit '6d0bca6d6783d3f7bbff5d413b158c6b60720bd8' into feature/48-usergroup-management [`e442b92`](https://git.odit.services/lfk/frontend/commit/e442b92a5f31d2222184aaea55de17d96ccfecbf)
|
||||
- new license file version [CI SKIP] [`afd73d5`](https://git.odit.services/lfk/frontend/commit/afd73d53bee7eb2fd3244caaeb1a9867bff68721)
|
||||
- Merge pull request 'Addresses for orgs and a bunch of bugfixes feature/72-adddress_for_everyone' (#73) from feature/72-adddress_for_everyone into dev [`652e55e`](https://git.odit.services/lfk/frontend/commit/652e55e80e9e7a6c14e7dbeb0ccf6259f11f9368)
|
||||
- Implemented org address creation modal logic [`86f1300`](https://git.odit.services/lfk/frontend/commit/86f13003b5400ba5ea14bcc6bb9b7e7a9301c212)
|
||||
- ✨ ForgotPassword demo for translation with interpolation [`505ca6a`](https://git.odit.services/lfk/frontend/commit/505ca6a58effae334f35ae99de798d85bd8fa1a2)
|
||||
- 🐞 fixed address removal bug ContactDetail [`1eea935`](https://git.odit.services/lfk/frontend/commit/1eea93520749ac4fb4054004fc7ae01a02a05f68)
|
||||
- Fixed wrong relation getting targeted [`4f3f7d1`](https://git.odit.services/lfk/frontend/commit/4f3f7d1edb3c4f06dcda75461f87fe3688cf20fb)
|
||||
- Replaced untranslated key with already existant key [`56b5008`](https://git.odit.services/lfk/frontend/commit/56b50082782b3d62f7fe5854d0d37da3a8dd7759)
|
||||
- Replaced untranslated key with already existant key [`555778f`](https://git.odit.services/lfk/frontend/commit/555778fca43fd4546968205fc41617a10d4c7727)
|
||||
- Unified key translation style [`ec1a622`](https://git.odit.services/lfk/frontend/commit/ec1a6226a9f3d512404a5af7119b0508b21e03d6)
|
||||
- Merge commit '9faa93e29239182871b82bca211531fb95d37b7f' into feature/69-translation-keys [`5f1c8f3`](https://git.odit.services/lfk/frontend/commit/5f1c8f3627b5603063821c1a32774d4a000606ac)
|
||||
- new license file version [CI SKIP] [`3834079`](https://git.odit.services/lfk/frontend/commit/3834079481d36a38fbb6d61a56c56320c075d59d)
|
||||
- Merge pull request 'component/ structure cleanup feature/68-component-cleanup' (#70) from feature/68-component-cleanup into dev [`9faa93e`](https://git.odit.services/lfk/frontend/commit/9faa93e29239182871b82bca211531fb95d37b7f)
|
||||
- ✨ basic Contact components [`054c7fa`](https://git.odit.services/lfk/frontend/commit/054c7faaacfca30ab15f6fcb4241949aef4c87eb)
|
||||
- Sorted locales [`e64b318`](https://git.odit.services/lfk/frontend/commit/e64b318a42741812900feaa7a825b384687bf7d2)
|
||||
- ✨ basic UserGroup components [`0361f8a`](https://git.odit.services/lfk/frontend/commit/0361f8ad6991e04bc621c3201bd14d6ace9adc76)
|
||||
- 🌎 Contacts i18n [`c1251d3`](https://git.odit.services/lfk/frontend/commit/c1251d333298326e25ef7573e14ed24124f621de)
|
||||
- Now w/ 100% german translation 🌍 [`6c2a5f9`](https://git.odit.services/lfk/frontend/commit/6c2a5f904d6d0ab709a503130efc9e20784b9fc3)
|
||||
- Added license to package [`dc0c738`](https://git.odit.services/lfk/frontend/commit/dc0c7384710985524e8caceebde06918b878ec6c)
|
||||
- ✨ UserGroupsEmptyState, UserGroupsOverview, basic GroupDetail [`eddfeb1`](https://git.odit.services/lfk/frontend/commit/eddfeb10a55cbf276f29e406ad262d46ac3d1786)
|
||||
- ✨ ContactDetail route [`6f4f4cc`](https://git.odit.services/lfk/frontend/commit/6f4f4ccb16d91c9ab11f65bc9c01faafa6004f5c)
|
||||
- AddContactModal - allow optional address [`7138ca1`](https://git.odit.services/lfk/frontend/commit/7138ca1f5f03a6f5dc54e9d91bc1d432e354b77c)
|
||||
- Initial component sort/cleanup [`c0534a3`](https://git.odit.services/lfk/frontend/commit/c0534a3b06a6f818c94adb70bca2a898ec70c2ab)
|
||||
- ContactDetail - added checkbox for optional address [`894160f`](https://git.odit.services/lfk/frontend/commit/894160f3f771fa8c3566566626cfe60858fc3ab1)
|
||||
- 🚧 WIP on ContactDetail [`4541304`](https://git.odit.services/lfk/frontend/commit/4541304fa8033cfc875a08faca85bab86691a1c5)
|
||||
- renamed folder and removed useless files [`e1427f3`](https://git.odit.services/lfk/frontend/commit/e1427f3ecbf1e6d6dbb0b3e8c7c9514cb68c2c08)
|
||||
- 🐞 fixed null addresses in ContactsOverview [`6a91bd5`](https://git.odit.services/lfk/frontend/commit/6a91bd53e2f26d72a407a266b660cbfae0902a20)
|
||||
- ✨ OrgDetail - edit contact [`1586c2f`](https://git.odit.services/lfk/frontend/commit/1586c2f9e625a5eaa116251e5ebd83fcebd3bee5)
|
||||
- ✨ ContactsEmptyState [`a7098df`](https://git.odit.services/lfk/frontend/commit/a7098df9cfe6ba4dffe2ed121b1e9ae69f40e89d)
|
||||
- ✨ TeamDetail - edit contact [`2033572`](https://git.odit.services/lfk/frontend/commit/2033572c83654bc51ece17ef60e29c425001fe1c)
|
||||
- Fixed org deletion dialog [`a4c955c`](https://git.odit.services/lfk/frontend/commit/a4c955ce8530238bcd1eb91db2cee7dae6a9fe8c)
|
||||
- 🧹 ContactOverview refinement [`0f01330`](https://git.odit.services/lfk/frontend/commit/0f013304ef34d848652351a69e5374f61166db10)
|
||||
- 🔗 link to ContactDetail from OrgOverview [`1a4cf21`](https://git.odit.services/lfk/frontend/commit/1a4cf211eb5d5278e8d7cf375ba534b1c24a1315)
|
||||
- German spell check [`83495b1`](https://git.odit.services/lfk/frontend/commit/83495b101c851590473c769121d7a10299bcbcce)
|
||||
- 🎉 working AddContactModal [`45e7f6a`](https://git.odit.services/lfk/frontend/commit/45e7f6a0d1315db8779111545f317ba746680a28)
|
||||
- Removed usless console logs [`7278648`](https://git.odit.services/lfk/frontend/commit/72786486421e2161144c04c354e46eb07e00c502)
|
||||
- 🎉 ContactDetail + ContactOverview [`4ef1b7a`](https://git.odit.services/lfk/frontend/commit/4ef1b7abe8458903ba91ea8aad7566205c8776c4)
|
||||
- Gendered some stuff [`ce678c1`](https://git.odit.services/lfk/frontend/commit/ce678c1b769db7ab59a003752329e7598f7d86d5)
|
||||
- Fixed contact update detection bug [`696d3ff`](https://git.odit.services/lfk/frontend/commit/696d3ffabf8a254480344aa5bfb1b5a4360da528)
|
||||
- 🔗 link to ContactDetail from TeamsOverview [`b01fe05`](https://git.odit.services/lfk/frontend/commit/b01fe050d2a5db5f736e25859c44f8106d1eb526)
|
||||
- Fixed store destrucuured import [`f086027`](https://git.odit.services/lfk/frontend/commit/f08602791040da3820b8d2317339dd0d3baa260c)
|
||||
- Fixed group posting issue [`e4ae1dd`](https://git.odit.services/lfk/frontend/commit/e4ae1dd475e5c3a826eecd6af934e9c30b9a722a)
|
||||
- Fixed modal multiselect [`46cd262`](https://git.odit.services/lfk/frontend/commit/46cd262fabc5d89a80283d9c8510c2a8d476a6c5)
|
||||
- new license file version [CI SKIP] [`eb46c5e`](https://git.odit.services/lfk/frontend/commit/eb46c5eea65e24e1470a79b3ba9d380b4ce31a6f)
|
||||
- Merge pull request 'i18n fixed + dependency bumps bugfix/99-i18n_run' (#102) from bugfix/99-i18n_run into dev [`100094e`](https://git.odit.services/lfk/frontend/commit/100094e803fdbb2bc79e2b58d9eb9a9f1b4346ae)
|
||||
- Added select workaround for all things team🏠 [`5ad42d6`](https://git.odit.services/lfk/frontend/commit/5ad42d6ca7a3823a265e54d9dc7835e4a3e2e89c)
|
||||
- Implemented svelt select bug workaround for scan detail🔥🔥🔥 [`cda4512`](https://git.odit.services/lfk/frontend/commit/cda45128223ccc47456e2548b048e371d80bb7c2)
|
||||
- Fix for bug discovered by @philipp [`d28a0e1`](https://git.odit.services/lfk/frontend/commit/d28a0e1dbb877b3e369b106a103a3bfc52dd1e6a)
|
||||
- Added german translations for the new keys [`635e2ba`](https://git.odit.services/lfk/frontend/commit/635e2ba0e07c04ef0e3b35438193521e2ed2368b)
|
||||
- Fix for bug discovered by @philipp [`94d52df`](https://git.odit.services/lfk/frontend/commit/94d52df322fca1790776300b2d4be6a3996cd57f)
|
||||
- Svelte select is now 100% keyboard useable (or at least in one modal it is....) [`eb6af4b`](https://git.odit.services/lfk/frontend/commit/eb6af4b4f0b561653fe57ec41c272cb1cb127ecc)
|
||||
- Added patime to track scan detail [`937265e`](https://git.odit.services/lfk/frontend/commit/937265e82890c26046ccf321a3a4d6b9258674a9)
|
||||
- sorted translations 🌍 [`e723cbf`](https://git.odit.services/lfk/frontend/commit/e723cbf3b301ecb0de6426345def3fe53618a29c)
|
||||
- Removed lodash as a dependency 🗑 [`f09224d`](https://git.odit.services/lfk/frontend/commit/f09224d5c02a2c2d2f1ac221314d2c22758143ba)
|
||||
- Added translation keys [`99c3050`](https://git.odit.services/lfk/frontend/commit/99c30504115b068b65a48c651091252371b180ae)
|
||||
- Found a hiddeen missing key👀👀 [`00d16ef`](https://git.odit.services/lfk/frontend/commit/00d16ef59f2af3a540708cd61c195ea0ead86995)
|
||||
- Bumped svelte-* dependencies (non-dev)🔝 [`b4e7f90`](https://git.odit.services/lfk/frontend/commit/b4e7f9046c29aa45661f175f7b8cdca5d6a1a9a0)
|
||||
- Bumped svelte-related dev dependencies🔥 [`5204ba5`](https://git.odit.services/lfk/frontend/commit/5204ba5e24ca6e8ab0c5ad0255c54eede15a3baf)
|
||||
- Bumped router [`1b9b9ed`](https://git.odit.services/lfk/frontend/commit/1b9b9ed3723b0c12ab3b65eb0d94ec8c2c16ef42)
|
||||
- new license file version [CI SKIP] [`7521ad8`](https://git.odit.services/lfk/frontend/commit/7521ad8bbbb094bbe9ba723d03b3e9eb7f6a3243)
|
||||
- Merge pull request 'Scan management feature/92-scan_mgnt' (#101) from feature/92-scan_mgnt into dev [`b994065`](https://git.odit.services/lfk/frontend/commit/b994065e1810c44f4f9373b71baf632cccb34967)
|
||||
- Merge pull request 'Svelte select dropdown fix bugfix/98-dropdowns' (#100) from bugfix/98-dropdowns into dev [`a7fb2b8`](https://git.odit.services/lfk/frontend/commit/a7fb2b8a1a1e36a420ecbfce0ae41f685d6e24f8)
|
||||
- Sorted translations [`95eb8b6`](https://git.odit.services/lfk/frontend/commit/95eb8b6ae4d427c3ed7c64ac2d43b27545a64e3d)
|
||||
- Basic scan detail [`107360c`](https://git.odit.services/lfk/frontend/commit/107360cd93f00beb73bf0e3a50ca45fbfed63dfc)
|
||||
- Fixed emptystate 🛠 [`e9d5527`](https://git.odit.services/lfk/frontend/commit/e9d5527482b2dd2c61b83642051c4f808906139b)
|
||||
- Implemented basic scan creation [`1ada5d9`](https://git.odit.services/lfk/frontend/commit/1ada5d9c2c4d78868ca87b5cb05c0b6d770c7e9c)
|
||||
- Bugfix for download button dropdown outsideclick [`6a925cb`](https://git.odit.services/lfk/frontend/commit/6a925cb27f06101a7292aae7e77223a0cd204dfa)
|
||||
- Added basic scan overview [`eb0910b`](https://git.odit.services/lfk/frontend/commit/eb0910be575f4d83ab4f81a75a76cdfac46db19b)
|
||||
- Advanced Scan detail [`284bdc6`](https://git.odit.services/lfk/frontend/commit/284bdc6e33508fe4e277ea5fd312bea84881c882)
|
||||
- Added contact selection via svelte select [`7edc342`](https://git.odit.services/lfk/frontend/commit/7edc3427e10166d2a5e1b911cc459b26b37f984b)
|
||||
- Runner detail now uses svelte select🔥🔥 [`cee1ab1`](https://git.odit.services/lfk/frontend/commit/cee1ab1347beb80f7e391f41117b25ecef212032)
|
||||
- Added formatted laptime [`5afa541`](https://git.odit.services/lfk/frontend/commit/5afa541b303d9a650b5fd5a46cd4dd7b839d6085)
|
||||
- Added scans to sidebar (including a new icon) [`2cf8e02`](https://git.odit.services/lfk/frontend/commit/2cf8e0291ada3a9f70a8172ec95ed98be86ad7d0)
|
||||
- Adjusted filter [`53aa3bc`](https://git.odit.services/lfk/frontend/commit/53aa3bc3ae111399b22a122ad8912d78a12b8d79)
|
||||
- Org detail now uses svelte select [`6b59067`](https://git.odit.services/lfk/frontend/commit/6b590671bcb95c8c223860137ffbf2c82d05a144)
|
||||
- Add runner now uses svelte-select [`0e682bf`](https://git.odit.services/lfk/frontend/commit/0e682bf6302aea388ecfe6c92ad571db04d1c496)
|
||||
- Added basic files for scans [`f67e089`](https://git.odit.services/lfk/frontend/commit/f67e089ff39aa885983c063b82b60ba0ea432b69)
|
||||
- Added new scan icon to add scan modal [`9e5a093`](https://git.odit.services/lfk/frontend/commit/9e5a093a3a472ad06c7f0f0faee3b3ad318c8c44)
|
||||
- Now using svelte-select [`2a644d7`](https://git.odit.services/lfk/frontend/commit/2a644d70704cd3ffc5f0d7dd7894b2389ab90b1f)
|
||||
- MAde detail editable through the more reacctive process [`8b95b30`](https://git.odit.services/lfk/frontend/commit/8b95b300e283b25a9e25acbd6ffd5c003e30e59c)
|
||||
- Add Team now uses the new select [`1da1578`](https://git.odit.services/lfk/frontend/commit/1da15783d56ff4a998f872ce6842e83707b274ff)
|
||||
- Formatting [`e1bd364`](https://git.odit.services/lfk/frontend/commit/e1bd364278e590b8081c10fae3f642b91936c69b)
|
||||
- Fixed broken change detection [`a45c5da`](https://git.odit.services/lfk/frontend/commit/a45c5da0a7b9ef8f3a60b2b50cb8d1bd68d6ede8)
|
||||
- Fixed bugs with stuff not being displayed🛠 [`ff1bc8a`](https://git.odit.services/lfk/frontend/commit/ff1bc8a44a0d020d57aaba5a3eb255a22d65bb3d)
|
||||
- Now routing scans "start" page [`915bbbb`](https://git.odit.services/lfk/frontend/commit/915bbbbde023c34feb4595629d59546970ba8c94)
|
||||
- Added translations 🌎 [`8acbfa8`](https://git.odit.services/lfk/frontend/commit/8acbfa89674130667da11bca00879a30163b3523)
|
||||
- Now checking selectables for not being null [`5a2172b`](https://git.odit.services/lfk/frontend/commit/5a2172bb9b878c77c4f09e65237ce1a179c95b8c)
|
||||
- formatting [`9d0c6b9`](https://git.odit.services/lfk/frontend/commit/9d0c6b9ef44846bf59a521b71b2c4d9e91189ed5)
|
||||
- Fixed initial select value [`d3a3de2`](https://git.odit.services/lfk/frontend/commit/d3a3de2eac40503a5c626e59f9b5036e482b7399)
|
||||
- Small bugfixes [`dfa38d3`](https://git.odit.services/lfk/frontend/commit/dfa38d34215921a10619de71c7a7cf390be3b722)
|
||||
- Added clear event [`ee0c149`](https://git.odit.services/lfk/frontend/commit/ee0c1496e67316a7473fdcccecad67cb1d10cdf9)
|
||||
- Now routing scan detail [`abf9aa4`](https://git.odit.services/lfk/frontend/commit/abf9aa475b62ead1bfa185c39f8934fba508f9d8)
|
||||
- Small bugfixes [`6e04b71`](https://git.odit.services/lfk/frontend/commit/6e04b71c1aaed142152f1ef045c69f02ee116a3f)
|
||||
- Reset array [`8252a35`](https://git.odit.services/lfk/frontend/commit/8252a35771bbde82cfcf4f049be8536193df9a17)
|
||||
- Removed useless console.logs [`fc668c6`](https://git.odit.services/lfk/frontend/commit/fc668c68806bc0b132d818d64ee2c833ce3ace06)
|
||||
- Bumped lfk lib version [`bb7f2a6`](https://git.odit.services/lfk/frontend/commit/bb7f2a611a199f59932f61be36464ed654d76a06)
|
||||
- Fixed visual bug (overflow) [`4e51b12`](https://git.odit.services/lfk/frontend/commit/4e51b128e6d13d222b196175ddc5fbc5c1f9597e)
|
||||
- Bumped svelte select version [`0277263`](https://git.odit.services/lfk/frontend/commit/0277263f9825e78812e0518d0a849535c0fe99a4)
|
||||
- Removed depreciated information [`99fb420`](https://git.odit.services/lfk/frontend/commit/99fb420d5804c6061d806f518d8d3e742b20eacb)
|
||||
- Merge pull request 'Make dropdowns (selects) searchable feature/91-searchable_dropdowns' (#97) from feature/91-searchable_dropdowns into dev [`b541c93`](https://git.odit.services/lfk/frontend/commit/b541c93797b1a0317fee8c934e9803a9f2f7677d)
|
||||
- Fixed typo✏ [`e6df764`](https://git.odit.services/lfk/frontend/commit/e6df76456204282c7724f62ada6a902c771ec451)
|
||||
- Reapplied change from dev [`b841cc8`](https://git.odit.services/lfk/frontend/commit/b841cc8b959546d04daa0bacc04265a95573cd12)
|
||||
- Removed console log 🤫 [`bc2a8ca`](https://git.odit.services/lfk/frontend/commit/bc2a8caf3e3f87de11a7402c433d95d1851b4e4c)
|
||||
- Applied Docker MTU fix 🛠 [`f24b2b9`](https://git.odit.services/lfk/frontend/commit/f24b2b9b4cdb5e00eacea35be3199a38352d8a55)
|
||||
- Small bugfix 🛠 [`1a115a8`](https://git.odit.services/lfk/frontend/commit/1a115a842350da0b0ece58a9b5176a90897db9b7)
|
||||
- Merge pull request 'Scan station management feature/93-scan_stations' (#95) from feature/93-scan_stations into dev [`d00446d`](https://git.odit.services/lfk/frontend/commit/d00446dc7b27d67589a7eb7f251b6b8d60dedd43)
|
||||
- Fixed case sensitivity [`c6db6c5`](https://git.odit.services/lfk/frontend/commit/c6db6c553588c7cfb33fd3105122b63ecf6c12fb)
|
||||
- Sorted translations [`74c042a`](https://git.odit.services/lfk/frontend/commit/74c042a86b7e98ee0dd7f28981836ca33d1d6576)
|
||||
- Sorted translations 👀 [`a5d1b76`](https://git.odit.services/lfk/frontend/commit/a5d1b7689161ac491ab6aa68aad3625e5207bdb6)
|
||||
- Added translations for runner searching [`8c4a54e`](https://git.odit.services/lfk/frontend/commit/8c4a54eb07c8c6cc9ee4ea1b5c620a12bdabc0e3)
|
||||
- Sorted translations [`476f919`](https://git.odit.services/lfk/frontend/commit/476f9191211c473244f2e05a1d840eabada8190a)
|
||||
- Added search languagke keys [`47f0cd0`](https://git.odit.services/lfk/frontend/commit/47f0cd0b589729ea0d60e12c3f3ead7a2538e9ff)
|
||||
- i18n run: Added keys 🌍 [`50aa891`](https://git.odit.services/lfk/frontend/commit/50aa8917090af743fa99e9da79327496640a0014)
|
||||
- Added new translation keys 🌍 [`1aa2b3b`](https://git.odit.services/lfk/frontend/commit/1aa2b3b065816f82c85b5320261a10b9c4d1879c)
|
||||
- Added german translations 🇩🇪 [`e6d80c8`](https://git.odit.services/lfk/frontend/commit/e6d80c8ccb1e15cbac421b883da07be370c89456)
|
||||
- Added german translations [`e93f4e9`](https://git.odit.services/lfk/frontend/commit/e93f4e99f9f768b7e2b81088c3d47c3363197ab2)
|
||||
- Basic scanstation creation [`9ee7685`](https://git.odit.services/lfk/frontend/commit/9ee768551f0d617257452f7a89992f25927de02a)
|
||||
- Added scanstation detail [`258b3ce`](https://git.odit.services/lfk/frontend/commit/258b3cea66148a1a2beb14dd7aba5c785ff30c83)
|
||||
- Added station token copy modal [`8856671`](https://git.odit.services/lfk/frontend/commit/88566719ec4eab243369f9f26151e9f6377ddfa6)
|
||||
- Added station deletion confirmation dialog [`9f754ef`](https://git.odit.services/lfk/frontend/commit/9f754ef0e98ab78548391796db96e69b15fcd20e)
|
||||
- New fancy selects for donation details [`76be8d5`](https://git.odit.services/lfk/frontend/commit/76be8d5a8766c55e59e34dab2bfa0d24734b7886)
|
||||
- Spelling+Formatting [`7ff1d50`](https://git.odit.services/lfk/frontend/commit/7ff1d5007935946423d49eb559cb9e15f7dbb023)
|
||||
- Finished scanstationmodal (without i18n) [`83e782c`](https://git.odit.services/lfk/frontend/commit/83e782c7c567d3747eb4e0a4313f6e7de6f2355f)
|
||||
- Now with custom label generation functions [`48b8dfe`](https://git.odit.services/lfk/frontend/commit/48b8dfe973c880f4bad5884cd49769f14ba0f78d)
|
||||
- Updated ci secrets and type [`65111e8`](https://git.odit.services/lfk/frontend/commit/65111e87c1dc5a397f47b94282a18c0eb9888794)
|
||||
- New select [`fe16c66`](https://git.odit.services/lfk/frontend/commit/fe16c66cf2d9ee2a950b0865b43fe7797b9540b2)
|
||||
- Added custom placeholders [`1c330d0`](https://git.odit.services/lfk/frontend/commit/1c330d0301d5f3167a49161974eb09ff2324ba16)
|
||||
- Added new select for runners [`dab5bee`](https://git.odit.services/lfk/frontend/commit/dab5bee3c0ed48f0e7562b2d829a25cb8b80f2c6)
|
||||
- Added scanstations to sidebar [`4b47e70`](https://git.odit.services/lfk/frontend/commit/4b47e70b13507034dc321a80e4e61fd387749571)
|
||||
- Added fancier active states [`95b1490`](https://git.odit.services/lfk/frontend/commit/95b1490f8493168a07e3db167ee8c9ac81730429)
|
||||
- Finished scanstations base view [`85fa9d9`](https://git.odit.services/lfk/frontend/commit/85fa9d942ea8e8d636509bf0db79b56f4c1a20b8)
|
||||
- Added missing clear [`1bc8404`](https://git.odit.services/lfk/frontend/commit/1bc840430f6c6e886d38c50a1c5b31ae2204a615)
|
||||
- Added icon 🖼 [`e8e3ddc`](https://git.odit.services/lfk/frontend/commit/e8e3ddceff08e9b3b024da8e6b534a86b35f6f39)
|
||||
- Added translation strings [`88ad64f`](https://git.odit.services/lfk/frontend/commit/88ad64f113878784dfc0808ffdc83c8aca85588f)
|
||||
- Added custom filter/search [`f97be4e`](https://git.odit.services/lfk/frontend/commit/f97be4e7291f45f9240a3491603b9c0982b37a68)
|
||||
- Merge pull request 'Well that was less work than expected ....' (#96) from feature/90-translations into dev [`64b6c4d`](https://git.odit.services/lfk/frontend/commit/64b6c4d5f7a6f56370336828f05a56520976135d)
|
||||
- And with working i18n 🌍 [`e07d1e4`](https://git.odit.services/lfk/frontend/commit/e07d1e42e2ed4e21d053aef85432c9dbb9f103f4)
|
||||
- Sorted translations [`6870e31`](https://git.odit.services/lfk/frontend/commit/6870e31a8143187d98e39f1964139a0f57328779)
|
||||
- Sorted translations [`e487213`](https://git.odit.services/lfk/frontend/commit/e4872131c84d5021a0b02a944550fbcd99fb5c1a)
|
||||
- Added translation keyz [`3693025`](https://git.odit.services/lfk/frontend/commit/36930259d2bd250af8453ac3ed9349503c5f109d)
|
||||
- Translated stuff 🌍 [`dcaca2e`](https://git.odit.services/lfk/frontend/commit/dcaca2ecbded329b3240a30e8b2d51fc392483eb)
|
||||
- Moved pdf generation to function instead of onclick for all components [`22e9f53`](https://git.odit.services/lfk/frontend/commit/22e9f53c42d27177bd101d3724ff7e640850f5f6)
|
||||
- New download buttons for everyone (that can generate sponsoring contracts) [`e24b84e`](https://git.odit.services/lfk/frontend/commit/e24b84e7095fc929d1c160646dfaa01a260f229b)
|
||||
- Now routing to gorup permissions [`af7e44c`](https://git.odit.services/lfk/frontend/commit/af7e44cf7cb168eb9d017951c5e9cf4e0ead4673)
|
||||
- Now routing scan statins overview [`ca9c390`](https://git.odit.services/lfk/frontend/commit/ca9c390bb265e5c1b1f8752e118c5f3c560ddc82)
|
||||
- Implemented rough outside click handler for the dropdown [`c2bd696`](https://git.odit.services/lfk/frontend/commit/c2bd696bfedcfdaf0b13eb165d800691d58ca010)
|
||||
- Working button onklicks [`3b7c25b`](https://git.odit.services/lfk/frontend/commit/3b7c25b106b5369e622fabb844302463a55971b5)
|
||||
- Added basic table for scanstations [`c53b579`](https://git.odit.services/lfk/frontend/commit/c53b579fca6f65b8d34ab63a8ec8321100e563bd)
|
||||
- Added permissions list to usergroup detail [`05099d0`](https://git.odit.services/lfk/frontend/commit/05099d066bb383b4883b4fae59da35e419935827)
|
||||
- Working suergroup permissions overview [`7c32486`](https://git.odit.services/lfk/frontend/commit/7c324869a463d07af8c8f43b1853544c4a0d3440)
|
||||
- Switched the icon style [`305b18e`](https://git.odit.services/lfk/frontend/commit/305b18ef57c885d7cd1295557f8651f546b7934a)
|
||||
- Basic sponsoring language dropdown for runners [`6079e1f`](https://git.odit.services/lfk/frontend/commit/6079e1fa90249cfc94ed210fb40bd6fcf7e9ec11)
|
||||
- Updated users icon [`8ebc88a`](https://git.odit.services/lfk/frontend/commit/8ebc88aebb5af1fc6361582745d57d37ea6905e1)
|
||||
- You can now delete a station from it's detail [`c4acf77`](https://git.odit.services/lfk/frontend/commit/c4acf774ec6ab59eb24da437548667a5d26d624b)
|
||||
- Updated users icon [`c111ec9`](https://git.odit.services/lfk/frontend/commit/c111ec9d9113adac7f19fc5f0b527e0755cafd0e)
|
||||
- More i18n 🌍 [`e85cdaf`](https://git.odit.services/lfk/frontend/commit/e85cdaf3240abc78f9bf6353e911f157a06f11ca)
|
||||
- Added group detail routing [`937486a`](https://git.odit.services/lfk/frontend/commit/937486a66bd0c8bacbb867c469e7a69c30be2a5e)
|
||||
- Changed row order [`773fbfc`](https://git.odit.services/lfk/frontend/commit/773fbfc579014dcf67c87b43ab0a0d9d11ea23d6)
|
||||
- Added missing translations 🌍 [`599d340`](https://git.odit.services/lfk/frontend/commit/599d340a72a9577a28fd652648558fee1ccd6bf1)
|
||||
- Added missing translations 🌍 [`89b7fb8`](https://git.odit.services/lfk/frontend/commit/89b7fb8072bdc463cd9ac2926fef7f92c9b7130c)
|
||||
- Now with dropdown aiutoclose [`c89caf7`](https://git.odit.services/lfk/frontend/commit/c89caf78558d379ad587b37375280d5319c51cd2)
|
||||
- Now routing scan station detail [`a3daa2d`](https://git.odit.services/lfk/frontend/commit/a3daa2d24f5ed76fbde5d073360b2ca0a98fa9ac)
|
||||
- You can now add scanstations [`e45f8fa`](https://git.odit.services/lfk/frontend/commit/e45f8fa9efabcb18f69577a368235ee568dc16cb)
|
||||
- Clicking on a dropdown option now closes it everywhere [`9fec315`](https://git.odit.services/lfk/frontend/commit/9fec31591007253ced7a9c8d29552980138a5971)
|
||||
- Removed locale overrides [`9a8a978`](https://git.odit.services/lfk/frontend/commit/9a8a978e4959b36c5d6beccdcec6c313e1529e65)
|
||||
- Udergroup permission reactivity fix [`bfc9315`](https://git.odit.services/lfk/frontend/commit/bfc93158f50bfa78a26340b609dffcc6b164f90c)
|
||||
- Added "tooltip" [`2de861d`](https://git.odit.services/lfk/frontend/commit/2de861d4c13da8327b2bd9ec34f17c71e83105fc)
|
||||
- Fixed nameing [`5e417f0`](https://git.odit.services/lfk/frontend/commit/5e417f0714c3aa0189d9a7148d81d48ca922802b)
|
||||
- Changed group icon [`16e1434`](https://git.odit.services/lfk/frontend/commit/16e1434f2a53270d237a9345d55748f9b3d0460b)
|
||||
- New image for emptystate [`e8de1f6`](https://git.odit.services/lfk/frontend/commit/e8de1f6d9c120636f51f7e916692690050060719)
|
||||
- Added german translation 🇩🇪 [`95fcd1d`](https://git.odit.services/lfk/frontend/commit/95fcd1dcc49247a620e030084674c23c871472b6)
|
||||
- Fixed routing [`891ea2d`](https://git.odit.services/lfk/frontend/commit/891ea2da12679049c018e87b8474af91978d9f56)
|
||||
- Well that was less work than expected .... [`8d8695b`](https://git.odit.services/lfk/frontend/commit/8d8695ba13b0183b5f1535bd48c162bb809b01f0)
|
||||
- Added cursor-pointer [`27a1f57`](https://git.odit.services/lfk/frontend/commit/27a1f57ed34577f0c6865161559081763d29c6dc)
|
||||
- Spelling [`bd22d3b`](https://git.odit.services/lfk/frontend/commit/bd22d3be3626429fb3d82c881dfe58c41fdcd00b)
|
||||
- Switched pipeline type to kubernetes [`ba9d458`](https://git.odit.services/lfk/frontend/commit/ba9d4587cb5ff203b5ad67681c333834ac3213a9)
|
||||
- Fixed emptystate svg [`870e772`](https://git.odit.services/lfk/frontend/commit/870e772da27d1ee2bf59b4d110cd3161bc52a865)
|
||||
- new license file version [CI SKIP] [`7d654f4`](https://git.odit.services/lfk/frontend/commit/7d654f4a208b42e43899d770137b6dc90a2a2aa4)
|
||||
- Merge pull request 'Spnonsoring contract language selector feature/84-sponsoringcontract_language_selector' (#89) from feature/84-sponsoringcontract_language_selector into dev [`b810bb0`](https://git.odit.services/lfk/frontend/commit/b810bb01dbbe3d506af3852fcda8e1365a570c70)
|
||||
- Merge pull request 'Usergroup management in the UI feature/48-usergroup-management' (#88) from feature/48-usergroup-management into dev [`434466b`](https://git.odit.services/lfk/frontend/commit/434466b306ec11ad46e5ee99bec22bdcd01872b6)
|
||||
- Fixed root breadcrumb linking [`e1ac35f`](https://git.odit.services/lfk/frontend/commit/e1ac35f848e810191b98b2dc2b9f6ec7e4975f6f)
|
||||
- Added missing translations 🌍 [`29f99f0`](https://git.odit.services/lfk/frontend/commit/29f99f0b2047686327fe8c6f6ae68427c6db724b)
|
||||
- Formatting [`b8725c9`](https://git.odit.services/lfk/frontend/commit/b8725c96cdf8057498503728d8c8a7934983d14c)
|
||||
- Fixed Back linking [`4397566`](https://git.odit.services/lfk/frontend/commit/4397566f1e9ce8f0f1e5a6ba7c3c500dddb64bd0)
|
||||
- Fix for user permission availdable [`7e80608`](https://git.odit.services/lfk/frontend/commit/7e80608066d158221a36cb251d2ba4dd2a27c785)
|
||||
- Dependency bump 👊 [`2b57d49`](https://git.odit.services/lfk/frontend/commit/2b57d49e4e703ca15dc151ab69614dd893e8a0a5)
|
||||
- Removed filepond [`ca41f4d`](https://git.odit.services/lfk/frontend/commit/ca41f4d4f26871b2768a1cc1d438cd99f21956b9)
|
||||
- Reimported simple.css [`e2fb9a6`](https://git.odit.services/lfk/frontend/commit/e2fb9a66adbc2ecb12b3705a24fd6469d0f3af38)
|
||||
- Fixed store not being found [`543b3bd`](https://git.odit.services/lfk/frontend/commit/543b3bd937bdb8e0ac1fabee3c996be5d7874348)
|
||||
- new license file version [CI SKIP] [`0c9785a`](https://git.odit.services/lfk/frontend/commit/0c9785af36807608970ff3c91549c7b694a9d5c4)
|
||||
- Fixed address update bug [`14e5d0e`](https://git.odit.services/lfk/frontend/commit/14e5d0e7405f010e0d55aa31b0f3fd5f050d4f57)
|
||||
- Removed debug output [`27609dc`](https://git.odit.services/lfk/frontend/commit/27609dc5e0bf9a78ef37f0b3b74cc2ca25bfddbf)
|
||||
- Merge pull request 'Translated everything feature/65-translations' (#66) from feature/65-translations into dev [`3f54180`](https://git.odit.services/lfk/frontend/commit/3f5418083ff1a3ce883563610c8e4c67244df64f)
|
||||
- Fixed import modal width [`d822e4a`](https://git.odit.services/lfk/frontend/commit/d822e4ab3f61a019c9bdea3e56acdea8711f1b8f)
|
||||
- User permission update reactivity fix [`5994b22`](https://git.odit.services/lfk/frontend/commit/5994b22464e38fcde6f1073da073782d00dfbdc8)
|
||||
|
||||
#### [0.6.0](https://git.odit.services/lfk/frontend/compare/0.5.0...0.6.0)
|
||||
|
||||
> 12 February 2021
|
||||
|
||||
- Merge pull request 'feature/52-runner-filters' (#63) from feature/52-runner-filters into dev [`#52`](https://git.odit.services/lfk/frontend/issues/52)
|
||||
- Merge pull request 'feature/43-password-reset' (#61) from feature/43-password-reset into dev [`#43`](https://git.odit.services/lfk/frontend/issues/43)
|
||||
- Merge pull request 'feature/51-teamoverview-badge-org' (#59) from feature/51-teamoverview-badge-org into dev [`#51`](https://git.odit.services/lfk/frontend/issues/51)
|
||||
|
@ -19,6 +381,7 @@ All notable changes to this project will be documented in this file. Dates are d
|
|||
- 👀 ResetPassword - success and error states [`8b2f196`](https://git.odit.services/lfk/frontend/commit/8b2f1965e2a754da6e40a3051e8ae3e771d70336)
|
||||
- added Privacy page [`5741cbe`](https://git.odit.services/lfk/frontend/commit/5741cbe7562542ba2b81a9a6d6be7fb0f5145801)
|
||||
- ImportRunnerModal - differenciate between team and org import [`acf0562`](https://git.odit.services/lfk/frontend/commit/acf0562851a77b9122473ffb1753a94b4272e53b)
|
||||
- 🚀RELEASE v0.6.0 [`087c85e`](https://git.odit.services/lfk/frontend/commit/087c85e58674e317cbe11bd135d3f051defa7911)
|
||||
- ✨ RunnersOverview - basic working filter [`575b4ce`](https://git.odit.services/lfk/frontend/commit/575b4ce9708625fbec23c49101f44825c6a75bce)
|
||||
- basic select filtering in RunnersOverview [`e415258`](https://git.odit.services/lfk/frontend/commit/e415258787c776d4a5291632f47c2fcceba9a040)
|
||||
- WIP on filter [`e23821a`](https://git.odit.services/lfk/frontend/commit/e23821a7cbe73fda420e4bcaaa2dbf5a89b56cc9)
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/favicon.png" />
|
||||
<link rel="manifest" href="/manifest.webmanifest">
|
||||
<link rel="apple-touch-icon" href="/lfk-logo.png">
|
||||
<meta name="theme-color" content="#FFFFFF">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Lauf Für Kaya! - Admin" />
|
||||
<title>Lauf für Kaya! - Admin</title>
|
||||
__TAILWIND_INSERT__
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.6.0-RELEASE_INFO</span>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<script src="/env.js"></script>
|
||||
<script defer type="module" src="/_dist_/index.js"></script>
|
||||
</body>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/favicon.png" />
|
||||
<link rel="manifest" href="/manifest.webmanifest">
|
||||
<link rel="apple-touch-icon" href="/lfk-logo.png">
|
||||
<meta name="theme-color" content="#FFFFFF">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Lauf Für Kaya! - Admin" />
|
||||
<title>Lauf für Kaya! - Admin</title>
|
||||
__TAILWIND_INSERT__
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.8.0-RELEASE_INFO</span>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<script src="/env.js"></script>
|
||||
<script defer type="module" src="/_dist_/index.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
123
package.json
123
package.json
|
@ -1,62 +1,61 @@
|
|||
{
|
||||
"name": "@odit/lfk-frontend",
|
||||
"version": "0.6.0",
|
||||
"scripts": {
|
||||
"i18n-order": "node order.js",
|
||||
"dev:all": "yarn prebuild && snowpack dev",
|
||||
"dev": "cross-env NODE_ENV_ODIT=development_fast node template-copy.js && yarn build:sw && snowpack dev",
|
||||
"build": "yarn prebuild && snowpack build",
|
||||
"prebuild": "cross-env NODE_ENV_ODIT=production node template-copy.js && yarn build:sw",
|
||||
"build:sw": "workbox generateSW workbox-config.js",
|
||||
"release": "release-it",
|
||||
"licenses:export": "license-exporter --json -o public"
|
||||
},
|
||||
"license": "CC-BY-NC-SA-4.0",
|
||||
"dependencies": {
|
||||
"@odit/lfk-client-js": "0.4.5",
|
||||
"csvtojson": "^2.0.10",
|
||||
"gridjs": "3.3.0",
|
||||
"localforage": "1.9.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"marked": "^2.0.0",
|
||||
"svelte-focus-trap": "1.0.1",
|
||||
"svelte-i18n": "3.3.2",
|
||||
"svelte-select": "^3.16.1",
|
||||
"tailwindcss": "2.0.3",
|
||||
"tinro": "0.5.12",
|
||||
"toastify-js": "1.9.3",
|
||||
"validator": "13.5.2",
|
||||
"xlsx": "^0.16.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@odit/license-exporter": "^0.0.10",
|
||||
"@snowpack/plugin-svelte": "3.5.2",
|
||||
"auto-changelog": "^2.2.1",
|
||||
"autoprefixer": "10.2.4",
|
||||
"cross-env": "^7.0.3",
|
||||
"postcss": "8.2.6",
|
||||
"postcss-load-config": "3.0.1",
|
||||
"release-it": "^14.4.0",
|
||||
"snowpack": "3.0.11",
|
||||
"svelte": "3.32.3",
|
||||
"svelte-preprocess": "4.6.8",
|
||||
"workbox-cli": "6.1.0"
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
"commit": true,
|
||||
"requireCleanWorkingDir": false,
|
||||
"commitMessage": "🚀RELEASE v${version}",
|
||||
"push": false,
|
||||
"tag": true,
|
||||
"tagName": null,
|
||||
"tagAnnotation": "v${version}"
|
||||
},
|
||||
"npm": {
|
||||
"publish": false
|
||||
},
|
||||
"hooks": {
|
||||
"after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md && node versionbuilder.js && git add index.template.html && node order.js && git add src/locales"
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "@odit/lfk-frontend",
|
||||
"version": "0.8.0",
|
||||
"scripts": {
|
||||
"i18n-order": "node order.js",
|
||||
"dev:all": "yarn prebuild && snowpack dev",
|
||||
"dev": "cross-env NODE_ENV_ODIT=development_fast node template-copy.js && yarn build:sw && snowpack dev",
|
||||
"build": "yarn prebuild && snowpack build",
|
||||
"prebuild": "cross-env NODE_ENV_ODIT=production node template-copy.js && yarn build:sw",
|
||||
"build:sw": "workbox generateSW workbox-config.js",
|
||||
"release": "release-it",
|
||||
"licenses:export": "license-exporter --json -o public"
|
||||
},
|
||||
"license": "CC-BY-NC-SA-4.0",
|
||||
"dependencies": {
|
||||
"@odit/lfk-client-js": "0.6.4",
|
||||
"csvtojson": "^2.0.10",
|
||||
"gridjs": "3.3.0",
|
||||
"localforage": "1.9.0",
|
||||
"marked": "^2.0.1",
|
||||
"svelte-focus-trap": "1.0.1",
|
||||
"svelte-i18n": "3.3.7",
|
||||
"svelte-select": "^3.17.0",
|
||||
"tailwindcss": "2.0.3",
|
||||
"tinro": "0.6.1",
|
||||
"toastify-js": "1.9.3",
|
||||
"validator": "13.5.2",
|
||||
"xlsx": "^0.16.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@odit/license-exporter": "^0.0.11",
|
||||
"@snowpack/plugin-svelte": "3.5.2",
|
||||
"auto-changelog": "^2.2.1",
|
||||
"autoprefixer": "10.2.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"postcss": "8.2.8",
|
||||
"postcss-load-config": "3.0.1",
|
||||
"release-it": "^14.4.1",
|
||||
"snowpack": "3.0.13",
|
||||
"svelte": "3.35.0",
|
||||
"svelte-preprocess": "4.6.9",
|
||||
"workbox-cli": "6.1.2"
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
"commit": true,
|
||||
"requireCleanWorkingDir": false,
|
||||
"commitMessage": "🚀RELEASE v${version}",
|
||||
"push": false,
|
||||
"tag": true,
|
||||
"tagName": null,
|
||||
"tagAnnotation": "v${version}"
|
||||
},
|
||||
"npm": {
|
||||
"publish": false
|
||||
},
|
||||
"hooks": {
|
||||
"after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md && node versionbuilder.js && git add index.template.html && node order.js && git add src/locales"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -42,7 +42,7 @@
|
|||
import MainDashContent from "./components/dashboard/MainDashContent.svelte";
|
||||
import Users from "./components/users/Users.svelte";
|
||||
import About from "./components/general/About.svelte";
|
||||
import Settings from "./components/general/Settings.svelte";
|
||||
import Settings from "./components/settings/Settings.svelte";
|
||||
import Transition from "./components/base/Transition.svelte";
|
||||
import Orgs from "./components/orgs/Orgs.svelte";
|
||||
import Runners from "./components/runners/Runners.svelte";
|
||||
|
@ -69,6 +69,11 @@
|
|||
import Donations from "./components/donations/Donations.svelte";
|
||||
import DonationDetail from "./components/donations/DonationDetail.svelte";
|
||||
import GroupDetail from "./components/groups/GroupDetail.svelte";
|
||||
import ScanStationsOverview from "./components/scanstations/ScanStationsOverview.svelte";
|
||||
import ScanStations from "./components/scanstations/ScanStations.svelte";
|
||||
import ScanStationDetail from "./components/scanstations/ScanStationDetail.svelte";
|
||||
import Scans from "./components/scans/Scans.svelte";
|
||||
import ScanDetail from "./components/scans/ScanDetail.svelte";
|
||||
store.init();
|
||||
registerSW();
|
||||
</script>
|
||||
|
@ -180,6 +185,22 @@
|
|||
<DonationDetail {params} />
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path="/scans/*">
|
||||
<Route path="/">
|
||||
<Scans />
|
||||
</Route>
|
||||
<Route path="/:scanid" let:params>
|
||||
<ScanDetail {params} />
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path="/scanstations/*">
|
||||
<Route path="/">
|
||||
<ScanStations />
|
||||
</Route>
|
||||
<Route path="/:stationid" let:params>
|
||||
<ScanStationDetail {params} />
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path="/about">
|
||||
<About />
|
||||
</Route>
|
||||
|
|
|
@ -172,21 +172,61 @@
|
|||
<span>{$_('tracks')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
<a
|
||||
class:bg-gray-100={$router.path === '/contacts/'}
|
||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||
href="/contacts/">
|
||||
<svg
|
||||
fill="currentColor"
|
||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
d="M2 22a8 8 0 1 1 16 0H2zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6 6 2.685 6 6-2.685 6-6 6zm10 4h4v2h-4v-2zm-3-5h7v2h-7v-2zm2-5h5v2h-5V7z" /></svg>
|
||||
<span>{$_('contacts')}</span>
|
||||
</a>
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:GET')}
|
||||
<a
|
||||
class:bg-gray-100={$router.path === '/scans/'}
|
||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||
href="/scans/">
|
||||
<svg
|
||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||
fill="currentColor"
|
||||
width="24"
|
||||
height="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M2 4h2v16H2V4zm4 0h1v16H6V4zm2 0h2v16H8V4zm3 0h2v16h-2V4zm3 0h2v16h-2V4zm3 0h1v16h-1V4zm2 0h3v16h-3V4z" /></svg>
|
||||
<span>Scans</span>
|
||||
</a>
|
||||
{/if}
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT:GET')}
|
||||
<a
|
||||
class:bg-gray-100={$router.path === '/contacts/'}
|
||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||
href="/contacts/">
|
||||
<svg
|
||||
fill="currentColor"
|
||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
d="M2 22a8 8 0 1 1 16 0H2zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6 6 2.685 6 6-2.685 6-6 6zm10 4h4v2h-4v-2zm-3-5h7v2h-7v-2zm2-5h5v2h-5V7z" /></svg>
|
||||
<span>{$_('contacts')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('STATION:GET')}
|
||||
<a
|
||||
class:bg-gray-100={$router.path === '/scanstations/'}
|
||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||
href="/scanstations/">
|
||||
<svg
|
||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||
fill="currentColor"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"><path
|
||||
fill="none"
|
||||
d="M0 0h24v24H0z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></svg>
|
||||
<span>{$_('scanstations')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
<a
|
||||
class:bg-gray-100={$router.path === '/settings/'}
|
||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||
|
|
|
@ -7,9 +7,15 @@
|
|||
DonorService,
|
||||
RunnerService,
|
||||
} from "@odit/lfk-client-js";
|
||||
import Select from "svelte-select";
|
||||
import Toastify from "toastify-js";
|
||||
export let modal_open;
|
||||
export let current_donations;
|
||||
const getDonorLabel = (option) =>
|
||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||
const filterDonors = (label, filterText, option) =>
|
||||
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||
option.value.id.toString().startsWith(filterText.toLowerCase());
|
||||
function focus(el) {
|
||||
el.focus();
|
||||
}
|
||||
|
@ -19,12 +25,14 @@
|
|||
$: runners = [];
|
||||
$: is_fixed = false;
|
||||
DonorService.donorControllerGetAll().then((val) => {
|
||||
donors = val;
|
||||
donor = donors[0].id || 0;
|
||||
donors = val.map((r) => {
|
||||
return { label: getDonorLabel(r), value: r };
|
||||
});
|
||||
});
|
||||
RunnerService.runnerControllerGetAll().then((val) => {
|
||||
runners = val;
|
||||
runner = runners[0].id || 0;
|
||||
runners = val.map((r) => {
|
||||
return { label: getDonorLabel(r), value: r };
|
||||
});
|
||||
});
|
||||
$: amount_input = 0;
|
||||
$: processed_last_submit = true;
|
||||
|
@ -158,7 +166,7 @@
|
|||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||
aria-hidden="true">​</span>
|
||||
<div
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline">
|
||||
|
@ -178,8 +186,9 @@
|
|||
</div>
|
||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
<!-- TODO: -->
|
||||
{#if is_fixed}{$_('create-a-new-fixed-donation')}{:else}{$_('create-a-new-distance-donation')}{/if}
|
||||
{#if is_fixed}
|
||||
{$_('create-a-new-fixed-donation')}
|
||||
{:else}{$_('create-a-new-distance-donation')}{/if}
|
||||
</h3>
|
||||
<label class="content-center align-middle object-center">
|
||||
<span
|
||||
|
@ -203,41 +212,39 @@
|
|||
<label
|
||||
for="donor"
|
||||
class="block text-sm font-medium text-gray-700">{$_('donor')}</label>
|
||||
<select
|
||||
bind:value={donor}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
{#each donors as d}
|
||||
<option value={d.id}>
|
||||
{d.firstname}
|
||||
{d.middlename || ''}
|
||||
{d.lastname}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => filterDonors(label, filterText, option)}
|
||||
items={donors}
|
||||
showChevron={true}
|
||||
placeholder={$_('search-for-donor-name-or-id')}
|
||||
noOptionsMessage={$_('no-donors-found')}
|
||||
on:select={(selectedValue) => (donor = selectedValue.detail.value.id)}
|
||||
on:clear={() => (donors = null)} />
|
||||
</div>
|
||||
{#if !is_fixed}
|
||||
<div class="col-span-6">
|
||||
<label
|
||||
for="donor"
|
||||
class="block text-sm font-medium text-gray-700">{$_('runner')}</label>
|
||||
<select
|
||||
bind:value={runner}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
{#each runners as r}
|
||||
<option value={r.id}>
|
||||
{r.firstname}
|
||||
{r.middlename || ''}
|
||||
{r.lastname}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => filterDonors(label, filterText, option)}
|
||||
items={runners}
|
||||
showChevron={true}
|
||||
placeholder={$_('search-for-runner-by-name-or-id')}
|
||||
noOptionsMessage={$_('no-runners-found')}
|
||||
on:select={(selectedValue) => (runner = selectedValue.detail.value.id)}
|
||||
on:clear={() => (runner = null)} />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="col-span-6">
|
||||
<label
|
||||
for="donation_amount_eur"
|
||||
class="block text-sm font-medium text-gray-700">
|
||||
{#if !is_fixed}{$_('amount-per-kilometer')}{:else}{$_('donation-amount')}{/if}</label>
|
||||
{#if !is_fixed}
|
||||
{$_('amount-per-kilometer')}
|
||||
{:else}{$_('donation-amount')}{/if}</label>
|
||||
<div class="mt-1 flex rounded-md shadow-sm">
|
||||
<input
|
||||
autocomplete="off"
|
||||
|
|
|
@ -8,44 +8,60 @@
|
|||
} from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import PromiseError from "../base/PromiseError.svelte";
|
||||
import Select from "svelte-select";
|
||||
let data_loaded = false;
|
||||
export let params;
|
||||
$: delete_triggered = false;
|
||||
$: original_data = {};
|
||||
$: original_comparison_string = "";
|
||||
$: editable = {};
|
||||
$: donor = {};
|
||||
$: runner = {};
|
||||
$: current_donors = [];
|
||||
$: current_runners = [];
|
||||
$: amount_input = 0;
|
||||
$: is_amount_valid = amount_input > 0;
|
||||
$: is_everything_set =
|
||||
editable.donor != null &&
|
||||
((original_data.responseType == "DISTANCEDONATION" &&
|
||||
editable?.runner != null) ||
|
||||
original_data.responseType !== "DISTANCEDONATION");
|
||||
$: changes_performed =
|
||||
!(original_comparison_string === JSON.stringify(editable)) ||
|
||||
!(JSON.stringify(original_data) === JSON.stringify(editable)) ||
|
||||
(original_data.responseType == "DISTANCEDONATION" &&
|
||||
!(Math.floor(amount_input * 100) === original_data.amountPerDistance)) ||
|
||||
(original_data.responseType !== "DISTANCEDONATION" &&
|
||||
!(Math.floor(amount_input * 100) === original_data.amount));
|
||||
$: save_enabled = changes_performed && is_amount_valid;
|
||||
const donor_promise = DonorService.donorControllerGetAll().then((val) => {
|
||||
current_donors = val;
|
||||
});
|
||||
const runner_promise = RunnerService.runnerControllerGetAll().then((val) => {
|
||||
current_runners = val;
|
||||
});
|
||||
$: save_enabled = changes_performed && is_amount_valid && is_everything_set;
|
||||
|
||||
const promise = DonationService.donationControllerGetOne(
|
||||
params.donationid
|
||||
).then((data) => {
|
||||
data_loaded = true;
|
||||
original_data = Object.assign(original_data, data);
|
||||
editable = Object.assign(editable, original_data);
|
||||
editable.donor = data.donor.id;
|
||||
if (data.responseType == "DISTANCEDONATION") {
|
||||
editable.runner = data.runner.id;
|
||||
amount_input = data.amountPerDistance / 100;
|
||||
RunnerService.runnerControllerGetAll().then((val) => {
|
||||
current_runners = val.map((r) => {
|
||||
return { label: getDonorLabel(r), value: r };
|
||||
});
|
||||
runner = current_runners.find((g) => g.value.id == editable.runner.id);
|
||||
});
|
||||
} else {
|
||||
amount_input = data.amount / 100;
|
||||
}
|
||||
original_comparison_string = JSON.stringify(editable);
|
||||
DonorService.donorControllerGetAll().then((val) => {
|
||||
current_donors = val.map((r) => {
|
||||
return { label: getDonorLabel(r), value: r };
|
||||
});
|
||||
donor = current_donors.find((g) => g.value.id == editable.donor.id);
|
||||
});
|
||||
});
|
||||
const getDonorLabel = (option) =>
|
||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||
const filterDonors = (label, filterText, option) =>
|
||||
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||
option.value.id.toString().startsWith(filterText.toLowerCase());
|
||||
|
||||
function submit() {
|
||||
if (data_loaded === true && save_enabled) {
|
||||
|
@ -53,14 +69,18 @@
|
|||
text: "Donation is being updated",
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
let postdata = {};
|
||||
if (original_data.responseType === "DISTANCEDONATION") {
|
||||
editable.amountPerDistance = Math.floor(amount_input * 100);
|
||||
postdata = Object.assign(postdata, editable);
|
||||
postdata.runner = postdata.runner.id;
|
||||
postdata.donor = postdata.donor.id;
|
||||
DonationService.donationControllerPutDistance(
|
||||
original_data.id,
|
||||
editable
|
||||
postdata
|
||||
)
|
||||
.then((resp) => {
|
||||
Object.assign(original_data, resp);
|
||||
Object.assign(original_data, editable);
|
||||
original_data = original_data;
|
||||
Toastify({
|
||||
text: "updated donation",
|
||||
|
@ -71,7 +91,9 @@
|
|||
.catch((err) => {});
|
||||
} else {
|
||||
editable.amount = Math.floor(amount_input * 100);
|
||||
DonationService.donationControllerPutFixed(original_data.id, editable)
|
||||
postdata = Object.assign(postdata, editable);
|
||||
postdata.donor = postdata.donor.id;
|
||||
DonationService.donationControllerPutFixed(original_data.id, postdata)
|
||||
.then((resp) => {
|
||||
Object.assign(original_data, editable);
|
||||
original_data = original_data;
|
||||
|
@ -103,7 +125,7 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
{#await donor_promise && runner_promise && promise}
|
||||
{#await promise}
|
||||
{$_('loading-donation-details')}
|
||||
{:then}
|
||||
<section class="container p-5 select-none">
|
||||
|
@ -192,7 +214,8 @@
|
|||
</div>
|
||||
<!-- -->
|
||||
<div>
|
||||
<span class="font-medium text-gray-700">{$_('total-donation-amount')}:</span>
|
||||
<span
|
||||
class="font-medium text-gray-700">{$_('total-donation-amount')}:</span>
|
||||
<span>{(editable.amount / 100)
|
||||
.toFixed(2)
|
||||
.toLocaleString('de-DE', { valute: 'EUR' })}€</span>
|
||||
|
@ -201,34 +224,32 @@
|
|||
<label
|
||||
for="donor"
|
||||
class="block font-medium text-gray-700">{$_('donor')}</label>
|
||||
<select
|
||||
bind:value={editable.donor}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
{#each current_donors as d}
|
||||
<option value={d.id}>
|
||||
{d.firstname}
|
||||
{d.middlename || ''}
|
||||
{d.lastname}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => filterDonors(label, filterText, option)}
|
||||
items={current_donors}
|
||||
showChevron={true}
|
||||
placeholder={$_('search-for-donor-name-or-id')}
|
||||
noOptionsMessage={$_('no-donors-found')}
|
||||
bind:selectedValue={donor}
|
||||
on:select={(selectedValue) => (editable.donor = selectedValue.detail.value)}
|
||||
on:clear={() => (editable.donor = null)} />
|
||||
</div>
|
||||
{#if original_data.responseType == 'DISTANCEDONATION'}
|
||||
<div class=" w-full">
|
||||
<label
|
||||
for="donor"
|
||||
class="block font-medium text-gray-700">{$_('runner')}</label>
|
||||
<select
|
||||
bind:value={editable.runner}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
{#each current_runners as r}
|
||||
<option value={r.id}>
|
||||
{r.firstname}
|
||||
{r.middlename || ''}
|
||||
{r.lastname}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => filterDonors(label, filterText, option)}
|
||||
items={current_runners}
|
||||
showChevron={true}
|
||||
placeholder={$_('search-for-runner-by-name-or-id')}
|
||||
noOptionsMessage={$_('no-runners-found')}
|
||||
bind:selectedValue={runner}
|
||||
on:select={(selectedValue) => (editable.runner = selectedValue.detail.value)}
|
||||
on:clear={() => (editable.runner = null)} />
|
||||
</div>
|
||||
{/if}
|
||||
<div class=" w-full">
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import FormLayout from "../base/FormLayout.svelte";
|
||||
</script>
|
||||
|
||||
<div class="pt-12 px-4 sm:px-6 lg:px-8 lg:pt-20 bg-gray-900 pb-12">
|
||||
<div class="text-center mb-8">
|
||||
<h1
|
||||
class="mt-9 font-display text-4xl leading-none font-semibold text-white sm:text-5xl lg:text-6xl">
|
||||
🔨<br />{$_('settings')}
|
||||
</h1>
|
||||
<p
|
||||
class="mt-2 max-w-xl mx-auto text-xl lg:max-w-3xl lg:text-2xl text-gray-300">
|
||||
<span class="text-lg">configure your profile however you want</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-0 pb-16 bg-gray-50 overflow-hidden lg:pt-12 lg:py-24">
|
||||
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
|
||||
<!-- <h2 class="text-4xl font-display font-semibold text-gray-900 md:text-5xl">
|
||||
General
|
||||
</h2> -->
|
||||
<div
|
||||
class="max-w-3xl mx-auto text-xl leading-8 font-medium text-gray-900 mb-16">
|
||||
<p class="text-center">
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Temporibus et
|
||||
amet voluptate nulla accusantium vero blanditiis nobis facere veritatis.
|
||||
Impedit deserunt saepe aliquid unde consequuntur officia consequatur
|
||||
fugit iusto dolorem?
|
||||
</p>
|
||||
</div>
|
||||
<FormLayout />
|
||||
</div>
|
||||
</div>
|
|
@ -1,221 +1,220 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import lodashIsEqual from "lodash.isequal";
|
||||
import store from "../../store";
|
||||
import {
|
||||
UserGroupService
|
||||
} from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import PromiseError from "../base/PromiseError.svelte";
|
||||
let data_loaded = false;
|
||||
export let params;
|
||||
const promise = UserGroupService.userGroupControllerGetOne(params.groupid);
|
||||
const colors = [
|
||||
"#f3558e",
|
||||
"#17b978",
|
||||
"#3498db",
|
||||
"#3f3b3b",
|
||||
"#775ada",
|
||||
"#7ed6df_#000000",
|
||||
"#000000",
|
||||
"#21e6c1_#000000",
|
||||
"#c0392b",
|
||||
"#d35400",
|
||||
"#7f8c8d",
|
||||
"#6ab04c",
|
||||
"#4834d4",
|
||||
"#ff1f5a",
|
||||
"#eac100",
|
||||
];
|
||||
let matched_colors = [];
|
||||
$: delete_triggered = false;
|
||||
$: search_permission = "";
|
||||
$: original_data = {};
|
||||
$: editable = {};
|
||||
$: changes_performed = !lodashIsEqual(original_data, editable);
|
||||
$: isGroupnameValid = editable.name !== "";
|
||||
$: save_enabled =
|
||||
changes_performed && isGroupnameValid
|
||||
promise.then((data) => {
|
||||
let current_target = "";
|
||||
let colorindex = -1;
|
||||
data.permissions = data.permissions.sort();
|
||||
data.permissions.forEach((p) => {
|
||||
const target = p.split(":")[0];
|
||||
if (current_target !== p.split(":")[0]) {
|
||||
colorindex++;
|
||||
current_target = p.split(":")[0];
|
||||
}
|
||||
let background = colors[colorindex];
|
||||
let foreground = "#fff";
|
||||
if (background.includes("_")) {
|
||||
foreground = background.split("_")[1];
|
||||
background = background.split("_")[0];
|
||||
}
|
||||
matched_colors[target] = [background, foreground];
|
||||
});
|
||||
data_loaded = true;
|
||||
original_data = Object.assign(original_data, data);
|
||||
editable = Object.assign(editable, original_data);
|
||||
});
|
||||
function submit() {
|
||||
if (data_loaded === true && save_enabled) {
|
||||
Toastify({
|
||||
text: $_('updateing-group'),
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
UserGroupService.userGroupControllerPut(original_data.id, editable)
|
||||
.then((resp) => {
|
||||
Object.assign(original_data, editable);
|
||||
original_data = editable;
|
||||
Object.assign(original_data, editable);
|
||||
Toastify({
|
||||
text: $_('group-updated'),
|
||||
duration: 2500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
})
|
||||
.catch((err) => {});
|
||||
} else {
|
||||
}
|
||||
}
|
||||
function deleteGroup() {
|
||||
UserGroupService.userGroupControllerRemove(original_data.id, true)
|
||||
.then((resp) => {
|
||||
location.replace("./");
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
</script>
|
||||
|
||||
{#await promise}
|
||||
{$_('loading-group-detail')}
|
||||
{:then}
|
||||
<section class="container p-5 select-none">
|
||||
<div class="flex flex-row mb-4">
|
||||
<div class="w-full">
|
||||
<nav class="w-full flex">
|
||||
<ol class="list-none flex flex-row items-center justify-start">
|
||||
<li class="flex items-center">
|
||||
<svg class="flex-shrink-0 w-5 h-5 mr-2" fill="currentColor" width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M610.5 341.3c2.6-14.1 2.6-28.5 0-42.6l25.8-14.9c3-1.7 4.3-5.2 3.3-8.5-6.7-21.6-18.2-41.2-33.2-57.4-2.3-2.5-6-3.1-9-1.4l-25.8 14.9c-10.9-9.3-23.4-16.5-36.9-21.3v-29.8c0-3.4-2.4-6.4-5.7-7.1-22.3-5-45-4.8-66.2 0-3.3.7-5.7 3.7-5.7 7.1v29.8c-13.5 4.8-26 12-36.9 21.3l-25.8-14.9c-2.9-1.7-6.7-1.1-9 1.4-15 16.2-26.5 35.8-33.2 57.4-1 3.3.4 6.8 3.3 8.5l25.8 14.9c-2.6 14.1-2.6 28.5 0 42.6l-25.8 14.9c-3 1.7-4.3 5.2-3.3 8.5 6.7 21.6 18.2 41.1 33.2 57.4 2.3 2.5 6 3.1 9 1.4l25.8-14.9c10.9 9.3 23.4 16.5 36.9 21.3v29.8c0 3.4 2.4 6.4 5.7 7.1 22.3 5 45 4.8 66.2 0 3.3-.7 5.7-3.7 5.7-7.1v-29.8c13.5-4.8 26-12 36.9-21.3l25.8 14.9c2.9 1.7 6.7 1.1 9-1.4 15-16.2 26.5-35.8 33.2-57.4 1-3.3-.4-6.8-3.3-8.5l-25.8-14.9zM496 368.5c-26.8 0-48.5-21.8-48.5-48.5s21.8-48.5 48.5-48.5 48.5 21.8 48.5 48.5-21.7 48.5-48.5 48.5zM96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm224 32c1.9 0 3.7-.5 5.6-.6 8.3-21.7 20.5-42.1 36.3-59.2 7.4-8 17.9-12.6 28.9-12.6 6.9 0 13.7 1.8 19.6 5.3l7.9 4.6c.8-.5 1.6-.9 2.4-1.4 7-14.6 11.2-30.8 11.2-48 0-61.9-50.1-112-112-112S208 82.1 208 144c0 61.9 50.1 112 112 112zm105.2 194.5c-2.3-1.2-4.6-2.6-6.8-3.9-8.2 4.8-15.3 9.8-27.5 9.8-10.9 0-21.4-4.6-28.9-12.6-18.3-19.8-32.3-43.9-40.2-69.6-10.7-34.5 24.9-49.7 25.8-50.3-.1-2.6-.1-5.2 0-7.8l-7.9-4.6c-3.8-2.2-7-5-9.8-8.1-3.3.2-6.5.6-9.8.6-24.6 0-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h255.4c-3.7-6-6.2-12.8-6.2-20.3v-9.2zM173.1 274.6C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z"></path></svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<a class="mr-2" href="../">{$_('groups')}</a><svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="h-3 w-3 mr-2 stroke-current"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"><line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12" />
|
||||
<polyline points="12 5 19 12 12 19" /></svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<span class="mr-2">{editable.name}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||
{original_data.name}
|
||||
<span data-id="group_actions_${editable.id}">
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:DELETE')}
|
||||
{#if delete_triggered}
|
||||
<button
|
||||
on:click={deleteGroup}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-deletion')}</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = !delete_triggered;
|
||||
}}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm">{$_('cancel')}</button>
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = true;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-group')}</button>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
disabled={!save_enabled}
|
||||
class:opacity-50={!save_enabled}
|
||||
type="button"
|
||||
on:click={submit}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('save-changes')}</button>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="title"
|
||||
class="font-medium text-gray-700">{$_('name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('name')}
|
||||
type="text"
|
||||
bind:value={editable.name}
|
||||
class:border-red-500={!isGroupnameValid}
|
||||
class:focus:border-red-500={!isGroupnameValid}
|
||||
class:focus:ring-red-500={!isGroupnameValid}
|
||||
name="title"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
||||
{#if !isGroupnameValid}
|
||||
<span
|
||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||
{$_('group-name-is-required')}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="firstname"
|
||||
class="font-medium text-gray-700">{$_('description')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('description')}
|
||||
type="text"
|
||||
bind:value={editable.description}
|
||||
name="firstname"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full mt-8">
|
||||
<p class="font-medium mb-4">
|
||||
{$_('permissions')}
|
||||
<a
|
||||
class="px-4 py-2 bg-gray-500 rounded-md text-white"
|
||||
href="/groups/{params.groupid}/permissions/">{$_('edit-permissions')}</a>
|
||||
</p>
|
||||
<div class="w-full sm:my-px sm:px-px sm:w-1/2">
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="{$_('search-for-permission')}"
|
||||
type="text"
|
||||
bind:value={search_permission}
|
||||
class="mt-4 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
{#each original_data.permissions as p}
|
||||
{#if p.toLowerCase().includes(search_permission.toLowerCase())}
|
||||
<span
|
||||
style="background:{matched_colors[p.split(':')[0]][0]};color:{matched_colors[p.split(':')[0]][1]};"
|
||||
class="mt-1 inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-indigo-100 rounded">{p}</span>
|
||||
<!-- -->
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
{:catch error}
|
||||
<PromiseError {error} />
|
||||
{/await}
|
||||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import store from "../../store";
|
||||
import {
|
||||
UserGroupService
|
||||
} from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import PromiseError from "../base/PromiseError.svelte";
|
||||
let data_loaded = false;
|
||||
export let params;
|
||||
const promise = UserGroupService.userGroupControllerGetOne(params.groupid);
|
||||
const colors = [
|
||||
"#f3558e",
|
||||
"#17b978",
|
||||
"#3498db",
|
||||
"#3f3b3b",
|
||||
"#775ada",
|
||||
"#7ed6df_#000000",
|
||||
"#000000",
|
||||
"#21e6c1_#000000",
|
||||
"#c0392b",
|
||||
"#d35400",
|
||||
"#7f8c8d",
|
||||
"#6ab04c",
|
||||
"#4834d4",
|
||||
"#ff1f5a",
|
||||
"#eac100",
|
||||
];
|
||||
let matched_colors = [];
|
||||
$: delete_triggered = false;
|
||||
$: search_permission = "";
|
||||
$: original_data = {};
|
||||
$: editable = {};
|
||||
$: changes_performed = !(JSON.stringify(original_data) == JSON.stringify(editable));
|
||||
$: isGroupnameValid = editable.name !== "";
|
||||
$: save_enabled =
|
||||
changes_performed && isGroupnameValid
|
||||
promise.then((data) => {
|
||||
let current_target = "";
|
||||
let colorindex = -1;
|
||||
data.permissions = data.permissions.sort();
|
||||
data.permissions.forEach((p) => {
|
||||
const target = p.split(":")[0];
|
||||
if (current_target !== p.split(":")[0]) {
|
||||
colorindex++;
|
||||
current_target = p.split(":")[0];
|
||||
}
|
||||
let background = colors[colorindex];
|
||||
let foreground = "#fff";
|
||||
if (background.includes("_")) {
|
||||
foreground = background.split("_")[1];
|
||||
background = background.split("_")[0];
|
||||
}
|
||||
matched_colors[target] = [background, foreground];
|
||||
});
|
||||
data_loaded = true;
|
||||
original_data = Object.assign(original_data, data);
|
||||
editable = Object.assign(editable, original_data);
|
||||
});
|
||||
function submit() {
|
||||
if (data_loaded === true && save_enabled) {
|
||||
Toastify({
|
||||
text: $_('updateing-group'),
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
UserGroupService.userGroupControllerPut(original_data.id, editable)
|
||||
.then((resp) => {
|
||||
Object.assign(original_data, editable);
|
||||
original_data = editable;
|
||||
Object.assign(original_data, editable);
|
||||
Toastify({
|
||||
text: $_('group-updated'),
|
||||
duration: 2500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
})
|
||||
.catch((err) => {});
|
||||
} else {
|
||||
}
|
||||
}
|
||||
function deleteGroup() {
|
||||
UserGroupService.userGroupControllerRemove(original_data.id, true)
|
||||
.then((resp) => {
|
||||
location.replace("./");
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
</script>
|
||||
|
||||
{#await promise}
|
||||
{$_('loading-group-detail')}
|
||||
{:then}
|
||||
<section class="container p-5 select-none">
|
||||
<div class="flex flex-row mb-4">
|
||||
<div class="w-full">
|
||||
<nav class="w-full flex">
|
||||
<ol class="list-none flex flex-row items-center justify-start">
|
||||
<li class="flex items-center">
|
||||
<svg class="flex-shrink-0 w-5 h-5 mr-2" fill="currentColor" width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M610.5 341.3c2.6-14.1 2.6-28.5 0-42.6l25.8-14.9c3-1.7 4.3-5.2 3.3-8.5-6.7-21.6-18.2-41.2-33.2-57.4-2.3-2.5-6-3.1-9-1.4l-25.8 14.9c-10.9-9.3-23.4-16.5-36.9-21.3v-29.8c0-3.4-2.4-6.4-5.7-7.1-22.3-5-45-4.8-66.2 0-3.3.7-5.7 3.7-5.7 7.1v29.8c-13.5 4.8-26 12-36.9 21.3l-25.8-14.9c-2.9-1.7-6.7-1.1-9 1.4-15 16.2-26.5 35.8-33.2 57.4-1 3.3.4 6.8 3.3 8.5l25.8 14.9c-2.6 14.1-2.6 28.5 0 42.6l-25.8 14.9c-3 1.7-4.3 5.2-3.3 8.5 6.7 21.6 18.2 41.1 33.2 57.4 2.3 2.5 6 3.1 9 1.4l25.8-14.9c10.9 9.3 23.4 16.5 36.9 21.3v29.8c0 3.4 2.4 6.4 5.7 7.1 22.3 5 45 4.8 66.2 0 3.3-.7 5.7-3.7 5.7-7.1v-29.8c13.5-4.8 26-12 36.9-21.3l25.8 14.9c2.9 1.7 6.7 1.1 9-1.4 15-16.2 26.5-35.8 33.2-57.4 1-3.3-.4-6.8-3.3-8.5l-25.8-14.9zM496 368.5c-26.8 0-48.5-21.8-48.5-48.5s21.8-48.5 48.5-48.5 48.5 21.8 48.5 48.5-21.7 48.5-48.5 48.5zM96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm224 32c1.9 0 3.7-.5 5.6-.6 8.3-21.7 20.5-42.1 36.3-59.2 7.4-8 17.9-12.6 28.9-12.6 6.9 0 13.7 1.8 19.6 5.3l7.9 4.6c.8-.5 1.6-.9 2.4-1.4 7-14.6 11.2-30.8 11.2-48 0-61.9-50.1-112-112-112S208 82.1 208 144c0 61.9 50.1 112 112 112zm105.2 194.5c-2.3-1.2-4.6-2.6-6.8-3.9-8.2 4.8-15.3 9.8-27.5 9.8-10.9 0-21.4-4.6-28.9-12.6-18.3-19.8-32.3-43.9-40.2-69.6-10.7-34.5 24.9-49.7 25.8-50.3-.1-2.6-.1-5.2 0-7.8l-7.9-4.6c-3.8-2.2-7-5-9.8-8.1-3.3.2-6.5.6-9.8.6-24.6 0-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h255.4c-3.7-6-6.2-12.8-6.2-20.3v-9.2zM173.1 274.6C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z"></path></svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<a class="mr-2" href="../">{$_('groups')}</a><svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="h-3 w-3 mr-2 stroke-current"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"><line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12" />
|
||||
<polyline points="12 5 19 12 12 19" /></svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<span class="mr-2">{editable.name}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||
{original_data.name}
|
||||
<span data-id="group_actions_${editable.id}">
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:DELETE')}
|
||||
{#if delete_triggered}
|
||||
<button
|
||||
on:click={deleteGroup}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-deletion')}</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = !delete_triggered;
|
||||
}}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm">{$_('cancel')}</button>
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = true;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-group')}</button>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
disabled={!save_enabled}
|
||||
class:opacity-50={!save_enabled}
|
||||
type="button"
|
||||
on:click={submit}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('save-changes')}</button>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="title"
|
||||
class="font-medium text-gray-700">{$_('name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('name')}
|
||||
type="text"
|
||||
bind:value={editable.name}
|
||||
class:border-red-500={!isGroupnameValid}
|
||||
class:focus:border-red-500={!isGroupnameValid}
|
||||
class:focus:ring-red-500={!isGroupnameValid}
|
||||
name="title"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
||||
{#if !isGroupnameValid}
|
||||
<span
|
||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||
{$_('group-name-is-required')}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="firstname"
|
||||
class="font-medium text-gray-700">{$_('description')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('description')}
|
||||
type="text"
|
||||
bind:value={editable.description}
|
||||
name="firstname"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full mt-8">
|
||||
<p class="font-medium mb-4">
|
||||
{$_('permissions')}
|
||||
<a
|
||||
class="px-4 py-2 bg-gray-500 rounded-md text-white"
|
||||
href="/groups/{params.groupid}/permissions/">{$_('edit-permissions')}</a>
|
||||
</p>
|
||||
<div class="w-full sm:my-px sm:px-px sm:w-1/2">
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="{$_('search-for-permission')}"
|
||||
type="text"
|
||||
bind:value={search_permission}
|
||||
class="mt-4 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
{#each original_data.permissions as p}
|
||||
{#if p.toLowerCase().includes(search_permission.toLowerCase())}
|
||||
<span
|
||||
style="background:{matched_colors[p.split(':')[0]][0]};color:{matched_colors[p.split(':')[0]][1]};"
|
||||
class="mt-1 inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-indigo-100 rounded">{p}</span>
|
||||
<!-- -->
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
{:catch error}
|
||||
<PromiseError {error} />
|
||||
{/await}
|
||||
|
|
|
@ -67,7 +67,6 @@ UserGroupService,
|
|||
delete p.responseType;
|
||||
grantedPermissions = grantedPermissions.concat([p]);
|
||||
});
|
||||
console.log(grantedPermissions)
|
||||
grantedPermissions_initial = grantedPermissions;
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
|
||||
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
|
||||
import PromiseError from "../base/PromiseError.svelte";
|
||||
import Select from "svelte-select";
|
||||
$: delete_triggered = false;
|
||||
$: address_valid_or_none =
|
||||
(isAddress1Valid && iszipcodevalid && iscityvalid) ||
|
||||
|
@ -19,22 +20,19 @@
|
|||
let contacts = [];
|
||||
export let params;
|
||||
$: editable = {};
|
||||
$: contact = {};
|
||||
$: data_loaded = false;
|
||||
$: data_changed = !(JSON.stringify(editable) === original);
|
||||
$: isAddress1Valid = editable.address?.address1?.trim().length !== 0;
|
||||
$: iszipcodevalid = editable.address?.postalcode?.trim().length !== 0;
|
||||
$: iscityvalid = editable.address?.city?.trim().length !== 0;
|
||||
$: sponsoring_contracts_download_open = false;
|
||||
|
||||
const getContactLabel = (option) =>
|
||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||
const promise = RunnerOrganizationService.runnerOrganizationControllerGetOne(
|
||||
params.orgid
|
||||
).then((value) => {
|
||||
data_loaded = true;
|
||||
if (value.contact) {
|
||||
if (value.contact !== "null") {
|
||||
value.contact = value.contact.id;
|
||||
}
|
||||
}
|
||||
value.address_checked = value.address.address1 !== null;
|
||||
if (value.address_checked === false) {
|
||||
value.address = {
|
||||
|
@ -49,16 +47,23 @@
|
|||
editable = editable;
|
||||
original_object = Object.assign(editable, value);
|
||||
original = JSON.stringify(value);
|
||||
});
|
||||
GroupContactService.groupContactControllerGetAll().then((val) => {
|
||||
contacts = val;
|
||||
GroupContactService.groupContactControllerGetAll().then((val) => {
|
||||
contacts = val.map((r) => {
|
||||
return { label: getContactLabel(r), value: r };
|
||||
});
|
||||
if (editable.contact) {
|
||||
contact = contacts.find((g) => g.value.id == editable.contact.id);
|
||||
} else {
|
||||
contact = null;
|
||||
}
|
||||
});
|
||||
});
|
||||
let modal_open = false;
|
||||
let delete_org = {};
|
||||
document.addEventListener("click", function (e) {
|
||||
if (
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown:menu"
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
||||
) {
|
||||
sponsoring_contracts_download_open = false;
|
||||
}
|
||||
|
@ -91,13 +96,14 @@
|
|||
if (postdata.address_checked === false) {
|
||||
postdata.address = null;
|
||||
}
|
||||
postdata.contact = postdata.contact === "null" ? null : postdata.contact;
|
||||
postdata.contact = postdata.contact?.id;
|
||||
RunnerOrganizationService.runnerOrganizationControllerPut(
|
||||
original_object.id,
|
||||
postdata
|
||||
)
|
||||
.then((resp) => {
|
||||
original = JSON.stringify(editable);
|
||||
original_object = Object.assign({}, editable);
|
||||
original = JSON.stringify(original_object);
|
||||
Toastify({
|
||||
text: $_("updated-organization"),
|
||||
duration: 2500,
|
||||
|
@ -188,7 +194,17 @@
|
|||
aria-haspopup="true"
|
||||
aria-expanded="true">
|
||||
{$_('generate-sponsoring-contracts')}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="-mr-1 ml-2 h-5 w-5"><path fill="none" d="M0 0h24v24H0z"/><path fill="currentColor" d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z"/></svg>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
class="-mr-1 ml-2 h-5 w-5"><path
|
||||
fill="none"
|
||||
d="M0 0h24v24H0z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
{#if sponsoring_contracts_download_open}
|
||||
|
@ -349,19 +365,22 @@
|
|||
<label
|
||||
for="contact"
|
||||
class="font-medium text-gray-700">{$_('contact')}</label>
|
||||
<select
|
||||
name="contact"
|
||||
bind:value={editable.contact}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
<option value="null">no contact</option>
|
||||
{#each contacts as c}
|
||||
<option value={c.id}>
|
||||
{c.firstname}
|
||||
{c.middlename || ''}
|
||||
{c.lastname}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => label
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
filterText.toLowerCase()
|
||||
) || option.value.id
|
||||
.toString()
|
||||
.startsWith(filterText.toLowerCase())}
|
||||
items={contacts}
|
||||
showChevron={true}
|
||||
placeholder={$_('no-contact-selected')}
|
||||
noOptionsMessage={$_('no-contact-found')}
|
||||
bind:selectedValue={contact}
|
||||
on:select={(selectedValue) => (editable.contact = selectedValue.detail.value)}
|
||||
on:clear={() => (editable.contact = null)} />
|
||||
</div>
|
||||
<!-- -->
|
||||
<div class="flex items-start mt-2">
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
|
||||
document.addEventListener("click", function (e) {
|
||||
if (
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown:menu"
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
||||
) {
|
||||
sponsoring_contracts_download_open = false;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
import isEmail from "validator/es/lib/isEmail";
|
||||
import isMobilePhone from "validator/es/lib/isMobilePhone";
|
||||
import Toastify from "toastify-js";
|
||||
import Select from "svelte-select";
|
||||
export let modal_open;
|
||||
export let current_runners;
|
||||
$: selected_team = undefined;
|
||||
|
@ -20,11 +21,15 @@
|
|||
let email_input;
|
||||
let teams = [];
|
||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||
teams = val;
|
||||
teams = val.map((r) => {
|
||||
return { label: `${r.parentGroup.name} > ${r.name}`, value: r };
|
||||
});
|
||||
});
|
||||
let orgs = [];
|
||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||
orgs = val;
|
||||
orgs = val.map((r) => {
|
||||
return { label: r.name, value: r };
|
||||
});
|
||||
});
|
||||
function focus(el) {
|
||||
el.focus();
|
||||
|
@ -136,7 +141,7 @@
|
|||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||
aria-hidden="true">​</span>
|
||||
<div
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline">
|
||||
|
@ -206,7 +211,7 @@
|
|||
class="block text-sm font-medium text-gray-700">{$_('last-name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="{$_('last-name')}"
|
||||
placeholder={$_('last-name')}
|
||||
class:border-red-500={!isLastnameValid}
|
||||
class:focus:border-red-500={!isLastnameValid}
|
||||
class:focus:ring-red-500={!isLastnameValid}
|
||||
|
@ -226,21 +231,21 @@
|
|||
<label
|
||||
for="team"
|
||||
class="block text-sm font-medium text-gray-700">{$_('team')}</label>
|
||||
<select
|
||||
name="team"
|
||||
bind:value={selected_team}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
{#each teams as team}
|
||||
<option value={team.id}>
|
||||
{team.parentGroup.name}
|
||||
>
|
||||
{team.name}
|
||||
</option>
|
||||
{/each}
|
||||
{#each orgs as org}
|
||||
<option value={org.id}>{org.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => label
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
filterText.toLowerCase()
|
||||
) || option.value.id
|
||||
.toString()
|
||||
.startsWith(filterText.toLowerCase())}
|
||||
items={orgs.concat(teams)}
|
||||
showChevron={true}
|
||||
placeholder={$_('search-for-an-organization-or-team-by-name-or-id')}
|
||||
noOptionsMessage={$_('no-organization-or-team-found')}
|
||||
on:select={(selectedValue) => (selected_team = selectedValue.detail.value.id)}
|
||||
on:clear={() => (selected_team = null)} />
|
||||
</div>
|
||||
<div class="col-span-6">
|
||||
<label
|
||||
|
@ -248,7 +253,7 @@
|
|||
class="block text-sm font-medium text-gray-700">{$_('phone')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="{$_('phone')}"
|
||||
placeholder={$_('phone')}
|
||||
class:border-red-500={!isPhoneValidOrEmpty}
|
||||
class:focus:border-red-500={!isPhoneValidOrEmpty}
|
||||
class:focus:ring-red-500={!isPhoneValidOrEmpty}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
RunnerOrganizationService,
|
||||
} from "@odit/lfk-client-js";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import Select from "svelte-select";
|
||||
export let opened_from;
|
||||
export let passed_org;
|
||||
export let passed_orgs;
|
||||
|
@ -35,22 +36,18 @@
|
|||
}
|
||||
};
|
||||
})();
|
||||
let orgs = [];
|
||||
let groups = [];
|
||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||
orgs = val;
|
||||
if(opened_from === 'OrgOverview'){
|
||||
selected_org = orgs[0].id
|
||||
}
|
||||
});
|
||||
let teams = [];
|
||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||
teams = val;
|
||||
if (opened_from === "RunnerOverview" && teams.length>0) {
|
||||
selected_org_or_team = "TEAM_" + teams[0].id;
|
||||
}
|
||||
if(teams.length==0 && orgs.length>0){
|
||||
selected_org_or_team = "ORG_" + orgs[0].id
|
||||
}
|
||||
const orgs = val.map((r) => {
|
||||
return { label: r.name, value: `ORG_${r.id}` };
|
||||
});
|
||||
groups = groups.concat(orgs);
|
||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||
const teams = val.map((r) => {
|
||||
return { label: `${r.parentGroup.name} > ${r.name}`, value: `TEAM_${r.id}` };
|
||||
});
|
||||
groups = groups.concat(teams);
|
||||
});
|
||||
});
|
||||
let selected_org;
|
||||
$: selected_org_or_team = "";
|
||||
|
@ -264,21 +261,23 @@
|
|||
{/if}
|
||||
{#if opened_from === 'RunnerOverview'}
|
||||
<p>{$_('group')}</p>
|
||||
<select
|
||||
name="team"
|
||||
bind:value={selected_org_or_team}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
{#each teams as team}
|
||||
<option value="TEAM_{team.id}">
|
||||
{team.parentGroup.name}
|
||||
>
|
||||
{team.name}
|
||||
</option>
|
||||
{/each}
|
||||
{#each orgs as org}
|
||||
<option value="ORG_{org.id}">{org.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => label
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
filterText.toLowerCase()
|
||||
) || option.id.value
|
||||
.toString()
|
||||
.startsWith(filterText.toLowerCase())}
|
||||
items={groups}
|
||||
showChevron={true}
|
||||
placeholder={$_('search-for-an-organization-or-team-by-name-or-id')}
|
||||
noOptionsMessage={$_('no-organization-or-team-found')}
|
||||
on:select={(selectedValue) => {
|
||||
selected_org_or_team = selectedValue.detail.value;
|
||||
}}
|
||||
on:clear={() => (selected_org_or_team = null)} />
|
||||
{/if}
|
||||
{#if opened_from === 'OrgDetail'}
|
||||
<p>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<script>
|
||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||
import lodashIsEqual from "lodash.isequal";
|
||||
import store from "../../store";
|
||||
import {
|
||||
RunnerService,
|
||||
|
@ -10,6 +9,7 @@
|
|||
import Toastify from "toastify-js";
|
||||
import PromiseError from "../base/PromiseError.svelte";
|
||||
import isEmail from "validator/es/lib/isEmail";
|
||||
import Select from "svelte-select";
|
||||
let data_loaded = false;
|
||||
export let params;
|
||||
const runner_promise = RunnerService.runnerControllerGetOne(params.runnerid);
|
||||
|
@ -18,48 +18,61 @@
|
|||
$: original_data_pdf = {};
|
||||
$: original_data = {};
|
||||
$: editable = {};
|
||||
$: changes_performed = !lodashIsEqual(original_data, editable);
|
||||
$: group = {}
|
||||
$: changes_performed = !(JSON.stringify(original_data) == JSON.stringify(editable));
|
||||
$: isEmailValid =
|
||||
(editable.email || "") === "" ||
|
||||
(editable.email && isEmail(editable.email || ""));
|
||||
$: isFirstnameValid = editable.firstname !== "";
|
||||
$: isLastnameValid = editable.lastname !== "";
|
||||
$: save_enabled =
|
||||
changes_performed && isFirstnameValid && isLastnameValid && isEmailValid;
|
||||
changes_performed &&
|
||||
isFirstnameValid &&
|
||||
isLastnameValid &&
|
||||
isEmailValid &&
|
||||
editable.group != null;
|
||||
runner_promise.then((data) => {
|
||||
data_loaded = true;
|
||||
original_data_pdf = Object.assign(original_data_pdf, data);
|
||||
data.group = data.group.id;
|
||||
original_data = Object.assign(original_data, data);
|
||||
original_data.group = original_data.group.id;
|
||||
editable = Object.assign(editable, original_data);
|
||||
|
||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||
const orgs = val.map((r) => {
|
||||
return { label: r.name, value: r };
|
||||
});
|
||||
groups = groups.concat(orgs);
|
||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||
const teams = val.map((r) => {
|
||||
return { label: `${r.parentGroup.name} > ${r.name}`, value: r };
|
||||
});
|
||||
groups = groups.concat(teams);
|
||||
group = groups.find(g => g.value.id == editable.group)
|
||||
});
|
||||
});
|
||||
});
|
||||
document.addEventListener("click", function (e) {
|
||||
if (
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown:menu"
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
||||
) {
|
||||
sponsoring_contracts_download_open = false;
|
||||
}
|
||||
});
|
||||
let orgs = [];
|
||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||
orgs = val;
|
||||
});
|
||||
let teams = [];
|
||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||
teams = val;
|
||||
});
|
||||
let groups = [];
|
||||
function submit() {
|
||||
if (data_loaded === true && save_enabled) {
|
||||
Toastify({
|
||||
text: $_("updating-runner"),
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
RunnerService.runnerControllerPut(original_data.id, editable)
|
||||
let postdata = {};
|
||||
postdata = Object.assign(postdata, editable);
|
||||
RunnerService.runnerControllerPut(original_data.id, postdata)
|
||||
.then((resp) => {
|
||||
Object.assign(original_data, editable);
|
||||
original_data = editable;
|
||||
Object.assign(original_data, editable);
|
||||
original_data = original_data;
|
||||
Toastify({
|
||||
text: $_("runner-updated"),
|
||||
duration: 2500,
|
||||
|
@ -206,7 +219,17 @@
|
|||
aria-haspopup="true"
|
||||
aria-expanded="true">
|
||||
{$_('generate-sponsoring-contract')}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="-mr-1 ml-2 h-5 w-5"><path fill="none" d="M0 0h24v24H0z"/><path fill="currentColor" d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z"/></svg>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
class="-mr-1 ml-2 h-5 w-5"><path
|
||||
fill="none"
|
||||
d="M0 0h24v24H0z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
{#if sponsoring_contracts_download_open}
|
||||
|
@ -349,21 +372,20 @@
|
|||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<span class="font-medium text-gray-700">{$_('group')}</span>
|
||||
<select
|
||||
bind:value={editable.group}
|
||||
name="team"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
{#each teams as team}
|
||||
<option value={team.id}>
|
||||
{team.parentGroup.name}
|
||||
>
|
||||
{team.name}
|
||||
</option>
|
||||
{/each}
|
||||
{#each orgs as org}
|
||||
<option value={org.id}>{org.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => label
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
filterText.toLowerCase()
|
||||
) || option.id.value.toString().startsWith(filterText.toLowerCase())}
|
||||
items={groups}
|
||||
showChevron={true}
|
||||
placeholder={$_('search-for-an-organization-or-team-by-name-or-id')}
|
||||
noOptionsMessage={$_('no-organization-or-team-found')}
|
||||
bind:selectedValue={group}
|
||||
on:select={(selectedValue) => {editable.group = selectedValue.detail.value.id}}
|
||||
on:clear={() => (editable.group = null)} />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<span class="font-medium text-gray-700">{$_('distance')}</span>
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
.concat(mappedteams);
|
||||
document.addEventListener("click", function (e) {
|
||||
if (
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown:menu"
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
||||
) {
|
||||
sponsoring_contracts_download_open = false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import { clickOutside } from "../base/outsideclick";
|
||||
import { focusTrap } from "svelte-focus-trap";
|
||||
import {
|
||||
RunnerService,
|
||||
ScanService,
|
||||
} from "@odit/lfk-client-js";
|
||||
import Select from "svelte-select";
|
||||
import Toastify from "toastify-js";
|
||||
export let modal_open;
|
||||
export let current_scans;
|
||||
const getRunnerLabel = (option) =>
|
||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||
const filterRunners = (label, filterText, option) =>
|
||||
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||
option.value.toString().startsWith(filterText.toLowerCase());
|
||||
function focus(el) {
|
||||
el.focus();
|
||||
}
|
||||
$: runner = 0;
|
||||
$: runners = [];
|
||||
RunnerService.runnerControllerGetAll().then((val) => {
|
||||
runners = val.map(r => {return {label: getRunnerLabel(r), value: r}});
|
||||
});
|
||||
$: distance_input = 0;
|
||||
$: processed_last_submit = true;
|
||||
$: is_distance_valid = distance_input > 0;
|
||||
$: createbtnenabled = is_distance_valid;
|
||||
(() => {
|
||||
document.onkeydown = (e) => {
|
||||
e = e || window.event;
|
||||
if (e.key === "Escape") {
|
||||
modal_open = false;
|
||||
}
|
||||
if (e.keyCode === 13) {
|
||||
if (createbtnenabled === true) {
|
||||
createbtnenabled = false;
|
||||
submit();
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
function submit() {
|
||||
if (processed_last_submit === true) {
|
||||
processed_last_submit = false;
|
||||
const toast = Toastify({
|
||||
text: $_('adding-scan'),
|
||||
duration: -1,
|
||||
}).showToast();
|
||||
let postdata = {
|
||||
runner,
|
||||
distance: distance_input,
|
||||
};
|
||||
ScanService.scanControllerPost(postdata)
|
||||
.then((result) => {
|
||||
runner = 0;
|
||||
distance_input = 0;
|
||||
modal_open = false;
|
||||
//
|
||||
Toastify({
|
||||
text: $_('scan-added'),
|
||||
duration: 500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
current_scans.push(result);
|
||||
current_scans = current_scans;
|
||||
})
|
||||
.catch((err) => {
|
||||
//
|
||||
})
|
||||
.finally(() => {
|
||||
processed_last_submit = true;
|
||||
//
|
||||
toast.hideToast();
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if modal_open}
|
||||
<div
|
||||
class="fixed z-10 inset-0 overflow-y-auto"
|
||||
use:focusTrap
|
||||
use:clickOutside
|
||||
on:click_outside={() => {
|
||||
modal_open = false;
|
||||
}}>
|
||||
<div
|
||||
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
||||
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
|
||||
<div
|
||||
class="absolute inset-0 bg-gray-500 opacity-75"
|
||||
data-id="modal_backdrop" />
|
||||
</div>
|
||||
<span
|
||||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||
aria-hidden="true">​</span>
|
||||
<div
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline">
|
||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div
|
||||
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<svg
|
||||
class="h-6 w-6 text-blue-600"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M2 4h2v16H2V4zm4 0h1v16H6V4zm2 0h2v16H8V4zm3 0h2v16h-2V4zm3 0h2v16h-2V4zm3 0h1v16h-1V4zm2 0h3v16h-3V4z" /></svg>
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
{$_('create-a-new-scan-fixed-only')}
|
||||
</h3>
|
||||
<div class="mt-2 mb-6">
|
||||
<p class="text-sm text-gray-500">
|
||||
{$_('please-provide-the-nessecary-information-to-create-a-new-scan')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-6 gap-6">
|
||||
<div class="col-span-6">
|
||||
<label
|
||||
for="donor"
|
||||
class="block text-sm font-medium text-gray-700">{$_('runner')}</label>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => filterRunners(label, filterText, option)}
|
||||
items={runners}
|
||||
showChevron={true}
|
||||
placeholder={$_('search-for-runner-by-name-or-id')}
|
||||
noOptionsMessage={$_('no-runners-found')}
|
||||
on:select={(selectedValue) => (runner = selectedValue.detail.value.id)}
|
||||
on:clear={() => (runner = null)} />
|
||||
</div>
|
||||
<div class="col-span-6">
|
||||
<label
|
||||
for="donation_amount_eur"
|
||||
class="block text-sm font-medium text-gray-700">
|
||||
{$_('distance')}</label>
|
||||
<div class="mt-1 flex rounded-md shadow-sm">
|
||||
<input
|
||||
autocomplete="off"
|
||||
class:border-red-500={!is_distance_valid}
|
||||
class:focus:border-red-500={!is_distance_valid}
|
||||
class:focus:ring-red-500={!is_distance_valid}
|
||||
bind:value={distance_input}
|
||||
type="number"
|
||||
step="1"
|
||||
name="donation_amount_eur"
|
||||
class="focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 p-2"
|
||||
placeholder="400" />
|
||||
<span
|
||||
class="inline-flex items-center px-3 rounded-r-md border border-gray-300 bg-gray-50 text-gray-500 text-sm">m</span>
|
||||
</div>
|
||||
{#if !is_distance_valid}
|
||||
<span
|
||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||
{$_('the-scans-distance-must-be-greater-than-0m')}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||
<button
|
||||
disabled={!createbtnenabled}
|
||||
class:opacity-50={!createbtnenabled}
|
||||
on:click={submit}
|
||||
type="button"
|
||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('create')}
|
||||
</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
modal_open = false;
|
||||
}}
|
||||
type="button"
|
||||
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('cancel')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
|
@ -0,0 +1,272 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import store from "../../store";
|
||||
import {
|
||||
RunnerService,
|
||||
ScanService,
|
||||
} from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import PromiseError from "../base/PromiseError.svelte";
|
||||
import Select from "svelte-select";
|
||||
let data_loaded = false;
|
||||
export let params;
|
||||
$: delete_triggered = false;
|
||||
$: original_data = {};
|
||||
$: editable = {};
|
||||
$: current_runners = [];
|
||||
$: is_distance_valid = editable.distance > 0;
|
||||
$: is_everything_set =
|
||||
editable.runner != null &&
|
||||
((original_data.responseType === "TRACKSCAN" && editable.track != null) ||
|
||||
original_data.responseType !== "TRACKSCAN");
|
||||
$: runner = {};
|
||||
$: changes_performed = !(
|
||||
JSON.stringify(original_data) === JSON.stringify(editable)
|
||||
);
|
||||
$: save_enabled = changes_performed && is_everything_set && is_distance_valid;
|
||||
|
||||
const promise = ScanService.scanControllerGetOne(params.scanid).then(
|
||||
(data) => {
|
||||
data_loaded = true;
|
||||
original_data = Object.assign(original_data, data);
|
||||
original_data.runner = original_data.runner.id;
|
||||
editable = Object.assign(editable, original_data);
|
||||
RunnerService.runnerControllerGetAll().then(
|
||||
(val) => {
|
||||
current_runners = val.map((r) => {
|
||||
return { label: getRunnerLabel(r), value: r };
|
||||
});
|
||||
runner = current_runners.find(r => r.value.id == editable.runner);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
const getRunnerLabel = (option) =>
|
||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||
const filterRunners = (label, filterText, option) =>
|
||||
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||
option.value.id.toString().startsWith(filterText.toLowerCase());
|
||||
|
||||
function submit() {
|
||||
if (data_loaded === true && save_enabled) {
|
||||
Toastify({
|
||||
text: $_('scan-is-being-updated'),
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
let postdata = {};
|
||||
if (original_data.responseType === "TRACKSCAN") {
|
||||
postdata = Object.assign(postdata, editable);
|
||||
postdata.track = postdata.track.id;
|
||||
ScanService.scanControllerPutTrackScan(original_data.id, postdata)
|
||||
.then((resp) => {
|
||||
Object.assign(original_data, editable);
|
||||
original_data = original_data;
|
||||
Toastify({
|
||||
text: $_('updated-scan'),
|
||||
duration: 2500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
})
|
||||
.catch((err) => {});
|
||||
} else {
|
||||
postdata = Object.assign(postdata, editable);
|
||||
ScanService.scanControllerPut(original_data.id, postdata)
|
||||
.then((resp) => {
|
||||
Object.assign(original_data, editable);
|
||||
original_data = original_data;
|
||||
Toastify({
|
||||
text: $_('updated-scan'),
|
||||
duration: 2500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
function deleteScan() {
|
||||
ScanService.scanControllerRemove(original_data.id, false)
|
||||
.then((resp) => {
|
||||
Toastify({
|
||||
text: $_('deleted-scan'),
|
||||
duration: 500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
location.replace("./");
|
||||
})
|
||||
.catch((err) => {
|
||||
modal_open = true;
|
||||
delete_scan = original_data;
|
||||
});
|
||||
}
|
||||
function format_laptime(laptime){
|
||||
if(laptime == 0 || laptime == null){return $_('first-scan-of-the-day')}
|
||||
if(laptime < 60){return `${laptime}s`}
|
||||
if(laptime < 3600){return `${Math.floor(laptime / 60)}min ${laptime - (Math.floor(laptime / 60)*60)}s`}
|
||||
return `${Math.floor(laptime / 3600)}h ${laptime - (Math.floor(laptime / 3600)*3600)}min ${laptime - (Math.floor(laptime / 3600)*3600) - (Math.floor(laptime / 60)*60)}`
|
||||
}
|
||||
</script>
|
||||
|
||||
{#await promise}
|
||||
Loading scan details
|
||||
{:then}
|
||||
<section class="container p-5 select-none">
|
||||
<div class="flex flex-row mb-4">
|
||||
<div class="w-full">
|
||||
<nav class="w-full flex">
|
||||
<ol class="list-none flex flex-row items-center justify-start">
|
||||
<li class="flex items-center">
|
||||
<svg
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"><path
|
||||
fill="currentColor"
|
||||
d="M2 4h2v16H2V4zm4 0h1v16H6V4zm2 0h2v16H8V4zm3 0h2v16h-2V4zm3 0h2v16h-2V4zm3 0h1v16h-1V4zm2 0h3v16h-3V4z" /></svg>
|
||||
</li>
|
||||
<li class="flex items-center ml-2">
|
||||
<a class="mr-2" href="./">Scans</a><svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="h-3 w-3 mr-2 stroke-current"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"><line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12" />
|
||||
<polyline points="12 5 19 12 12 19" /></svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<span class="mr-2">{original_data.id}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||
{runner.value?.firstname}
|
||||
{runner.value?.middlename || ''}
|
||||
{runner.value?.lastname}
|
||||
#{original_data.id}
|
||||
<span data-id="donation_actions_${original_data.id}">
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:DELETE')}
|
||||
{#if delete_triggered}
|
||||
<button
|
||||
on:click={deleteScan}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:">{$_('confirm-deletion')}</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = !delete_triggered;
|
||||
}}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:">{$_('cancel')}</button>
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = true;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:">{$_('delete-scan')}</button>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
disabled={!save_enabled}
|
||||
class:opacity-50={!save_enabled}
|
||||
type="button"
|
||||
on:click={submit}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:">{$_('save-changes')}</button>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div class="w-full inline-flex">
|
||||
<label for="valid" class="block font-medium text-gray-700">{$_('status')}:
|
||||
</label>
|
||||
|
||||
<input
|
||||
id="valid"
|
||||
on:change={() => {
|
||||
editable.valid = !editable.valid;
|
||||
}}
|
||||
name="valid"
|
||||
type="checkbox"
|
||||
checked={editable.valid}
|
||||
class="focus:ring-indigo-500 align-bottom h-7 w-5font-medium text-indigo-600 border-gray-300 rounded" />
|
||||
|
||||
<p class="font-medium">
|
||||
{#if editable.valid}{$_('valid')}{:else}{$_('invalid')}{/if}
|
||||
</p>
|
||||
</div>
|
||||
{#if editable.responseType === 'TRACKSCAN'}
|
||||
<div class="w-full inline-flex">
|
||||
<label for="valid" class="block font-semibold text-gray-700">{$_('track')}:
|
||||
</label>
|
||||
<a
|
||||
href="../tracks"
|
||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{editable.track.name}
|
||||
</a>
|
||||
</div>
|
||||
<div class="w-full inline-flex pb-3">
|
||||
<label for="valid" class="block font-semibold text-gray-700">{$_('laptime')}: {format_laptime(editable.laptime)}
|
||||
</label>
|
||||
</div>
|
||||
{/if}
|
||||
<div class=" w-full">
|
||||
<label
|
||||
for="runner"
|
||||
class="block font-medium text-gray-700">{$_('runner')}</label>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => filterRunners(label, filterText, option)}
|
||||
items={current_runners}
|
||||
showChevron={true}
|
||||
isDisabled={editable.responseType === 'TRACKSCAN'}
|
||||
placeholder={$_('search-for-runner-by-name-or-id')}
|
||||
noOptionsMessage={$_('no-runners-found')}
|
||||
bind:selectedValue={runner}
|
||||
on:select={(selectedValue) => {
|
||||
editable.runner = selectedValue.detail.value.id;
|
||||
}}
|
||||
on:clear={() => (editable.runner = null)} />
|
||||
</div>
|
||||
<div class=" w-full">
|
||||
<label
|
||||
for="scan_distance"
|
||||
class="block text-sm font-medium text-gray-700">
|
||||
{$_('distance')}</label>
|
||||
<div class="mt-1 flex rounded-md shadow-sm">
|
||||
<input
|
||||
autocomplete="off"
|
||||
class:border-red-500={!is_distance_valid}
|
||||
class:focus:border-red-500={!is_distance_valid}
|
||||
class:focus:ring-red-500={!is_distance_valid}
|
||||
bind:value={editable.distance}
|
||||
disabled={editable.responseType === 'TRACKSCAN'}
|
||||
type="number"
|
||||
step="1"
|
||||
name="scan_distance"
|
||||
class="focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 p-2"
|
||||
placeholder="400" />
|
||||
<span
|
||||
class="inline-flex items-center px-3 rounded-r-md border border-gray-300 bg-gray-50 text-gray-500 text-sm">m</span>
|
||||
</div>
|
||||
{#if !is_distance_valid}
|
||||
<span
|
||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||
{$_('the-scans-distance-must-be-greater-than-0m')}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</section>
|
||||
{:catch error}
|
||||
<PromiseError {error} />
|
||||
{/await}
|
|
@ -0,0 +1,29 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import store from "../../store";
|
||||
import AddScanModal from "./AddScanModal.svelte";
|
||||
import ScansOverview from "./ScansOverview.svelte";
|
||||
$: current_scans = [];
|
||||
export let modal_open = false;
|
||||
</script>
|
||||
|
||||
<section class="container p-5">
|
||||
<span class="mb-1 text-3xl font-extrabold leading-tight">
|
||||
{$_('scans')}
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:CREATE')}
|
||||
<button
|
||||
on:click={() => {
|
||||
modal_open = true;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('add-scan')}
|
||||
</button>
|
||||
{/if}
|
||||
</span>
|
||||
<ScansOverview bind:current_scans />
|
||||
</section>
|
||||
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:CREATE')}
|
||||
<AddScanModal bind:current_scans bind:modal_open />
|
||||
{/if}
|
|
@ -0,0 +1,12 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import scans_empty from "./scans.svg";
|
||||
</script>
|
||||
|
||||
<div class="text-center items-center justify-center">
|
||||
<p class="mb-16 text-lg text-gray-500">
|
||||
<img class="w-full" style="height:15rem" src={scans_empty} alt="" />
|
||||
<span class="font-bold">{$_('there-are-no-scans-yet')}</span><br />
|
||||
<span>{$_('add-your-fist-scan')}</span>
|
||||
</p>
|
||||
</div>
|
|
@ -0,0 +1,201 @@
|
|||
<script>
|
||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||
import {
|
||||
ScanService,
|
||||
} from "@odit/lfk-client-js";
|
||||
import store from "../../store";
|
||||
import Toastify from "toastify-js";
|
||||
import ScansEmptyState from "./ScansEmptyState.svelte";
|
||||
$: searchvalue = "";
|
||||
$: active_deletes = [];
|
||||
export let current_scans = [];
|
||||
const scans_promise = ScanService.scanControllerGetAll().then((val) => {
|
||||
current_scans = val;
|
||||
});
|
||||
function should_display_based_on_id(id) {
|
||||
if (searchvalue.toString().slice(-1) === "*") {
|
||||
return id.toString().startsWith(searchvalue.replace("*", ""));
|
||||
}
|
||||
return id.toString() === searchvalue;
|
||||
}
|
||||
function format_laptime(laptime){
|
||||
if(laptime == 0 || laptime == null){return $_('first-scan-of-the-day')}
|
||||
if(laptime < 60){return `${laptime}s`}
|
||||
if(laptime < 3600){return `${Math.floor(laptime / 60)}min ${laptime - (Math.floor(laptime / 60)*60)}s`}
|
||||
return `${Math.floor(laptime / 3600)}h ${laptime - (Math.floor(laptime / 3600)*3600)}min ${laptime - (Math.floor(laptime / 3600)*3600) - (Math.floor(laptime / 60)*60)}`
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:GET')}
|
||||
{#await scans_promise}
|
||||
<div
|
||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||
role="alert">
|
||||
<p class="font-bold">{$_('scans-are-being-loaded')}</p>
|
||||
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
||||
</div>
|
||||
{:then}
|
||||
{#if current_scans.length === 0}
|
||||
<ScansEmptyState />
|
||||
{:else}
|
||||
<input
|
||||
type="search"
|
||||
bind:value={searchvalue}
|
||||
placeholder={$_('datatable.search')}
|
||||
aria-label={$_('datatable.search')}
|
||||
class="gridjs-input gridjs-search-input mb-4" />
|
||||
<div
|
||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
||||
<table class="divide-y divide-gray-200 w-full">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
{$_('runner')}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
{$_('distance-track')}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
{$_('laptime')}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
{$_('status')}
|
||||
</th>
|
||||
<th scope="col" class="relative px-6 py-3">
|
||||
<span class="sr-only">{$_('action')}</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
{#each current_scans as scan}
|
||||
{#if scan.track?.name
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
searchvalue.toLowerCase()
|
||||
) || scan.runner?.firstname
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
searchvalue.toLowerCase()
|
||||
) || scan.runner?.middlename
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
searchvalue.toLowerCase()
|
||||
) || scan.runner?.lastname
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
searchvalue.toLowerCase()
|
||||
) || should_display_based_on_id(scan.id)}
|
||||
<tr data-rowid="scan_{scan.id}">
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center">
|
||||
<a
|
||||
href="../runners/{scan.runner.id}"
|
||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{scan.runner.firstname}
|
||||
{scan.runner.middlename || ''}
|
||||
{scan.runner.lastname}</a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
{#if scan.distance < 1000}
|
||||
{scan.distance}m
|
||||
{:else}{scan.distance / 1000}km{/if}
|
||||
{#if scan.track}
|
||||
<a
|
||||
href="../tracks"
|
||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{scan.track.name}
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
{#if scan.responseType === "TRACKSCAN"}
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
{format_laptime(scan.lapTime)}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
{$_('scan-with-fixed-distance')}
|
||||
</div>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center">
|
||||
{#if scan.valid}
|
||||
<span
|
||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('valid')}</span>
|
||||
{:else}
|
||||
<span
|
||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('invalid')}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
{#if active_deletes[scan.id] === true}
|
||||
<td
|
||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||
<button
|
||||
on:click={() => {
|
||||
active_deletes[scan.id] = false;
|
||||
}}
|
||||
tabindex="0"
|
||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
ScanService.scanControllerRemove(scan.id, false).then(
|
||||
(resp) => {
|
||||
current_scans = current_scans.filter(
|
||||
(obj) => obj.id !== scan.id
|
||||
);
|
||||
Toastify({
|
||||
text: 'Scan deleted',
|
||||
duration: 500,
|
||||
backgroundColor:
|
||||
'linear-gradient(to right, #00b09b, #96c93d)',
|
||||
}).showToast();
|
||||
}
|
||||
);
|
||||
}}
|
||||
tabindex="0"
|
||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||
</td>
|
||||
{:else}
|
||||
<td
|
||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||
<a
|
||||
href="./{scan.id}"
|
||||
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:DELETE')}
|
||||
<button
|
||||
on:click={() => {
|
||||
active_deletes[scan.id] = true;
|
||||
}}
|
||||
tabindex="0"
|
||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||
{/if}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/if}
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
{:catch error}
|
||||
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
||||
<span class="inline-block align-middle mr-8">
|
||||
<b class="capitalize">{$_('general_promise_error')}</b>
|
||||
{error}
|
||||
</span>
|
||||
</div>
|
||||
{/await}
|
||||
{/if}
|
|
@ -0,0 +1 @@
|
|||
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="598.11" height="535.11"><path d="M3.35 120.07a4.6 4.6 0 00-3.18 5.66l76.72 273.98a4.6 4.6 0 005.65 3.18l282.82-79.19a4.6 4.6 0 003.18-5.66L291.82 44.07a4.6 4.6 0 00-5.65-3.19z" fill="#e6e6e6"/><path d="M86.1 389.95l269.5-75.46-72.99-260.67-269.5 75.46z" fill="#fff"/><path d="M48.74 164.1c-1.8.5-2.54 3.48-1.65 6.65s3.07 5.33 4.87 4.83l122.91-34.42c1.8-.5 2.54-3.49 1.66-6.65s-3.08-5.34-4.87-4.84zM58.64 199.44c-1.8.5-2.54 3.5-1.65 6.66s3.07 5.34 4.87 4.83l122.91-34.42c1.8-.5 2.54-3.49 1.65-6.65s-3.07-5.34-4.86-4.83zM68.42 234.39c-1.8.5-2.54 3.49-1.65 6.66s3.07 5.33 4.87 4.83l122.92-34.42c1.8-.5 2.54-3.5 1.65-6.66s-3.07-5.33-4.87-4.83zM78.32 269.74c-1.8.5-2.54 3.49-1.65 6.66s3.07 5.33 4.87 4.83l122.92-34.42c1.8-.5 2.54-3.49 1.65-6.66s-3.07-5.33-4.87-4.83zM234.04 112.61a5.97 5.97 0 103.21 11.5l22.98-6.44a5.97 5.97 0 00-3.22-11.49zM243.74 147.28a5.97 5.97 0 103.22 11.49l22.98-6.43a5.97 5.97 0 00-3.22-11.5zM253.45 181.95a5.97 5.97 0 103.22 11.49l22.98-6.44a5.97 5.97 0 00-3.22-11.49zM263.16 216.61a5.97 5.97 0 003.21 11.5l22.98-6.44a5.97 5.97 0 00-3.21-11.49z" fill="#e6e6e6"/><path d="M272.43 276.7a7.6 7.6 0 104.1 14.64l29.28-8.2a7.6 7.6 0 00-4.1-14.64z" fill="#6c63ff"/><path fill="#e6e6e6" d="M85.9 307.81l216.66-60.67.54 1.93-216.67 60.67z"/><path fill="#a0616a" d="M520.2 506.07l-17.38 4.2-24.47-65.02 25.65-6.2 16.2 67.02z"/><path d="M472.85 535.11l-.12-.48a22.23 22.23 0 0116.37-26.8l34-8.23 5.33 22.08z" fill="#2f2e41"/><path fill="#a0616a" d="M443.28 517.91H425.4l-8.5-68.96h26.38v68.96z"/><path d="M447.6 535.01h-57.18v-.5a22.2 22.2 0 0122.2-22.2h34.99zM416.88 490.99l-17.36-206.87 71.86-13.25.28-.05 21.03 13.52-7.32 76.14 33.7 118.7-29.1 7.65-33.75-110.08-7.73-33.48-3.96 43.5 2.94 107.28z" fill="#2f2e41"/><path d="M397.3 288.81l-.2-.24 24.84-186.96.03-.24.17-.18c.37-.36 9.07-8.96 18.02-8.96 1.3 0 2.52-.03 3.7-.06 6.85-.18 12.26-.32 18.69 6.1 6.55 6.56 27.92 30.47 27.92 63.23 0 31.7 2.88 130.22 2.91 131.21l.04 1.4-1.16-.76c-.3-.19-29.03-18.49-53.14-1.48-7.53 5.32-14.3 7.18-20.09 7.18-13.47 0-21.62-10.1-21.73-10.24z" fill="#6c63ff"/><circle cx="737.3" cy="227.82" r="35.82" transform="rotate(-28.66 229.78 725.57)" fill="#a0616a"/><path d="M381.53 328.99a14.66 14.66 0 00.85-22.47l20.34-47.97-26.63 4.9-15.23 44.8A14.74 14.74 0 00381.53 329z" fill="#a0616a"/><path d="M361.88 291.67l6.55-13.83a2.7 2.7 0 01-.97-1c-6.12-10.6 30.84-98.67 33.3-104.51-.37-3.18-4.25-36.85-1.41-48.2 3.34-13.35 10.2-19.58 22.93-20.81 14.04-1.32 17.83 17.75 17.86 17.94l.02 49.02-16.12 56.43-36.75 74.97z" fill="#6c63ff"/><path d="M440.94 58.87c-4.3.56-7.54-3.83-9.04-7.9s-2.64-8.78-6.38-10.98c-5.1-3-11.62.61-17.45-.38-6.59-1.11-10.87-8.1-11.2-14.76s2.31-13.1 4.92-19.24l.9 7.64A15.16 15.16 0 01409.33 0l-1.17 11.22c.73-6.29 7.5-11.16 13.7-9.85l-.19 6.68c7.6-.9 15.28-1.81 22.91-1.12s15.31 3.1 21.1 8.13c8.64 7.51 11.8 19.89 10.74 31.3s-5.77 22.13-10.68 32.48c-1.23 2.6-2.94 5.54-5.8 5.88-2.58.3-4.93-1.86-5.73-4.32s-.41-5.14.07-7.69c.72-3.84 1.63-7.77.95-11.63s-3.45-7.66-7.33-8.13-7.86 3.97-6 7.4z" fill="#2f2e41"/><path fill="#3f3d56" d="M597.73 535.1H339.99v-2.11h258.12l-.38 2.1z"/></svg>
|
After Width: | Height: | Size: 3.1 KiB |
|
@ -0,0 +1,205 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import { clickOutside } from "../base/outsideclick";
|
||||
import { focusTrap } from "svelte-focus-trap";
|
||||
import { ScanStationService, TrackService } from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import Select from "svelte-select";
|
||||
export let modal_open;
|
||||
export let new_station;
|
||||
export let current_stations;
|
||||
export let copy_modal_open;
|
||||
let tracks = [];
|
||||
TrackService.trackControllerGetAll().then((val) => {
|
||||
tracks = val.map((t) => {
|
||||
return { label: t.name || `#${t.id}`, value: t };
|
||||
});
|
||||
});
|
||||
function focus(el) {
|
||||
el.focus();
|
||||
}
|
||||
$: description = "";
|
||||
$: track = null;
|
||||
$: enabled = true;
|
||||
$: createbtnenabled = track != null;
|
||||
$: processed_last_submit = true;
|
||||
(() => {
|
||||
document.onkeydown = (e) => {
|
||||
e = e || window.event;
|
||||
if (e.key === "Escape") {
|
||||
modal_open = false;
|
||||
}
|
||||
if (e.keyCode === 13) {
|
||||
if (createbtnenabled === true) {
|
||||
createbtnenabled = false;
|
||||
submit();
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
function submit() {
|
||||
if (processed_last_submit === true) {
|
||||
processed_last_submit = false;
|
||||
const toast = Toastify({
|
||||
text: $_("scanstation-is-being-added"),
|
||||
duration: -1,
|
||||
}).showToast();
|
||||
let postdata = {
|
||||
description,
|
||||
enabled,
|
||||
track,
|
||||
};
|
||||
ScanStationService.scanStationControllerPost(postdata)
|
||||
.then((result) => {
|
||||
description = "";
|
||||
track = tracks[0].id;
|
||||
enabled = true;
|
||||
modal_open = false;
|
||||
//
|
||||
Toastify({
|
||||
text: $_("scanstation-added"),
|
||||
duration: 500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
current_stations.push(result);
|
||||
current_stations = current_stations;
|
||||
new_station = result;
|
||||
copy_modal_open = true;
|
||||
})
|
||||
.catch((err) => {
|
||||
//
|
||||
})
|
||||
.finally(() => {
|
||||
processed_last_submit = true;
|
||||
//
|
||||
toast.hideToast();
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if modal_open}
|
||||
<div
|
||||
class="fixed z-10 inset-0 overflow-y-auto"
|
||||
use:focusTrap
|
||||
use:clickOutside
|
||||
on:click_outside={() => {
|
||||
modal_open = false;
|
||||
}}>
|
||||
<div
|
||||
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
||||
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
|
||||
<div
|
||||
class="absolute inset-0 bg-gray-500 opacity-75"
|
||||
data-id="modal_backdrop" />
|
||||
</div>
|
||||
<span
|
||||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||
aria-hidden="true">​</span>
|
||||
<div
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline">
|
||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div
|
||||
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<svg
|
||||
class="h-6 w-6 text-blue-600"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></svg>
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
{$_('create-a-new-scanstation')}
|
||||
</h3>
|
||||
<div class="mt-2 mb-6">
|
||||
<p class="text-sm text-gray-500">
|
||||
{$_('please-provide-the-required-information-to-create-a-new-scanstation')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-6 gap-6">
|
||||
<div class="col-span-6">
|
||||
<label
|
||||
for="track"
|
||||
class="block text-sm font-medium text-gray-700">Track</label>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => label
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
filterText.toLowerCase()
|
||||
) || option.value.id
|
||||
.toString()
|
||||
.startsWith(filterText.toLowerCase())}
|
||||
items={tracks}
|
||||
showChevron={true}
|
||||
placeholder="Search for a track (by name or id)."
|
||||
noOptionsMessage="No track found"
|
||||
on:select={(selectedValue) => (track = selectedValue.detail.value.id)}
|
||||
on:clear={() => (track = null)} />
|
||||
</div>
|
||||
<div class="col-span-6">
|
||||
<label
|
||||
for="description"
|
||||
class="block text-sm font-medium text-gray-700">{$_('description')}</label>
|
||||
<input
|
||||
use:focus
|
||||
autocomplete="off"
|
||||
placeholder={$_('description')}
|
||||
bind:value={description}
|
||||
type="text"
|
||||
name="description"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="col-span-6">
|
||||
<label
|
||||
for="enabled"
|
||||
class="font-medium text-gray-700">{$_('enabled_large')}</label>
|
||||
<br />
|
||||
<p class="text-gray-500">
|
||||
<input
|
||||
id="enabled"
|
||||
on:change={() => {
|
||||
enabled = !enabled;
|
||||
}}
|
||||
name="enabled"
|
||||
type="checkbox"
|
||||
checked={enabled}
|
||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||
{$_('this-scanstation-is')}
|
||||
{#if enabled}{$_('enabled')}{:else}{$_('disabled')}{/if}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||
<button
|
||||
disabled={!createbtnenabled}
|
||||
class:opacity-50={!createbtnenabled}
|
||||
on:click={submit}
|
||||
type="button"
|
||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('create')}
|
||||
</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
modal_open = false;
|
||||
}}
|
||||
type="button"
|
||||
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('cancel')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
|
@ -0,0 +1,92 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import { clickOutside } from "../base/outsideclick";
|
||||
import { focusTrap } from "svelte-focus-trap";
|
||||
import { ScanStationService } from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
export let modal_open;
|
||||
export let delete_station;
|
||||
const dispatch = createEventDispatcher();
|
||||
function cancelDelete() {
|
||||
modal_open = false;
|
||||
dispatch("cancelDelete", { id: delete_station.id });
|
||||
}
|
||||
function deleteStation() {
|
||||
ScanStationService.donorControllerRemove(
|
||||
delete_station.id,
|
||||
true
|
||||
)
|
||||
.then((resp) => {
|
||||
Toastify({
|
||||
text: $_('station-deleted'),
|
||||
duration: 500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
location.replace("./");
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if modal_open}
|
||||
<div
|
||||
class="fixed z-10 inset-0 overflow-y-auto"
|
||||
use:focusTrap
|
||||
use:clickOutside
|
||||
on:click_outside={cancelDelete}>
|
||||
<div
|
||||
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
||||
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
|
||||
<div
|
||||
class="absolute inset-0 bg-gray-500 opacity-75"
|
||||
data-id="modal_backdrop" />
|
||||
</div>
|
||||
<span
|
||||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||
aria-hidden="true">​</span>
|
||||
<div
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline">
|
||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div
|
||||
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<svg class="h-6 w-6 text-blue-600" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z"/></svg>
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
{$_('attention')}
|
||||
</h3>
|
||||
<div class="mt-2 mb-6">
|
||||
<p class="text-sm text-gray-500">
|
||||
{$_(
|
||||
'do-you-want-to-delete-this-donor-with-all-related-donations'
|
||||
)}
|
||||
<br />
|
||||
{$_('all-associated-scans-will-get-deleted-as-well')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||
<button
|
||||
on:click={deleteStation}
|
||||
type="button"
|
||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('confirm-delete-station-with-all-scans')}
|
||||
</button>
|
||||
<button
|
||||
on:click={cancelDelete}
|
||||
type="button"
|
||||
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('cancel-keep-station')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
|
@ -0,0 +1,125 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import { focusTrap } from "svelte-focus-trap";
|
||||
import Toastify from "toastify-js";
|
||||
import { tick, createEventDispatcher } from "svelte";
|
||||
export let copy_modal_open;
|
||||
export let new_station;
|
||||
const dispatch = createEventDispatcher();
|
||||
let valueCopy = null;
|
||||
let areaDom;
|
||||
let copied = false;
|
||||
function close() {
|
||||
copy_modal_open = false;
|
||||
}
|
||||
async function copy() {
|
||||
valueCopy = new_station.key;
|
||||
await tick();
|
||||
areaDom.focus();
|
||||
areaDom.select();
|
||||
try {
|
||||
const successful = document.execCommand("copy");
|
||||
if (!successful) {
|
||||
throw new Error();
|
||||
}
|
||||
Toastify({
|
||||
text: $_('copied-token-to-clipboard'),
|
||||
duration: 500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
copied = true;
|
||||
} catch (err) {
|
||||
Toastify({
|
||||
text: $_('error-whyile-copying-to-clipboard'),
|
||||
duration: 500,
|
||||
backgroundColor:
|
||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
||||
}).showToast();
|
||||
}
|
||||
|
||||
// we can notifi by event or storage about copy status
|
||||
valueCopy = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if copy_modal_open}
|
||||
{#if valueCopy != null}
|
||||
<textarea bind:this={areaDom}>{valueCopy}</textarea>
|
||||
{/if}
|
||||
<div class="fixed z-10 inset-0 overflow-y-auto" use:focusTrap>
|
||||
<div
|
||||
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
||||
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
|
||||
<div
|
||||
class="absolute inset-0 bg-gray-500 opacity-75"
|
||||
data-id="modal_backdrop" />
|
||||
</div>
|
||||
<span
|
||||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||
aria-hidden="true">​</span>
|
||||
<div
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline">
|
||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div
|
||||
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<svg
|
||||
class="h-6 w-6 text-blue-600"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></svg>
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">{$_('token')}</h3>
|
||||
<div class="mt-2 mb-6">
|
||||
<p class="text-sm text-gray-500">
|
||||
{$_('the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again')}
|
||||
<br />
|
||||
{$_('please-copy-the-token-and-store-it-somewhere-save')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-2 mb-6">
|
||||
<label
|
||||
for="token"
|
||||
class="block text-sm font-medium text-gray-700">Token</label>
|
||||
<div on:click={copy} class="inline-flex">
|
||||
<p
|
||||
name="token"
|
||||
class:bg-green-200={copied}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 p-2">
|
||||
{new_station.key}
|
||||
</p>
|
||||
<div
|
||||
class="bg-gray-200 border-gray-300 border-t border-b border-r text-black rounded-r-md sm:text-sm p-2 mt-1 cursor-pointer">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M7 4V2h10v2h3l1 1v16a1 1 0 01-1 1H4a1 1 0 01-1-1V5l1-1h3zm0 2H5v14h14V6h-2v2H7V6zm2-2v2h6V4H9z" /></svg>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-gray-500 text-xs">{$_('click-to-copy-token-to-clipboard')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||
<button
|
||||
on:click={close}
|
||||
type="button"
|
||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-green-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('yes-i-copied-the-token')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
|
@ -0,0 +1,206 @@
|
|||
<script>
|
||||
import { t, _ } from "svelte-i18n";
|
||||
import store from "../../store";
|
||||
import { ScanStationService, TrackService } from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import PromiseError from "../base/PromiseError.svelte";
|
||||
import ConfirmScanStationDeletion from "./ConfirmScanStationDeletion.svelte";
|
||||
import Select from "svelte-select";
|
||||
let data_loaded = false;
|
||||
let modal_open;
|
||||
let delete_station;
|
||||
export let params;
|
||||
$: delete_triggered = false;
|
||||
$: original_data = {};
|
||||
$: editable = {};
|
||||
$: tracks = [];
|
||||
$: track = {};
|
||||
$: changes_performed = !(
|
||||
JSON.stringify(original_data) === JSON.stringify(editable)
|
||||
);
|
||||
$: save_enabled = changes_performed;
|
||||
const promise = ScanStationService.scanStationControllerGetOne(
|
||||
params.stationid
|
||||
).then((data) => {
|
||||
data_loaded = true;
|
||||
data.track = data.track.id;
|
||||
original_data = Object.assign(original_data, data);
|
||||
editable = Object.assign(editable, original_data);
|
||||
TrackService.trackControllerGetAll().then((val) => {
|
||||
tracks = val.map((t) => {
|
||||
return { label: t.name || `#{t.id}`, value: t };
|
||||
});
|
||||
track = tracks.find((t) => t.value.id == editable.track);
|
||||
});
|
||||
});
|
||||
function submit() {
|
||||
if (data_loaded === true && save_enabled) {
|
||||
Toastify({
|
||||
text: $_("station-is-being-updated"),
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
ScanStationService.scanStationControllerPut(original_data.id, editable)
|
||||
.then((resp) => {
|
||||
Object.assign(original_data, editable);
|
||||
original_data = original_data;
|
||||
Toastify({
|
||||
text: $_("updated-station"),
|
||||
duration: 2500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
})
|
||||
.catch((err) => {});
|
||||
} else {
|
||||
}
|
||||
}
|
||||
function deleteStation() {
|
||||
ScanStationService.scanStationControllerRemove(original_data.id, false)
|
||||
.then((resp) => {
|
||||
Toastify({
|
||||
text: $_("station-deleted"),
|
||||
duration: 500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
location.replace("./");
|
||||
})
|
||||
.catch((err) => {
|
||||
modal_open = true;
|
||||
delete_station = original_data;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<ConfirmScanStationDeletion bind:modal_open bind:delete_station />
|
||||
{#await promise}
|
||||
{$_('loading-station-details')}
|
||||
{:then}
|
||||
<section class="container p-5 select-none">
|
||||
<div class="flex flex-row mb-4">
|
||||
<div class="w-full">
|
||||
<nav class="w-full flex">
|
||||
<ol class="list-none flex flex-row items-center justify-start">
|
||||
<li class="flex items-center">
|
||||
<svg
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||
<path
|
||||
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></svg>
|
||||
</li>
|
||||
<li class="flex items-center ml-2">
|
||||
<a class="mr-2" href="./">{$_('scanstation')}</a><svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="h-3 w-3 mr-2 stroke-current"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"><line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12" />
|
||||
<polyline points="12 5 19 12 12 19" /></svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<span class="mr-2">#{original_data.id}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||
#{original_data.id}
|
||||
<span data-id="stations_actions_${editable.id}">
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('STATION:DELETE')}
|
||||
{#if delete_triggered}
|
||||
<button
|
||||
on:click={deleteStation}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-deletion')}</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = !delete_triggered;
|
||||
}}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm">{$_('cancel')}</button>
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = true;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-station')}</button>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
disabled={!save_enabled}
|
||||
class:opacity-50={!save_enabled}
|
||||
type="button"
|
||||
on:click={submit}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('save-changes')}</button>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="track"
|
||||
class="block text-sm font-medium text-gray-700">Track</label>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => label
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
filterText.toLowerCase()
|
||||
) || option.value.id
|
||||
.toString()
|
||||
.startsWith(filterText.toLowerCase())}
|
||||
items={tracks}
|
||||
showChevron={true}
|
||||
placeholder="Search for a track (by name or id)."
|
||||
noOptionsMessage="No track found"
|
||||
bind:selectedValue={track}
|
||||
on:select={(selectedValue) => (editable.track = selectedValue.detail.value.id)}
|
||||
on:clear={() => (track = null)} />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="description"
|
||||
class="font-medium text-gray-700">{$_('description')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('description')}
|
||||
type="text"
|
||||
bind:value={editable.description}
|
||||
name="description"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="enabled"
|
||||
class="ml-1 font-medium text-gray-700">{$_('enabled')}</label>
|
||||
<br />
|
||||
<p class="text-gray-500">
|
||||
<input
|
||||
id="enabled"
|
||||
on:change={() => {
|
||||
editable.enabled = !editable.enabled;
|
||||
}}
|
||||
name="enabled"
|
||||
type="checkbox"
|
||||
checked={editable.enabled}
|
||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||
{$_('this-scanstation-is')}
|
||||
{#if editable.enabled}{$_('enabled')}{:else}{$_('disabled')}{/if}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
{:catch error}
|
||||
<PromiseError {error} />
|
||||
{/await}
|
|
@ -0,0 +1,33 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import store from "../../store";
|
||||
import AddScanStationModal from "./AddScanStationModal.svelte";
|
||||
import CopyScanStationTokenModal from "./CopyScanStationTokenModal.svelte";
|
||||
import ScanStationsOverview from "./ScanStationsOverview.svelte";
|
||||
export let modal_open = false;
|
||||
export let copy_modal_open = false;
|
||||
export let new_station = {};
|
||||
let current_stations = [];
|
||||
</script>
|
||||
|
||||
<section class="container p-5">
|
||||
<span class="mb-1 text-3xl font-extrabold leading-tight">
|
||||
{$_('scanstations')}
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('STATION:CREATE')}
|
||||
<button
|
||||
on:click={() => {
|
||||
modal_open = true;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('create-a-new-scanstation')}
|
||||
</button>
|
||||
{/if}
|
||||
</span>
|
||||
<ScanStationsOverview bind:current_stations bind:modal_open bind:new_station bind:copy_modal_open />
|
||||
</section>
|
||||
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('STATION:CREATE')}
|
||||
<AddScanStationModal bind:modal_open bind:current_stations bind:new_station bind:copy_modal_open/>
|
||||
<CopyScanStationTokenModal bind:copy_modal_open bind:new_station />
|
||||
{/if}
|
|
@ -0,0 +1,21 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import AddScanStationModal from "./AddScanStationModal.svelte";
|
||||
import CopyScanStationTokenModal from "./CopyScanStationTokenModal.svelte";
|
||||
import scanstations_empty from "./scanstations_empty.svg";
|
||||
let modal_open = false;
|
||||
let copy_modal_open = false;
|
||||
let new_station = {};
|
||||
let current_stations = [];
|
||||
</script>
|
||||
|
||||
<div class="text-center items-center justify-center">
|
||||
<p class="mb-16 text-lg text-gray-500">
|
||||
<img class="w-full h-44" src={scanstations_empty} alt="" />
|
||||
<span class="font-bold">{$_('you-dont-have-any-scanstations-yet')}.</span><br />
|
||||
<span>{$_('add-the-first-scanstation')}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<AddScanStationModal bind:modal_open bind:current_stations bind:new_station bind:copy_modal_open/>
|
||||
<CopyScanStationTokenModal bind:copy_modal_open bind:new_station />
|
|
@ -0,0 +1,169 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import Toastify from "toastify-js";
|
||||
import { ScanStationService } from "@odit/lfk-client-js";
|
||||
const promise = ScanStationService.scanStationControllerGetAll().then(
|
||||
(result) => {
|
||||
current_stations = result;
|
||||
}
|
||||
);
|
||||
import store from "../../store";
|
||||
import ScanStationsEmptyState from "./ScanStationsEmptyState.svelte";
|
||||
import ConfirmScanStationDeletion from "./ConfirmScanStationDeletion.svelte";
|
||||
$: searchvalue = "";
|
||||
$: active_deletes = [];
|
||||
let delete_station = {};
|
||||
let modal_open = false;
|
||||
export let current_stations = [];
|
||||
</script>
|
||||
|
||||
<ConfirmScanStationDeletion
|
||||
on:cancelDelete={(event) => {
|
||||
modal_open = false;
|
||||
active_deletes[event.detail.id] = false;
|
||||
}}
|
||||
bind:modal_open
|
||||
bind:delete_station />
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('STATION:GET')}
|
||||
{#await promise}
|
||||
<div
|
||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||
role="alert">
|
||||
<p class="font-bold">{$_('scanstations-are-being-loaded')}</p>
|
||||
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
||||
</div>
|
||||
{:then}
|
||||
{#if current_stations.length === 0}
|
||||
<ScanStationsEmptyState />
|
||||
{:else}
|
||||
<input
|
||||
type="search"
|
||||
bind:value={searchvalue}
|
||||
placeholder={$_('datatable.search')}
|
||||
aria-label={$_('datatable.search')}
|
||||
class="gridjs-input gridjs-search-input mb-4" />
|
||||
<div
|
||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
||||
<table class="divide-y divide-gray-200 w-full">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
{$_('track')}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
{$_('description')}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
{$_('status')}
|
||||
</th>
|
||||
<th scope="col" class="relative px-6 py-3">
|
||||
<span class="sr-only">{$_('action')}</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
{#each current_stations as s}
|
||||
{#if Object.values(s)
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.includes(searchvalue)}
|
||||
<tr data-rowid="station_{s.id}">
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center">
|
||||
<div class="ml-4">
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
<a
|
||||
href="../tracks"
|
||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">
|
||||
{s.track.name || s.track.distance + 'm'}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center">
|
||||
<div class="ml-4">
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
{s.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center">
|
||||
{#if s.enabled}
|
||||
<span
|
||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('active')}</span>
|
||||
{:else}
|
||||
<span
|
||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('inactive')}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
{#if active_deletes[s.id] === true}
|
||||
<td
|
||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||
<button
|
||||
on:click={() => {
|
||||
active_deletes[s.id] = false;
|
||||
}}
|
||||
tabindex="0"
|
||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
ScanStationService.scanStationControllerRemove(s.id, false)
|
||||
.then((resp) => {
|
||||
current_stations = current_stations.filter((obj) => obj.id !== s.id);
|
||||
Toastify({
|
||||
text: $_('station-deleted'),
|
||||
duration: 500,
|
||||
backgroundColor:
|
||||
'linear-gradient(to right, #00b09b, #96c93d)',
|
||||
}).showToast();
|
||||
})
|
||||
.catch((err) => {
|
||||
modal_open = true;
|
||||
delete_station = s;
|
||||
});
|
||||
}}
|
||||
tabindex="0"
|
||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||
</td>
|
||||
{:else}
|
||||
<td
|
||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||
<a
|
||||
href="/scanstations/{s.id}"
|
||||
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('STATION:DELETE')}
|
||||
<button
|
||||
on:click={() => {
|
||||
active_deletes[s.id] = true;
|
||||
}}
|
||||
tabindex="0"
|
||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||
{/if}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/if}
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
{:catch error}
|
||||
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
||||
<span class="inline-block align-middle mr-8">
|
||||
<b class="capitalize">{$_('general_promise_error')}</b>
|
||||
{error}
|
||||
</span>
|
||||
</div>
|
||||
{/await}
|
||||
{/if}
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 5.0 KiB |
|
@ -0,0 +1,90 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import { clickOutside } from "../base/outsideclick";
|
||||
import { focusTrap } from "svelte-focus-trap";
|
||||
import { MeService } from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
export let modal_open;
|
||||
export let delete_triggered;
|
||||
const dispatch = createEventDispatcher();
|
||||
function cancelDelete() {
|
||||
modal_open = false;
|
||||
delete_triggered = false;
|
||||
dispatch("cancelDelete");
|
||||
}
|
||||
function deleteMe() {
|
||||
MeService.meControllerRemove(true)
|
||||
.then((resp) => {
|
||||
Toastify({
|
||||
text: "Profile deleted!",
|
||||
duration: 500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
location.replace("../");
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if modal_open}
|
||||
<div
|
||||
class="fixed z-10 inset-0 overflow-y-auto"
|
||||
use:focusTrap
|
||||
use:clickOutside
|
||||
on:click_outside={cancelDelete}>
|
||||
<div
|
||||
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
||||
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
|
||||
<div
|
||||
class="absolute inset-0 bg-gray-500 opacity-75"
|
||||
data-id="modal_backdrop" />
|
||||
</div>
|
||||
<span
|
||||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||
aria-hidden="true">​</span>
|
||||
<div
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline">
|
||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div
|
||||
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<svg class="h-6 w-6 text-blue-600" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M9.33 11.5h2.17A4.5 4.5 0 0116 16H9v1h8v-1a5.58 5.58 0 00-.89-3H19a5 5 0 014.52 2.85A13.15 13.15 0 0113 21c-2.76 0-5.1-.59-7-1.63v-9.3a6.97 6.97 0 013.33 1.43zM5 19a1 1 0 01-1 1H2a1 1 0 01-1-1v-9a1 1 0 011-1h2a1 1 0 011 1v9zM18 5a3 3 0 110 6 3 3 0 010-6zm-7-3a3 3 0 110 6 3 3 0 010-6z"/></svg>
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
{$_('attention')}
|
||||
</h3>
|
||||
<div class="mt-2 mb-6">
|
||||
<p class="text-sm text-gray-500">
|
||||
{$_('do-you-really-want-to-delete-your-profile')}
|
||||
<br />
|
||||
{$_('you-are-going-to-loose-all-permissions-and-access-to-the-runner-system')}
|
||||
<br>
|
||||
{$_('after-deletion-we-cant-restore-your-old-profile')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||
<button
|
||||
on:click={deleteMe}
|
||||
type="button"
|
||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('confirm-delete-my-user-profile')}
|
||||
</button>
|
||||
<button
|
||||
on:click={cancelDelete}
|
||||
type="button"
|
||||
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('cancel-keep-my-profile')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
|
@ -0,0 +1,319 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import isEmail from "validator/es/lib/isEmail";
|
||||
import { MeService } from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import ConfirmProfileDeletion from "./ConfirmProfileDeletion.svelte";
|
||||
$: data_loaded = false;
|
||||
$: delete_triggered = false;
|
||||
$: original_data = {};
|
||||
$: editable = {};
|
||||
$: modal_open = false;
|
||||
$: password_change = "";
|
||||
$: password_confirm = "";
|
||||
$: changes_performed = !(
|
||||
JSON.stringify(editable) === JSON.stringify(original_data)
|
||||
);
|
||||
$: save_enabled = changes_performed && isEmail(editable.email);
|
||||
$: update_password_enabled =
|
||||
password_change.length > 0 && password_change === password_confirm;
|
||||
const user_promise = MeService.meControllerGet().then((data) => {
|
||||
data_loaded = true;
|
||||
data.groups = data.groups.map((g) => g.id);
|
||||
data.permissions = [0];
|
||||
original_data = Object.assign(original_data, data);
|
||||
editable = Object.assign(editable, original_data);
|
||||
});
|
||||
function submit() {
|
||||
if (data_loaded === true && save_enabled) {
|
||||
Toastify({
|
||||
text: $_("updating-your-profile"),
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
MeService.meControllerPut(editable)
|
||||
.then((resp) => {
|
||||
original_data = Object.assign(original_data, editable);
|
||||
Toastify({
|
||||
text: $_("profile-updated"),
|
||||
duration: 2500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
}
|
||||
function changePassword() {
|
||||
if (data_loaded === true && update_password_enabled) {
|
||||
Toastify({
|
||||
text: $_('changing-your-password'),
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
let postdata = Object.assign({}, original_data);
|
||||
postdata.password = password_confirm;
|
||||
MeService.meControllerPut(postdata)
|
||||
.then((resp) => {
|
||||
password_confirm = "";
|
||||
password_change = "";
|
||||
postdata = {};
|
||||
Toastify({
|
||||
text: $_('password-changed'),
|
||||
duration: 2500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
setTimeout(() => {
|
||||
location.replace("./");
|
||||
}, 500);
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<ConfirmProfileDeletion bind:modal_open bind:delete_triggered />
|
||||
<div class="pt-12 px-4 sm:px-6 lg:px-8 lg:pt-20 bg-gray-900 pb-12">
|
||||
<div class="text-center mb-8">
|
||||
<h1
|
||||
class="mt-9 font-display text-4xl leading-none font-semibold text-white sm:text-5xl lg:text-6xl">
|
||||
🔨<br />{$_('settings')}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-0 pb-16 bg-gray-50 overflow-hidden lg:pt-12 lg:py-24">
|
||||
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
|
||||
<div>
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<div class="px-4 sm:px-0">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">
|
||||
{$_('profile')}
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-gray-600">
|
||||
{$_('everything-concerning-your-profile')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{#await user_promise}
|
||||
{$_('loading-profile-data')}
|
||||
{:then}
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
<div class="shadow sm:rounded-md sm:overflow-hidden">
|
||||
<div class="px-4 py-5 bg-white space-y-6 sm:p-6">
|
||||
<div>
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
<label class="block text-sm font-medium text-gray-700">
|
||||
{$_('profile-picture')}
|
||||
</label>
|
||||
<div class="mt-2 flex items-center">
|
||||
<span
|
||||
class="inline-block h-20 w-20 rounded-full overflow-hidden bg-gray-100">
|
||||
<img
|
||||
alt={$_('profile-picture')}
|
||||
class="h-20 w-20 rounded-full overflow-hidden bg-gray-100"
|
||||
src={editable.profilePic || 'https://lauf-fuer-kaya.de/lfk-logo.png'} />
|
||||
</span>
|
||||
<!-- <button
|
||||
type="button"
|
||||
class="ml-5 bg-white py-2 px-3 border border-gray-300 rounded-md shadow-sm text-sm leading-4 font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||
Change
|
||||
</button> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="username"
|
||||
class="font-medium text-gray-700">{$_('username')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('username')}
|
||||
type="text"
|
||||
bind:value={editable.username}
|
||||
name="username"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="email"
|
||||
class="font-medium text-gray-700">{$_('e-mail-adress')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('e-mail-adress')}
|
||||
type="email"
|
||||
bind:value={editable.email}
|
||||
name="email"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
{#if !isEmail(editable.email)}
|
||||
<span
|
||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">{$_('valid-email-is-required')}</span>
|
||||
{/if}
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="firstname"
|
||||
class="font-medium text-gray-700">{$_('first-name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('first-name')}
|
||||
type="text"
|
||||
bind:value={editable.firstname}
|
||||
name="firstname"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="middlename"
|
||||
class="font-medium text-gray-700">{$_('middle-name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('middle-name')}
|
||||
type="text"
|
||||
bind:value={editable.middlename}
|
||||
name="middlename"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="lastname"
|
||||
class="font-medium text-gray-700">{$_('last-name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('last-name')}
|
||||
type="text"
|
||||
bind:value={editable.lastname}
|
||||
name="lastname"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!save_enabled}
|
||||
class:opacity-50={!save_enabled}
|
||||
on:click={submit}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('save-changes')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
|
||||
<div>
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<div class="px-4 sm:px-0">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">
|
||||
{$_('password')}
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-gray-600">
|
||||
{$_('change-your-password-here')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{#await user_promise}
|
||||
{$_('loading-profile-data')}
|
||||
{:then}
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
<div class="shadow sm:rounded-md sm:overflow-hidden">
|
||||
<div class="px-4 py-3 bg-gray-50 text-left sm:px-6">
|
||||
<label
|
||||
for="new_password"
|
||||
class="font-medium text-gray-700">{$_('new-password')}</label>
|
||||
<div class="-mt-px relative">
|
||||
<input
|
||||
aria-label={$_('password')}
|
||||
type="password"
|
||||
required=""
|
||||
bind:value={password_change}
|
||||
class="border-gray-300 placeholder-gray-500 appearance-none rounded-md relative block w-full px-3 py-2 border focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
|
||||
placeholder={$_('password')} />
|
||||
</div>
|
||||
<label
|
||||
for="new_password"
|
||||
class="font-medium text-gray-700">{$_('confirm-the-new-password')}</label>
|
||||
<div class="-mt-px relative">
|
||||
<input
|
||||
aria-label={$_('password')}
|
||||
type="password"
|
||||
required=""
|
||||
bind:value={password_confirm}
|
||||
class="border-gray-300 placeholder-gray-500 appearance-none rounded-md relative block w-full px-3 py-2 border focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
|
||||
placeholder={$_('password')} />
|
||||
</div>
|
||||
{#if password_change != password_confirm && password_change.length > 0}
|
||||
<span
|
||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">{$_('passwords-dont-match')}</span>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!update_password_enabled}
|
||||
class:opacity-50={!update_password_enabled}
|
||||
on:click={changePassword}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
{$_('update-password')}
|
||||
</button>
|
||||
{#if update_password_enabled}
|
||||
<p>
|
||||
{$_('after-the-update-youll-get-logged-out-please-login-with-your-new-password-after-that')}
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
|
||||
<div>
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<div class="px-4 sm:px-0">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">
|
||||
{$_('danger-zone')}
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-gray-600">
|
||||
{$_('stuff-that-could-harm-your-profile')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{#await user_promise}
|
||||
{$_('loading-profile-data')}
|
||||
{:then}
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
<div class="shadow sm:rounded-md sm:overflow-hidden">
|
||||
<div class="px-4 py-3 bg-gray-50 text-left sm:px-6">
|
||||
<span data-id="donor_actions_${editable.id}">
|
||||
{#if delete_triggered}
|
||||
<button
|
||||
on:click={() => {
|
||||
modal_open = true;
|
||||
}}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:">{$_('confirm-deletion')}</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = !delete_triggered;
|
||||
}}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:">{$_('cancel')}</button>
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = true;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:">{$_('delete-profile')}</button>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -6,6 +6,7 @@
|
|||
RunnerOrganizationService,
|
||||
RunnerTeamService,
|
||||
} from "@odit/lfk-client-js";
|
||||
import Select from "svelte-select";
|
||||
import Toastify from "toastify-js";
|
||||
export let modal_open;
|
||||
export let current_teams;
|
||||
|
@ -34,7 +35,9 @@
|
|||
$: parentGroup = undefined;
|
||||
$: orgs = [];
|
||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||
orgs = val;
|
||||
orgs = val.map((r) => {
|
||||
return { label: r.name, value: r };
|
||||
});
|
||||
});
|
||||
function submit() {
|
||||
if (processed_last_submit === true) {
|
||||
|
@ -90,7 +93,7 @@
|
|||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||
aria-hidden="true">​</span>
|
||||
<div
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline">
|
||||
|
@ -145,13 +148,27 @@
|
|||
<label
|
||||
for="firstname"
|
||||
class="block text-sm font-medium text-gray-700">{$_('organization')}</label>
|
||||
<select
|
||||
bind:value={parentGroup}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
{#each orgs as t}
|
||||
<option value={t.id}>{t.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => label
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
filterText.toLowerCase()
|
||||
) || option.value.id
|
||||
.toString()
|
||||
.startsWith(filterText.toLowerCase())}
|
||||
items={orgs}
|
||||
showChevron={true}
|
||||
placeholder={$_('search-for-an-organization-by-name-or-id')}
|
||||
noOptionsMessage={$_('no-organizations-found')}
|
||||
on:select={(selectedValue) => (parentGroup = selectedValue.detail.value.id)}
|
||||
on:clear={() => (parentGroup = null)} />
|
||||
{#if !parentGroup}
|
||||
<span
|
||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||
{$_('you-have-to-provide-an-organization')}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||
import Toastify from "toastify-js";
|
||||
import store from "../../store";
|
||||
import Select from "svelte-select";
|
||||
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
|
||||
import PromiseError from "../base/PromiseError.svelte";
|
||||
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
|
||||
import Teams from "./Teams.svelte";
|
||||
let [teamdata, original, delete_team, orgs, contacts, modal_open] = [
|
||||
{},
|
||||
{},
|
||||
|
@ -21,33 +23,43 @@
|
|||
export let params;
|
||||
export let import_modal_open = false;
|
||||
$: delete_triggered = false;
|
||||
$: save_enabled = !data_changed;
|
||||
$: save_enabled = !data_changed && teamdata.parentGroup != null;
|
||||
$: data_loaded = false;
|
||||
$: data_changed = JSON.stringify(teamdata) === JSON.stringify(original);
|
||||
$: sponsoring_contracts_download_open = false;
|
||||
$: group = {};
|
||||
$: contact = {};
|
||||
//
|
||||
const getContactLabel = (option) =>
|
||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||
const promise = RunnerTeamService.runnerTeamControllerGetOne(
|
||||
params.teamid
|
||||
).then((value) => {
|
||||
data_loaded = true;
|
||||
if (value.contact) {
|
||||
if (value.contact !== "null") {
|
||||
value.contact = value.contact.id;
|
||||
}
|
||||
}
|
||||
teamdata = Object.assign(teamdata, value);
|
||||
original = Object.assign(original, value);
|
||||
});
|
||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||
orgs = val;
|
||||
});
|
||||
GroupContactService.groupContactControllerGetAll().then((val) => {
|
||||
contacts = val;
|
||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||
orgs = val.map((r) => {
|
||||
return { label: r.name, value: r };
|
||||
});
|
||||
group = orgs.find((g) => g.value.id == teamdata.parentGroup.id);
|
||||
});
|
||||
GroupContactService.groupContactControllerGetAll().then((val) => {
|
||||
contacts = val.map((r) => {
|
||||
return { label: getContactLabel(r), value: r };
|
||||
});
|
||||
if(teamdata.contact){
|
||||
contact = contacts.find((g) => g.value.id == teamdata.contact.id);
|
||||
}
|
||||
else{
|
||||
contact = null;
|
||||
}
|
||||
});
|
||||
});
|
||||
document.addEventListener("click", function (e) {
|
||||
if (
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown:menu"
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
||||
) {
|
||||
sponsoring_contracts_download_open = false;
|
||||
}
|
||||
|
@ -73,15 +85,13 @@
|
|||
text: "updating team",
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
teamdata.parentGroup = teamdata.parentGroup.id;
|
||||
let postdata = teamdata;
|
||||
postdata.contact = postdata.contact === "null" ? null : postdata.contact;
|
||||
postdata.parentGroup = teamdata.parentGroup.id;
|
||||
postdata.contact = teamdata.contact?.id;
|
||||
RunnerTeamService.runnerTeamControllerPut(original.id, postdata)
|
||||
.then((resp) => {
|
||||
Object.assign(original, teamdata);
|
||||
original = teamdata;
|
||||
Object.assign(original, teamdata);
|
||||
//
|
||||
original = original;
|
||||
Toastify({
|
||||
text: "updated team",
|
||||
duration: 2500,
|
||||
|
@ -170,7 +180,17 @@
|
|||
aria-haspopup="true"
|
||||
aria-expanded="true">
|
||||
{$_('generate-sponsoring-contracts')}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="-mr-1 ml-2 h-5 w-5"><path fill="none" d="M0 0h24v24H0z"/><path fill="currentColor" d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z"/></svg>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
class="-mr-1 ml-2 h-5 w-5"><path
|
||||
fill="none"
|
||||
d="M0 0h24v24H0z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
{#if sponsoring_contracts_download_open}
|
||||
|
@ -333,32 +353,41 @@
|
|||
<label
|
||||
for="contact"
|
||||
class="font-medium text-gray-700">{$_('contact')}</label>
|
||||
<select
|
||||
name="contact"
|
||||
bind:value={teamdata.contact}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
<option value="null">no contact</option>
|
||||
{#each contacts as c}
|
||||
<option value={c.id}>
|
||||
{c.firstname}
|
||||
{c.middlename || ''}
|
||||
{c.lastname}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => label
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
filterText.toLowerCase()
|
||||
) || option.value.id
|
||||
.toString()
|
||||
.startsWith(filterText.toLowerCase())}
|
||||
items={contacts}
|
||||
showChevron={true}
|
||||
placeholder={$_('no-contact-selected')}
|
||||
noOptionsMessage={$_('no-contact-found')}
|
||||
bind:selectedValue={contact}
|
||||
on:select={(selectedValue)=> teamdata.contact = selectedValue.detail.value}
|
||||
on:clear={() => (teamdata.contact = null)} />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="org"
|
||||
class="font-medium text-gray-700">{$_('organization')}</label>
|
||||
<select
|
||||
name="org"
|
||||
bind:value={teamdata.parentGroup}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
|
||||
{#each orgs as o}
|
||||
<option value={o.id}>{o.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Select
|
||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||
itemFilter={(label, filterText, option) => label
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
filterText.toLowerCase()
|
||||
) || option.id.value.toString().startsWith(filterText.toLowerCase())}
|
||||
items={orgs}
|
||||
showChevron={true}
|
||||
placeholder={$_('search-for-an-organization-by-name-or-id')}
|
||||
noOptionsMessage={$_('no-organizations-found')}
|
||||
bind:selectedValue={group}
|
||||
on:select={(selectedValue)=> teamdata.parentGroup = selectedValue.detail.value}
|
||||
on:clear={() => (teamdata.parentGroup = null)} />
|
||||
</div>
|
||||
</section>
|
||||
{:else}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import store, { users as usersstore } from "../../store.js";
|
||||
import TeamsEmptyState from "./TeamsEmptyState.svelte";
|
||||
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
|
||||
import { clickOutside } from "../base/outsideclick";
|
||||
$: searchvalue = "";
|
||||
$: active_deletes = [];
|
||||
$: sponsoring_contracts_download_open = false;
|
||||
|
@ -19,12 +20,12 @@
|
|||
usersstore.set(data);
|
||||
});
|
||||
document.addEventListener("click", function (e) {
|
||||
if (
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode.parentNode.id != "sponsoring:dropdown:menu"
|
||||
) {
|
||||
sponsoring_contracts_download_open = false;
|
||||
}
|
||||
if (
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
||||
) {
|
||||
sponsoring_contracts_download_open = false;
|
||||
}
|
||||
});
|
||||
async function generateSponsoringContract(locale) {
|
||||
sponsoring_contracts_download_open = false;
|
||||
|
@ -111,54 +112,67 @@
|
|||
class="gridjs-input gridjs-search-input mb-4" />
|
||||
<div class="h-12">
|
||||
{#if current_teams.some((r) => r.is_selected === true)}
|
||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
||||
<div>
|
||||
<button
|
||||
on:click={() => {
|
||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-600 text-base font-medium text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex"
|
||||
id="options-menu"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="true">
|
||||
{$_('generate-sponsoring-contracts')}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="-mr-1 ml-2 h-5 w-5"><path fill="none" d="M0 0h24v24H0z"/><path fill="currentColor" d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
{#if sponsoring_contracts_download_open}
|
||||
<div
|
||||
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"
|
||||
id="sponsoring:dropdown:menu">
|
||||
<div
|
||||
class="py-1"
|
||||
role="menu"
|
||||
aria-orientation="vertical"
|
||||
aria-labelledby="options-menu">
|
||||
<span
|
||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
|
||||
<button
|
||||
on:click={() => {
|
||||
generateSponsoringContract('de');
|
||||
}}
|
||||
type="submit"
|
||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900 inline-flex"
|
||||
role="menuitem">
|
||||
{$_('german')}
|
||||
</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
generateSponsoringContract('en');
|
||||
}}
|
||||
type="submit"
|
||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900 inline-flex"
|
||||
role="menuitem">
|
||||
{$_('english')}
|
||||
</button>
|
||||
</div>
|
||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
||||
<div>
|
||||
<button
|
||||
on:click={() => {
|
||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-600 text-base font-medium text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex"
|
||||
id="options-menu"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="true">
|
||||
{$_('generate-sponsoring-contracts')}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
class="-mr-1 ml-2 h-5 w-5"><path
|
||||
fill="none"
|
||||
d="M0 0h24v24H0z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if sponsoring_contracts_download_open}
|
||||
<div
|
||||
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"
|
||||
id="sponsoring:dropdown:menu"
|
||||
on:click_outside={() => {
|
||||
sponsoring_contracts_download_open = false;
|
||||
}}>
|
||||
<div
|
||||
class="py-1"
|
||||
role="menu"
|
||||
aria-orientation="vertical"
|
||||
aria-labelledby="options-menu">
|
||||
<span
|
||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
|
||||
<button
|
||||
on:click={() => {
|
||||
generateSponsoringContract('de');
|
||||
}}
|
||||
type="submit"
|
||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900 inline-flex"
|
||||
role="menuitem">
|
||||
{$_('german')}
|
||||
</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
generateSponsoringContract('en');
|
||||
}}
|
||||
type="submit"
|
||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900 inline-flex"
|
||||
role="menuitem">
|
||||
{$_('english')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -1,327 +1,326 @@
|
|||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import lodashIsEqual from "lodash.isequal";
|
||||
import store from "../../store";
|
||||
import isEmail from "validator/es/lib/isEmail";
|
||||
import { UserService, UserGroupService } from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import PromiseError from "../base/PromiseError.svelte";
|
||||
export let params;
|
||||
const user_promise = UserService.userControllerGetOne(params.userid);
|
||||
let data_loaded = false;
|
||||
let usergroups_array_original = [];
|
||||
const colors = [
|
||||
"#f3558e",
|
||||
"#17b978",
|
||||
"#3498db",
|
||||
"#3f3b3b",
|
||||
"#775ada",
|
||||
"#7ed6df_#000000",
|
||||
"#000000",
|
||||
"#21e6c1_#000000",
|
||||
"#c0392b",
|
||||
"#d35400",
|
||||
"#7f8c8d",
|
||||
"#6ab04c",
|
||||
"#4834d4",
|
||||
"#ff1f5a",
|
||||
"#eac100",
|
||||
];
|
||||
let matched_colors = [];
|
||||
$: delete_triggered = false;
|
||||
$: original_data = {};
|
||||
$: editable_userdata = {};
|
||||
$: allgroups = [];
|
||||
$: allgroups_ids = [];
|
||||
$: usergroups_array = [];
|
||||
$: search_permission = "";
|
||||
user_promise.then((data) => {
|
||||
let current_target = "";
|
||||
let colorindex = -1;
|
||||
// alphabetically sort permissions for color compatibility for target
|
||||
data.permissions = data.permissions.sort();
|
||||
data.permissions.forEach((p) => {
|
||||
const target = p.split(":")[0];
|
||||
if (current_target !== p.split(":")[0]) {
|
||||
colorindex++;
|
||||
current_target = p.split(":")[0];
|
||||
}
|
||||
let background = colors[colorindex];
|
||||
let foreground = "#fff";
|
||||
if (background.includes("_")) {
|
||||
foreground = background.split("_")[1];
|
||||
background = background.split("_")[0];
|
||||
}
|
||||
matched_colors[target] = [background, foreground];
|
||||
});
|
||||
//
|
||||
data_loaded = true;
|
||||
original_data = Object.assign(original_data, data);
|
||||
editable_userdata = data;
|
||||
data.groups.forEach((g) => {
|
||||
usergroups_array = usergroups_array.concat([g.id]);
|
||||
});
|
||||
usergroups_array_original = usergroups_array;
|
||||
allgroups.forEach((g) => {
|
||||
allgroups_ids.push(g.id);
|
||||
});
|
||||
});
|
||||
UserGroupService.userGroupControllerGetAll().then((data) => {
|
||||
allgroups = data;
|
||||
});
|
||||
$: changes_performed = !lodashIsEqual(original_data, editable_userdata);
|
||||
$: groups_changed =
|
||||
JSON.stringify(usergroups_array) ===
|
||||
JSON.stringify(usergroups_array_original);
|
||||
$: save_enabled =
|
||||
(changes_performed || !groups_changed) && isEmail(editable_userdata.email);
|
||||
function submit() {
|
||||
if (data_loaded === true && save_enabled) {
|
||||
editable_userdata.groups = usergroups_array;
|
||||
Toastify({
|
||||
text: $_("updating-user"),
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
UserService.userControllerPut(original_data.id, editable_userdata)
|
||||
.then((resp) => {
|
||||
Object.assign(original_data, resp);
|
||||
Object.assign(editable_userdata, resp);
|
||||
original_data.permissions = resp.permissions;
|
||||
usergroups_array = [];
|
||||
resp.groups.forEach((g) => {
|
||||
usergroups_array = usergroups_array.concat([g.id]);
|
||||
});
|
||||
usergroups_array_original = usergroups_array;
|
||||
//
|
||||
Toastify({
|
||||
text: $_("user-updated"),
|
||||
duration: 2500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
}
|
||||
function deleteUser() {
|
||||
UserService.userControllerRemove(original_data.id, true)
|
||||
.then((resp) => {
|
||||
location.replace("./");
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
</script>
|
||||
|
||||
{#await user_promise}
|
||||
<!-- -->
|
||||
{:then user}
|
||||
<section class="container p-5 select-none">
|
||||
<div class="flex flex-row mb-4">
|
||||
<div class="w-full">
|
||||
<nav class="w-full flex">
|
||||
<ol class="list-none flex flex-row items-center justify-start">
|
||||
<li class="flex items-center">
|
||||
<svg
|
||||
class="flex-shrink-0 w-5 h-5 mr-2"
|
||||
fill="currentColor"
|
||||
width="24"
|
||||
height="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"><path
|
||||
fill="currentColor"
|
||||
d="M12 14v8H4a8 8 0 018-8zm0-1a6 6 0 110-12 6 6 0 010 12zm2.6 5.81a3.51 3.51 0 010-1.62l-1-.57 1-1.74 1 .58a3.5 3.5 0 011.4-.82V13.5h2v1.15a3.5 3.5 0 011.4.8l1-.57 1 1.74-1 .57a3.51 3.51 0 010 1.62l1 .57-1 1.74-1-.58a3.5 3.5 0 01-1.4.82v1.14h-2v-1.15a3.5 3.5 0 01-1.4-.8l-1 .57-1-1.74 1-.57zM18 17a1 1 0 100 2 1 1 0 000-2z" /></svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<a class="mr-2" href="./">{$_('users')}</a><svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="h-3 w-3 mr-2 stroke-current"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"><line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12" />
|
||||
<polyline points="12 5 19 12 12 19" /></svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<span class="mr-2">{original_data.firstname}
|
||||
{original_data.middlename || ''}
|
||||
{original_data.lastname}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8 text-3xl font-extrabold">
|
||||
{original_data.firstname}
|
||||
{original_data.middlename || ''}
|
||||
{original_data.lastname}
|
||||
<span data-id="user_actions_${editable_userdata.id}">
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
|
||||
{#if delete_triggered}
|
||||
<button
|
||||
on:click={deleteUser}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-delete')}</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = !delete_triggered;
|
||||
}}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm">{$_('cancel')}</button>
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = true;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-user')}</button>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
disabled={!save_enabled}
|
||||
class:opacity-50={!save_enabled}
|
||||
type="button"
|
||||
on:click={submit}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('save-changes')}</button>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<div class="mt-3 text-sm w-full">
|
||||
<p class="ml-1 font-medium text-gray-700">{$_('profile-picture')}</p>
|
||||
<img
|
||||
alt={$_('profile-picture')}
|
||||
class="h-20 w-20 rounded-full overflow-hidden bg-gray-100"
|
||||
src={editable_userdata.profilePic} />
|
||||
</div>
|
||||
<div class="mt-3 text-sm w-full">
|
||||
<label
|
||||
for="enabled"
|
||||
class="ml-1 font-medium text-gray-700">{$_('active')}?</label>
|
||||
<br />
|
||||
<p class="text-gray-500">
|
||||
<input
|
||||
id="enabled"
|
||||
on:change={() => {
|
||||
editable_userdata.enabled = !editable_userdata.enabled;
|
||||
}}
|
||||
name="enabled"
|
||||
type="checkbox"
|
||||
checked={editable_userdata.enabled}
|
||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||
{$_('set-the-user-active-inactive')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="firstname"
|
||||
class="font-medium text-gray-700">{$_('first-name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('first-name')}
|
||||
type="text"
|
||||
bind:value={editable_userdata.firstname}
|
||||
name="firstname"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="middlename"
|
||||
class="font-medium text-gray-700">{$_('middle-name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('middle-name')}
|
||||
type="text"
|
||||
bind:value={editable_userdata.middlename}
|
||||
name="middlename"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="lastname"
|
||||
class="font-medium text-gray-700">{$_('last-name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('last-name')}
|
||||
type="text"
|
||||
bind:value={editable_userdata.lastname}
|
||||
name="lastname"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="email"
|
||||
class="font-medium text-gray-700">{$_('e-mail-adress')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('e-mail-adress')}
|
||||
type="email"
|
||||
bind:value={editable_userdata.email}
|
||||
name="email"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
{#if !isEmail(editable_userdata.email)}
|
||||
<span
|
||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">{$_('valid-email-is-required')}</span>
|
||||
{/if}
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="username"
|
||||
class="font-medium text-gray-700">{$_('username')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('username')}
|
||||
type="text"
|
||||
bind:value={editable_userdata.username}
|
||||
name="username"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<span class="font-medium">{$_('groups')}</span>
|
||||
<!-- svelte-ignore a11y-no-onchange -->
|
||||
<select
|
||||
bind:value={usergroups_array}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2"
|
||||
multiple>
|
||||
{#each allgroups as g}
|
||||
{#if usergroups_array.includes(g.id)}
|
||||
<option selected value={g.id}>{g.name}</option>
|
||||
{:else}
|
||||
<option value={g.id}>{g.name}</option>
|
||||
{/if}
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="text-sm w-full mt-8">
|
||||
<p class="font-medium mb-4">
|
||||
{$_('permissions')}
|
||||
<a
|
||||
class="px-4 py-2 bg-gray-500 rounded-md text-white"
|
||||
href="/users/{params.userid}/permissions/">{$_('edit-permissions')}</a>
|
||||
</p>
|
||||
<div class="w-full sm:my-px sm:px-px sm:w-1/2">
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="{$_('search-for-permission')}"
|
||||
type="text"
|
||||
bind:value={search_permission}
|
||||
class="mt-4 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
{#each original_data.permissions as p}
|
||||
{#if p.toLowerCase().includes(search_permission.toLowerCase())}
|
||||
<span
|
||||
style="background:{matched_colors[p.split(':')[0]][0]};color:{matched_colors[p.split(':')[0]][1]};"
|
||||
class="mt-1 inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-indigo-100 rounded">{p}</span>
|
||||
<!-- -->
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
{:catch error}
|
||||
<PromiseError {error} />
|
||||
{/await}
|
||||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import store from "../../store";
|
||||
import isEmail from "validator/es/lib/isEmail";
|
||||
import { UserService, UserGroupService } from "@odit/lfk-client-js";
|
||||
import Toastify from "toastify-js";
|
||||
import PromiseError from "../base/PromiseError.svelte";
|
||||
export let params;
|
||||
const user_promise = UserService.userControllerGetOne(params.userid);
|
||||
let data_loaded = false;
|
||||
let usergroups_array_original = [];
|
||||
const colors = [
|
||||
"#f3558e",
|
||||
"#17b978",
|
||||
"#3498db",
|
||||
"#3f3b3b",
|
||||
"#775ada",
|
||||
"#7ed6df_#000000",
|
||||
"#000000",
|
||||
"#21e6c1_#000000",
|
||||
"#c0392b",
|
||||
"#d35400",
|
||||
"#7f8c8d",
|
||||
"#6ab04c",
|
||||
"#4834d4",
|
||||
"#ff1f5a",
|
||||
"#eac100",
|
||||
];
|
||||
let matched_colors = [];
|
||||
$: delete_triggered = false;
|
||||
$: original_data = {};
|
||||
$: editable_userdata = {};
|
||||
$: allgroups = [];
|
||||
$: allgroups_ids = [];
|
||||
$: usergroups_array = [];
|
||||
$: search_permission = "";
|
||||
user_promise.then((data) => {
|
||||
let current_target = "";
|
||||
let colorindex = -1;
|
||||
// alphabetically sort permissions for color compatibility for target
|
||||
data.permissions = data.permissions.sort();
|
||||
data.permissions.forEach((p) => {
|
||||
const target = p.split(":")[0];
|
||||
if (current_target !== p.split(":")[0]) {
|
||||
colorindex++;
|
||||
current_target = p.split(":")[0];
|
||||
}
|
||||
let background = colors[colorindex];
|
||||
let foreground = "#fff";
|
||||
if (background.includes("_")) {
|
||||
foreground = background.split("_")[1];
|
||||
background = background.split("_")[0];
|
||||
}
|
||||
matched_colors[target] = [background, foreground];
|
||||
});
|
||||
//
|
||||
data_loaded = true;
|
||||
original_data = Object.assign(original_data, data);
|
||||
editable_userdata = data;
|
||||
data.groups.forEach((g) => {
|
||||
usergroups_array = usergroups_array.concat([g.id]);
|
||||
});
|
||||
usergroups_array_original = usergroups_array;
|
||||
allgroups.forEach((g) => {
|
||||
allgroups_ids.push(g.id);
|
||||
});
|
||||
});
|
||||
UserGroupService.userGroupControllerGetAll().then((data) => {
|
||||
allgroups = data;
|
||||
});
|
||||
$: changes_performed = !(JSON.stringify(original_data) == JSON.stringify(editable_userdata));
|
||||
$: groups_changed =
|
||||
JSON.stringify(usergroups_array) ===
|
||||
JSON.stringify(usergroups_array_original);
|
||||
$: save_enabled =
|
||||
(changes_performed || !groups_changed) && isEmail(editable_userdata.email);
|
||||
function submit() {
|
||||
if (data_loaded === true && save_enabled) {
|
||||
editable_userdata.groups = usergroups_array;
|
||||
Toastify({
|
||||
text: $_("updating-user"),
|
||||
duration: 2500,
|
||||
}).showToast();
|
||||
UserService.userControllerPut(original_data.id, editable_userdata)
|
||||
.then((resp) => {
|
||||
Object.assign(original_data, resp);
|
||||
Object.assign(editable_userdata, resp);
|
||||
original_data.permissions = resp.permissions;
|
||||
usergroups_array = [];
|
||||
resp.groups.forEach((g) => {
|
||||
usergroups_array = usergroups_array.concat([g.id]);
|
||||
});
|
||||
usergroups_array_original = usergroups_array;
|
||||
//
|
||||
Toastify({
|
||||
text: $_("user-updated"),
|
||||
duration: 2500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
}
|
||||
function deleteUser() {
|
||||
UserService.userControllerRemove(original_data.id, true)
|
||||
.then((resp) => {
|
||||
location.replace("./");
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
</script>
|
||||
|
||||
{#await user_promise}
|
||||
<!-- -->
|
||||
{:then user}
|
||||
<section class="container p-5 select-none">
|
||||
<div class="flex flex-row mb-4">
|
||||
<div class="w-full">
|
||||
<nav class="w-full flex">
|
||||
<ol class="list-none flex flex-row items-center justify-start">
|
||||
<li class="flex items-center">
|
||||
<svg
|
||||
class="flex-shrink-0 w-5 h-5 mr-2"
|
||||
fill="currentColor"
|
||||
width="24"
|
||||
height="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"><path
|
||||
fill="currentColor"
|
||||
d="M12 14v8H4a8 8 0 018-8zm0-1a6 6 0 110-12 6 6 0 010 12zm2.6 5.81a3.51 3.51 0 010-1.62l-1-.57 1-1.74 1 .58a3.5 3.5 0 011.4-.82V13.5h2v1.15a3.5 3.5 0 011.4.8l1-.57 1 1.74-1 .57a3.51 3.51 0 010 1.62l1 .57-1 1.74-1-.58a3.5 3.5 0 01-1.4.82v1.14h-2v-1.15a3.5 3.5 0 01-1.4-.8l-1 .57-1-1.74 1-.57zM18 17a1 1 0 100 2 1 1 0 000-2z" /></svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<a class="mr-2" href="./">{$_('users')}</a><svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="h-3 w-3 mr-2 stroke-current"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"><line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12" />
|
||||
<polyline points="12 5 19 12 12 19" /></svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<span class="mr-2">{original_data.firstname}
|
||||
{original_data.middlename || ''}
|
||||
{original_data.lastname}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8 text-3xl font-extrabold">
|
||||
{original_data.firstname}
|
||||
{original_data.middlename || ''}
|
||||
{original_data.lastname}
|
||||
<span data-id="user_actions_${editable_userdata.id}">
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
|
||||
{#if delete_triggered}
|
||||
<button
|
||||
on:click={deleteUser}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-delete')}</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = !delete_triggered;
|
||||
}}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm">{$_('cancel')}</button>
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
on:click={() => {
|
||||
delete_triggered = true;
|
||||
}}
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-user')}</button>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if !delete_triggered}
|
||||
<button
|
||||
disabled={!save_enabled}
|
||||
class:opacity-50={!save_enabled}
|
||||
type="button"
|
||||
on:click={submit}
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('save-changes')}</button>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<div class="mt-3 text-sm w-full">
|
||||
<p class="ml-1 font-medium text-gray-700">{$_('profile-picture')}</p>
|
||||
<img
|
||||
alt={$_('profile-picture')}
|
||||
class="h-20 w-20 rounded-full overflow-hidden bg-gray-100"
|
||||
src={editable_userdata.profilePic} />
|
||||
</div>
|
||||
<div class="mt-3 text-sm w-full">
|
||||
<label
|
||||
for="enabled"
|
||||
class="ml-1 font-medium text-gray-700">{$_('active')}?</label>
|
||||
<br />
|
||||
<p class="text-gray-500">
|
||||
<input
|
||||
id="enabled"
|
||||
on:change={() => {
|
||||
editable_userdata.enabled = !editable_userdata.enabled;
|
||||
}}
|
||||
name="enabled"
|
||||
type="checkbox"
|
||||
checked={editable_userdata.enabled}
|
||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||
{$_('set-the-user-active-inactive')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="firstname"
|
||||
class="font-medium text-gray-700">{$_('first-name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('first-name')}
|
||||
type="text"
|
||||
bind:value={editable_userdata.firstname}
|
||||
name="firstname"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="middlename"
|
||||
class="font-medium text-gray-700">{$_('middle-name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('middle-name')}
|
||||
type="text"
|
||||
bind:value={editable_userdata.middlename}
|
||||
name="middlename"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="lastname"
|
||||
class="font-medium text-gray-700">{$_('last-name')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('last-name')}
|
||||
type="text"
|
||||
bind:value={editable_userdata.lastname}
|
||||
name="lastname"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="email"
|
||||
class="font-medium text-gray-700">{$_('e-mail-adress')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('e-mail-adress')}
|
||||
type="email"
|
||||
bind:value={editable_userdata.email}
|
||||
name="email"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
{#if !isEmail(editable_userdata.email)}
|
||||
<span
|
||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">{$_('valid-email-is-required')}</span>
|
||||
{/if}
|
||||
<div class="text-sm w-full">
|
||||
<label
|
||||
for="username"
|
||||
class="font-medium text-gray-700">{$_('username')}</label>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder={$_('username')}
|
||||
type="text"
|
||||
bind:value={editable_userdata.username}
|
||||
name="username"
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
<span class="font-medium">{$_('groups')}</span>
|
||||
<!-- svelte-ignore a11y-no-onchange -->
|
||||
<select
|
||||
bind:value={usergroups_array}
|
||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2"
|
||||
multiple>
|
||||
{#each allgroups as g}
|
||||
{#if usergroups_array.includes(g.id)}
|
||||
<option selected value={g.id}>{g.name}</option>
|
||||
{:else}
|
||||
<option value={g.id}>{g.name}</option>
|
||||
{/if}
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="text-sm w-full mt-8">
|
||||
<p class="font-medium mb-4">
|
||||
{$_('permissions')}
|
||||
<a
|
||||
class="px-4 py-2 bg-gray-500 rounded-md text-white"
|
||||
href="/users/{params.userid}/permissions/">{$_('edit-permissions')}</a>
|
||||
</p>
|
||||
<div class="w-full sm:my-px sm:px-px sm:w-1/2">
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="{$_('search-for-permission')}"
|
||||
type="text"
|
||||
bind:value={search_permission}
|
||||
class="mt-4 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
|
||||
</div>
|
||||
{#each original_data.permissions as p}
|
||||
{#if p.toLowerCase().includes(search_permission.toLowerCase())}
|
||||
<span
|
||||
style="background:{matched_colors[p.split(':')[0]][0]};color:{matched_colors[p.split(':')[0]][1]};"
|
||||
class="mt-1 inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-indigo-100 rounded">{p}</span>
|
||||
<!-- -->
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
{:catch error}
|
||||
<PromiseError {error} />
|
||||
{/await}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"active": "Aktiv",
|
||||
"add-donation": "Sponsoring erstellen",
|
||||
"add-donor": "Sponsor:in erstellen",
|
||||
"add-scan": "Scan erstellen",
|
||||
"add-user-group": "Neue Gruppe erstellen",
|
||||
"add-your-first-contact": "Erstelle den ersten Kontakt",
|
||||
"add-your-first-donor": "Erstelle die erste Sponsor:in",
|
||||
|
@ -15,8 +16,12 @@
|
|||
"add-your-first-team": "Erstelle das erste Team",
|
||||
"add-your-first-track": "Erstelle den ersten Track (Laufstrecke).",
|
||||
"add-your-first-user": "Erstelle die erste Benutzer:in",
|
||||
"add-your-fist-scan": "Füge deinene ersten Scan hinzu",
|
||||
"adding-scan": "Scan wird hinzugefügt",
|
||||
"address": "Adresse",
|
||||
"address-is-required": "Du musst eine Adresse angeben",
|
||||
"after-deletion-we-cant-restore-your-old-profile": "Nach der Löschung können auch die Admins dein Profil nicht wiederherstellen!",
|
||||
"after-the-update-youll-get-logged-out-please-login-with-your-new-password-after-that": "Nach der Änderung wirst du abgemeldet - bitte melde dich dann mit deinem neuen Passwort an.",
|
||||
"all-associated-donations-will-get-deleted-as-well": "Alle Sponsorings dieser Sponsor:in werden ebenfalls gelöscht",
|
||||
"all-associated-runners-will-be-deleted-too": "Alle zugehörigen Läufer:innen werden auch gelöscht!",
|
||||
"all-associated-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch gelöscht!",
|
||||
|
@ -31,18 +36,23 @@
|
|||
"cancel": "Abbrechen",
|
||||
"cancel-delete": "Löschen abbrechen",
|
||||
"cancel-keep-donor": "Abbrechen, Sponsor:in behalten",
|
||||
"cancel-keep-my-profile": "Abbrechen, mein Profil behalten",
|
||||
"cancel-keep-organization": "Abbrechen und Organisation bearbeiten",
|
||||
"cancel-keep-team": "Abbrechen, Team behalten",
|
||||
"cannot-reset-your-password-directly": "Schade. \nWir können das Passwort leider nicht direkt zurücksetzen.\nBitte sende uns eine Mail in der du deine Identität bestätigst.",
|
||||
"change-your-password-here": "Hier kannst du dein Passwort ändern",
|
||||
"changing-your-password": "Passwort wird geändert",
|
||||
"city": "Stadt",
|
||||
"close": "Schließen",
|
||||
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
|
||||
"confirm": "Bestätigen",
|
||||
"confirm-delete": "Löschung Bestätigen",
|
||||
"confirm-delete-donor-with-all-donations": "Bestätigen, Sponsor:in mit allen Sponsorings löschen",
|
||||
"confirm-delete-my-user-profile": "Bestätigung, mein Benutzerprofil löschen",
|
||||
"confirm-delete-organization-and-associated-teams-runners": "Bestätugung, lösche die Organisation und alle zugehörigen Teams und Läufer:innen.",
|
||||
"confirm-delete-team-and-associated-runners": "Bestätigung, lösche das Team mitsamt seinen Läufer:innen.",
|
||||
"confirm-deletion": "Löschung Bestätigen",
|
||||
"confirm-the-new-password": "Neues Passwort bestätigen",
|
||||
"contact": "Kontakt",
|
||||
"contact-deleted": "Kontakt gelöscht",
|
||||
"contact-information": "Kontaktinformation",
|
||||
|
@ -60,6 +70,8 @@
|
|||
"create-a-new-fixed-donation": "Erstelle eine neue Festbetragsspende",
|
||||
"create-a-new-organization": "Neue Organisation anlegen",
|
||||
"create-a-new-runner": "Neue Läufer:in erstellen",
|
||||
"create-a-new-scan-fixed-only": "Neuen Scan erstellen (nur mit Festdistanz)",
|
||||
"create-a-new-scanstation": "Neue Station erstellen",
|
||||
"create-a-new-team": "Erstelle ein neues Team",
|
||||
"create-a-new-track": "Neuen Track erstellen",
|
||||
"create-a-new-user": "Neue Benutzer:in anlegen",
|
||||
|
@ -74,6 +86,7 @@
|
|||
"csv_import__lastname": "Nachname",
|
||||
"csv_import__middlename": "Mittelname",
|
||||
"csv_import__team": "Team",
|
||||
"danger-zone": "Gefahrenzone",
|
||||
"dashboard-greeting": "Moin",
|
||||
"dashboard-title": "Dashboard",
|
||||
"datatable": {
|
||||
|
@ -97,9 +110,13 @@
|
|||
"delete-donor": "Sponsor:in löschen",
|
||||
"delete-group": "Gruppe löschen",
|
||||
"delete-organization": "Organisation löschen",
|
||||
"delete-profile": "Profil löschen",
|
||||
"delete-runner": "Läufer:in löschen",
|
||||
"delete-scan": "Scan löschen",
|
||||
"delete-station": "Station löschen",
|
||||
"delete-team": "Team Löschen",
|
||||
"delete-user": "Benutzer:in löschen",
|
||||
"deleted-scan": "Scan wurde gelöscht",
|
||||
"dependency_name": "Name",
|
||||
"description": "Beschreibung",
|
||||
"description-optional": "Beschreibung (optional)",
|
||||
|
@ -108,6 +125,8 @@
|
|||
"distance": "Distanz",
|
||||
"distance-donation": "Sponsoring",
|
||||
"distance-in-km": "Distanz (in KM)",
|
||||
"distance-track": "Distanz (+Track)",
|
||||
"do-you-really-want-to-delete-your-profile": "Möchtest du dein Profil wirklich löschen?",
|
||||
"do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?",
|
||||
"do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} löschen?",
|
||||
"do-you-want-to-delete-this-donor-with-all-related-donations": "Möchtest du diese Sponsor:in mit all ihren Sponsorings löschen?",
|
||||
|
@ -128,14 +147,17 @@
|
|||
"edit": "Bearbeiten",
|
||||
"edit-permissions": "Berechtigungen bearbeiten",
|
||||
"email_address_or_username": "E-Mail-Adresse/ Benutzername",
|
||||
"enabled": "aktiviert",
|
||||
"english": "Englisch",
|
||||
"error_on_login": "😢Fehler beim Login",
|
||||
"erteilte": "Direkt erteilte",
|
||||
"everything-concerning-your-profile": "Alles zu deinem Profil",
|
||||
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃♂️🏃♀️🏃♂️",
|
||||
"faq": "FAQ",
|
||||
"filter-by-organization-team": "Filtern nach Organisation / Team",
|
||||
"first-name": "Vorname",
|
||||
"first-name-is-required": "Vorname muss angegeben werden",
|
||||
"first-scan-of-the-day": "Erster Scan des Tages",
|
||||
"fixed-donation": "Festbetragsspende",
|
||||
"forgot_password": "Passwort vergessen?",
|
||||
"geerbte": "geerbte",
|
||||
|
@ -156,6 +178,7 @@
|
|||
"group-name-is-required": "Der Gruppenname muss angegeben werden.",
|
||||
"group-updated": "Gruppe aktualisiert",
|
||||
"groups": "Gruppen",
|
||||
"groups-are-being-loaded": "Gruppen werden geladen",
|
||||
"home": "Start",
|
||||
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
|
||||
"import-finished": "Import abgeschlossen",
|
||||
|
@ -166,9 +189,11 @@
|
|||
"inactive": "Inaktiv",
|
||||
"installed-version": "Installierte Version",
|
||||
"internal-error": "Interner Fehler",
|
||||
"invalid": "Ungültig",
|
||||
"invalid-mail-reset": "Das ist keine gültige E-Mail",
|
||||
"laeufer-hinzufuegen": "Läufer:in hinzufügen",
|
||||
"laeufer-importieren": "Läufer:innen importieren",
|
||||
"laptime": "Rundenzeit",
|
||||
"last-name": "Nachname",
|
||||
"last-name-is-required": "Nachname muss angegeben werden",
|
||||
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
|
||||
|
@ -177,7 +202,10 @@
|
|||
"loading-contact-details": "Kontaktdaten werden geladen ...",
|
||||
"loading-donation-details": "Lade Sponsoringdetails",
|
||||
"loading-donor-details": "Lade Details",
|
||||
"loading-group-detail": "Lade Gruppendetails...",
|
||||
"loading-profile-data": "Lade Profildaten",
|
||||
"loading-runners": "Läufer:innen werden geladen...",
|
||||
"loading-station-details": "Lade Scanstation-Details ...",
|
||||
"log_in": "Anmelden",
|
||||
"log_in_to_your_account": "Bitte melde dich an",
|
||||
"login_is_checked": "Login wird überprüft",
|
||||
|
@ -190,9 +218,15 @@
|
|||
"name": "Name",
|
||||
"name-is-required": "Der Gruppenname muss angegeben werden",
|
||||
"new-password": "Neues Passwort",
|
||||
"no-contact-found": "Keine Kontakte gefunden",
|
||||
"no-contact-selected": "Kein Kontakt ausgewählt",
|
||||
"no-contact-specified": "Kein Kontakt angegeben",
|
||||
"no-donors-found": "Keine Spender:innen gefunden",
|
||||
"no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢",
|
||||
"no-organization-or-team-found": "Keine Organisationen oder Teams gefunden",
|
||||
"no-organization-specified": "Keine Organisation angegeben",
|
||||
"no-organizations-found": "Keine Organisationen gefunden",
|
||||
"no-runners-found": "Keine Läufer:innen gefunden",
|
||||
"no-tracks-added-yet": "Es wurden noch keine Tracks erstellt.",
|
||||
"organization": "Organisation",
|
||||
"organization-added": "Organisation hinzugefügt",
|
||||
|
@ -205,11 +239,13 @@
|
|||
"orgs": "Organisationen",
|
||||
"oss_credit_description": "Wir verwenden eine Menge Open Source-Software bei diesen Projekten und möchten uns bei den folgenden Projekten und Mitwirkenden bedanken, die dazu beitragen, Open Source großartig zu machen!",
|
||||
"password": "Passwort",
|
||||
"password-changed": "Passwort wurde aktualisiert!",
|
||||
"password-is-required": "Passwort muss angegeben werden",
|
||||
"password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!",
|
||||
"password-reset-in-progress": "Passwort wird zurückgesetzt...",
|
||||
"password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.",
|
||||
"password-reset-successful": "Passwort erfolgreich zurückgesetzt!",
|
||||
"passwords-dont-match": "Die Passwörter stimmen nicht überein.",
|
||||
"pdf-generation-failed": "PDF Generierung fehlgeschlagen!",
|
||||
"pdf-successfully-generated": "PDF wurde erfolgreich generiert!",
|
||||
"pdfs-successfully-generated": "Alle PDFs wurden generiert!",
|
||||
|
@ -220,6 +256,7 @@
|
|||
"please-provide-a-password": "Bitte gebe ein Passwort an...",
|
||||
"please-provide-the-nessecary-information-to-add-a-new-donor": "Bitte mach die Notwendigen Angaben, um eine neue Sponsor:in zu erstellen",
|
||||
"please-provide-the-nessecary-information-to-create-a-new-donation": "Bitte gebe alle für das Sponsoring notwendigen Daten an.",
|
||||
"please-provide-the-nessecary-information-to-create-a-new-scan": "Bitte gebe alle notwendigen Informationen an, um einen neuen Scan zu erstellen.",
|
||||
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
|
||||
"please-provide-the-required-information-for-creating-a-new-user-group": "Bitte gebe alle für eine neue Gruppe notwendigen Informationen an.",
|
||||
"please-provide-the-required-information-to-add-a-new-contact": "Bitte gebe alle nötigen Informationen an, im den neuen Kontakt zu erstellen.",
|
||||
|
@ -231,7 +268,9 @@
|
|||
"please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...",
|
||||
"privacy": "Datenschutz",
|
||||
"privacy-loading": "Datenschutzerklärung lädt...",
|
||||
"profile": "Profil",
|
||||
"profile-picture": "Profilbild",
|
||||
"profile-updated": "Profil wurde aktualisiert!",
|
||||
"read-license": "Lizenz-Text lesen",
|
||||
"receipt-needed": "Spendenquittung benötigt",
|
||||
"repo_link": "Link",
|
||||
|
@ -249,15 +288,29 @@
|
|||
"runners-are-being-loaded": "Läufer:innen werden geladen ...",
|
||||
"save": "Speichern",
|
||||
"save-changes": "Änderungen speichern",
|
||||
"scan-added": "Scan hinzugefügt",
|
||||
"scan-is-being-updated": "Scan wird aktualisiert",
|
||||
"scan-with-fixed-distance": "Scan mit Festdistanz",
|
||||
"scans": "Scans",
|
||||
"scans-are-being-loaded": "Scans werden geladen",
|
||||
"scanstation": "Scanner Station",
|
||||
"scanstations": "Scanner Stationen",
|
||||
"scanstations-are-being-loaded": "Scannerstationen werden geladen...",
|
||||
"search-for-an-organization-by-name-or-id": "Suche eine Organisation (via Name oder Id)",
|
||||
"search-for-an-organization-or-team-by-name-or-id": "Suche eine Organisation oder ein Team (via Name oder Id)",
|
||||
"search-for-donor-name-or-id": "Suche eine Spender:in (via Name oder Id)",
|
||||
"search-for-permission": "Berechtigungen durchsuchen",
|
||||
"search-for-runner-by-name-or-id": "Suche eine Läufer:in (via Name oder Id)",
|
||||
"select-all": "Alle auswählen",
|
||||
"select-language": "Sprache auswählen",
|
||||
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
|
||||
"set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen",
|
||||
"settings": "Einstellungen",
|
||||
"settings-for-your-profile": "Die Einstellungen deines Accounts",
|
||||
"something-about-the-group": "Infos zur Gruppe",
|
||||
"stats-are-being-loaded": "Die Statistiken werden geladen...",
|
||||
"status": "Status",
|
||||
"stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können",
|
||||
"successful-password-reset": "Passwort erfolgreich zurückgesetzt!",
|
||||
"team": "Team",
|
||||
"team-detail-is-being-loaded": "Team wird geladen...",
|
||||
|
@ -266,18 +319,22 @@
|
|||
"teams": "Teams",
|
||||
"teams-are-being-loaded": "Teams werden geladen ...",
|
||||
"the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "Die angegebene Telefonnummer ist nicht korrekt. <br /> Bitte gebe eine Telefonnummer im internationalen Format an...",
|
||||
"the-scans-distance-must-be-greater-than-0m": "Die Distanz muss größer als 0m sein.",
|
||||
"there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.",
|
||||
"there-are-no-donors-yet": "Es gibt noch keine Sponsor:innen",
|
||||
"there-are-no-groups-yet": "Es gibt noch keine Gruppen",
|
||||
"there-are-no-organizations-added-yet": "Es wurden noch keine Organisationen hinzugefügt.",
|
||||
"there-are-no-runners-added-yet": "Es wurden noch keine Läufer:innen hinzugefügt.",
|
||||
"there-are-no-scans-yet": "Es gibt noch keine scans",
|
||||
"there-are-no-teams-added-yet": "Es wurden noch keine Teams hinzugefügt.",
|
||||
"there-are-no-users-added-yet": "Es wurden noch keine Benutzer hinzugefügt.",
|
||||
"this-might-take-a-moment": "Das könnte einen kleinen Moment dauern",
|
||||
"this-scanstation-is": "Diese Station ist",
|
||||
"total-distance": "gelaufene Strecke",
|
||||
"total-donation-amount": "Gesamtbetrag",
|
||||
"total-donations": "Spendensumme",
|
||||
"total-scans": "gesamte Scans",
|
||||
"track": "Track",
|
||||
"track-added": "Track hinzugefügt",
|
||||
"track-data-is-being-loaded": "Trackdaten werden geladen",
|
||||
"track-is-being-added": "Track wird hinzugefügt...",
|
||||
|
@ -286,26 +343,33 @@
|
|||
"track-name": "Trackname",
|
||||
"track-name-must-not-be-empty": "Der Name muss angegeben werden",
|
||||
"tracks": "Tracks",
|
||||
"update-password": "Passwort ändern",
|
||||
"updated-contact": "Kontakt aktualisiert!",
|
||||
"updated-donor": "Sponsor:in wurde aktualisiert",
|
||||
"updated-organization": "Organisation wurde aktualisiert",
|
||||
"updated-scan": "Scan wurde aktualisiert",
|
||||
"updateing-group": "Gruppe wird aktualisiert...",
|
||||
"updating-organization": "Organisation wird aktualisiert",
|
||||
"updating-permissions": "Berechtigungen werden aktualisiert...",
|
||||
"updating-runner": "Läufer:in wird aktualisiert.",
|
||||
"updating-user": "Benutzer:in wird aktualisiert...",
|
||||
"updating-your-profile": "Profil wird aktualisiert...",
|
||||
"user-added": "Benutzer hinzugefügt",
|
||||
"user-groups": "Benutzergruppen",
|
||||
"user-is-being-added": "Benutzer wird hinzugefügt ...",
|
||||
"user-updated": "Benutzer:in wurde aktualisiert",
|
||||
"username": "Benutzername",
|
||||
"users": "Benutzer",
|
||||
"valid": "Gültig",
|
||||
"valid-city-is-required": "Du musst eine Stadt angeben",
|
||||
"valid-email-is-required": "Es wird eine valide E-Mail Adresse benötigt",
|
||||
"valid-international-phone-number-is-required": "Du musst eine Telefonnummer im internationalen Format angeben...",
|
||||
"valid-zipcode-postal-code-is-required": "Du musst eine valide Postleitzahl angeben",
|
||||
"verfuegbare": "Verfügbar",
|
||||
"welcome_wavinghand": "Willkommen 👋",
|
||||
"yes-i-copied-the-token": "Ja, ich habe den Token kopiert",
|
||||
"you-are-going-to-loose-all-permissions-and-access-to-the-runner-system": "Du wirst all deine Berechtigungen und den Zugriff aufs Läufersystem verlieren!",
|
||||
"you-can-now-use-your-new-password-to-log-in-to-your-account": "Du kannst dich jetzt mit deinem neuen Passwort anmelden! 🎉",
|
||||
"you-have-to-provide-an-organization": "Du musst eine Organisation angeben",
|
||||
"zip-postal-code": "Postleitzahl"
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
"active": "Active",
|
||||
"add-donation": "Add donation",
|
||||
"add-donor": "add donor",
|
||||
"add-scan": "Add scan",
|
||||
"add-user-group": "Add User Group",
|
||||
"add-your-first-contact": "Add your first contact",
|
||||
"add-your-first-donor": "add your first donor",
|
||||
|
@ -15,8 +16,12 @@
|
|||
"add-your-first-team": "Add your first team",
|
||||
"add-your-first-track": "Add your first track.",
|
||||
"add-your-first-user": "Add your first user",
|
||||
"add-your-fist-scan": "Add your fist scan",
|
||||
"adding-scan": "Adding Scan",
|
||||
"address": "Address",
|
||||
"address-is-required": "Address is required",
|
||||
"after-deletion-we-cant-restore-your-old-profile": "After deletion we can't restore your old profile!",
|
||||
"after-the-update-youll-get-logged-out-please-login-with-your-new-password-after-that": "After the update you'll get logged out - Please login with your new password after that.",
|
||||
"all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well",
|
||||
"all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!",
|
||||
"all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!",
|
||||
|
@ -31,18 +36,23 @@
|
|||
"cancel": "Cancel",
|
||||
"cancel-delete": "Cancel Delete",
|
||||
"cancel-keep-donor": "Cancel, keep donor",
|
||||
"cancel-keep-my-profile": "Cancel, keep my profile",
|
||||
"cancel-keep-organization": "Cancel, keep organization",
|
||||
"cancel-keep-team": "Cancel, keep team",
|
||||
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
|
||||
"change-your-password-here": "Change your password here",
|
||||
"changing-your-password": "Changing your password",
|
||||
"city": "City",
|
||||
"close": "Close",
|
||||
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
|
||||
"confirm": "Confirm",
|
||||
"confirm-delete": "Confirm Delete",
|
||||
"confirm-delete-donor-with-all-donations": "Confirm, delete donor with all donations",
|
||||
"confirm-delete-my-user-profile": "Confirm, delete my user profile",
|
||||
"confirm-delete-organization-and-associated-teams-runners": "Confirm, delete organization and associated teams+runners.",
|
||||
"confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.",
|
||||
"confirm-deletion": "Confirm Deletion",
|
||||
"confirm-the-new-password": "Confirm the new password",
|
||||
"contact": "Contact",
|
||||
"contact-deleted": "Contact deleted",
|
||||
"contact-information": "Contact Information",
|
||||
|
@ -60,6 +70,8 @@
|
|||
"create-a-new-fixed-donation": "Create a new fixed donation",
|
||||
"create-a-new-organization": "Create a new Organization",
|
||||
"create-a-new-runner": "Create a new Runner",
|
||||
"create-a-new-scan-fixed-only": "Create a new scan (fixed only)",
|
||||
"create-a-new-scanstation": "Create a new station",
|
||||
"create-a-new-team": "Create a new team",
|
||||
"create-a-new-track": "Create a new Track",
|
||||
"create-a-new-user": "Create a new User",
|
||||
|
@ -74,6 +86,7 @@
|
|||
"csv_import__lastname": "Lastname",
|
||||
"csv_import__middlename": "Middlename",
|
||||
"csv_import__team": "Team",
|
||||
"danger-zone": "Danger zone",
|
||||
"dashboard-greeting": "hello there",
|
||||
"dashboard-title": "Dashboard",
|
||||
"datatable": {
|
||||
|
@ -97,9 +110,13 @@
|
|||
"delete-donor": "Delete donor",
|
||||
"delete-group": "Delete Group",
|
||||
"delete-organization": "Delete Organization",
|
||||
"delete-profile": "Delete Profile",
|
||||
"delete-runner": "Delete Runner",
|
||||
"delete-scan": "Delete scan",
|
||||
"delete-station": "Delete station",
|
||||
"delete-team": "Delete Team",
|
||||
"delete-user": "Delete User",
|
||||
"deleted-scan": "Deleted scan",
|
||||
"dependency_name": "Name",
|
||||
"description": "description",
|
||||
"description-optional": "Description (optional)",
|
||||
|
@ -108,6 +125,8 @@
|
|||
"distance": "Distance",
|
||||
"distance-donation": "distance donation",
|
||||
"distance-in-km": "Distance in km",
|
||||
"distance-track": "Distance (+Track)",
|
||||
"do-you-really-want-to-delete-your-profile": "Do you really want to delete your profile?",
|
||||
"do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?",
|
||||
"do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?",
|
||||
"do-you-want-to-delete-this-donor-with-all-related-donations": "Do you want to delete this donor with all related donations",
|
||||
|
@ -128,14 +147,17 @@
|
|||
"edit": "Edit",
|
||||
"edit-permissions": "edit permissions",
|
||||
"email_address_or_username": "Email / username",
|
||||
"enabled": "enabled",
|
||||
"english": "English",
|
||||
"error_on_login": "Error on login",
|
||||
"erteilte": "Directly granted",
|
||||
"everything-concerning-your-profile": "Everything concerning your profile",
|
||||
"everything-is-more-fun-together": "everything is more fun together 🏃♂️🏃♀️🏃♂️",
|
||||
"faq": "FAQ",
|
||||
"filter-by-organization-team": "Filter by Organization/ Team",
|
||||
"first-name": "First name",
|
||||
"first-name-is-required": "First Name is required",
|
||||
"first-scan-of-the-day": "First scan of the day.",
|
||||
"fixed-donation": "fixed donation",
|
||||
"forgot_password": "Forgot your password?",
|
||||
"geerbte": "inherited",
|
||||
|
@ -156,6 +178,7 @@
|
|||
"group-name-is-required": "Group name is required",
|
||||
"group-updated": "group updated",
|
||||
"groups": "Groups",
|
||||
"groups-are-being-loaded": "Groups are being loaded",
|
||||
"home": "Home",
|
||||
"icon-image-credits": "We also want to thank these projects for illustrations and icons:",
|
||||
"import-finished": "Import finished",
|
||||
|
@ -166,9 +189,11 @@
|
|||
"inactive": "Inactive",
|
||||
"installed-version": "Installed version",
|
||||
"internal-error": "Internal Error",
|
||||
"invalid": "Invalid",
|
||||
"invalid-mail-reset": "the provided email is invalid",
|
||||
"laeufer-hinzufuegen": "Add runner",
|
||||
"laeufer-importieren": "Läufer importieren",
|
||||
"laptime": "Laptime",
|
||||
"last-name": "Last name",
|
||||
"last-name-is-required": "Last Name is required",
|
||||
"lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.",
|
||||
|
@ -177,7 +202,10 @@
|
|||
"loading-contact-details": "Loading contact details...",
|
||||
"loading-donation-details": "Loading donation details",
|
||||
"loading-donor-details": "Loading donor details",
|
||||
"loading-group-detail": "Loading group detail...",
|
||||
"loading-profile-data": "Loading profile data",
|
||||
"loading-runners": "loading runners...",
|
||||
"loading-station-details": "Loading station details",
|
||||
"log_in": "Log in",
|
||||
"log_in_to_your_account": "Log in to your account",
|
||||
"login_is_checked": "Login is being checked...",
|
||||
|
@ -190,9 +218,15 @@
|
|||
"name": "Name",
|
||||
"name-is-required": "Name is required",
|
||||
"new-password": "New password",
|
||||
"no-contact-found": "No contacts found",
|
||||
"no-contact-selected": "No contact selected",
|
||||
"no-contact-specified": "no contact specified",
|
||||
"no-donors-found": "No donors found",
|
||||
"no-license-text-could-be-found": "No license text could be found 😢",
|
||||
"no-organization-or-team-found": "No organization or team found",
|
||||
"no-organization-specified": "no organization specified",
|
||||
"no-organizations-found": "No organizations found",
|
||||
"no-runners-found": "No runners found",
|
||||
"no-tracks-added-yet": "there are no tracks added yet.",
|
||||
"organization": "Organization",
|
||||
"organization-added": "Organization added",
|
||||
|
@ -202,14 +236,16 @@
|
|||
"organization-name-is-required": "Organization name is required",
|
||||
"organizations": "Organizations",
|
||||
"organizations-are-being-loaded": "organizations are being loaded...",
|
||||
"orgs": "Orgs",
|
||||
"orgs": "Organizations",
|
||||
"oss_credit_description": "We use a lot of open source software on these projects, and would like to thank the following projects and contributors who help make open source great!",
|
||||
"password": "Password",
|
||||
"password-changed": "Password changed!",
|
||||
"password-is-required": "Password is required",
|
||||
"password-reset-failed": "Password reset failed!",
|
||||
"password-reset-in-progress": "Password Reset in Progress...",
|
||||
"password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".",
|
||||
"password-reset-successful": "Password Reset successful!",
|
||||
"passwords-dont-match": "Passwords don't match",
|
||||
"pdf-generation-failed": "PDF generation failed!",
|
||||
"pdf-successfully-generated": "PDF successfully generated!",
|
||||
"pdfs-successfully-generated": "PDFs successfully generated!",
|
||||
|
@ -220,6 +256,7 @@
|
|||
"please-provide-a-password": "Please provide a password...",
|
||||
"please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor",
|
||||
"please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation",
|
||||
"please-provide-the-nessecary-information-to-create-a-new-scan": "Please provide the nessecary information to create a new scan.",
|
||||
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
|
||||
"please-provide-the-required-information-for-creating-a-new-user-group": "Please provide the required information for creating a new user group.",
|
||||
"please-provide-the-required-information-to-add-a-new-contact": "Please provide the required information to add a new contact.",
|
||||
|
@ -231,7 +268,9 @@
|
|||
"please-request-a-new-reset-mail": "Please request a new reset mail...",
|
||||
"privacy": "Privacy",
|
||||
"privacy-loading": "Privacy loading...",
|
||||
"profile": "Profile",
|
||||
"profile-picture": "Profile Picture",
|
||||
"profile-updated": "Profile updated!",
|
||||
"read-license": "Read License",
|
||||
"receipt-needed": "Receipt needed",
|
||||
"repo_link": "Link",
|
||||
|
@ -249,15 +288,29 @@
|
|||
"runners-are-being-loaded": "runners are being loaded...",
|
||||
"save": "Save",
|
||||
"save-changes": "Save Changes",
|
||||
"scan-added": "Scan added",
|
||||
"scan-is-being-updated": "Scan is being updated",
|
||||
"scan-with-fixed-distance": "Scan with fixed distance",
|
||||
"scans": "Scans",
|
||||
"scans-are-being-loaded": "Scans are being loaded",
|
||||
"scanstation": "Scanstation",
|
||||
"scanstations": "Scanstations",
|
||||
"scanstations-are-being-loaded": "Loading scanstations...",
|
||||
"search-for-an-organization-by-name-or-id": "Search for an organization (by name or id)",
|
||||
"search-for-an-organization-or-team-by-name-or-id": "Search for an organization or team (by name or id)",
|
||||
"search-for-donor-name-or-id": "Search for donor (by name or id)",
|
||||
"search-for-permission": "Search for permission",
|
||||
"search-for-runner-by-name-or-id": "Search for runner (by name or id)",
|
||||
"select-all": "select all",
|
||||
"select-language": "Select language",
|
||||
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
|
||||
"set-the-user-active-inactive": "set the user active/ inactive",
|
||||
"settings": "Settings",
|
||||
"settings-for-your-profile": "Settings for your profile",
|
||||
"something-about-the-group": "Something about the group...",
|
||||
"stats-are-being-loaded": "stats are being loaded...",
|
||||
"status": "Status",
|
||||
"stuff-that-could-harm-your-profile": "Stuff that could harm your profile",
|
||||
"successful-password-reset": "Successful password reset!",
|
||||
"team": "Team",
|
||||
"team-detail-is-being-loaded": "team detail is being loaded...",
|
||||
|
@ -266,18 +319,22 @@
|
|||
"teams": "Teams",
|
||||
"teams-are-being-loaded": "teams are being loaded...",
|
||||
"the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "the provided phone number is invalid.<br />please enter a valid international number...",
|
||||
"the-scans-distance-must-be-greater-than-0m": "The scan's distance must be greater than 0m",
|
||||
"there-are-no-contacts-added-yet": "There are no contacts added yet.",
|
||||
"there-are-no-donors-yet": "There are no donors yet",
|
||||
"there-are-no-groups-yet": "There are no groups yet",
|
||||
"there-are-no-organizations-added-yet": "There are no organizations added yet.",
|
||||
"there-are-no-runners-added-yet": "There are no runners added yet.",
|
||||
"there-are-no-scans-yet": "There are no scans yet",
|
||||
"there-are-no-teams-added-yet": "There are no teams added yet.",
|
||||
"there-are-no-users-added-yet": "There are no users added yet.",
|
||||
"this-might-take-a-moment": "This might take a moment 👀",
|
||||
"this-scanstation-is": "This scanstation is",
|
||||
"total-distance": "total distance",
|
||||
"total-donation-amount": "total donation amount",
|
||||
"total-donations": "total donations",
|
||||
"total-scans": "total scans",
|
||||
"track": "Track",
|
||||
"track-added": "Track added",
|
||||
"track-data-is-being-loaded": "Track data is being loaded",
|
||||
"track-is-being-added": "Track is being added...",
|
||||
|
@ -286,26 +343,33 @@
|
|||
"track-name": "Track name",
|
||||
"track-name-must-not-be-empty": "Track name must not be empty",
|
||||
"tracks": "Tracks",
|
||||
"update-password": "Update password",
|
||||
"updated-contact": "Updated contact!",
|
||||
"updated-donor": "updated donor",
|
||||
"updated-organization": "updated organization",
|
||||
"updated-scan": "updated scan",
|
||||
"updateing-group": "updateing group...",
|
||||
"updating-organization": "updating organization",
|
||||
"updating-permissions": "updating permissions...",
|
||||
"updating-runner": "Updating runner...",
|
||||
"updating-user": "updating user...",
|
||||
"updating-your-profile": "Updating your profile...",
|
||||
"user-added": "User added",
|
||||
"user-groups": "User Groups",
|
||||
"user-is-being-added": "User is being added...",
|
||||
"user-updated": "User updated",
|
||||
"username": "Username",
|
||||
"users": "Users",
|
||||
"valid": "Valid",
|
||||
"valid-city-is-required": "Valid city is required",
|
||||
"valid-email-is-required": "valid email is required",
|
||||
"valid-international-phone-number-is-required": "valid international phone number is required...",
|
||||
"valid-zipcode-postal-code-is-required": "Valid zipcode/ postal code is required",
|
||||
"verfuegbare": "availdable",
|
||||
"welcome_wavinghand": "Welcome 👋",
|
||||
"yes-i-copied-the-token": "Yes, I copied the token",
|
||||
"you-are-going-to-loose-all-permissions-and-access-to-the-runner-system": "You are going to loose all permissions and access to the runner system!",
|
||||
"you-can-now-use-your-new-password-to-log-in-to-your-account": "You can now use your new password to log in to your account! 🎉",
|
||||
"you-have-to-provide-an-organization": "You have to provide an organization",
|
||||
"zip-postal-code": "ZIP/ postal code"
|
||||
}
|
Loading…
Reference in New Issue