Compare commits

...

72 Commits

Author SHA1 Message Date
9c5fc6b61c 🚀RELEASE v0.14.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-14 19:28:00 +02:00
302caf015f new license file version [CI SKIP] 2021-04-14 17:27:30 +00:00
e11296071a Merge pull request 'added donor receipt list download to DonorsOverview' (#134) from feature/132-export-donors-receipt-list into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #134
close #132
2021-04-14 17:26:10 +00:00
112eb29f93 Switched to selfhosted images
ref #132
2021-04-14 19:24:06 +02:00
c6c97516b3 Sorted translations 🌎
ref #132
2021-04-14 19:23:26 +02:00
03676b2894 Fixed typos in translations
ref #132
2021-04-14 19:23:07 +02:00
9ca57fac2e bump @odit/lfk-client-js@0.11.0
ref #132
2021-04-14 18:58:57 +02:00
18f151c1fb general version bump
ref #132
2021-04-14 18:57:14 +02:00
e90e56d8b2 replace donationAmount with paidDonationAmount
ref #132
2021-04-14 18:54:05 +02:00
d241ca5698 added donor receipt list download to DonorsOverview
ref #132
2021-04-14 18:43:51 +02:00
b512cf8667 🚀RELEASE v0.13.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-11 21:14:03 +02:00
a24d2923c6 For await fix
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-11 21:13:44 +02:00
467808abef 🚀RELEASE v0.13.0
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-11 21:08:58 +02:00
861f1f2216 Merge pull request 'Better org pdf generation feature/130-org_doc_splitting' (#131) from feature/130-org_doc_splitting into dev
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #131
2021-04-11 19:07:53 +00:00
509b22bea0 Org certificate generation now runs in sequence
ref #130
2021-04-11 21:00:33 +02:00
7447b2f4c1 Fixed const -> let
ref #130
2021-04-11 20:54:38 +02:00
fef14b6e4f Org card generation now runs in sequence
ref #130
2021-04-11 20:53:58 +02:00
01d2a7e6aa Org contract generation now runs in sequence
ref #130
2021-04-11 20:48:20 +02:00
ac586fec5a Hotfix: Org * generation🐞
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-11 20:17:34 +02:00
5476808683 Emergency document server url change
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-11 20:10:08 +02:00
331d737796 🚀RELEASE v0.12.5
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-08 19:30:20 +02:00
ef81b8adf9 Merge pull request 'Added runner team's parentorg name to runenr overciew' (#129) from feature/128-runner_orgs into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #129
2021-04-08 17:29:27 +00:00
8a7d635cef Switched to html entity
ref #128
2021-04-08 18:00:47 +02:00
4c259c1eef Added runner team's parentorg name to runenr overciew
ref #128
2021-04-08 17:58:49 +02:00
5b4ede5e2f 🚀RELEASE v0.12.4
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-08 17:34:32 +02:00
d0ab3dda78 🚑 [HOTFIX] - drop "svelte-infinite-loading"
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-08 17:34:04 +02:00
d9cf51b4bb 🚀RELEASE v0.12.3
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-08 17:30:23 +02:00
aa17f24220 new license file version [CI SKIP] 2021-04-08 15:28:50 +00:00
cf60edf7d4 Merge pull request 'fix' (#126) from bugfix/125-mobile into dev
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #126
close #125
2021-04-08 15:27:22 +00:00
ffbc243194 custom css fix for collapsed_navigation
ref #125
2021-04-07 21:44:29 +02:00
b6b07cf30c 🐞 bugfix for svelte x tailwind class names
ref #125
2021-04-07 21:35:01 +02:00
495a6b22bd almost fixed... 2021-04-07 21:28:21 +02:00
0acaffbdfa fix
ref #125
2021-04-07 20:25:04 +02:00
6043bc4517 🚀RELEASE v0.12.2
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-07 20:11:21 +02:00
e6ed066e3f Merge pull request 'feature/110-virtual_list' (#124) from feature/110-virtual_list into dev
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #124
2021-04-07 18:10:02 +00:00
ee4e8655b8 Merge branch 'dev' into feature/110-virtual_list 2021-04-07 20:09:35 +02:00
37970d2be6 pre-merge fixes
ref #110
2021-04-07 18:59:46 +02:00
1376788016 updated virtual scroll list 2021-04-07 18:38:52 +02:00
4cad86cf85 fixed height table 2021-04-07 18:19:58 +02:00
6304116edb wip on virtuallist 2021-04-06 22:16:24 +02:00
834ff8fa63 🚀RELEASE v0.12.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-06 16:47:37 +02:00
1f428a535e Merge pull request 'ImportRunnerModal Cancel Button feature/122-import_cancel' (#123) from feature/112-import_cancel into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #123
2021-04-06 14:42:37 +00:00
0c40966970 Added cancel button for the first stage of runner import
ref #112
2021-04-05 16:23:24 +02:00
9da071fe9b Escape now triggers foll modal close (including reset) instead of just hiding th modal
ref #112
2021-04-05 16:14:43 +02:00
892a04f289 🚀RELEASE v0.12.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-05 16:09:17 +02:00
27cc9727f1 Fixed package version
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-05 16:08:41 +02:00
f0738d451b Merge pull request 'Implmented certificate generation feature/119-Certificate_generation' (#120) from feature/119-Certificate_generation into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #120
2021-04-05 14:05:38 +00:00
9e6a8daf2c Sorted translations 🌍
ref #119
2021-04-05 16:04:44 +02:00
bfacfec765 The PFS Prefixes now get translated via i18n
ref #119
2021-04-05 16:04:26 +02:00
0bae5bf32b sponsoring pdf names now include their locale
ref #119
2021-04-05 15:37:12 +02:00
22b09d16d0 Cleaned up generation strings and added the schem for single runner generations for sponsoring contracts
ref #119
2021-04-05 15:36:01 +02:00
9c867e106e Cleaned up generation strings and added the schem for single runner generations for cards
ref #119
2021-04-05 15:33:55 +02:00
304f28a3c1 certificate pdf names now include their locale
ref #119
2021-04-05 15:31:52 +02:00
d65d3793de Changed the basic nameing generation for runenr certificate files
ref #119
2021-04-05 15:31:01 +02:00
3638d87bd2 Runnercard pdfs now include their locale
ref #119
2021-04-05 15:28:13 +02:00
b97a92860d Fixed wrong permissiong getting checked
ref #119
2021-04-05 15:24:42 +02:00
7c86a5eeb3 added missing/ wrong translations + formatting!
ref #119
2021-04-05 12:02:18 +02:00
d23dbaaf69 Removed useless console.log
ref #119
2021-04-03 20:05:27 +02:00
e6ffc371e1 Certificate generation from org detail
ref #119
2021-04-03 20:03:57 +02:00
3177c6eaa3 Certificate generation from org overview
ref #119
2021-04-03 20:02:52 +02:00
acd2f0519d Certificate generation from team detail
ref #119
2021-04-03 20:00:51 +02:00
18ec100c33 Certificate generation from team overview
ref #119
2021-04-03 19:59:34 +02:00
fa55fce76e Merge branch 'feature/119-Certificate_generation' of git.odit.services:lfk/frontend into feature/119-Certificate_generation 2021-04-03 19:59:20 +02:00
f47d5e347d Copy-paste fix
ref #119
2021-04-03 19:59:18 +02:00
7488a8b597 Copy-paste fix
ref #119
2021-04-03 19:58:24 +02:00
2e3ac154be Implemented generation for orgs
ref #119
2021-04-03 19:52:41 +02:00
2472640755 Implemented generation for teams
ref #119
2021-04-03 19:51:01 +02:00
7b685d6cad Added certificate generation from runner overview and detail
ref #119
2021-04-03 19:48:31 +02:00
17f6f4e616 Added i18n
ref #119
2021-04-03 19:46:17 +02:00
48cfc15cfb Removed useless console log
ref #119
2021-04-03 19:44:57 +02:00
bb9b779cee You can now generate certificates from the runner overview
ref #119
2021-04-03 19:44:26 +02:00
af63ce67ae Added basic certificate generation component
ref #119
2021-04-03 19:38:54 +02:00
23 changed files with 1411 additions and 675 deletions

View File

@@ -27,7 +27,7 @@ name: build:dev
steps: steps:
- name: run full license export - name: run full license export
depends_on: ["clone"] depends_on: ["clone"]
image: node:alpine image: registry.odit.services/hub/library/node:alpine
commands: commands:
- yarn - yarn
- yarn licenses:export - yarn licenses:export

View File

@@ -2,15 +2,159 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC. All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [0.14.0](https://git.odit.services/lfk/frontend/compare/0.13.1...0.14.0)
- Merge pull request 'added donor receipt list download to DonorsOverview' (#134) from feature/132-export-donors-receipt-list into dev [`#132`](https://git.odit.services/lfk/frontend/issues/132)
- Sorted translations 🌎 [`c6c9751`](https://git.odit.services/lfk/frontend/commit/c6c97516b3981ef580d620c0c8a6fcc42f26facd)
- Fixed typos in translations [`03676b2`](https://git.odit.services/lfk/frontend/commit/03676b2894892c3559118b93e969c063b53b081e)
- added donor receipt list download to DonorsOverview [`d241ca5`](https://git.odit.services/lfk/frontend/commit/d241ca569838abbe9581fbd319f7f3b563cb7dcc)
- ⏫ general version bump [`18f151c`](https://git.odit.services/lfk/frontend/commit/18f151c1fb878a74c3d1a2c2a2debf7913739417)
- new license file version [CI SKIP] [`302caf0`](https://git.odit.services/lfk/frontend/commit/302caf015f88f77e2b2ae2b67680e79f987ad81e)
- Switched to selfhosted images [`112eb29`](https://git.odit.services/lfk/frontend/commit/112eb29f932cd936f1d6c2308dcaeaf8cb642490)
- ⏫ bump @odit/lfk-client-js@0.11.0 [`9ca57fa`](https://git.odit.services/lfk/frontend/commit/9ca57fac2eeabbf25142a507fb9c0fa3c90b4e74)
- replace donationAmount with paidDonationAmount [`e90e56d`](https://git.odit.services/lfk/frontend/commit/e90e56d8b26aef23aba2bbb0c3942ba4d7feb224)
#### [0.13.1](https://git.odit.services/lfk/frontend/compare/0.13.0...0.13.1)
> 11 April 2021
- 🚀RELEASE v0.13.1 [`b512cf8`](https://git.odit.services/lfk/frontend/commit/b512cf86674f1c60b5ac790985ededdfd6554185)
- For await fix [`a24d292`](https://git.odit.services/lfk/frontend/commit/a24d2923c6e6da90d610c05183d29d47eaf2ed30)
#### [0.13.0](https://git.odit.services/lfk/frontend/compare/0.12.5...0.13.0)
> 11 April 2021
- 🚀RELEASE v0.13.0 [`467808a`](https://git.odit.services/lfk/frontend/commit/467808abefe127dac66a2837fcce3197dddb140f)
- Merge pull request 'Better org pdf generation feature/130-org_doc_splitting' (#131) from feature/130-org_doc_splitting into dev [`861f1f2`](https://git.odit.services/lfk/frontend/commit/861f1f221653283e7586aa2c67b205337fd44398)
- Org card generation now runs in sequence [`fef14b6`](https://git.odit.services/lfk/frontend/commit/fef14b6e4fb47ad92da61de91fedce96aea26b2c)
- Org certificate generation now runs in sequence [`509b22b`](https://git.odit.services/lfk/frontend/commit/509b22bea0dd3e4446e6ecc37d27644e9bf2ad50)
- Org contract generation now runs in sequence [`01d2a7e`](https://git.odit.services/lfk/frontend/commit/01d2a7e6aa709b3f2d71575f705fc962e97e2742)
- Emergency document server url change [`5476808`](https://git.odit.services/lfk/frontend/commit/5476808683a919bc34dbaea1f1ed276d49750096)
- Fixed const -> let [`7447b2f`](https://git.odit.services/lfk/frontend/commit/7447b2f4c134a585905db6733093eab13e6f7c47)
- Hotfix: Org * generation🐞 [`ac586fe`](https://git.odit.services/lfk/frontend/commit/ac586fec5abd324d590ba99cdfe8ddddefbf95e6)
#### [0.12.5](https://git.odit.services/lfk/frontend/compare/0.12.4...0.12.5)
> 8 April 2021
- 🚀RELEASE v0.12.5 [`331d737`](https://git.odit.services/lfk/frontend/commit/331d737796c82454b1c19fa1840ccc20e36d2626)
- Merge pull request 'Added runner team's parentorg name to runenr overciew' (#129) from feature/128-runner_orgs into dev [`ef81b8a`](https://git.odit.services/lfk/frontend/commit/ef81b8adf9bef685a55936d7544bf645c0d6ecbe)
- Switched to html entity [`8a7d635`](https://git.odit.services/lfk/frontend/commit/8a7d635cef2d465e70c84e1f7a7b90b98a8dbab1)
- Added runner team's parentorg name to runenr overciew [`4c259c1`](https://git.odit.services/lfk/frontend/commit/4c259c1eef2b0166ce6a8493d0c9e9d5ede11146)
#### [0.12.4](https://git.odit.services/lfk/frontend/compare/0.12.3...0.12.4)
> 8 April 2021
- 🚀RELEASE v0.12.4 [`5b4ede5`](https://git.odit.services/lfk/frontend/commit/5b4ede5e2f6a26b475a7a4b430a4146d21fb9671)
- 🚑 [HOTFIX] - drop "svelte-infinite-loading" [`d0ab3dd`](https://git.odit.services/lfk/frontend/commit/d0ab3dda78bbad2cea18a2491056530897d56607)
#### [0.12.3](https://git.odit.services/lfk/frontend/compare/0.12.2...0.12.3)
> 8 April 2021
- Merge pull request 'fix' (#126) from bugfix/125-mobile into dev [`#125`](https://git.odit.services/lfk/frontend/issues/125)
- almost fixed... [`495a6b2`](https://git.odit.services/lfk/frontend/commit/495a6b22bd8036593f390bdb862d325524cefbcc)
- 🐞 bugfix for svelte x tailwind class names [`b6b07cf`](https://git.odit.services/lfk/frontend/commit/b6b07cf30cc6533bd5dbfec1f813c16fde85634d)
- fix [`0acaffb`](https://git.odit.services/lfk/frontend/commit/0acaffbdfa359e52654a5afe2788aa59fe6f9036)
- 🚀RELEASE v0.12.3 [`d9cf51b`](https://git.odit.services/lfk/frontend/commit/d9cf51b4bbc2136594a03c5d0eeb8cb3f3440b2a)
- custom css fix for collapsed_navigation [`ffbc243`](https://git.odit.services/lfk/frontend/commit/ffbc243194c7faeb4fe61c12711a1c441c3994ef)
- new license file version [CI SKIP] [`aa17f24`](https://git.odit.services/lfk/frontend/commit/aa17f242209f7e7cecff774ace7a35b581adec1f)
#### [0.12.2](https://git.odit.services/lfk/frontend/compare/0.12.1...0.12.2)
> 7 April 2021
- 🚀RELEASE v0.12.2 [`6043bc4`](https://git.odit.services/lfk/frontend/commit/6043bc45174d51ab110b0ed10a8679d96127ab87)
- Merge pull request 'feature/110-virtual_list' (#124) from feature/110-virtual_list into dev [`e6ed066`](https://git.odit.services/lfk/frontend/commit/e6ed066e3ffabba6519f94d801d21a27819d0492)
- wip on virtuallist [`6304116`](https://git.odit.services/lfk/frontend/commit/6304116edb7f5e3c7b67c15e0b1740d34c513155)
- fixed height table [`4cad86c`](https://git.odit.services/lfk/frontend/commit/4cad86cf852468428d77103d052c6974b17c34c3)
- pre-merge fixes [`37970d2`](https://git.odit.services/lfk/frontend/commit/37970d2be6b6502701914e41e5bfe2c418438480)
- updated virtual scroll list [`1376788`](https://git.odit.services/lfk/frontend/commit/1376788016e767f006661f8c9e6747781f2dce55)
#### [0.12.1](https://git.odit.services/lfk/frontend/compare/0.12.0...0.12.1)
> 6 April 2021
- 🚀RELEASE v0.12.1 [`834ff8f`](https://git.odit.services/lfk/frontend/commit/834ff8fa63178f36dcacf931c128ba67a3e7bd1b)
- Merge pull request 'ImportRunnerModal Cancel Button feature/122-import_cancel' (#123) from feature/112-import_cancel into dev [`1f428a5`](https://git.odit.services/lfk/frontend/commit/1f428a535e3ae619cbf8db51d04255aac8dd8614)
- Added cancel button for the first stage of runner import [`0c40966`](https://git.odit.services/lfk/frontend/commit/0c409669700d3a8096cc04716154b0fdca458fe5)
- Escape now triggers foll modal close (including reset) instead of just hiding th modal [`9da071f`](https://git.odit.services/lfk/frontend/commit/9da071fe9ba067160334682bf00163e3630fe919)
#### [0.12.0](https://git.odit.services/lfk/frontend/compare/0.11.0...0.12.0)
> 5 April 2021
- Merge pull request 'feature/108_vite_migration' (#118) from feature/108_vite_migration into dev [`#108`](https://git.odit.services/lfk/frontend/issues/108)
- 🚀RELEASE v0.12.0 [`892a04f`](https://git.odit.services/lfk/frontend/commit/892a04f28930481715eb486b1ef4efeb98a6e999)
- Fixed package version [`27cc972`](https://git.odit.services/lfk/frontend/commit/27cc9727f1d02d186c3ccadb06e5b4b1b1d6202d)
- Merge pull request 'Implmented certificate generation feature/119-Certificate_generation' (#120) from feature/119-Certificate_generation into dev [`f0738d4`](https://git.odit.services/lfk/frontend/commit/f0738d451b02e4a298b5f9cb8ab0be16aed10a38)
- The PFS Prefixes now get translated via i18n [`bfacfec`](https://git.odit.services/lfk/frontend/commit/bfacfec76511cae3015f52698fdcbd80a7a15981)
- Sorted translations 🌍 [`9e6a8da`](https://git.odit.services/lfk/frontend/commit/9e6a8daf2c394cf17da532382ec7d049a0f89577)
- added missing/ wrong translations + formatting! [`7c86a5e`](https://git.odit.services/lfk/frontend/commit/7c86a5eeb370a43451d180a09a501066b023b9a0)
- Added i18n [`17f6f4e`](https://git.odit.services/lfk/frontend/commit/17f6f4e616bf57424ee12ad53b939429c02a0171)
- Added basic certificate generation component [`af63ce6`](https://git.odit.services/lfk/frontend/commit/af63ce67ae7d8f8a70706c3bd6755197908996ff)
- basic ViteJS migration [`ae79e9f`](https://git.odit.services/lfk/frontend/commit/ae79e9fea1963e977ef468e8e56f87d68916fadd)
- Implemented generation for orgs [`2e3ac15`](https://git.odit.services/lfk/frontend/commit/2e3ac154be0bf0776cd00f7d510f41ec676ae690)
- Implemented generation for teams [`2472640`](https://git.odit.services/lfk/frontend/commit/2472640755e3e41259a44127a875d00517a25842)
- updated default entrypoint [`95c8fde`](https://git.odit.services/lfk/frontend/commit/95c8fde72fca5cd5a644d51a33dc88e0b59fce92)
- ⏫📍 version bump + pin [`b065b4f`](https://git.odit.services/lfk/frontend/commit/b065b4ff218d07952fa45989e6e2ee7df13e07c1)
- 🧹 reorder + fix package [`12433f7`](https://git.odit.services/lfk/frontend/commit/12433f7c236906fe2b29848a0acaa6be1724da56)
- 🔨 re-added VS Code devcontainer config [`9318709`](https://git.odit.services/lfk/frontend/commit/93187099d32c506329b1437642aae985f2850689)
- 🐳 new Dockerfiles [`0f32968`](https://git.odit.services/lfk/frontend/commit/0f32968fae8b55a13d387918211983d0e61f85ab)
- 📃 added readme [`aa24b1d`](https://git.odit.services/lfk/frontend/commit/aa24b1dce5d6d73c8f42fc57f81b692350bf9665)
- Copy-paste fix [`f47d5e3`](https://git.odit.services/lfk/frontend/commit/f47d5e347d97ee127fa0380620138a9672665cd5)
- 🔨🔥 alpine based devcontainer with working yarn PnP [`777304f`](https://git.odit.services/lfk/frontend/commit/777304f2593df36f4e89d2ba7680add183ff062f)
- Copy-paste fix [`7488a8b`](https://git.odit.services/lfk/frontend/commit/7488a8b597a148c309e1b4499d277fed7f3bf9f4)
- You can now generate certificates from the runner overview [`bb9b779`](https://git.odit.services/lfk/frontend/commit/bb9b779cee909ab85ef52f13be0a917f1c0a9e62)
- Cleaned up generation strings and added the schem for single runner generations for cards [`9c867e1`](https://git.odit.services/lfk/frontend/commit/9c867e106edd68784e6d19743519c1952a0f0bc7)
- Changed the basic nameing generation for runenr certificate files [`d65d379`](https://git.odit.services/lfk/frontend/commit/d65d3793de869bcd6733a1bbdac378d0bc1128b3)
- ⏫ version bumps [`d7fecfb`](https://git.odit.services/lfk/frontend/commit/d7fecfbd0bc01f1cd44dea3c3837e0cc44afab12)
- Cleaned up generation strings and added the schem for single runner generations for sponsoring contracts [`22b09d1`](https://git.odit.services/lfk/frontend/commit/22b09d16d0acc2883e3448dad95ed0f4ea7c6aeb)
- Certificate generation from org overview [`3177c6e`](https://git.odit.services/lfk/frontend/commit/3177c6eaa31636ed4546f4797775a0f0a930f5d1)
- certificate pdf names now include their locale [`304f28a`](https://git.odit.services/lfk/frontend/commit/304f28a3c10bc4745aa5b7c80d7ba0e651540706)
- Runnercard pdfs now include their locale [`3638d87`](https://git.odit.services/lfk/frontend/commit/3638d87bd2ff83618eefda5af18ba19e38e3c2eb)
- 🐞 fix await for esNext [`a922776`](https://git.odit.services/lfk/frontend/commit/a9227768de29305b51d10c8a6e4fa1d39b7d998f)
- Certificate generation from team overview [`18ec100`](https://git.odit.services/lfk/frontend/commit/18ec100c33a1fbab526187e769dbae54d9db0867)
- Added certificate generation from runner overview and detail [`7b685d6`](https://git.odit.services/lfk/frontend/commit/7b685d6cad97d2f7f48c4b19bfc128e1355b70c4)
- package cleanup [`6be2ee6`](https://git.odit.services/lfk/frontend/commit/6be2ee626addaf5113b4b4821bd99a276bf4f329)
- sponsoring pdf names now include their locale [`0bae5bf`](https://git.odit.services/lfk/frontend/commit/0bae5bf32b8687057dca50cde21022ea8c3abee8)
- ✨ update licenses.json [`e99e9e0`](https://git.odit.services/lfk/frontend/commit/e99e9e07089520d5a48021e10d2af7739656641a)
- added windicss settings for VSCode [`008027d`](https://git.odit.services/lfk/frontend/commit/008027db0e2736a9bb9defd67178ab3fe580de04)
- Certificate generation from team detail [`acd2f05`](https://git.odit.services/lfk/frontend/commit/acd2f0519d62e55dad8e9c3c41e77b6967212502)
- ⚡💾 prevent env.js from being cached [`c5d1553`](https://git.odit.services/lfk/frontend/commit/c5d155396a92dfee6d592fb24a936ab521215f6d)
- for await fix - ViteJS [`aec5e34`](https://git.odit.services/lfk/frontend/commit/aec5e3473e687415fbfd69c550d9b012e1b1be43)
- Certificate generation from org detail [`e6ffc37`](https://git.odit.services/lfk/frontend/commit/e6ffc371e1ca2d4451e7dd4a3ca3c05564edb5fb)
- 🧹 drop unused dependencies [`ce50fa2`](https://git.odit.services/lfk/frontend/commit/ce50fa2a62f8ff98e8be9c66432caeebb3952019)
- 🐞 fix NGINX config [`5352410`](https://git.odit.services/lfk/frontend/commit/5352410d0c76fd14575d7beafc6a83f028062efe)
- Fixed wrong permissiong getting checked [`b97a928`](https://git.odit.services/lfk/frontend/commit/b97a92860d71eb0384170e245a67fa3ea3fd8e85)
- new license file version [CI SKIP] [`5cc4871`](https://git.odit.services/lfk/frontend/commit/5cc4871ec4be9f0af07738f6e3d44bdbe31cd25a)
- ⏫ bump @odit/lfk-client-js@0.10.1 [`8b74d6d`](https://git.odit.services/lfk/frontend/commit/8b74d6d759c8481f012c201e2ea0d12b29ddef90)
- 🔨 dev container open ⚡ [`ceb2146`](https://git.odit.services/lfk/frontend/commit/ceb2146c1b08bbe9250e4db7846e06bd89526c21)
- ⏫ version bump: vite-plugin-windicss@0.12.2 [`8d006d8`](https://git.odit.services/lfk/frontend/commit/8d006d8c74d71c43a9031d58f5a8c7fc55ed95fc)
- 🚚 move @svitejs/vite-plugin-svelte to @sveltejs/vite-plugin-svelte [`44b53da`](https://git.odit.services/lfk/frontend/commit/44b53da34516b00671b3e5060ba831e409ac3dd5)
- ⏫ upgrade vite-plugin-windicss@0.12.1 [`ab45fc1`](https://git.odit.services/lfk/frontend/commit/ab45fc144eaf14f63d86ee53c1db4eefd88f9c7f)
- 🐞 fix main.js linking [`467404b`](https://git.odit.services/lfk/frontend/commit/467404bfc87f3c08c5e227f194d71eea7cc48921)
- 🐞 fix vite config for production system [`10a011d`](https://git.odit.services/lfk/frontend/commit/10a011d8426e475105ff5d2d5cf4adca2ef7625c)
- fix dev script [`eb3ede9`](https://git.odit.services/lfk/frontend/commit/eb3ede9593e2e527df3e3a2f81c8e179bb555f51)
- ⏫ bump vite to 2.1.3 [`0cd3e93`](https://git.odit.services/lfk/frontend/commit/0cd3e937d852eeabe43eb6298bfabe20834240b2)
- Removed useless console.log [`d23dbaa`](https://git.odit.services/lfk/frontend/commit/d23dbaaf695a60fe5ebbc9945646a16b5fc45a16)
- Removed useless console log [`48cfc15`](https://git.odit.services/lfk/frontend/commit/48cfc15cfb09096db1bd5ddbe9138b1a604d581f)
#### [0.11.0](https://git.odit.services/lfk/frontend/compare/0.10.0...0.11.0) #### [0.11.0](https://git.odit.services/lfk/frontend/compare/0.10.0...0.11.0)
- Merge pull request 'Generate and print bulk blank cards feature/116-download_blanc_cards' (#117) from feature/116-download_blanc_cards into dev [`25d8b86`](https://git.odit.services/lfk/frontend/commit/25d8b86efd89c442d1bf308a8743134820acfd1f) > 30 March 2021
- Added button (including translations [`0614c76`](https://git.odit.services/lfk/frontend/commit/0614c76e924b18b512bab59933a26fec07cf483d) - Added button (including translations [`0614c76`](https://git.odit.services/lfk/frontend/commit/0614c76e924b18b512bab59933a26fec07cf483d)
- Added button (including translations [`97e338f`](https://git.odit.services/lfk/frontend/commit/97e338f9d4f388596d550990457254c7fa1a3492) - Added button (including translations [`97e338f`](https://git.odit.services/lfk/frontend/commit/97e338f9d4f388596d550990457254c7fa1a3492)
- Sorted translations [`89bb9c2`](https://git.odit.services/lfk/frontend/commit/89bb9c215e356e0940678f5cabd9e38bc203040e) - Sorted translations [`89bb9c2`](https://git.odit.services/lfk/frontend/commit/89bb9c215e356e0940678f5cabd9e38bc203040e)
- Added function for generating cards with pdf [`c8d6390`](https://git.odit.services/lfk/frontend/commit/c8d639024a5f2f72d6e30d2ce990b08bd71a5471) - Added function for generating cards with pdf [`c8d6390`](https://git.odit.services/lfk/frontend/commit/c8d639024a5f2f72d6e30d2ce990b08bd71a5471)
- 🚀RELEASE v0.11.0 [`f8ccf4f`](https://git.odit.services/lfk/frontend/commit/f8ccf4f5d8f68ecee31430029889b8ab1ecec682)
- Fixed button styling [`08cb079`](https://git.odit.services/lfk/frontend/commit/08cb079e9798392e26515d559af2637e74deea97) - Fixed button styling [`08cb079`](https://git.odit.services/lfk/frontend/commit/08cb079e9798392e26515d559af2637e74deea97)
- Now returning cards on creation with pdf [`1d999d4`](https://git.odit.services/lfk/frontend/commit/1d999d4910acb5efa21b3f9922cdb359babff404) - Now returning cards on creation with pdf [`1d999d4`](https://git.odit.services/lfk/frontend/commit/1d999d4910acb5efa21b3f9922cdb359babff404)
- new license file version [CI SKIP] [`8f8b998`](https://git.odit.services/lfk/frontend/commit/8f8b9988ad94ee9f3729a3fe6fdb4c558828d892)
- Merge pull request 'Generate and print bulk blank cards feature/116-download_blanc_cards' (#117) from feature/116-download_blanc_cards into dev [`25d8b86`](https://git.odit.services/lfk/frontend/commit/25d8b86efd89c442d1bf308a8743134820acfd1f)
- Added comment [`636f018`](https://git.odit.services/lfk/frontend/commit/636f018daa33b99468a257bfc33477e1e644d081) - Added comment [`636f018`](https://git.odit.services/lfk/frontend/commit/636f018daa33b99468a257bfc33477e1e644d081)
- Bumped lfk client js version [`2d18686`](https://git.odit.services/lfk/frontend/commit/2d18686ce782a434ca7bd34c07c36a35b9497273) - Bumped lfk client js version [`2d18686`](https://git.odit.services/lfk/frontend/commit/2d18686ce782a434ca7bd34c07c36a35b9497273)
- Bumped lfk-client-js [`7dfaa75`](https://git.odit.services/lfk/frontend/commit/7dfaa7579a22b13194fcdd1c02b4437958261472) - Bumped lfk-client-js [`7dfaa75`](https://git.odit.services/lfk/frontend/commit/7dfaa7579a22b13194fcdd1c02b4437958261472)

View File

@@ -1,22 +1,22 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="/favicon.png" /> <link rel="icon" href="/favicon.png" />
<link rel="manifest" href="/manifest.webmanifest"> <link rel="manifest" href="/manifest.webmanifest">
<link rel="apple-touch-icon" href="/lfk-logo.png"> <link rel="apple-touch-icon" href="/lfk-logo.png">
<meta name="theme-color" content="#FFFFFF"> <meta name="theme-color" content="#FFFFFF">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Lauf Für Kaya! - Admin" /> <meta name="description" content="Lauf Für Kaya! - Admin" />
<title>Lauf für Kaya! - Admin</title> <title>Lauf für Kaya! - Admin</title>
</head> </head>
<body> <body>
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.8.4-RELEASE_INFO</span> <span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.14.0-RELEASE_INFO</span>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/env.js"></script> <script src="/env.js"></script>
<script type="module" src="/src/main.js"></script> <script type="module" src="/src/main.js"></script>
</body> </body>
</html> </html>

View File

@@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-frontend", "name": "@odit/lfk-frontend",
"version": "0.8.4", "version": "0.14.0",
"scripts": { "scripts": {
"i18n-order": "node order.js", "i18n-order": "node order.js",
"dev": "vite", "dev": "vite",
@@ -11,9 +11,9 @@
"license": "CC-BY-NC-SA-4.0", "license": "CC-BY-NC-SA-4.0",
"devDependencies": { "devDependencies": {
"check-password-strength": "2.0.2", "check-password-strength": "2.0.2",
"@odit/lfk-client-js": "0.10.1", "@odit/lfk-client-js": "0.11.0",
"@odit/license-exporter": "0.0.11", "@odit/license-exporter": "0.0.11",
"@sveltejs/vite-plugin-svelte": "1.0.0-next.5", "@sveltejs/vite-plugin-svelte": "1.0.0-next.6",
"@types/html-minifier": "4.0.0", "@types/html-minifier": "4.0.0",
"auto-changelog": "2.2.1", "auto-changelog": "2.2.1",
"autoprefixer": "10.2.5", "autoprefixer": "10.2.5",
@@ -21,19 +21,19 @@
"gridjs": "3.4.0", "gridjs": "3.4.0",
"html-minifier": "4.0.0", "html-minifier": "4.0.0",
"localforage": "1.9.0", "localforage": "1.9.0",
"marked": "2.0.1", "marked": "2.0.3",
"release-it": "14.5.1", "release-it": "14.6.1",
"svelte": "3.37.0", "svelte": "3.37.0",
"svelte-focus-trap": "1.2.0", "svelte-focus-trap": "1.2.0",
"svelte-i18n": "3.3.9", "svelte-i18n": "3.3.9",
"svelte-preprocess": "4.7.0", "svelte-preprocess": "4.7.0",
"svelte-select": "3.17.0", "svelte-select": "3.17.0",
"tailwindcss": "2.0.4", "tailwindcss": "2.1.1",
"tinro": "0.6.1", "tinro": "0.6.1",
"toastify-js": "1.10.0", "toastify-js": "1.10.0",
"validator": "13.5.2", "validator": "13.5.2",
"vite": "2.1.5", "vite": "2.1.5",
"vite-plugin-windicss": "0.12.2", "vite-plugin-windicss": "0.14.0",
"xlsx": "0.16.9" "xlsx": "0.16.9"
}, },
"release-it": { "release-it": {

View File

@@ -1,5 +1,6 @@
const config = { const config = {
baseurl: 'http://localhost:4010', baseurl: 'http://localhost:4010',
baseurl_documentserver: 'http://localhost:4010/documents',
documentserver_key: 'NqZSYTy5AFQ7MppbLW5moqpTk7u7YrNUHKYhKYuThnnya2WpCOIU694hIZT1FzYe', documentserver_key: 'NqZSYTy5AFQ7MppbLW5moqpTk7u7YrNUHKYhKYuThnnya2WpCOIU694hIZT1FzYe',
// optional // optional
default_username: 'demo', default_username: 'demo',

File diff suppressed because one or more lines are too long

View File

@@ -77,7 +77,7 @@
duration: -1, duration: -1,
}).showToast(); }).showToast();
fetch( fetch(
`${config.baseurl}/documents/cards?&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/cards?&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {

View File

@@ -1,5 +1,5 @@
<script> <script>
import { getLocaleFromNavigator, json, _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { RunnerCardService } from "@odit/lfk-client-js"; import { RunnerCardService } from "@odit/lfk-client-js";
import store from "../../store"; import store from "../../store";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
@@ -11,11 +11,21 @@
export let editable = {}; export let editable = {};
export let original_data = {}; export let original_data = {};
export let current_cards = []; export let current_cards = [];
$: filtered_cards = current_cards.filter(function (c) {
if (
c.code.toLowerCase().includes(searchvalue_lowercase) ||
c.runner?.firstname.toLowerCase().includes(searchvalue_lowercase) ||
c.runner?.middlename.toLowerCase().includes(searchvalue_lowercase) ||
c.runner?.lastname.toLowerCase().includes(searchvalue_lowercase) ||
should_display_based_on_id(c.id)
) {
return true;
}
});
$: searchvalue = ""; $: searchvalue = "";
$: searchvalue_lowercase = searchvalue.toLowerCase();
$: active_deletes = []; $: active_deletes = [];
$: cards_show = current_cards.some( $: cards_show = current_cards.some((r) => r.is_selected === true);
(r) => r.is_selected === true
);
$: generate_cards = current_cards.filter((r) => r.is_selected === true); $: generate_cards = current_cards.filter((r) => r.is_selected === true);
const cards_promise = RunnerCardService.runnerCardControllerGetAll().then( const cards_promise = RunnerCardService.runnerCardControllerGetAll().then(
(val) => { (val) => {
@@ -46,8 +56,38 @@
original_data = Object.assign(original_data, card); original_data = Object.assign(original_data, card);
edit_modal_open = true; edit_modal_open = true;
} }
// -----------------
let scrollTop = 0;
$: rendered = filtered_cards;
let innerHeight = 0;
let ele;
$: updateSlice(scrollTop);
$: innerHeight = `${filtered_cards.length * 25}px`;
$: if (ele) updateSlice();
function updateSlice() {
const height = ele ? parseInt(ele.clientHeight) : 100;
const init = scrollTop / 25;
const end = Math.ceil((scrollTop + height) / 25);
rendered = filtered_cards.slice(init, end + 15);
}
function updateScroll($event) {
scrollTop = $event.target.scrollTop;
}
</script> </script>
<style>
table tbody {
display: block;
overflow-y: scroll;
}
table thead, table tbody tr {
display: table;
width: 100%;
table-layout: fixed;
}
</style>
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:UPDATE')} {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:UPDATE')}
<CardDetailModal <CardDetailModal
bind:current_cards bind:current_cards
@@ -121,107 +161,111 @@
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-gray-200"> <tbody class="divide-y divide-gray-200 virtual-wrapper"
{#each current_cards as card} on:scroll={updateScroll}
{#if card.code style="height: 70vh; width:100%"
.toLowerCase() bind:this={ele}
.includes( >
searchvalue.toLowerCase() {#each filtered_cards as card, index}
) || card.runner?.firstname {#if card.code
.toLowerCase() .toLowerCase()
.includes( .includes(
searchvalue.toLowerCase() searchvalue.toLowerCase()
) || card.runner?.middlename ) || card.runner?.firstname
.toLowerCase() .toLowerCase()
.includes( .includes(
searchvalue.toLowerCase() searchvalue.toLowerCase()
) || card.runner?.lastname ) || card.runner?.middlename
.toLowerCase() .toLowerCase()
.includes( .includes(
searchvalue.toLowerCase() searchvalue.toLowerCase()
) || should_display_based_on_id(card.id)} ) || card.runner?.lastname
<tr data-rowid="card_{card.id}"> .toLowerCase()
<td class="px-6 py-4 whitespace-nowrap"> .includes(
<input searchvalue.toLowerCase()
bind:checked={card.is_selected} ) || should_display_based_on_id(card.id)}
type="checkbox" <tr data-rowid="card_{card.id}">
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" /> <td class="px-6 py-4 whitespace-nowrap">
</td> <input
<td class="px-6 py-4 whitespace-nowrap"> bind:checked={card.is_selected}
<div class="flex items-center">{card.code}</div> type="checkbox"
</td> class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
<td class="px-6 py-4 whitespace-nowrap"> </td>
<div class="flex items-center"> <td class="px-6 py-4 whitespace-nowrap">
{#if card.runner} <div class="flex items-center">{card.code}</div>
<a </td>
href="../runners/{card.runner.id}" <td class="px-6 py-4 whitespace-nowrap">
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{card.runner.firstname} <div class="flex items-center">
{card.runner.middlename || ''} {#if card.runner}
{card.runner.lastname}</a> <a
{:else}{$_('non-blanko')}{/if} href="../runners/{card.runner.id}"
</div> class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{card.runner.firstname}
</td> {card.runner.middlename || ''}
<td class="px-6 py-4 whitespace-nowrap"> {card.runner.lastname}</a>
<div class="flex items-center"> {:else}{$_('non-blanko')}{/if}
{#if card.enabled} </div>
<span </td>
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('enabled')}</span> <td class="px-6 py-4 whitespace-nowrap">
{:else} <div class="flex items-center">
<span {#if card.enabled}
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('disabled')}</span> <span
{/if} class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('enabled')}</span>
</div> {:else}
</td> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('disabled')}</span>
{/if}
</div>
</td>
{#if active_deletes[card.id] === true} {#if active_deletes[card.id] === true}
<td <td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button <button
on:click={() => { on:click={() => {
active_deletes[card.id] = false; active_deletes[card.id] = false;
}} }}
tabindex="0" tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button> class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
<button <button
on:click={() => { on:click={() => {
RunnerCardService.runnerCardControllerRemove(card.id, false).then( RunnerCardService.runnerCardControllerRemove(card.id, false).then(
(resp) => { (resp) => {
current_cards = current_cards.filter( current_cards = current_cards.filter(
(obj) => obj.id !== card.id (obj) => obj.id !== card.id
); );
Toastify({ Toastify({
text: $_('card-deleted'), text: $_('card-deleted'),
duration: 500, duration: 500,
backgroundColor: backgroundColor:
'linear-gradient(to right, #00b09b, #96c93d)', 'linear-gradient(to right, #00b09b, #96c93d)',
}).showToast(); }).showToast();
} }
); );
}} }}
tabindex="0" tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button> class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
</td> </td>
{:else} {:else}
<td <td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button <button
on:click={() => { on:click={() => {
open_edit_modal(card); open_edit_modal(card);
}} }}
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</button> class="text-indigo-600 hover:text-indigo-900">{$_('details')}</button>
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:DELETE')} {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:DELETE')}
<button <button
on:click={() => { on:click={() => {
active_deletes[card.id] = true; active_deletes[card.id] = true;
}} }}
tabindex="0" tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button> class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
{/if} {/if}
</td> </td>
{/if} {/if}
</tr> </tr>
{/if} {/if}
{/each} {/each}
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@@ -12,11 +12,21 @@
} }
</script> </script>
<style>
.collapsed_navigation {
transform: translateX(-100%);
}
@media (min-width: 768px) {
.collapsed_navigation {
transform: translateX(0px);
}
}
</style>
<section class="min-h-screen bg-gray-50"> <section class="min-h-screen bg-gray-50">
<nav <div
class:-translate-x-full={!navOpen} class:collapsed_navigation={!navOpen}
class:translate-x-0={navOpen} class="select-none fixed top-0 left-0 z-20 h-full pb-10 overflow-x-hidden overflow-y-auto transition origin-left transform border-r w-60 bg-gray-50">
class="select-none fixed top-0 left-0 z-20 h-full pb-10 overflow-x-hidden overflow-y-auto transition origin-left transform border-r w-60 md:translate-x-0 bg-gray-50">
<a href="/" class="flex items-center px-4 py-5"> <a href="/" class="flex items-center px-4 py-5">
<img src="/lfk-logo.png" alt="Logo" class="h-10" /> <img src="/lfk-logo.png" alt="Logo" class="h-10" />
<h3 class="text-lg">Lauf für Kaya! Admin</h3> <h3 class="text-lg">Lauf für Kaya! Admin</h3>
@@ -297,14 +307,15 @@
<span>{$_('logout')}</span> <span>{$_('logout')}</span>
</span> </span>
</nav> </nav>
</nav> </div>
<div class="ml-0 transition md:ml-60"> <div class="ml-0 transition md:ml-60">
<header <header
on:click={() => {
navOpen = true;
}}
class="flex items-center justify-between w-full px-4 bg-white border-b h-14 md:hidden"> class="flex items-center justify-between w-full px-4 bg-white border-b h-14 md:hidden">
<button class="block btn btn-light md:hidden"> <button
on:click={() => {
navOpen = true;
}}
class="block btn btn-light md:hidden">
<span class="sr-only">Menu</span><svg <span class="sr-only">Menu</span><svg
class="w-4 h-4" class="w-4 h-4"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@@ -318,10 +329,13 @@
<NoComponentLoaded /> <NoComponentLoaded />
</slot> </slot>
</div> </div>
<div {#if navOpen === true}
on:click={() => { <div
navOpen = false; on:click={() => {
}} navOpen = false;
class:hidden={!navOpen} console.log({ navOpen });
class="fixed inset-0 z-10 w-screen h-screen bg-black bg-opacity-25 md:hidden" /> }}
class:hidden={!navOpen}
class="fixed inset-0 z-10 w-screen h-screen bg-black bg-opacity-25 md:hidden" />
{/if}
</section> </section>

View File

@@ -20,6 +20,31 @@
{$_('add-donor')} {$_('add-donor')}
</button> </button>
{/if} {/if}
{#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:GET')}
<button
on:click={() => {
const data = (current_donors.filter(d=>d.receiptNeeded===true)).map(function (d) {
d.address.address2=d.address.address2===""?"":" "+d.address.address2;
const address=`${d.address.address1}${d.address.address2}, ${d.address.postalcode} ${d.address.city}, ${d.address.country}`;
return [d.firstname,d.middlename,d.lastname,d.paidDonationAmount,address];
})
let csv = `${$_('csv_import__firstname')};${$_('csv_import__middlename')};${$_('csv_import__lastname')};${$_('total_donation_amount_in_eur')};${$_('address')}\n`;
data.forEach(function(row) {
csv += row.join(';');
csv += "\n";
});
let hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
hiddenElement.target = '_blank';
hiddenElement.download = `${$_('filename_sponsoringquittungsliste')}.csv`;
hiddenElement.click();
hiddenElement.remove();
}}
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">
{$_('sponsoring-quittungs-liste_herunterladen')}
</button>
{/if}
</span> </span>
<DonorsOverview bind:current_donors /> <DonorsOverview bind:current_donors />
</section> </section>

View File

@@ -1,5 +1,5 @@
<script> <script>
import { getLocaleFromNavigator, _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { DonationService, DonorService } from "@odit/lfk-client-js"; import { DonationService, DonorService } from "@odit/lfk-client-js";
import store from "../../store"; import store from "../../store";
import DonorsEmptyState from "./DonorsEmptyState.svelte"; import DonorsEmptyState from "./DonorsEmptyState.svelte";

View File

@@ -12,6 +12,7 @@
import Select from "svelte-select"; import Select from "svelte-select";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
import { tick } from "svelte"; import { tick } from "svelte";
$: delete_triggered = false; $: delete_triggered = false;
$: address_valid_or_none = $: address_valid_or_none =
@@ -34,6 +35,7 @@
$: iscityvalid = editable.address?.city?.trim().length !== 0; $: iscityvalid = editable.address?.city?.trim().length !== 0;
$: sponsoring_contracts_show = true; $: sponsoring_contracts_show = true;
$: cards_show = true; $: cards_show = true;
$: certificates_show = true;
$: generate_orgs = [original_object]; $: generate_orgs = [original_object];
$: registrationLink = `${config.baseurl}/selfservice/register/${editable.registrationKey}`; $: registrationLink = `${config.baseurl}/selfservice/register/${editable.registrationKey}`;
const getContactLabel = (option) => const getContactLabel = (option) =>
@@ -176,6 +178,7 @@
bind:sponsoring_contracts_show bind:sponsoring_contracts_show
bind:generate_orgs /> bind:generate_orgs />
<GenerateRunnerCards bind:cards_show bind:generate_orgs /> <GenerateRunnerCards bind:cards_show bind:generate_orgs />
<GenerateRunnerCertificates bind:certificates_show bind:generate_orgs />
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')} {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
<button <button
on:click={() => { on:click={() => {
@@ -186,7 +189,7 @@
{$_('import-runners')} {$_('import-runners')}
</button> </button>
{/if} {/if}
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')} {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
{#if delete_triggered} {#if delete_triggered}
<button <button
on:click={deleteOrganization} on:click={deleteOrganization}

View File

@@ -1,212 +1,219 @@
<script> <script>
import { getLocaleFromNavigator, _ } from "svelte-i18n"; import { getLocaleFromNavigator, _ } from "svelte-i18n";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
let modal_open = false; let modal_open = false;
let delete_org = {}; let delete_org = {};
import { RunnerOrganizationService } from "@odit/lfk-client-js"; import { RunnerOrganizationService } from "@odit/lfk-client-js";
import store from "../../store"; import store from "../../store";
import OrgsEmptyState from "./OrgsEmptyState.svelte"; import OrgsEmptyState from "./OrgsEmptyState.svelte";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte"; import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
$: searchvalue = ""; import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
$: active_deletes = []; $: searchvalue = "";
$: sponsoring_contracts_show = current_organizations.some((r) => r.is_selected === true); $: active_deletes = [];
$: cards_show = current_organizations.some((r) => r.is_selected === true); $: sponsoring_contracts_show = current_organizations.some((r) => r.is_selected === true);
$: generate_orgs = current_organizations.filter((r) => r.is_selected === true); $: cards_show = current_organizations.some((r) => r.is_selected === true);
export let current_organizations = []; $: generate_orgs = current_organizations.filter((r) => r.is_selected === true);
$: certificates_show = current_organizations.some(
const promise = RunnerOrganizationService.runnerOrganizationControllerGetAll().then( (r) => r.is_selected === true
(val) => { );
current_organizations = val; export let current_organizations = [];
}
); const promise = RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
</script> (val) => {
current_organizations = val;
<ConfirmOrgDeletion }
on:cancelDelete={(event) => { );
modal_open = false; </script>
active_deletes[event.detail.id] = false;
}} <ConfirmOrgDeletion
bind:modal_open on:cancelDelete={(event) => {
bind:delete_org /> modal_open = false;
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:GET')} active_deletes[event.detail.id] = false;
{#await promise} }}
<div bind:modal_open
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" bind:delete_org />
role="alert"> {#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:GET')}
<p class="font-bold">{$_('organizations-are-being-loaded')}</p> {#await promise}
<p class="text-sm">{$_('this-might-take-a-moment')}</p> <div
</div> class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
{:then} role="alert">
{#if current_organizations.length === 0} <p class="font-bold">{$_('organizations-are-being-loaded')}</p>
<OrgsEmptyState /> <p class="text-sm">{$_('this-might-take-a-moment')}</p>
{:else} </div>
<input {:then}
type="search" {#if current_organizations.length === 0}
bind:value={searchvalue} <OrgsEmptyState />
placeholder={$_('datatable.search')} {:else}
aria-label={$_('datatable.search')} <input
class="gridjs-input gridjs-search-input mb-4" /> type="search"
<div class="h-12"> bind:value={searchvalue}
<GenerateSponsoringContracts placeholder={$_('datatable.search')}
bind:sponsoring_contracts_show aria-label={$_('datatable.search')}
bind:generate_orgs /> class="gridjs-input gridjs-search-input mb-4" />
<GenerateRunnerCards <div class="h-12">
bind:cards_show <GenerateSponsoringContracts
bind:generate_orgs /> bind:sponsoring_contracts_show
</div> bind:generate_orgs />
<div <GenerateRunnerCards
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"> bind:cards_show
<table class="divide-y divide-gray-200 w-full"> bind:generate_orgs />
<thead class="bg-gray-50"> <GenerateRunnerCertificates
<tr> bind:certificates_show
<th bind:generate_orgs />
scope="col" </div>
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> <div
<span class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
on:click={() => { <table class="divide-y divide-gray-200 w-full">
const newstate = !current_organizations.some((r) => r.is_selected === true); <thead class="bg-gray-50">
current_organizations = current_organizations.map((r) => { <tr>
r.is_selected = newstate; <th
return r; scope="col"
}); class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
}} <span
class="underline cursor-pointer select-none">{#if current_organizations.some((r) => r.is_selected === true)} on:click={() => {
{$_('deselect-all')} const newstate = !current_organizations.some((r) => r.is_selected === true);
{:else}{$_('select-all')}{/if} current_organizations = current_organizations.map((r) => {
</span> r.is_selected = newstate;
</th> return r;
<th });
scope="col" }}
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> class="underline cursor-pointer select-none">{#if current_organizations.some((r) => r.is_selected === true)}
{$_('name')} {$_('deselect-all')}
</th> {:else}{$_('select-all')}{/if}
<th </span>
scope="col" </th>
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> <th
{$_('address')} scope="col"
</th> class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th {$_('name')}
scope="col" </th>
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> <th
{$_('contact')} scope="col"
</th> class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th scope="col" class="relative px-6 py-3"> {$_('address')}
<span class="sr-only">{$_('action')}</span> </th>
</th> <th
</tr> scope="col"
</thead> class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<tbody class="divide-y divide-gray-200"> {$_('contact')}
{#each current_organizations as o} </th>
{#if Object.values(o) <th scope="col" class="relative px-6 py-3">
.toString() <span class="sr-only">{$_('action')}</span>
.toLowerCase() </th>
.includes(searchvalue)} </tr>
<tr data-rowid="org_{o.id}"> </thead>
<td class="px-6 py-4 whitespace-nowrap"> <tbody class="divide-y divide-gray-200">
<input {#each current_organizations as o}
bind:checked={o.is_selected} {#if Object.values(o)
type="checkbox" .toString()
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" /> .toLowerCase()
</td> .includes(searchvalue)}
<td class="px-6 py-4 whitespace-nowrap"> <tr data-rowid="org_{o.id}">
<div class="flex items-center"> <td class="px-6 py-4 whitespace-nowrap">
<div class="ml-4"> <input
<div class="text-sm font-medium text-gray-900"> bind:checked={o.is_selected}
{o.name} type="checkbox"
</div> class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
</div> </td>
</div> <td class="px-6 py-4 whitespace-nowrap">
</td> <div class="flex items-center">
<td class="px-6 py-4 whitespace-nowrap"> <div class="ml-4">
<div class="flex items-center"> <div class="text-sm font-medium text-gray-900">
<div class="ml-4"> {o.name}
<div class="text-sm font-medium text-gray-900"> </div>
{#if o.address.address1 !== null} </div>
{o.address.address1}<br /> </div>
{o.address.address2 || ''}<br /> </td>
{o.address.postalcode} <td class="px-6 py-4 whitespace-nowrap">
{o.address.city} <div class="flex items-center">
{o.address.country} <div class="ml-4">
{/if} <div class="text-sm font-medium text-gray-900">
</div> {#if o.address.address1 !== null}
</div> {o.address.address1}<br />
</div> {o.address.address2 || ''}<br />
</td> {o.address.postalcode}
<td class="px-6 py-4 whitespace-nowrap"> {o.address.city}
<div class="flex items-center"> {o.address.country}
<div class="ml-4"> {/if}
<div class="text-sm font-medium text-gray-900"> </div>
{#if o.contact} </div>
<a </div>
href="../contacts/{o.contact.id}" </td>
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{o.contact.firstname} <td class="px-6 py-4 whitespace-nowrap">
{o.contact.middlename || ''} <div class="flex items-center">
{o.contact.lastname}</a> <div class="ml-4">
{:else}{$_('no-contact-specified')}{/if} <div class="text-sm font-medium text-gray-900">
</div> {#if o.contact}
</div> <a
</div> href="../contacts/{o.contact.id}"
</td> class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{o.contact.firstname}
{#if active_deletes[o.id] === true} {o.contact.middlename || ''}
<td {o.contact.lastname}</a>
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> {:else}{$_('no-contact-specified')}{/if}
<button </div>
on:click={() => { </div>
active_deletes[o.id] = false; </div>
}} </td>
tabindex="0" {#if active_deletes[o.id] === true}
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button> <td
<button class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
on:click={() => { <button
RunnerOrganizationService.runnerOrganizationControllerRemove(o.id, false) on:click={() => {
.then((resp) => { active_deletes[o.id] = false;
current_organizations = current_organizations.filter((obj) => obj.id !== o.id); }}
Toastify({ tabindex="0"
text: 'Organization deleted', class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
duration: 500, <button
backgroundColor: on:click={() => {
'linear-gradient(to right, #00b09b, #96c93d)', RunnerOrganizationService.runnerOrganizationControllerRemove(o.id, false)
}).showToast(); .then((resp) => {
}) current_organizations = current_organizations.filter((obj) => obj.id !== o.id);
.catch((err) => { Toastify({
modal_open = true; text: 'Organization deleted',
delete_org = o; duration: 500,
}); backgroundColor:
}} 'linear-gradient(to right, #00b09b, #96c93d)',
tabindex="0" }).showToast();
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button> })
</td> .catch((err) => {
{:else} modal_open = true;
<td delete_org = o;
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> });
<a }}
href="./{o.id}" tabindex="0"
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a> class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:DELETE')} </td>
<button {:else}
on:click={() => { <td
active_deletes[o.id] = true; class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
}} <a
tabindex="0" href="./{o.id}"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button> class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
{/if} {#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:DELETE')}
</td> <button
{/if} on:click={() => {
</tr> active_deletes[o.id] = true;
{/if} }}
{/each} tabindex="0"
</tbody> class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
</table> {/if}
</div> </td>
{/if} {/if}
{:catch error} </tr>
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500"> {/if}
<span class="inline-block align-middle mr-8"> {/each}
<b class="capitalize">{$_('general_promise_error')}</b> </tbody>
{error} </table>
</span> </div>
</div> {/if}
{/await} {:catch error}
{/if} <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}

View File

@@ -41,7 +41,7 @@
duration: -1, duration: -1,
}).showToast(); }).showToast();
fetch( fetch(
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -67,7 +67,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Runnercards.pdf"; a.download = `${$_('runnercards')}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -101,7 +101,7 @@
cards.push(card); cards.push(card);
} }
fetch( fetch(
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -127,7 +127,12 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Runnercards.pdf"; if(generate_runners.length == 1){
a.download = `${$_('runnercards')}_${generate_runners[0].firstname}_${generate_runners[0].lastname}-${locale}.pdf`;
}
else{
a.download = `Runnercards-${locale}.pdf`;
}
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -164,7 +169,7 @@
cards.push(card); cards.push(card);
} }
fetch( fetch(
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -191,7 +196,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsorings_" + t.name + ".pdf"; a.download = `${$_('runnercards')}_${t.name}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -211,15 +216,16 @@
async function generateOrgCards(locale) { async function generateOrgCards(locale) {
const toast = Toastify({ const toast = Toastify({
text: $_("generating-pdf"), text: $_("generating-pdfs"),
duration: -1, duration: -1,
}).showToast(); }).showToast();
let count = 0;
const current_cards = await RunnerCardService.runnerCardControllerGetAll(); const current_cards = await RunnerCardService.runnerCardControllerGetAll();
let count = 0;
let count_orgs =0;
for (const o of generate_orgs) { for (const o of generate_orgs) {
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners( count_orgs++;
o.id let count = 0;
); let runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(o.id, true)
let cards = []; let cards = [];
for (let runner of runners) { for (let runner of runners) {
let card = current_cards.find((c) => c.runner?.id == runner.id); let card = current_cards.find((c) => c.runner?.id == runner.id);
@@ -230,8 +236,8 @@
} }
cards.push(card); cards.push(card);
} }
fetch( await fetch(
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -240,39 +246,97 @@
body: JSON.stringify(cards), body: JSON.stringify(cards),
} }
) )
.then((response) => { .then((response) => {
if (response.status != "200") { if (response.status != "200") {
toast.hideToast(); toast.hideToast();
Toastify({ Toastify({
text: $_("pdf-generation-failed"), text: $_("pdf-generation-failed"),
duration: 3500, duration: 3500,
backgroundColor: backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast(); }).showToast();
} else { } else {
return response.blob(); return response.blob();
} }
}) })
.then((blob) => { .then((blob) => {
count++; const url = window.URL.createObjectURL(blob);
const url = window.URL.createObjectURL(blob); let a = document.createElement("a");
let a = document.createElement("a"); a.href = url;
a.href = url; a.download = `${$_('runnercards')}_${o.name}_direct-${locale}.pdf`;
a.download = "Sponsorings_" + o.name + ".pdf"; document.body.appendChild(a);
document.body.appendChild(a); a.click();
a.click(); a.remove();
a.remove(); if (count === o.teams.length && count_orgs === generate_orgs.length) {
if (count === generate_orgs.length) { toast.hideToast();
toast.hideToast(); console.log("here")
Toastify({ Toastify({
text: $_("pdfs-successfully-generated"), text: $_("pdfs-successfully-generated"),
duration: 3500, duration: 3500,
backgroundColor: backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)", "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
} }
}) })
.catch((err) => {}); .catch((err) => {});
for (const t of o.teams) {
count++;
let runners = await RunnerTeamService.runnerTeamControllerGetRunners(
t.id
);
let cards = [];
for (let runner of runners) {
let card = current_cards.find((c) => c.runner?.id == runner.id);
if (!card) {
card = await RunnerCardService.runnerCardControllerPost({
runner: runner.id,
});
}
cards.push(card);
}
await fetch(
`${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(cards),
}
)
.then((response) => {
if (response.status != "200") {
toast.hideToast();
Toastify({
text: $_("pdf-generation-failed"),
duration: 3500,
backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast();
} else {
return response.blob();
}
})
.then((blob) => {
const url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = `${$_('runnercards')}_${o.name}_${t.name}-${locale}.pdf`;
document.body.appendChild(a);
a.click();
a.remove();
if (count === o.teams.length && count_orgs === generate_orgs.length) {
toast.hideToast();
Toastify({
text: $_("pdfs-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
}
})
.catch((err) => {});
}
} }
} }
</script> </script>

View File

@@ -0,0 +1,331 @@
<script>
import { _ } from "svelte-i18n";
import {
DonationService,
RunnerTeamService,
RunnerOrganizationService
} from "@odit/lfk-client-js";
import Toastify from "toastify-js";
export let certificates_show = false;
export let generate_runners = [];
export let generate_orgs = [];
export let generate_teams = [];
$: certificates_dropdown_open = false;
document.addEventListener("click", function (e) {
if (
e.target.parentNode?.parentNode?.id != "certificates:dropdown" &&
e.target.parentNode?.parentNode?.id != "certificates:dropdown:menu"
) {
certificates_dropdown_open = false;
}
});
function generateCertificates(locale) {
certificates_dropdown_open = false;
if (generate_orgs.length > 0) {
generateOrgCertificates(locale);
} else if (generate_teams.length > 0) {
generateTeamCertificates(locale);
} else {
generateRunnerCertificates(locale);
}
}
async function generateRunnerCertificates(locale) {
const toast = Toastify({
text: $_("generating-pdf"),
duration: -1,
}).showToast();
const current_donations = (await DonationService.donationControllerGetAll()) || [];
let certificateRunners = [];
for (let runner of generate_runners) {
runner.distanceDonations = current_donations.find((d) => d.runner?.id == runner.id) || [];
certificateRunners.push(runner);
}
fetch(
`${config.baseurl_documentserver}/certificates?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(certificateRunners),
}
)
.then((response) => {
if (response.status != "200") {
toast.hideToast();
Toastify({
text: $_("pdf-generation-failed"),
duration: 3500,
backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast();
} else {
return response.blob();
}
})
.then((blob) => {
const url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
if(generate_runners.length == 1){
a.download = `${$_('certificates')}_${generate_runners[0].firstname}_${generate_runners[0].lastname}-${locale}.pdf`;
}
else{
a.download = `${$_('certificates')}-${locale}.pdf`;
}
document.body.appendChild(a);
a.click();
a.remove();
toast.hideToast();
Toastify({
text: $_("pdf-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
})
.catch((err) => {});
}
async function generateTeamCertificates(locale) {
const toast = Toastify({
text: $_("generating-pdfs"),
duration: -1,
}).showToast();
let count = 0;
const current_donations = (await DonationService.donationControllerGetAll()) || [];
for (const t of generate_teams) {
const runners = await RunnerTeamService.runnerTeamControllerGetRunners(
t.id
);
let certificateRunners = [];
for (let runner of runners) {
runner.distanceDonations = current_donations.find((d) => d.runner?.id == runner.id) || [];
certificateRunners.push(runner);
}
fetch(
`${config.baseurl_documentserver}/certificates?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(certificateRunners),
}
)
.then((response) => {
if (response.status != "200") {
toast.hideToast();
Toastify({
text: $_("pdf-generation-failed"),
duration: 3500,
backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast();
} else {
return response.blob();
}
})
.then((blob) => {
count++;
const url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = `${$_('certificates')}_${t.name}-${locale}.pdf`;
document.body.appendChild(a);
a.click();
a.remove();
if (count === generate_teams.length) {
toast.hideToast();
Toastify({
text: $_("pdfs-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
}
})
.catch((err) => {});
}
}
async function generateOrgCertificates(locale) {
const toast = Toastify({
text: $_("generating-pdfs"),
duration: -1,
}).showToast();
const current_donations = (await DonationService.donationControllerGetAll()) || [];
let count = 0;
let count_orgs =0;
for (const o of generate_orgs) {
count_orgs++;
let count = 0;
let runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(o.id, true)
let certificateRunners = [];
for (let runner of runners) {
runner.distanceDonations = current_donations.find((d) => d.runner?.id == runner.id) || [];
certificateRunners.push(runner);
}
await fetch(
`${config.baseurl_documentserver}/certificates?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(certificateRunners),
}
)
.then((response) => {
if (response.status != "200") {
toast.hideToast();
Toastify({
text: $_("pdf-generation-failed"),
duration: 3500,
backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast();
} else {
return response.blob();
}
})
.then((blob) => {
const url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = `${$_('certificates')}_${o.name}_direct-${locale}.pdf`;
document.body.appendChild(a);
a.click();
a.remove();
if (count === o.teams.length && count_orgs === generate_orgs.length) {
toast.hideToast();
console.log("here")
Toastify({
text: $_("pdfs-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
}
})
.catch((err) => {});
for (const t of o.teams) {
count++;
let runners = await RunnerTeamService.runnerTeamControllerGetRunners(
t.id
);
let certificateRunners = [];
for (let runner of runners) {
runner.distanceDonations = current_donations.find((d) => d.runner?.id == runner.id) || [];
certificateRunners.push(runner);
}
await fetch(
`${config.baseurl_documentserver}/certificates?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(certificateRunners),
}
)
.then((response) => {
if (response.status != "200") {
toast.hideToast();
Toastify({
text: $_("pdf-generation-failed"),
duration: 3500,
backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast();
} else {
return response.blob();
}
})
.then((blob) => {
const url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = `${$_('certificates')}_${o.name}_${t.name}-${locale}.pdf`;
document.body.appendChild(a);
a.click();
a.remove();
if (count === o.teams.length && count_orgs === generate_orgs.length) {
toast.hideToast();
Toastify({
text: $_("pdfs-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
}
})
.catch((err) => {});
}
}
}
</script>
{#if certificates_show}
<div id="certificates:dropdown" class="relative inline-block">
<div>
<button
on:click={() => {
certificates_dropdown_open = !certificates_dropdown_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-runner-certificates')}
<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 certificates_dropdown_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="certificates: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={() => {
generateCertificates('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"
role="menuitem">
{$_('german')}
</button>
<button
on:click={() => {
generateCertificates('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"
role="menuitem">
{$_('english')}
</button>
</div>
</div>
{/if}
</div>
{/if}

View File

@@ -43,7 +43,7 @@
t.id t.id
); );
fetch( fetch(
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -69,7 +69,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsorings_" + t.name + ".pdf"; a.download = `${$_('sponsorings')}_${t.name}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -92,12 +92,13 @@
text: $_("generating-pdf"), text: $_("generating-pdf"),
duration: -1, duration: -1,
}).showToast(); }).showToast();
let count_orgs =0;
for (const o of generate_orgs) { for (const o of generate_orgs) {
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners( count_orgs++;
o.id let count = 0;
); let runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(o.id, true)
fetch( await fetch(
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -106,39 +107,87 @@
body: JSON.stringify(runners), body: JSON.stringify(runners),
} }
) )
.then((response) => { .then((response) => {
if (response.status != "200") { if (response.status != "200") {
toast.hideToast(); toast.hideToast();
Toastify({ Toastify({
text: $_("pdf-generation-failed"), text: $_("pdf-generation-failed"),
duration: 3500, duration: 3500,
backgroundColor: backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast(); }).showToast();
} else { } else {
return response.blob(); return response.blob();
} }
}) })
.then((blob) => { .then((blob) => {
count++; const url = window.URL.createObjectURL(blob);
const url = window.URL.createObjectURL(blob); let a = document.createElement("a");
let a = document.createElement("a"); a.href = url;
a.href = url; a.download = `${$_('sponsorings')}_${o.name}_direct-${locale}.pdf`;
a.download = "Sponsorings_" + o.name + ".pdf"; document.body.appendChild(a);
document.body.appendChild(a); a.click();
a.click(); a.remove();
a.remove(); if (count === o.teams.length && count_orgs === generate_orgs.length) {
if (count === generate_orgs.length) { toast.hideToast();
toast.hideToast(); console.log("here")
Toastify({ Toastify({
text: $_("pdfs-successfully-generated"), text: $_("pdfs-successfully-generated"),
duration: 3500, duration: 3500,
backgroundColor: backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)", "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
} }
}) })
.catch((err) => {}); .catch((err) => {});
for (const t of o.teams) {
count++;
let runners = await RunnerTeamService.runnerTeamControllerGetRunners(
t.id
);
await fetch(
`${config.baseurl_documentserver}/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(runners),
}
)
.then((response) => {
if (response.status != "200") {
toast.hideToast();
Toastify({
text: $_("pdf-generation-failed"),
duration: 3500,
backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast();
} else {
return response.blob();
}
})
.then((blob) => {
const url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = `${$_('sponsorings')}_${o.name}_${t.name}-${locale}.pdf`;
document.body.appendChild(a);
a.click();
a.remove();
if (count === o.teams.length && count_orgs === generate_orgs.length) {
toast.hideToast();
Toastify({
text: $_("pdfs-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
}
})
.catch((err) => {});
}
} }
} }
@@ -148,7 +197,7 @@
duration: -1, duration: -1,
}).showToast(); }).showToast();
fetch( fetch(
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -174,7 +223,10 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsoring.pdf"; if(generate_runners.length == 1){
a.download = `${$_('sponsorings')}_${generate_runners[0].firstname}_${generate_runners[0].lastname}-${locale}.pdf`;
}
a.download = `${$_('sponsorings')}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();

View File

@@ -34,7 +34,7 @@
document.onkeydown = (e) => { document.onkeydown = (e) => {
e = e || window.event; e = e || window.event;
if (e.key === "Escape") { if (e.key === "Escape") {
import_modal_open = false; cancelModal();
} }
if (e.keyCode === 13) { if (e.keyCode === 13) {
// //
@@ -281,6 +281,16 @@
bind:files bind:files
type="file" /> type="file" />
</div> </div>
<div class="overflow-hidden relative mt-4 mb-4">
<button
on:click={() => {
cancelModal();
}}
type="button"
class="w-full 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 md:ml-40 mr-0 sm:ml-0 sm:w-auto sm:text-sm">
{$_('cancel')}
</button>
</div>
{/if} {/if}
{#if json_output.length > 0} {#if json_output.length > 0}
{#if opened_from === 'OrgOverview'} {#if opened_from === 'OrgOverview'}

View File

@@ -2,6 +2,7 @@
import { getLocaleFromNavigator, _ } from "svelte-i18n"; import { getLocaleFromNavigator, _ } from "svelte-i18n";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
import store from "../../store"; import store from "../../store";
import { import {
RunnerService, RunnerService,
@@ -36,6 +37,7 @@
editable.group != null; editable.group != null;
$: sponsoring_contracts_show = true; $: sponsoring_contracts_show = true;
$: cards_show = true; $: cards_show = true;
$: certificates_show = true;
$: generate_runners = [original_data_pdf]; $: generate_runners = [original_data_pdf];
runner_promise.then((data) => { runner_promise.then((data) => {
data_loaded = true; data_loaded = true;
@@ -158,7 +160,10 @@
bind:sponsoring_contracts_show bind:sponsoring_contracts_show
bind:generate_runners /> bind:generate_runners />
<GenerateRunnerCards <GenerateRunnerCards
bind:sponsoring_contracts_show bind:cards_show
bind:generate_runners />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_runners /> bind:generate_runners />
{#if !delete_triggered} {#if !delete_triggered}
<button <button

View File

@@ -10,6 +10,7 @@
import Select from "svelte-select"; import Select from "svelte-select";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
$: searchvalue = ""; $: searchvalue = "";
$: active_deletes = []; $: active_deletes = [];
export let current_runners = []; export let current_runners = [];
@@ -27,6 +28,9 @@
$: cards_show = current_runners.some( $: cards_show = current_runners.some(
(r) => r.is_selected === true (r) => r.is_selected === true
); );
$: certificates_show = current_runners.some(
(r) => r.is_selected === true
);
$: generate_runners = current_runners.filter((r) => r.is_selected === true); $: generate_runners = current_runners.filter((r) => r.is_selected === true);
$: teams = []; $: teams = [];
$: orgs = []; $: orgs = [];
@@ -92,6 +96,9 @@
<GenerateRunnerCards <GenerateRunnerCards
bind:cards_show bind:cards_show
bind:generate_runners /> bind:generate_runners />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_runners />
</div> </div>
<div <div
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"> class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
@@ -190,7 +197,7 @@
{#if runner.group.responseType === 'RUNNERTEAM'} {#if runner.group.responseType === 'RUNNERTEAM'}
<a <a
href="../teams/{runner.group.id}" href="../teams/{runner.group.id}"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{runner.group.name}</a> class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{runner.group.parentGroup.name} &gt; {runner.group.name}</a>
{/if} {/if}
{#if runner.group.responseType === 'RUNNERORGANIZATION'} {#if runner.group.responseType === 'RUNNERORGANIZATION'}
<a <a

View File

@@ -14,6 +14,7 @@
import Teams from "./Teams.svelte"; import Teams from "./Teams.svelte";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
let [teamdata, original, delete_team, orgs, contacts, modal_open] = [ let [teamdata, original, delete_team, orgs, contacts, modal_open] = [
{}, {},
{}, {},
@@ -30,6 +31,7 @@
$: data_changed = JSON.stringify(teamdata) === JSON.stringify(original); $: data_changed = JSON.stringify(teamdata) === JSON.stringify(original);
$: sponsoring_contracts_show = true; $: sponsoring_contracts_show = true;
$: cards_show = true; $: cards_show = true;
$: certificates_show = true;
$: generate_teams = [original]; $: generate_teams = [original];
$: group = {}; $: group = {};
$: contact = {}; $: contact = {};
@@ -122,6 +124,9 @@
<GenerateRunnerCards <GenerateRunnerCards
bind:cards_show bind:cards_show
bind:generate_teams /> bind:generate_teams />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_teams />
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')} {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
<button <button
on:click={() => { on:click={() => {

View File

@@ -1,217 +1,224 @@
<script> <script>
import { getLocaleFromNavigator, t, _ } from "svelte-i18n"; import { getLocaleFromNavigator, t, _ } from "svelte-i18n";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import { RunnerTeamService } from "@odit/lfk-client-js"; import { RunnerTeamService } from "@odit/lfk-client-js";
const teams_promise = RunnerTeamService.runnerTeamControllerGetAll(); const teams_promise = RunnerTeamService.runnerTeamControllerGetAll();
import store, { users as usersstore } from "../../store.js"; import store, { users as usersstore } from "../../store.js";
import TeamsEmptyState from "./TeamsEmptyState.svelte"; import TeamsEmptyState from "./TeamsEmptyState.svelte";
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte"; import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
import { clickOutside } from "../base/outsideclick"; import { clickOutside } from "../base/outsideclick";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
$: searchvalue = ""; import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
$: active_deletes = []; $: searchvalue = "";
$: sponsoring_contracts_show = current_teams.some( $: active_deletes = [];
(r) => r.is_selected === true $: sponsoring_contracts_show = current_teams.some(
); (r) => r.is_selected === true
$: cards_show = current_teams.some( );
(r) => r.is_selected === true $: cards_show = current_teams.some(
); (r) => r.is_selected === true
$: generate_teams = current_teams.filter((r) => r.is_selected === true); );
export let current_teams = []; $: certificates_show = current_teams.some(
let modal_open = false; (r) => r.is_selected === true
let delete_team = {}; );
usersstore.subscribe((val) => { $: generate_teams = current_teams.filter((r) => r.is_selected === true);
current_teams = val; export let current_teams = [];
}); let modal_open = false;
teams_promise.then((data) => { let delete_team = {};
usersstore.set(data); usersstore.subscribe((val) => {
}); current_teams = val;
</script> });
teams_promise.then((data) => {
<ConfirmTeamDeletion usersstore.set(data);
on:cancelDelete={(event) => { });
modal_open = false; </script>
active_deletes[event.detail.id] = false;
}} <ConfirmTeamDeletion
bind:modal_open on:cancelDelete={(event) => {
bind:delete_team /> modal_open = false;
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')} active_deletes[event.detail.id] = false;
{#await teams_promise} }}
<div bind:modal_open
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" bind:delete_team />
role="alert"> {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')}
<p class="font-bold">{$_('teams-are-being-loaded')}</p> {#await teams_promise}
<p class="text-sm">{$_('this-might-take-a-moment')}</p> <div
</div> class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
{:then} role="alert">
{#if current_teams.length === 0} <p class="font-bold">{$_('teams-are-being-loaded')}</p>
<TeamsEmptyState /> <p class="text-sm">{$_('this-might-take-a-moment')}</p>
{:else} </div>
<input {:then}
type="search" {#if current_teams.length === 0}
bind:value={searchvalue} <TeamsEmptyState />
placeholder={$_('datatable.search')} {:else}
aria-label={$_('datatable.search')} <input
class="gridjs-input gridjs-search-input mb-4" /> type="search"
<div class="h-12"> bind:value={searchvalue}
<GenerateSponsoringContracts placeholder={$_('datatable.search')}
bind:sponsoring_contracts_show aria-label={$_('datatable.search')}
bind:generate_teams /> class="gridjs-input gridjs-search-input mb-4" />
<GenerateRunnerCards <div class="h-12">
bind:cards_show <GenerateSponsoringContracts
bind:generate_teams /> bind:sponsoring_contracts_show
</div> bind:generate_teams />
<div <GenerateRunnerCards
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"> bind:cards_show
<table class="divide-y divide-gray-200 w-full"> bind:generate_teams />
<thead class="bg-gray-50"> <GenerateRunnerCertificates
<tr> bind:certificates_show
<th bind:generate_teams />
scope="col" </div>
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> <div
<span class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
on:click={() => { <table class="divide-y divide-gray-200 w-full">
const newstate = !current_teams.some((r) => r.is_selected === true); <thead class="bg-gray-50">
current_teams = current_teams.map((r) => { <tr>
r.is_selected = newstate; <th
return r; scope="col"
}); class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
}} <span
class="underline cursor-pointer select-none">{#if current_teams.some((r) => r.is_selected === true)} on:click={() => {
{$_('deselect-all')} const newstate = !current_teams.some((r) => r.is_selected === true);
{:else}{$_('select-all')}{/if} current_teams = current_teams.map((r) => {
</span> r.is_selected = newstate;
</th> return r;
<th });
scope="col" }}
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> class="underline cursor-pointer select-none">{#if current_teams.some((r) => r.is_selected === true)}
{$_('name')} {$_('deselect-all')}
</th> {:else}{$_('select-all')}{/if}
<th </span>
scope="col" </th>
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> <th
{$_('organization')} scope="col"
</th> class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th {$_('name')}
scope="col" </th>
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> <th
{$_('contact')} scope="col"
</th> class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th scope="col" class="relative px-6 py-3"> {$_('organization')}
<span class="sr-only">{$_('action')}</span> </th>
</th> <th
</tr> scope="col"
</thead> class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<tbody class="divide-y divide-gray-200"> {$_('contact')}
{#each current_teams as t} </th>
{#if Object.values(t) <th scope="col" class="relative px-6 py-3">
.toString() <span class="sr-only">{$_('action')}</span>
.toLowerCase() </th>
.includes(searchvalue)} </tr>
<tr data-rowid="team_{t.id}"> </thead>
<td class="px-6 py-4 whitespace-nowrap"> <tbody class="divide-y divide-gray-200">
<input {#each current_teams as t}
bind:checked={t.is_selected} {#if Object.values(t)
type="checkbox" .toString()
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" /> .toLowerCase()
</td> .includes(searchvalue)}
<td class="px-6 py-4 whitespace-nowrap"> <tr data-rowid="team_{t.id}">
<div class="flex items-center"> <td class="px-6 py-4 whitespace-nowrap">
<div class="ml-4"> <input
<div class="text-sm font-medium text-gray-900"> bind:checked={t.is_selected}
{t.name} type="checkbox"
</div> class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
</div> </td>
</div> <td class="px-6 py-4 whitespace-nowrap">
</td> <div class="flex items-center">
<td class="px-6 py-4 whitespace-nowrap"> <div class="ml-4">
<div class="flex items-center"> <div class="text-sm font-medium text-gray-900">
<div class="ml-4"> {t.name}
<div class="text-sm font-medium text-gray-900"> </div>
{#if t.parentGroup} </div>
<a </div>
href="../orgs/{t.parentGroup.id}" </td>
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.parentGroup.name}</a> <td class="px-6 py-4 whitespace-nowrap">
{:else}{$_('no-organization-specified')}{/if} <div class="flex items-center">
</div> <div class="ml-4">
</div> <div class="text-sm font-medium text-gray-900">
</div> {#if t.parentGroup}
</td> <a
<td class="px-6 py-4 whitespace-nowrap"> href="../orgs/{t.parentGroup.id}"
<div class="flex items-center"> class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.parentGroup.name}</a>
<div class="ml-4"> {:else}{$_('no-organization-specified')}{/if}
<div class="text-sm font-medium text-gray-900"> </div>
{#if t.contact} </div>
<a </div>
href="../contacts/{t.contact.id}" </td>
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.contact.firstname} <td class="px-6 py-4 whitespace-nowrap">
{t.contact.middlename || ''} <div class="flex items-center">
{t.contact.lastname}</a> <div class="ml-4">
{:else}{$_('no-contact-specified')}{/if} <div class="text-sm font-medium text-gray-900">
</div> {#if t.contact}
</div> <a
</div> href="../contacts/{t.contact.id}"
</td> class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.contact.firstname}
{#if active_deletes[t.id] === true} {t.contact.middlename || ''}
<td {t.contact.lastname}</a>
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> {:else}{$_('no-contact-specified')}{/if}
<button </div>
on:click={() => { </div>
active_deletes[t.id] = false; </div>
}} </td>
tabindex="0" {#if active_deletes[t.id] === true}
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel <td
Delete</button> class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button <button
on:click={() => { on:click={() => {
RunnerTeamService.runnerTeamControllerRemove(t.id, false) active_deletes[t.id] = false;
.then((resp) => { }}
current_teams = current_teams.filter((obj) => obj.id !== t.id); tabindex="0"
Toastify({ class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
text: $_('organization-deleted'), Delete</button>
duration: 500, <button
backgroundColor: on:click={() => {
'linear-gradient(to right, #00b09b, #96c93d)', RunnerTeamService.runnerTeamControllerRemove(t.id, false)
}).showToast(); .then((resp) => {
}) current_teams = current_teams.filter((obj) => obj.id !== t.id);
.catch((err) => { Toastify({
modal_open = true; text: $_('organization-deleted'),
delete_team = t; duration: 500,
}); backgroundColor:
}} 'linear-gradient(to right, #00b09b, #96c93d)',
tabindex="0" }).showToast();
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button> })
</td> .catch((err) => {
{:else} modal_open = true;
<td delete_team = t;
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> });
<a }}
href="./{t.id}" tabindex="0"
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a> class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')} </td>
<button {:else}
on:click={() => { <td
active_deletes[t.id] = true; class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
}} <a
tabindex="0" href="./{t.id}"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button> class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
{/if} {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')}
</td> <button
{/if} on:click={() => {
</tr> active_deletes[t.id] = true;
{/if} }}
{/each} tabindex="0"
</tbody> class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
</table> {/if}
</div> </td>
{/if} {/if}
{:catch error} </tr>
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500"> {/if}
<span class="inline-block align-middle mr-8"> {/each}
<b class="capitalize">{$_('general_promise_error')}</b> </tbody>
{error} </table>
</span> </div>
</div> {/if}
{/await} {:catch error}
{/if} <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}

View File

@@ -50,6 +50,7 @@
"card-deleted": "Karte gelöscht", "card-deleted": "Karte gelöscht",
"card-updated": "Karte aktualisiert", "card-updated": "Karte aktualisiert",
"cards": "Läuferkarten", "cards": "Läuferkarten",
"certificates": "Urkunden",
"change-your-password-here": "Hier kannst du dein Passwort ändern", "change-your-password-here": "Hier kannst du dein Passwort ändern",
"changing-your-password": "Passwort wird geändert", "changing-your-password": "Passwort wird geändert",
"city": "Stadt", "city": "Stadt",
@@ -182,6 +183,7 @@
"everything-concerning-your-profile": "Alles zu deinem Profil", "everything-concerning-your-profile": "Alles zu deinem Profil",
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃‍♂️🏃‍♀️🏃‍♂️", "everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃‍♂️🏃‍♀️🏃‍♂️",
"faq": "FAQ", "faq": "FAQ",
"filename_sponsoringquittungsliste": "SponsoringQuittungsListe",
"filter-by-organization-team": "Filtern nach Organisation / Team", "filter-by-organization-team": "Filtern nach Organisation / Team",
"first-name": "Vorname", "first-name": "Vorname",
"first-name-is-required": "Vorname muss angegeben werden", "first-name-is-required": "Vorname muss angegeben werden",
@@ -191,10 +193,12 @@
"geerbte": "geerbte", "geerbte": "geerbte",
"general-stats": "Allgemeine Statistiken", "general-stats": "Allgemeine Statistiken",
"general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten", "general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten",
"generate-runner-certificate": "Urkunde generieren",
"generate-runner-certificates": "Urkunden generieren",
"generate-runnercards": "Läuferkarten generieren", "generate-runnercards": "Läuferkarten generieren",
"generate-sponsoring-contract": "Sponsoringvertrag generieren", "generate-sponsoring-contract": "Sponsoringvertrag generieren",
"generate-sponsoring-contracts": "Sponsoringverträge generieren", "generate-sponsoring-contracts": "Sponsoringverträge generieren",
"generating-pdf": "Pdf wird generiert...", "generating-pdf": "PDF wird generiert...",
"generating-pdfs": "PDFs werden generiert...", "generating-pdfs": "PDFs werden generiert...",
"generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.", "generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.",
"german": "Deutsch", "german": "Deutsch",
@@ -321,6 +325,7 @@
"runner-import": "Läufer:innen Import", "runner-import": "Läufer:innen Import",
"runner-is-being-added": "Läufer:in wird hinzugefügt...", "runner-is-being-added": "Läufer:in wird hinzugefügt...",
"runner-updated": "Läufer:in aktualisiert!", "runner-updated": "Läufer:in aktualisiert!",
"runnercards": "Laeuferkarten",
"runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen", "runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen",
"runners": "Läufer", "runners": "Läufer",
"runners-are-being-imported": "Läufer:innen werden importiert ...", "runners-are-being-imported": "Läufer:innen werden importiert ...",
@@ -350,6 +355,8 @@
"settings": "Einstellungen", "settings": "Einstellungen",
"settings-for-your-profile": "Die Einstellungen deines Accounts", "settings-for-your-profile": "Die Einstellungen deines Accounts",
"something-about-the-group": "Infos zur Gruppe", "something-about-the-group": "Infos zur Gruppe",
"sponsoring-quittungs-liste_herunterladen": "Sponsoring-Quittungs-Liste herunterladen",
"sponsorings": "Sponsoringerklaerungen",
"stats-are-being-loaded": "Die Statistiken werden geladen...", "stats-are-being-loaded": "Die Statistiken werden geladen...",
"status": "Status", "status": "Status",
"stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können", "stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können",
@@ -381,6 +388,7 @@
"total-donation-amount": "Gesamtbetrag", "total-donation-amount": "Gesamtbetrag",
"total-donations": "Spendensumme", "total-donations": "Spendensumme",
"total-scans": "gesamte Scans", "total-scans": "gesamte Scans",
"total_donation_amount_in_eur": "Gesamtbetrag in €",
"track": "Track", "track": "Track",
"track-added": "Track hinzugefügt", "track-added": "Track hinzugefügt",
"track-data-is-being-loaded": "Trackdaten werden geladen", "track-data-is-being-loaded": "Trackdaten werden geladen",
@@ -390,6 +398,7 @@
"track-name": "Trackname", "track-name": "Trackname",
"track-name-must-not-be-empty": "Der Name muss angegeben werden", "track-name-must-not-be-empty": "Der Name muss angegeben werden",
"tracks": "Tracks", "tracks": "Tracks",
"update-card": "Karte aktualisieren",
"update-password": "Passwort ändern", "update-password": "Passwort ändern",
"updated-contact": "Kontakt aktualisiert!", "updated-contact": "Kontakt aktualisiert!",
"updated-donor": "Sponsor:in wurde aktualisiert", "updated-donor": "Sponsor:in wurde aktualisiert",

View File

@@ -6,7 +6,7 @@
"active": "Active", "active": "Active",
"add-card": "Add Card", "add-card": "Add Card",
"add-donation": "Add donation", "add-donation": "Add donation",
"add-donor": "add donor", "add-donor": "Add donor",
"add-scan": "Add scan", "add-scan": "Add scan",
"add-the-first-scanstation": "Add your first scanstation.", "add-the-first-scanstation": "Add your first scanstation.",
"add-user-group": "Add User Group", "add-user-group": "Add User Group",
@@ -50,6 +50,7 @@
"card-deleted": "Card deleted", "card-deleted": "Card deleted",
"card-updated": "Card updated", "card-updated": "Card updated",
"cards": "Cards", "cards": "Cards",
"certificates": "Certificates",
"change-your-password-here": "Change your password here", "change-your-password-here": "Change your password here",
"changing-your-password": "Changing your password", "changing-your-password": "Changing your password",
"city": "City", "city": "City",
@@ -182,6 +183,7 @@
"everything-concerning-your-profile": "Everything concerning your profile", "everything-concerning-your-profile": "Everything concerning your profile",
"everything-is-more-fun-together": "everything is more fun together 🏃‍♂️🏃‍♀️🏃‍♂️", "everything-is-more-fun-together": "everything is more fun together 🏃‍♂️🏃‍♀️🏃‍♂️",
"faq": "FAQ", "faq": "FAQ",
"filename_sponsoringquittungsliste": "DonorReceiptList",
"filter-by-organization-team": "Filter by Organization/ Team", "filter-by-organization-team": "Filter by Organization/ Team",
"first-name": "First name", "first-name": "First name",
"first-name-is-required": "First Name is required", "first-name-is-required": "First Name is required",
@@ -191,6 +193,8 @@
"geerbte": "inherited", "geerbte": "inherited",
"general-stats": "General Stats", "general-stats": "General Stats",
"general_promise_error": "😢 Error", "general_promise_error": "😢 Error",
"generate-runner-certificate": "Generate runner certificate",
"generate-runner-certificates": "Generate runner certificates",
"generate-runnercards": "Generate Runnercards", "generate-runnercards": "Generate Runnercards",
"generate-sponsoring-contract": "generate sponsoring contract", "generate-sponsoring-contract": "generate sponsoring contract",
"generate-sponsoring-contracts": "generate sponsoring contracts", "generate-sponsoring-contracts": "generate sponsoring contracts",
@@ -321,6 +325,7 @@
"runner-import": "Runner Import", "runner-import": "Runner Import",
"runner-is-being-added": "Runner is being added...", "runner-is-being-added": "Runner is being added...",
"runner-updated": "Runner updated!", "runner-updated": "Runner updated!",
"runnercards": "Runnercards",
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"", "runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
"runners": "Runners", "runners": "Runners",
"runners-are-being-imported": "Runners are being imported...", "runners-are-being-imported": "Runners are being imported...",
@@ -350,6 +355,8 @@
"settings": "Settings", "settings": "Settings",
"settings-for-your-profile": "Settings for your profile", "settings-for-your-profile": "Settings for your profile",
"something-about-the-group": "Something about the group...", "something-about-the-group": "Something about the group...",
"sponsoring-quittungs-liste_herunterladen": "Download donor receipt list",
"sponsorings": "Sponsorings",
"stats-are-being-loaded": "stats are being loaded...", "stats-are-being-loaded": "stats are being loaded...",
"status": "Status", "status": "Status",
"stuff-that-could-harm-your-profile": "Stuff that could harm your profile", "stuff-that-could-harm-your-profile": "Stuff that could harm your profile",
@@ -381,6 +388,7 @@
"total-donation-amount": "total donation amount", "total-donation-amount": "total donation amount",
"total-donations": "total donations", "total-donations": "total donations",
"total-scans": "total scans", "total-scans": "total scans",
"total_donation_amount_in_eur": "Total donation amount in €",
"track": "Track", "track": "Track",
"track-added": "Track added", "track-added": "Track added",
"track-data-is-being-loaded": "Track data is being loaded", "track-data-is-being-loaded": "Track data is being loaded",