Compare commits

..

10 Commits

Author SHA1 Message Date
6249502a88 🚀RELEASE v1.8.2
All checks were successful
Build Latest and dev images / build-container (push) Successful in 1m1s
Build release images / build-container (push) Successful in 56s
2025-03-26 22:02:25 +01:00
8a78034079 feat(dashboard): active item for teams + runners
All checks were successful
Build Latest and dev images / build-container (push) Successful in 57s
2025-03-26 22:01:18 +01:00
7633b7b056 feat: improvement of card,certificate,sponsoringcontract action buttons
All checks were successful
Build Latest and dev images / build-container (push) Successful in 1m1s
2025-03-26 21:59:55 +01:00
b8e6b24bf3 🚀RELEASE v1.8.1
All checks were successful
Build release images / build-container (push) Successful in 1m18s
Build Latest and dev images / build-container (push) Successful in 1m21s
2025-03-26 19:12:05 +01:00
97b7ca931f fix(pdf_generation): Only load direct runners for direct calls 2025-03-26 19:10:37 +01:00
48dd9acde5 🚀RELEASE v1.8.0
All checks were successful
Build release images / build-container (push) Successful in 1m13s
Build Latest and dev images / build-container (push) Successful in 1m15s
2025-03-26 16:03:19 +01:00
5147a20b3c fix(DonorDetail): donor deletion
All checks were successful
Build Latest and dev images / build-container (push) Successful in 1m20s
2025-03-26 15:57:44 +01:00
bb2319a78d chore(deps): bump
Some checks failed
Build Latest and dev images / build-container (push) Failing after 23s
2025-03-26 15:35:53 +01:00
7c10d95c1c feat(RunnerOrganizationService.runnerOrganizationControllerGetRunners): load all runners in org
All checks were successful
Build Latest and dev images / build-container (push) Successful in 1m7s
2025-03-26 15:34:38 +01:00
f734d1e3f6 feat: cleanup TeamDetail + OrgDetail 2025-03-26 15:33:34 +01:00
34 changed files with 2191 additions and 2204 deletions

View File

@@ -2,12 +2,52 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [1.8.2](https://git.odit.services/lfk/frontend/compare/1.8.1...1.8.2)
- feat: improvement of card,certificate,sponsoringcontract action buttons [`7633b7b`](https://git.odit.services/lfk/frontend/commit/7633b7b05671342bc30e0bbecbcd9450e06b5e4d)
- feat(dashboard): active item for teams + runners [`8a78034`](https://git.odit.services/lfk/frontend/commit/8a780340792445fff1f78db994fb78acb5da8304)
#### [1.8.1](https://git.odit.services/lfk/frontend/compare/1.8.0...1.8.1)
> 26 March 2025
- 🚀RELEASE v1.8.1 [`b8e6b24`](https://git.odit.services/lfk/frontend/commit/b8e6b24bf32379c3f4a1679d422e6fdcc45f7c99)
- fix(pdf_generation): Only load direct runners for direct calls [`97b7ca9`](https://git.odit.services/lfk/frontend/commit/97b7ca931f607ee64509ad10c2269632fc691091)
#### [1.8.0](https://git.odit.services/lfk/frontend/compare/1.7.0...1.8.0)
> 26 March 2025
- wip [`824ecfa`](https://git.odit.services/lfk/frontend/commit/824ecfab2e976cd7c6cd2851be8a9be5c6b686e1)
- wip [`0a6cf61`](https://git.odit.services/lfk/frontend/commit/0a6cf619b09be837d5503f4695250c7edaeeaff5)
- feat: improve fonts + button positions [`c37fb98`](https://git.odit.services/lfk/frontend/commit/c37fb98bed377744981e927ea8d22db9e20c55ca)
- 🚀RELEASE v1.8.0 [`48dd9ac`](https://git.odit.services/lfk/frontend/commit/48dd9acde595b882630855d5e6af3cfa18fc9ecf)
- wip [`1bc5314`](https://git.odit.services/lfk/frontend/commit/1bc53146b9f024f3cab613b227d29304d687c92b)
- wip [`e82350d`](https://git.odit.services/lfk/frontend/commit/e82350df4af082d2bbb322658c6c022d83b819ae)
- wip [`37cdbba`](https://git.odit.services/lfk/frontend/commit/37cdbba0a3563875e19bee560f2cd5c8fc2d7a6e)
- feat: improve input readability [`79e6a42`](https://git.odit.services/lfk/frontend/commit/79e6a4212d06029766d0a853686ed97879ebd349)
- wip [`5f5d827`](https://git.odit.services/lfk/frontend/commit/5f5d8277b98363ef15a92621fca0a209345aca95)
- chore(deps): bump [`bb2319a`](https://git.odit.services/lfk/frontend/commit/bb2319a78d253a2d6239a0d3daedc90fd29abdd0)
- feat: cleanup TeamDetail + OrgDetail [`f734d1e`](https://git.odit.services/lfk/frontend/commit/f734d1e3f643a500a6432a389c3103045cc51262)
- refactor(ci): Switch to actions for dev [`847fa28`](https://git.odit.services/lfk/frontend/commit/847fa288f1b5bbc422cc2944bbe66e80c5a00407)
- refactor(ci): Add Gitea workflow for building release images and remove Woodpecker configuration [`3ec18a6`](https://git.odit.services/lfk/frontend/commit/3ec18a696435ada26bf2de2220b190dc630a9759)
- feat: athiti font [`391186d`](https://git.odit.services/lfk/frontend/commit/391186d01f3b96638a3569dc2843bf181dc3f02c)
- fix(DonorDetail): donor deletion [`5147a20`](https://git.odit.services/lfk/frontend/commit/5147a20b3c4a46968482b1e3517047351c94f77e)
- feat(dashboard): full width for sidebar items [`975f145`](https://git.odit.services/lfk/frontend/commit/975f145444e5a478524ea2cbbfb9059b93617185)
- wip [`3d3ce29`](https://git.odit.services/lfk/frontend/commit/3d3ce2918bc20cf1080a2b5153ddd8aaf51374b4)
- feat(RunnerOrganizationService.runnerOrganizationControllerGetRunners): load all runners in org [`7c10d95`](https://git.odit.services/lfk/frontend/commit/7c10d95c1c68f4842fd323698e004a5ebf2c96cf)
- wip [`050a146`](https://git.odit.services/lfk/frontend/commit/050a146ae070d67d8308db4b9612fd6eacbb9923)
- fix(ci): Correct tag pattern syntax in release workflow [`e567bb3`](https://git.odit.services/lfk/frontend/commit/e567bb35c3b3f6eb73a2f0bc72f601e70f881ac8)
#### [1.7.0](https://git.odit.services/lfk/frontend/compare/1.6.0...1.7.0)
> 17 December 2024
- refactor(pdfgeneration): Switch cards over to new service [`e230984`](https://git.odit.services/lfk/frontend/commit/e23098410c7d0b326cdbbb3a4b63fed10611e252)
- refactor(pdfgeneration): Switch to new document-server api [`878d971`](https://git.odit.services/lfk/frontend/commit/878d9714cbc0a60cfd96bd1faf8af6af46e6fb5e)
- refactor(pdfgeneration): Switched contract generation over to new document-server [`f99b7f4`](https://git.odit.services/lfk/frontend/commit/f99b7f4bb8f166bb966022ddd10689c082d248f0)
- refactor(cards): Switched over to new document-server api [`65ce02e`](https://git.odit.services/lfk/frontend/commit/65ce02e777e6e9b3cfed248de680e5f292b3a639)
- 🚀RELEASE v1.7.0 [`ae056cd`](https://git.odit.services/lfk/frontend/commit/ae056cd88cb27f003845fa4534553cde841c7f99)
- fix(pdfgeneration): Added parent_group [`7f989b2`](https://git.odit.services/lfk/frontend/commit/7f989b206b16e2687d01a38da8e3ea9be0a52ba5)
#### [1.6.0](https://git.odit.services/lfk/frontend/compare/1.5.3...1.6.0)
@@ -721,7 +761,7 @@ All notable changes to this project will be documented in this file. Dates are d
- 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)
- 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)
@@ -1220,7 +1260,7 @@ All notable changes to this project will be documented in this file. Dates are d
- Removed lodash as a dependency 🗑 [`f09224d`](https://git.odit.services/lfk/frontend/commit/f09224d5c02a2c2d2f1ac221314d2c22758143ba)
- Added translation keys [`99c3050`](https://git.odit.services/lfk/frontend/commit/99c30504115b068b65a48c651091252371b180ae)
- Found a hiddeen missing key👀👀 [`00d16ef`](https://git.odit.services/lfk/frontend/commit/00d16ef59f2af3a540708cd61c195ea0ead86995)
- Bumped svelte-\* dependencies (non-dev)🔝 [`b4e7f90`](https://git.odit.services/lfk/frontend/commit/b4e7f9046c29aa45661f175f7b8cdca5d6a1a9a0)
- Bumped svelte-* dependencies (non-dev)🔝 [`b4e7f90`](https://git.odit.services/lfk/frontend/commit/b4e7f9046c29aa45661f175f7b8cdca5d6a1a9a0)
- Bumped svelte-related dev dependencies🔥 [`5204ba5`](https://git.odit.services/lfk/frontend/commit/5204ba5e24ca6e8ab0c5ad0255c54eede15a3baf)
- Bumped router [`1b9b9ed`](https://git.odit.services/lfk/frontend/commit/1b9b9ed3723b0c12ab3b65eb0d94ec8c2c16ef42)
- new license file version [CI SKIP] [`7521ad8`](https://git.odit.services/lfk/frontend/commit/7521ad8bbbb094bbe9ba723d03b3e9eb7f6a3243)
@@ -1824,7 +1864,7 @@ All notable changes to this project will be documented in this file. Dates are d
- Added drone file with pipeline for dev [`9bf21a0`](https://git.odit.services/lfk/frontend/commit/9bf21a0eeb6d32cab18dcbb55f571969773fffac)
- DataTable [`d293859`](https://git.odit.services/lfk/frontend/commit/d2938591bf157e88acfd274ff1dfd527a1ce8588)
- 🚧 move to new config based env [`2cdd1cd`](https://git.odit.services/lfk/frontend/commit/2cdd1cd96196f586abfa50ba2f2b05f99545c669)
- Dashboard - dropdown arrow change [`b27fb8c`](https://git.odit.services/lfk/frontend/commit/b27fb8c0b5532710c97947731f0725e37f13c579)
- Dashboard - dropdown arrow change [`b27fb8c`](https://git.odit.services/lfk/frontend/commit/b27fb8c0b5532710c97947731f0725e37f13c579)
- filepond integration ✅ [`ada6888`](https://git.odit.services/lfk/frontend/commit/ada68887a2e6a4a552c1d093f5ec1afaebd918d3)
- more translations [`186803f`](https://git.odit.services/lfk/frontend/commit/186803f8216c991927d8f5c8ec6aa19016267858)
- general cleanups [`428d2e2`](https://git.odit.services/lfk/frontend/commit/428d2e25790e7509c535970accbe9f79fbf6ab65)

View File

@@ -1,4 +1,4 @@
FROM registry.odit.services/hub/library/node:23.2.0-alpine3.20 AS build
FROM registry.odit.services/hub/library/node:23.10.0-alpine3.21 AS build
ARG NPM_REGISTRY_URL=https://registry.npmjs.org
WORKDIR /app

View File

@@ -13,7 +13,7 @@
<body>
<span style="display: none; visibility: hidden" id="buildinfo"
>RELEASE_INFO-1.7.0-RELEASE_INFO</span
>RELEASE_INFO-1.8.2-RELEASE_INFO</span
>
<noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/env.js"></script>

View File

@@ -1,6 +1,6 @@
{
"name": "@odit/lfk-frontend",
"version": "1.7.0",
"version": "1.8.2",
"type": "module",
"scripts": {
"i18n-order": "node order.js",
@@ -15,10 +15,10 @@
"@odit/license-exporter": "0.2.0",
"@sveltejs/vite-plugin-svelte": "2.1.1",
"auto-changelog": "2.5.0",
"autoprefixer": "10.4.20",
"postcss": "8.4.49",
"prettier": "3.3.3",
"prettier-plugin-svelte": "3.2.8",
"autoprefixer": "10.4.21",
"postcss": "8.5.3",
"prettier": "3.5.3",
"prettier-plugin-svelte": "3.3.3",
"release-it": "17.10.0",
"svelte-select": "3.17.0",
"tailwindcss": "3.4.15",
@@ -55,7 +55,7 @@
"svelte-french-toast": "1.2.0",
"svelte-i18n": "3.6.0",
"tinro": "0.6.12",
"validator": "13.12.0",
"validator": "13.15.0",
"xlsx": "0.18.5"
},
"volta": {

134
pnpm-lock.yaml generated
View File

@@ -47,8 +47,8 @@ importers:
specifier: 0.6.12
version: 0.6.12
validator:
specifier: 13.12.0
version: 13.12.0
specifier: 13.15.0
version: 13.15.0
xlsx:
specifier: 0.18.5
version: 0.18.5
@@ -63,17 +63,17 @@ importers:
specifier: 2.5.0
version: 2.5.0
autoprefixer:
specifier: 10.4.20
version: 10.4.20(postcss@8.4.49)
specifier: 10.4.21
version: 10.4.21(postcss@8.5.3)
postcss:
specifier: 8.4.49
version: 8.4.49
specifier: 8.5.3
version: 8.5.3
prettier:
specifier: 3.3.3
version: 3.3.3
specifier: 3.5.3
version: 3.5.3
prettier-plugin-svelte:
specifier: 3.2.8
version: 3.2.8(prettier@3.3.3)(svelte@3.58.0)
specifier: 3.3.3
version: 3.3.3(prettier@3.5.3)(svelte@3.58.0)
release-it:
specifier: 17.10.0
version: 17.10.0
@@ -711,10 +711,10 @@ packages:
engines: { node: ">=8.3" }
hasBin: true
autoprefixer@10.4.20:
autoprefixer@10.4.21:
resolution:
{
integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==,
integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==,
}
engines: { node: ^10 || ^12 || >=14 }
hasBin: true
@@ -791,10 +791,10 @@ packages:
}
engines: { node: ">=8" }
browserslist@4.24.2:
browserslist@4.24.4:
resolution:
{
integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==,
integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==,
}
engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 }
hasBin: true
@@ -840,10 +840,10 @@ packages:
}
engines: { node: ">=16" }
caniuse-lite@1.0.30001683:
caniuse-lite@1.0.30001707:
resolution:
{
integrity: sha512-iqmNnThZ0n70mNwvxpEC2nBJ037ZHZUoBI5Gorh1Mw6IlEAZujEoU1tXA628iZfzm7R9FvFzxbfdgml82a3k8Q==,
integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==,
}
cfb@1.2.2:
@@ -1161,10 +1161,10 @@ packages:
integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==,
}
electron-to-chromium@1.5.63:
electron-to-chromium@1.5.124:
resolution:
{
integrity: sha512-ddeXKuY9BHo/mw145axlyWjlJ1UBt4WK3AlvkT7W2AbqfRQoacVoRUCF6wL3uIx/8wT9oLKXzI+rFqHHscByaA==,
integrity: sha512-riELkpDUqBi00gqreV3RIGoowxGrfueEKBd6zPdOk/I8lvuFpBGNkYoHof3zUHbiTBsIU8oxdIIL/WNrAG1/7A==,
}
emoji-regex@10.4.0:
@@ -2146,10 +2146,10 @@ packages:
integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==,
}
nanoid@3.3.7:
nanoid@3.3.11:
resolution:
{
integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==,
integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==,
}
engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 }
hasBin: true
@@ -2192,10 +2192,10 @@ packages:
encoding:
optional: true
node-releases@2.0.18:
node-releases@2.0.19:
resolution:
{
integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==,
integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==,
}
normalize-path@3.0.0:
@@ -2486,26 +2486,26 @@ packages:
integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==,
}
postcss@8.4.49:
postcss@8.5.3:
resolution:
{
integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==,
integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==,
}
engines: { node: ^10 || ^12 || >=14 }
prettier-plugin-svelte@3.2.8:
prettier-plugin-svelte@3.3.3:
resolution:
{
integrity: sha512-PAHmmU5cGZdnhW4mWhmvxuG2PVbbHIxUuPOdUKvfE+d4Qt2d29iU5VWrPdsaW5YqVEE0nqhlvN4eoKmVMpIF3Q==,
integrity: sha512-yViK9zqQ+H2qZD1w/bH7W8i+bVfKrD8GIFjkFe4Thl6kCT9SlAsXVNmt3jCvQOCsnOhcvYgsoVlRV/Eu6x5nNw==,
}
peerDependencies:
prettier: ^3.0.0
svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0
prettier@3.3.3:
prettier@3.5.3:
resolution:
{
integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==,
integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==,
}
engines: { node: ">=14" }
hasBin: true
@@ -3101,10 +3101,10 @@ packages:
}
engines: { node: ">= 10.0.0" }
update-browserslist-db@1.1.1:
update-browserslist-db@1.1.3:
resolution:
{
integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==,
integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==,
}
hasBin: true
peerDependencies:
@@ -3130,10 +3130,10 @@ packages:
integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==,
}
validator@13.12.0:
validator@13.15.0:
resolution:
{
integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==,
integrity: sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==,
}
engines: { node: ">= 0.10" }
@@ -3655,14 +3655,14 @@ snapshots:
transitivePeerDependencies:
- encoding
autoprefixer@10.4.20(postcss@8.4.49):
autoprefixer@10.4.21(postcss@8.5.3):
dependencies:
browserslist: 4.24.2
caniuse-lite: 1.0.30001683
browserslist: 4.24.4
caniuse-lite: 1.0.30001707
fraction.js: 4.3.7
normalize-range: 0.1.2
picocolors: 1.1.1
postcss: 8.4.49
postcss: 8.5.3
postcss-value-parser: 4.2.0
balanced-match@1.0.2: {}
@@ -3707,12 +3707,12 @@ snapshots:
dependencies:
fill-range: 7.1.1
browserslist@4.24.2:
browserslist@4.24.4:
dependencies:
caniuse-lite: 1.0.30001683
electron-to-chromium: 1.5.63
node-releases: 2.0.18
update-browserslist-db: 1.1.1(browserslist@4.24.2)
caniuse-lite: 1.0.30001707
electron-to-chromium: 1.5.124
node-releases: 2.0.19
update-browserslist-db: 1.1.3(browserslist@4.24.4)
buffer@5.7.1:
dependencies:
@@ -3731,7 +3731,7 @@ snapshots:
camelcase@8.0.0: {}
caniuse-lite@1.0.30001683: {}
caniuse-lite@1.0.30001707: {}
cfb@1.2.2:
dependencies:
@@ -3892,7 +3892,7 @@ snapshots:
eastasianwidth@0.2.0: {}
electron-to-chromium@1.5.63: {}
electron-to-chromium@1.5.124: {}
emoji-regex@10.4.0: {}
@@ -4441,7 +4441,7 @@ snapshots:
object-assign: 4.1.1
thenify-all: 1.6.0
nanoid@3.3.7: {}
nanoid@3.3.11: {}
neo-async@2.6.2: {}
@@ -4457,7 +4457,7 @@ snapshots:
dependencies:
whatwg-url: 5.0.0
node-releases@2.0.18: {}
node-releases@2.0.19: {}
normalize-path@3.0.0: {}
@@ -4600,28 +4600,28 @@ snapshots:
pirates@4.0.6: {}
postcss-import@15.1.0(postcss@8.4.49):
postcss-import@15.1.0(postcss@8.5.3):
dependencies:
postcss: 8.4.49
postcss: 8.5.3
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.8
postcss-js@4.0.1(postcss@8.4.49):
postcss-js@4.0.1(postcss@8.5.3):
dependencies:
camelcase-css: 2.0.1
postcss: 8.4.49
postcss: 8.5.3
postcss-load-config@4.0.2(postcss@8.4.49):
postcss-load-config@4.0.2(postcss@8.5.3):
dependencies:
lilconfig: 3.1.2
yaml: 2.6.1
optionalDependencies:
postcss: 8.4.49
postcss: 8.5.3
postcss-nested@6.2.0(postcss@8.4.49):
postcss-nested@6.2.0(postcss@8.5.3):
dependencies:
postcss: 8.4.49
postcss: 8.5.3
postcss-selector-parser: 6.1.2
postcss-selector-parser@6.1.2:
@@ -4631,18 +4631,18 @@ snapshots:
postcss-value-parser@4.2.0: {}
postcss@8.4.49:
postcss@8.5.3:
dependencies:
nanoid: 3.3.7
nanoid: 3.3.11
picocolors: 1.1.1
source-map-js: 1.2.1
prettier-plugin-svelte@3.2.8(prettier@3.3.3)(svelte@3.58.0):
prettier-plugin-svelte@3.3.3(prettier@3.5.3)(svelte@3.58.0):
dependencies:
prettier: 3.3.3
prettier: 3.5.3
svelte: 3.58.0
prettier@3.3.3: {}
prettier@3.5.3: {}
proto-list@1.2.4: {}
@@ -4930,11 +4930,11 @@ snapshots:
normalize-path: 3.0.0
object-hash: 3.0.0
picocolors: 1.1.1
postcss: 8.4.49
postcss-import: 15.1.0(postcss@8.4.49)
postcss-js: 4.0.1(postcss@8.4.49)
postcss-load-config: 4.0.2(postcss@8.4.49)
postcss-nested: 6.2.0(postcss@8.4.49)
postcss: 8.5.3
postcss-import: 15.1.0(postcss@8.5.3)
postcss-js: 4.0.1(postcss@8.5.3)
postcss-load-config: 4.0.2(postcss@8.5.3)
postcss-nested: 6.2.0(postcss@8.5.3)
postcss-selector-parser: 6.1.2
resolve: 1.22.8
sucrase: 3.35.0
@@ -4996,9 +4996,9 @@ snapshots:
universalify@2.0.1: {}
update-browserslist-db@1.1.1(browserslist@4.24.2):
update-browserslist-db@1.1.3(browserslist@4.24.4):
dependencies:
browserslist: 4.24.2
browserslist: 4.24.4
escalade: 3.2.0
picocolors: 1.1.1
@@ -5019,12 +5019,12 @@ snapshots:
util-deprecate@1.0.2: {}
validator@13.12.0: {}
validator@13.15.0: {}
vite@4.3.3:
dependencies:
esbuild: 0.17.16
postcss: 8.4.49
postcss: 8.5.3
rollup: 3.21.0
optionalDependencies:
fsevents: 2.3.2

View File

@@ -20,7 +20,7 @@
modal_open = true;
}}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0"
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:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("add-card")}
</button>
@@ -29,7 +29,7 @@
bulk_modal_open = true;
}}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0"
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:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("create-bulk-cards")}
</button>

View File

@@ -162,7 +162,7 @@
class:opacity-50={!save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{/if}

View File

@@ -42,7 +42,7 @@
</a>
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:GET")}
<a
class:activenav={$router.path === "/runners/"}
class:activenav={$router.path.includes("/runners/")}
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900 w-full font-semibold"
href="/runners/"
>
@@ -63,7 +63,7 @@
{/if}
{#if store.state.jwtinfo.userdetails.permissions.includes("TEAM:GET")}
<a
class:activenav={$router.path === "/teams/"}
class:activenav={$router.path.includes("/teams/")}
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900 w-full font-semibold"
href="/teams/"
>

View File

@@ -193,7 +193,7 @@
class:opacity-50={!save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{/if}

View File

@@ -1,12 +1,10 @@
<script>
import { DonorService } from "@odit/lfk-client-js";
import { _ } from "svelte-i18n";
import store from "../../store";
import { DonorService, DonationService } from "@odit/lfk-client-js";
import PromiseError from "../base/PromiseError.svelte";
import isEmail from "validator/es/lib/isEmail";
import ConfirmDonorDeletion from "./ConfirmDonorDeletion.svelte";
import toast from "svelte-french-toast";
import isEmail from "validator/es/lib/isEmail";
import PromiseError from "../base/PromiseError.svelte";
let data_loaded = false;
export let params;
$: delete_triggered = false;
@@ -53,8 +51,6 @@
$: isAddress1Valid = editable.address?.address1?.trim().length !== 0;
$: iszipcodevalid = editable.address?.postalcode?.trim().length !== 0;
$: iscityvalid = editable.address?.city?.trim().length !== 0;
let modal_open = false;
let delete_donor = {};
function submit() {
if (data_loaded === true && save_enabled) {
toast($_("donor-is-being-updated"));
@@ -79,19 +75,17 @@
}
}
function deleteDonor() {
DonorService.donorControllerRemove(original_data.id, false)
DonorService.donorControllerRemove(original_data.id, true)
.then((resp) => {
toast($_("donor-deleted"));
location.replace("./");
})
.catch((err) => {
modal_open = true;
delete_donor = original_data;
console.log(err);
});
}
</script>
<ConfirmDonorDeletion bind:modal_open bind:delete_donor />
{#await promise}
{$_("loading-donor-details")}
{:then}
@@ -101,7 +95,22 @@
<nav class="w-full flex">
<ol class="list-none flex flex-row items-center justify-start">
<li class="flex items-center">
<a class="mr-2" href="./"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="inline-block"><path d="m12 19-7-7 7-7"/><path d="M19 12H5"/></svg> {$_("donors")}</a>
<a class="mr-2" href="./"
><svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="inline-block"
><path d="m12 19-7-7 7-7" /><path d="M19 12H5" /></svg
>
{$_("donors")}</a
>
</li>
</ol>
</nav>
@@ -144,7 +153,7 @@
class:opacity-50={!save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{/if}
@@ -161,7 +170,8 @@
.toLocaleString("de-DE", { valute: "EUR" })}</span
>
|
<span class="font-semibold text-gray-700">{$_("total-paid-amount")}:</span>
<span class="font-semibold text-gray-700">{$_("total-paid-amount")}:</span
>
<span
>{(editable.paidDonationAmount / 100)
.toFixed(2)
@@ -275,7 +285,9 @@
{/if}
</div>
<div class="mt-2 w-full">
<label for="phone" class="font-semibold text-gray-700">{$_("phone")}</label>
<label for="phone" class="font-semibold text-gray-700"
>{$_("phone")}</label
>
<input
autocomplete="off"
placeholder={$_("phone")}

View File

@@ -18,7 +18,7 @@
modal_open = true;
}}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0"
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:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("add-donor")}
</button>
@@ -59,7 +59,7 @@
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:w-auto sm:text-sm mt-1 sm:mt-0"
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:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("sponsoring-quittungs-liste_herunterladen")}
</button>

View File

@@ -146,7 +146,7 @@
class:opacity-50={!save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{/if}

View File

@@ -141,7 +141,7 @@
class:opacity-50={save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{:else}

View File

@@ -3,18 +3,17 @@
GroupContactService,
RunnerOrganizationService,
} from "@odit/lfk-client-js";
import { getLocaleFromNavigator, _ } from "svelte-i18n";
import toast from "svelte-french-toast";
import store from "../../store";
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
import PromiseError from "../base/PromiseError.svelte";
import { _ } from "svelte-i18n";
import { tick } from "svelte";
import Select from "svelte-select";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import store from "../../store";
import PromiseError from "../base/PromiseError.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
import { tick } from "svelte";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
$: delete_triggered = false;
$: address_valid_or_none =
(isAddress1Valid && iszipcodevalid && iscityvalid) ||
@@ -25,7 +24,6 @@
let contacts = [];
let valueCopy = null;
let areaDom;
let copied = false;
export let params;
$: editable = {};
$: contact = {};
@@ -123,7 +121,6 @@
throw new Error();
}
toast($_("copied-link-to-clipboard"));
copied = true;
} catch (err) {
toast.error($_("error-whyile-copying-to-clipboard"));
}
@@ -176,7 +173,7 @@
</div>
<div class="mb-4 text-3xl font-extrabold leading-tight">
{original_object.name} [#{params.orgid}]
<span data-id="org_actions_${editable.id}">
<div data-id="org_actions_${editable.id}">
<GenerateSponsoringContracts
bind:sponsoring_contracts_show
bind:generate_orgs
@@ -226,11 +223,11 @@
disabled={!save_enabled}
class:opacity-50={!save_enabled}
type="button"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{/if}
</span>
</div>
</div>
<div class="text-sm w-full mt-2">
<label for="name" class="font-semibold text-gray-700">{$_("name")}</label>

View File

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

View File

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

View File

@@ -178,25 +178,20 @@
</script>
{#if cards_show}
<div>
<p class="text-base">{$_("generate-runnercards")}</p>
<div class="inline-flex rounded-lg shadow-2xs">
<button
on:click={() => {
generateRunnerCards("de");
}}
class="py-3 px-4 inline-flex items-center gap-x-2 -ms-px first:rounded-s-lg first:ms-0 last:rounded-e-lg text-sm font-medium focus:z-10 border border-gray-200 bg-blue-600 text-white shadow-2xs hover:bg-blue-800 focus:outline-hidden focus:bg-blue-800 disabled:opacity-50 disabled:pointer-events-none"
>
DE
</button>
<button
on:click={() => {
generateRunnerCards("en");
}}
class="py-3 px-4 inline-flex items-center gap-x-2 -ms-px first:rounded-s-lg first:ms-0 last:rounded-e-lg text-sm font-medium focus:z-10 border border-gray-200 bg-blue-600 text-white shadow-2xs hover:bg-blue-800 focus:outline-hidden focus:bg-blue-800 disabled:opacity-50 disabled:pointer-events-none"
>
EN
</button>
</div>
</div>
<button
on:click={() => {
generateRunnerCards("de");
}}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("generate-runnercards")}: DE
</button>
<button
on:click={() => {
generateRunnerCards("en");
}}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("generate-runnercards")}: EN
</button>
{/if}

View File

@@ -156,25 +156,20 @@
</script>
{#if certificates_show}
<div>
<p class="text-base">{$_("generate-runner-certificates")}</p>
<div class="inline-flex rounded-lg shadow-2xs">
<button
on:click={() => {
generateCertificates("de");
}}
class="py-3 px-4 inline-flex items-center gap-x-2 -ms-px first:rounded-s-lg first:ms-0 last:rounded-e-lg text-sm font-medium focus:z-10 border border-gray-200 bg-blue-600 text-white shadow-2xs hover:bg-blue-800 focus:outline-hidden focus:bg-blue-800 disabled:opacity-50 disabled:pointer-events-none"
>
DE
</button>
<button
on:click={() => {
generateCertificates("en");
}}
class="py-3 px-4 inline-flex items-center gap-x-2 -ms-px first:rounded-s-lg first:ms-0 last:rounded-e-lg text-sm font-medium focus:z-10 border border-gray-200 bg-blue-600 text-white shadow-2xs hover:bg-blue-800 focus:outline-hidden focus:bg-blue-800 disabled:opacity-50 disabled:pointer-events-none"
>
EN
</button>
</div>
</div>
<button
on:click={() => {
generateCertificates("de");
}}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("generate-runner-certificates")}: DE
</button>
<button
on:click={() => {
generateCertificates("en");
}}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("generate-runner-certificates")}: EN
</button>
{/if}

View File

@@ -119,25 +119,20 @@
</script>
{#if sponsoring_contracts_show}
<div>
<p class="text-base">{$_("generate-sponsoring-contracts")}</p>
<div class="inline-flex rounded-lg shadow-2xs">
<button
on:click={() => {
generateSponsoringContract("de");
}}
class="py-3 px-4 inline-flex items-center gap-x-2 -ms-px first:rounded-s-lg first:ms-0 last:rounded-e-lg text-sm font-medium focus:z-10 border border-gray-200 bg-blue-600 text-white shadow-2xs hover:bg-blue-800 focus:outline-hidden focus:bg-blue-800 disabled:opacity-50 disabled:pointer-events-none"
>
DE
</button>
<button
on:click={() => {
generateSponsoringContract("en");
}}
class="py-3 px-4 inline-flex items-center gap-x-2 -ms-px first:rounded-s-lg first:ms-0 last:rounded-e-lg text-sm font-medium focus:z-10 border border-gray-200 bg-blue-600 text-white shadow-2xs hover:bg-blue-800 focus:outline-hidden focus:bg-blue-800 disabled:opacity-50 disabled:pointer-events-none"
>
EN
</button>
</div>
</div>
<button
on:click={() => {
generateSponsoringContract("de");
}}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("generate-sponsoring-contracts")}: DE
</button>
<button
on:click={() => {
generateSponsoringContract("en");
}}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("generate-sponsoring-contracts")}: EN
</button>
{/if}

View File

@@ -125,20 +125,8 @@
{original_data.firstname}
{original_data.middlename || ""}
{original_data.lastname} [#{params.runnerid}]
<span
class="grid md:grid-cols-3 gap-1 md:gap-2"
data-id="runner_actions_${editable.id}"
>
<span data-id="runner_actions_${editable.id}">
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:DELETE")}
<GenerateSponsoringContracts
bind:sponsoring_contracts_show
bind:generate_runners
/>
<GenerateRunnerCards bind:cards_show bind:generate_runners />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_runners
/>
<div>
{#if delete_triggered}
<button
@@ -167,10 +155,19 @@
class:opacity-50={!save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{/if}
<GenerateSponsoringContracts
bind:sponsoring_contracts_show
bind:generate_runners
/>
<GenerateRunnerCards bind:cards_show bind:generate_runners />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_runners
/>
</div>
{/if}
</span>
@@ -259,7 +256,9 @@
{/if}
</div>
<div class="text-sm w-full mt-2">
<label for="phone" class="font-semibold text-gray-700">{$_("phone")}</label>
<label for="phone" class="font-semibold text-gray-700"
>{$_("phone")}</label
>
<input
autocomplete="off"
placeholder={$_("phone")}

View File

@@ -1,60 +1,317 @@
<script>
import { _ } from "svelte-i18n";
import store from "../../store";
import AddRunnerModal from "./AddRunnerModal.svelte";
import ImportRunnerModal from "./ImportRunnerModal.svelte";
import RunnersOverview from "./RunnersOverview.svelte";
$: current_runners = [];
export let modal_open = false;
export let import_modal_open = false;
let addRunners;
import {
RunnerOrganizationService,
RunnerService,
RunnerTeamService,
} from "@odit/lfk-client-js";
import {
createSvelteTable,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
renderComponent,
} from "@tanstack/svelte-table";
import { onMount } from "svelte";
import { writable } from "svelte/store";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import InputElement from "../shared/InputElement.svelte";
import TableActions from "../shared/TableActions.svelte";
import { groupFilter } from "../shared/tablefilters";
import DeleteRunnerModal from "./DeleteRunnerModal.svelte";
import TableBottom from "../shared/TableBottom.svelte";
import TableHeader from "../shared/TableHeader.svelte";
$: selectedRunners =
$table?.getSelectedRowModel().rows.map((row) => row.original) || [];
$: selected =
$table?.getSelectedRowModel().rows.map((row) => row.index) || [];
$: active_delete = undefined;
let dataLoaded = false;
export let current_runners = [];
$: sponsoring_contracts_show = selected.length > 0;
$: cards_show = selected.length > 0;
$: certificates_show = selected.length > 0;
$: teams = [];
$: orgs = [];
export const addRunners = (runners) => {
current_runners = current_runners.concat(...runners);
options.update((options) => ({
...options,
data: current_runners,
}));
};
//Section table
const columns = [
{
accessorKey: "id",
header: () => "id",
filterFn: `equalsString`,
},
{
accessorKey: "firstname",
header: () => $_("first-name"),
filterFn: `includesString`,
},
{
accessorKey: "middlename",
header: () => $_("middle-name"),
cell: (info) => {
if (!info || !info.getValue()) {
return "";
}
return info.getValue();
},
filterFn: `includesString`,
},
{
accessorKey: "lastname",
header: () => $_("last-name"),
filterFn: `includesString`,
},
{
accessorKey: "group",
header: () => $_("group"),
cell: (info) => {
const group = info.getValue();
if (group.responseType === "RUNNERORGANIZATION") {
return group.name;
}
return `${group.parentGroup.name} > ${group.name}`;
},
filterFn: `group`,
},
{
accessorKey: "distance",
header: () => $_("distance"),
cell: (info) => {
if (info.getValue() < 1000) {
return `${info.getValue()} m`;
}
return `${(info.getValue() / 1000).toFixed(1)} km`;
},
enableColumnFilter: false,
},
{
accessorKey: "actions",
header: () => $_("action"),
cell: (info) => {
return renderComponent(TableActions, {
detailsLink: `./${info.row.original.id}`,
deleteAction: () => {
active_delete =
current_runners[
current_runners.findIndex((r) => r.id == info.row.original.id)
];
},
deleteEnabled:
store.state.jwtinfo.userdetails.permissions.includes(
"RUNNER:DELETE"
),
});
},
enableColumnFilter: false,
enableSorting: false,
},
];
const options = writable({
data: [],
columns: columns,
filterFns: {
group: groupFilter,
},
initialState: {
pagination: {
pageSize: 50,
},
},
enableRowSelection: true,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
});
const table = createSvelteTable(options);
async function deleteRunner(delete_runner_id) {
await RunnerService.runnerControllerRemove(delete_runner_id, true);
current_runners = current_runners.filter((r) => r.id !== delete_runner_id);
options.update((options) => ({
...options,
data: current_runners,
}));
toast($_("runner-deleted"));
}
onMount(async () => {
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
teams = val;
});
RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
(val) => {
orgs = val;
}
);
let page = 0;
while (page >= 0) {
const runners = await RunnerService.runnerControllerGetAll(page, 500);
if (runners.length == 0) {
page = -2;
}
current_runners = current_runners.concat(...runners);
options.update((options) => ({
...options,
data: current_runners,
}));
dataLoaded = true;
page++;
}
});
import { _ } from "svelte-i18n";
import store from "../../store";
import AddRunnerModal from "./AddRunnerModal.svelte";
import ImportRunnerModal from "./ImportRunnerModal.svelte";
$: current_runners = [];
export let modal_open = false;
export let import_modal_open = false;
</script>
<section class="container p-5">
<h4 class="mb-1 text-3xl font-extrabold leading-tight">
{$_("runners")}
</h4>
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:CREATE")}
<button
on:click={() => {
modal_open = true;
}}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0"
>
{$_("laeufer-hinzufuegen")}
</button>
<button
on:click={() => {
import_modal_open = true;
}}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0"
>
{$_("import-runners")}
</button>
{/if}
<RunnersOverview bind:current_runners bind:addRunners />
<h4 class="mb-1 text-3xl font-extrabold leading-tight">
{$_("runners")}
</h4>
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:CREATE")}
<button
on:click={() => {
modal_open = true;
}}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("laeufer-hinzufuegen")}
</button>
<button
on:click={() => {
import_modal_open = true;
}}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("import-runners")}
</button>
{/if}
<DeleteRunnerModal
delete_runner={active_delete}
modal_open={active_delete != undefined}
on:delete={(event) => {
deleteRunner(event.detail.id);
}}
/>
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:GET")}
{#if !dataLoaded}
<div
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
role="alert"
>
<p class="font-bold">{$_("runners-are-being-loaded")}</p>
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
</div>
{:else}
<GenerateSponsoringContracts
bind:sponsoring_contracts_show
bind:generate_runners={selectedRunners}
/>
<GenerateRunnerCards
bind:cards_show
bind:generate_runners={selectedRunners}
/>
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_runners={selectedRunners}
/>
<div class="overflow-x-auto">
<table class="w-full">
<thead class="border-b border-gray-400">
{#each $table.getHeaderGroups() as headerGroup}
<tr class="select-none">
<th class="inset-y-0 left-0 px-4 py-2 text-left w-px">
<InputElement
type="checkbox"
checked={$table.getIsAllRowsSelected()}
indeterminate={$table.getIsSomeRowsSelected()}
on:change={() => $table.toggleAllRowsSelected()}
/>
</th>
{#each headerGroup.headers as header}
<TableHeader {header} />
{/each}
</tr>
{/each}
</thead>
<tbody>
{#each $table.getRowModel().rows as row}
<tr class="odd:bg-white even:bg-gray-100">
<td class="inset-y-0 left-0 px-4 py-2 text-center w-px">
<InputElement
type="checkbox"
checked={row.getIsSelected()}
on:change={() => row.toggleSelected()}
/>
</td>
{#each row.getVisibleCells() as cell}
<td>
<svelte:component
this={flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
/>
</td>
{/each}
</tr>
{/each}
</tbody>
</table>
</div>
<div class="h-2" />
{/if}
{/if}
<TableBottom {table} {selected} />
</section>
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:CREATE")}
<AddRunnerModal
bind:modal_open
on:created={(event) => {
addRunners(event.detail.runners);
}}
/>
<ImportRunnerModal
on:cancelDelete={(event) => {
import_modal_open = false;
}}
passed_team={{}}
passed_orgs={[]}
passed_org={{}}
opened_from="RunnerOverview"
bind:import_modal_open
on:created={(event) => {
addRunners(event.detail.runners);
}}
/>
<AddRunnerModal
bind:modal_open
on:created={(event) => {
addRunners(event.detail.runners);
}}
/>
<ImportRunnerModal
on:cancelDelete={(event) => {
import_modal_open = false;
}}
passed_team={{}}
passed_orgs={[]}
passed_org={{}}
opened_from="RunnerOverview"
bind:import_modal_open
on:created={(event) => {
addRunners(event.detail.runners);
}}
/>
{/if}
<style>
table tbody tr td:nth-child(2) {
font-family: monospace;
}
</style>

View File

@@ -1,267 +0,0 @@
<script>
import {
RunnerOrganizationService,
RunnerService,
RunnerTeamService,
} from "@odit/lfk-client-js";
import {
createSvelteTable,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
renderComponent,
} from "@tanstack/svelte-table";
import { onMount } from "svelte";
import { _ } from "svelte-i18n";
import { writable } from "svelte/store";
import store from "../../store";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import InputElement from "../shared/InputElement.svelte";
import TableActions from "../shared/TableActions.svelte";
import { groupFilter } from "../shared/tablefilters";
import DeleteRunnerModal from "./DeleteRunnerModal.svelte";
import TableBottom from "../shared/TableBottom.svelte";
import TableHeader from "../shared/TableHeader.svelte";
$: selectedRunners =
$table?.getSelectedRowModel().rows.map((row) => row.original) || [];
$: selected =
$table?.getSelectedRowModel().rows.map((row) => row.index) || [];
$: active_delete = undefined;
let dataLoaded = false;
export let current_runners = [];
$: sponsoring_contracts_show = selected.length > 0;
$: cards_show = selected.length > 0;
$: certificates_show = selected.length > 0;
$: teams = [];
$: orgs = [];
export const addRunners = (runners) => {
current_runners = current_runners.concat(...runners);
options.update((options) => ({
...options,
data: current_runners,
}));
};
//Section table
const columns = [
{
accessorKey: "id",
header: () => "id",
filterFn: `equalsString`,
},
{
accessorKey: "firstname",
header: () => $_("first-name"),
filterFn: `includesString`,
},
{
accessorKey: "middlename",
header: () => $_("middle-name"),
cell: (info) => {
if (!info || !info.getValue()) {
return "";
}
return info.getValue();
},
filterFn: `includesString`,
},
{
accessorKey: "lastname",
header: () => $_("last-name"),
filterFn: `includesString`,
},
{
accessorKey: "group",
header: () => $_("group"),
cell: (info) => {
const group = info.getValue();
if (group.responseType === "RUNNERORGANIZATION") {
return group.name;
}
return `${group.parentGroup.name} > ${group.name}`;
},
filterFn: `group`,
},
{
accessorKey: "distance",
header: () => $_("distance"),
cell: (info) => {
if (info.getValue() < 1000) {
return `${info.getValue()} m`;
}
return `${(info.getValue() / 1000).toFixed(1)} km`;
},
enableColumnFilter: false,
},
{
accessorKey: "actions",
header: () => $_("action"),
cell: (info) => {
return renderComponent(TableActions, {
detailsLink: `./${info.row.original.id}`,
deleteAction: () => {
active_delete =
current_runners[
current_runners.findIndex((r) => r.id == info.row.original.id)
];
},
deleteEnabled:
store.state.jwtinfo.userdetails.permissions.includes(
"RUNNER:DELETE"
),
});
},
enableColumnFilter: false,
enableSorting: false,
},
];
const options = writable({
data: [],
columns: columns,
filterFns: {
group: groupFilter,
},
initialState: {
pagination: {
pageSize: 50,
},
},
enableRowSelection: true,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
});
const table = createSvelteTable(options);
async function deleteRunner(delete_runner_id) {
await RunnerService.runnerControllerRemove(delete_runner_id, true);
current_runners = current_runners.filter((r) => r.id !== delete_runner_id);
options.update((options) => ({
...options,
data: current_runners,
}));
toast($_("runner-deleted"));
}
onMount(async () => {
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
teams = val;
});
RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
(val) => {
orgs = val;
}
);
let page = 0;
while (page >= 0) {
const runners = await RunnerService.runnerControllerGetAll(page, 500);
if (runners.length == 0) {
page = -2;
}
current_runners = current_runners.concat(...runners);
options.update((options) => ({
...options,
data: current_runners,
}));
dataLoaded = true;
page++;
}
});
</script>
<DeleteRunnerModal
delete_runner={active_delete}
modal_open={active_delete != undefined}
on:delete={(event) => {
deleteRunner(event.detail.id);
}}
/>
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:GET")}
{#if !dataLoaded}
<div
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
role="alert"
>
<p class="font-bold">{$_("runners-are-being-loaded")}</p>
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
</div>
{:else}
<div class="h-12 mt-2">
<GenerateSponsoringContracts
bind:sponsoring_contracts_show
bind:generate_runners={selectedRunners}
/>
<GenerateRunnerCards
bind:cards_show
bind:generate_runners={selectedRunners}
/>
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_runners={selectedRunners}
/>
</div>
<div class="overflow-x-auto">
<table class="w-full">
<thead class="border-b border-gray-400">
{#each $table.getHeaderGroups() as headerGroup}
<tr class="select-none">
<th class="inset-y-0 left-0 px-4 py-2 text-left w-px">
<InputElement
type="checkbox"
checked={$table.getIsAllRowsSelected()}
indeterminate={$table.getIsSomeRowsSelected()}
on:change={() => $table.toggleAllRowsSelected()}
/>
</th>
{#each headerGroup.headers as header}
<TableHeader {header} />
{/each}
</tr>
{/each}
</thead>
<tbody>
{#each $table.getRowModel().rows as row}
<tr class="odd:bg-white even:bg-gray-100">
<td class="inset-y-0 left-0 px-4 py-2 text-center w-px">
<InputElement
type="checkbox"
checked={row.getIsSelected()}
on:change={() => row.toggleSelected()}
/>
</td>
{#each row.getVisibleCells() as cell}
<td>
<svelte:component
this={flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
/>
</td>
{/each}
</tr>
{/each}
</tbody>
</table>
</div>
<div class="h-2" />
{/if}
{/if}
<TableBottom {table} {selected} />
<style>
table tbody tr td:nth-child(2) {
font-family: monospace;
}
</style>

View File

@@ -169,7 +169,7 @@
class:opacity-50={!save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{/if}

View File

@@ -125,7 +125,7 @@
class:opacity-50={!save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{/if}

View File

@@ -161,7 +161,7 @@
disabled={!save_enabled}
class:opacity-50={!save_enabled}
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("save-changes")}
</button>
@@ -225,7 +225,7 @@
disabled={!update_password_enabled}
class:opacity-50={!update_password_enabled}
on:click={changePassword}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>
{$_("update-password")}
</button>

View File

@@ -112,71 +112,24 @@
<div class="w-full">
<nav class="w-full flex">
<ol class="list-none flex flex-row items-center justify-start">
<li class="mr-2 flex items-center">
<svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="h-3 w-3 stroke-current"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
<polyline points="9 22 9 12 15 12 15 22" /></svg
>
</li>
<li class="flex items-center">
<a class="mr-2" href="/">Home</a><svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="h-3 w-3 mr-2 stroke-current"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
><line x1="5" y1="12" x2="19" y2="12" />
<polyline points="12 5 19 12 12 19" /></svg
<a class="mr-2" href="./"
><svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="inline-block"
><path d="m12 19-7-7 7-7" /><path d="M19 12H5" /></svg
>
{$_("teams")}</a
>
</li>
<li class="mr-2 flex items-center">
<svg
class="flex-shrink-0 w-5 h-5 mr-2"
fill="currentColor"
width="24"
height="24"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 640 512"
><path
fill="currentColor"
d="M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z"
/></svg
>
</li>
<li class="flex items-center">
<a class="mr-2" href="./">Teams</a><svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="h-3 w-3 mr-2 stroke-current"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
><line x1="5" y1="12" x2="19" y2="12" />
<polyline points="12 5 19 12 12 19" /></svg
>
</li>
<li class="flex items-center">
<span class="mr-2">Team-Details #{params.teamid}</span>
</li>
</ol>
</nav>
</div>
@@ -185,8 +138,8 @@
{#if group}
{group.label}{" > "}
{/if}
{original.name}
<span data-id="org_actions_${teamdata.id}">
{original.name} [#{params.teamid}]
<div data-id="org_actions_${teamdata.id}">
<GenerateSponsoringContracts
bind:sponsoring_contracts_show
bind:generate_teams
@@ -239,11 +192,11 @@
disabled={!save_enabled}
class:opacity-50={!save_enabled}
type="button"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{/if}
</span>
</div>
</div>
<div class="text-sm w-full mt-2">
<label for="name" class="font-semibold text-gray-700">Name</label>

View File

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

View File

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

View File

@@ -172,7 +172,7 @@
class:opacity-50={!save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{/if}

View File

@@ -150,7 +150,7 @@
class:opacity-50={save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
>{$_("save-changes")}</button
>
{:else}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
module.exports = {
darkMode: 'selector',
mode: "jit",
content: ["./src/**/*.svelte"],
theme: {

118
yarn.lock
View File

@@ -184,6 +184,13 @@ __metadata:
languageName: node
linkType: hard
"@fontsource/athiti@npm:^5.2.5":
version: 5.2.5
resolution: "@fontsource/athiti@npm:5.2.5"
checksum: 10c0/df7dfd1a200f8644698c4a1167208106d52663e622f0fe7654f6381dc029438cd2189780fdd0f8cb3f557717d2e2bbbaf2e6d13d01c1122682927d69d782d28d
languageName: node
linkType: hard
"@formatjs/ecma402-abstract@npm:1.11.4":
version: 1.11.4
resolution: "@formatjs/ecma402-abstract@npm:1.11.4"
@@ -495,21 +502,22 @@ __metadata:
version: 0.0.0-use.local
resolution: "@odit/lfk-frontend@workspace:."
dependencies:
"@fontsource/athiti": "npm:^5.2.5"
"@odit/lfk-client-js": "npm:1.1.3"
"@odit/license-exporter": "npm:0.2.0"
"@paralleldrive/cuid2": "npm:2.2.2"
"@sveltejs/vite-plugin-svelte": "npm:2.1.1"
"@tanstack/svelte-table": "npm:8.9.1"
auto-changelog: "npm:2.5.0"
autoprefixer: "npm:10.4.20"
autoprefixer: "npm:10.4.21"
bwip-js: "npm:3.4.0"
check-password-strength: "npm:2.0.10"
csvtojson: "npm:2.0.10"
localforage: "npm:1.10.0"
marked: "npm:4.3.0"
postcss: "npm:8.4.49"
prettier: "npm:3.3.3"
prettier-plugin-svelte: "npm:3.2.8"
postcss: "npm:8.5.3"
prettier: "npm:3.5.3"
prettier-plugin-svelte: "npm:3.3.3"
release-it: "npm:17.10.0"
svelte: "npm:3.58.0"
svelte-french-toast: "npm:1.2.0"
@@ -517,7 +525,7 @@ __metadata:
svelte-select: "npm:3.17.0"
tailwindcss: "npm:3.4.15"
tinro: "npm:0.6.12"
validator: "npm:13.12.0"
validator: "npm:13.15.0"
vite: "npm:4.3.3"
xlsx: "npm:0.18.5"
languageName: unknown
@@ -782,21 +790,21 @@ __metadata:
languageName: node
linkType: hard
"autoprefixer@npm:10.4.20":
version: 10.4.20
resolution: "autoprefixer@npm:10.4.20"
"autoprefixer@npm:10.4.21":
version: 10.4.21
resolution: "autoprefixer@npm:10.4.21"
dependencies:
browserslist: "npm:^4.23.3"
caniuse-lite: "npm:^1.0.30001646"
browserslist: "npm:^4.24.4"
caniuse-lite: "npm:^1.0.30001702"
fraction.js: "npm:^4.3.7"
normalize-range: "npm:^0.1.2"
picocolors: "npm:^1.0.1"
picocolors: "npm:^1.1.1"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
postcss: ^8.1.0
bin:
autoprefixer: bin/autoprefixer
checksum: 10c0/e1f00978a26e7c5b54ab12036d8c13833fad7222828fc90914771b1263f51b28c7ddb5803049de4e77696cbd02bb25cfc3634e80533025bb26c26aacdf938940
checksum: 10c0/de5b71d26d0baff4bbfb3d59f7cf7114a6030c9eeb66167acf49a32c5b61c68e308f1e0f869d92334436a221035d08b51cd1b2f2c4689b8d955149423c16d4d4
languageName: node
linkType: hard
@@ -897,17 +905,17 @@ __metadata:
languageName: node
linkType: hard
"browserslist@npm:^4.23.3":
version: 4.24.2
resolution: "browserslist@npm:4.24.2"
"browserslist@npm:^4.24.4":
version: 4.24.4
resolution: "browserslist@npm:4.24.4"
dependencies:
caniuse-lite: "npm:^1.0.30001669"
electron-to-chromium: "npm:^1.5.41"
node-releases: "npm:^2.0.18"
caniuse-lite: "npm:^1.0.30001688"
electron-to-chromium: "npm:^1.5.73"
node-releases: "npm:^2.0.19"
update-browserslist-db: "npm:^1.1.1"
bin:
browserslist: cli.js
checksum: 10c0/d747c9fb65ed7b4f1abcae4959405707ed9a7b835639f8a9ba0da2911995a6ab9b0648fd05baf2a4d4e3cf7f9fdbad56d3753f91881e365992c1d49c8d88ff7a
checksum: 10c0/db7ebc1733cf471e0b490b4f47e3e2ea2947ce417192c9246644e92c667dd56a71406cc58f62ca7587caf828364892e9952904a02b7aead752bc65b62a37cfe9
languageName: node
linkType: hard
@@ -980,10 +988,10 @@ __metadata:
languageName: node
linkType: hard
"caniuse-lite@npm:^1.0.30001646, caniuse-lite@npm:^1.0.30001669":
version: 1.0.30001684
resolution: "caniuse-lite@npm:1.0.30001684"
checksum: 10c0/446485ca3d9caf408a339a44636a86a2b119ec247492393ae661cd93dccd6668401dd2dfec1e149be4e44563cd1e23351b44453a52fa2c2f19e2bf3287c865f6
"caniuse-lite@npm:^1.0.30001688, caniuse-lite@npm:^1.0.30001702":
version: 1.0.30001707
resolution: "caniuse-lite@npm:1.0.30001707"
checksum: 10c0/a1beaf84bad4f6617bbc5616d6bc0c9cab73e73f7e9e09b6466af5195b1bc393e0f6f19643d7a1c88bd3f4bfa122d7bea81cf6225ec3ade57d5b1dd3478c1a1b
languageName: node
linkType: hard
@@ -1387,10 +1395,10 @@ __metadata:
languageName: node
linkType: hard
"electron-to-chromium@npm:^1.5.41":
version: 1.5.65
resolution: "electron-to-chromium@npm:1.5.65"
checksum: 10c0/4d2db76ca63d34aad9d5392d850a89fecb4d740a3f0e3ab945f23850ed99789df4e09dd36a28cedcf3b4757dd7c82d5d159bfdf1d29f815d172a9132b4ba3bb9
"electron-to-chromium@npm:^1.5.73":
version: 1.5.124
resolution: "electron-to-chromium@npm:1.5.124"
checksum: 10c0/f27de21f8763836daf5593bbedb8b78f41e88519aa27d3232e9f3e34b0a0fd5aee9cc37a31c3a36d2fa32291827738e996e866ad8ceb479e4c45bc0ee396ecba
languageName: node
linkType: hard
@@ -2944,6 +2952,15 @@ __metadata:
languageName: node
linkType: hard
"nanoid@npm:^3.3.8":
version: 3.3.11
resolution: "nanoid@npm:3.3.11"
bin:
nanoid: bin/nanoid.cjs
checksum: 10c0/40e7f70b3d15f725ca072dfc4f74e81fcf1fbb02e491cf58ac0c79093adc9b0a73b152bcde57df4b79cd097e13023d7504acb38404a4da7bc1cd8e887b82fe0b
languageName: node
linkType: hard
"negotiator@npm:^0.6.3":
version: 0.6.4
resolution: "negotiator@npm:0.6.4"
@@ -3015,10 +3032,10 @@ __metadata:
languageName: node
linkType: hard
"node-releases@npm:^2.0.18":
version: 2.0.18
resolution: "node-releases@npm:2.0.18"
checksum: 10c0/786ac9db9d7226339e1dc84bbb42007cb054a346bd9257e6aa154d294f01bc6a6cddb1348fa099f079be6580acbb470e3c048effd5f719325abd0179e566fd27
"node-releases@npm:^2.0.19":
version: 2.0.19
resolution: "node-releases@npm:2.0.19"
checksum: 10c0/52a0dbd25ccf545892670d1551690fe0facb6a471e15f2cfa1b20142a5b255b3aa254af5f59d6ecb69c2bec7390bc643c43aa63b13bf5e64b6075952e716b1aa
languageName: node
linkType: hard
@@ -3325,7 +3342,7 @@ __metadata:
languageName: node
linkType: hard
"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1":
"picocolors@npm:^1.0.0, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1":
version: 1.1.1
resolution: "picocolors@npm:1.1.1"
checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
@@ -3423,7 +3440,18 @@ __metadata:
languageName: node
linkType: hard
"postcss@npm:8.4.49, postcss@npm:^8.4.23, postcss@npm:^8.4.47":
"postcss@npm:8.5.3":
version: 8.5.3
resolution: "postcss@npm:8.5.3"
dependencies:
nanoid: "npm:^3.3.8"
picocolors: "npm:^1.1.1"
source-map-js: "npm:^1.2.1"
checksum: 10c0/b75510d7b28c3ab728c8733dd01538314a18c52af426f199a3c9177e63eb08602a3938bfb66b62dc01350b9aed62087eabbf229af97a1659eb8d3513cec823b3
languageName: node
linkType: hard
"postcss@npm:^8.4.23, postcss@npm:^8.4.47":
version: 8.4.49
resolution: "postcss@npm:8.4.49"
dependencies:
@@ -3434,22 +3462,22 @@ __metadata:
languageName: node
linkType: hard
"prettier-plugin-svelte@npm:3.2.8":
version: 3.2.8
resolution: "prettier-plugin-svelte@npm:3.2.8"
"prettier-plugin-svelte@npm:3.3.3":
version: 3.3.3
resolution: "prettier-plugin-svelte@npm:3.3.3"
peerDependencies:
prettier: ^3.0.0
svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0
checksum: 10c0/aa5d8f3777911cf14ac920aaf74cbefa47b71cdb06279ea7eecab92cd7964f928ff3e213cf3194f30ffc3d4d1621c94eee97717a2c0cfc906cefc4e9e191aff6
checksum: 10c0/5e0a73d7ef2385dc26bbc2c679dd3c2d6a5b73eb32b6aab5cafde816eff7de91c4d32f4fb192ef37a21345ca3dd94e6a9e31c8ad4ee34a797d78bc7da8f76216
languageName: node
linkType: hard
"prettier@npm:3.3.3":
version: 3.3.3
resolution: "prettier@npm:3.3.3"
"prettier@npm:3.5.3":
version: 3.5.3
resolution: "prettier@npm:3.5.3"
bin:
prettier: bin/prettier.cjs
checksum: 10c0/b85828b08e7505716324e4245549b9205c0cacb25342a030ba8885aba2039a115dbcf75a0b7ca3b37bc9d101ee61fab8113fc69ca3359f2a226f1ecc07ad2e26
checksum: 10c0/3880cb90b9dc0635819ab52ff571518c35bd7f15a6e80a2054c05dbc8a3aa6e74f135519e91197de63705bcb38388ded7e7230e2178432a1468005406238b877
languageName: node
linkType: hard
@@ -4362,10 +4390,10 @@ __metadata:
languageName: node
linkType: hard
"validator@npm:13.12.0":
version: 13.12.0
resolution: "validator@npm:13.12.0"
checksum: 10c0/21d48a7947c9e8498790550f56cd7971e0e3d724c73388226b109c1bac2728f4f88caddfc2f7ed4b076f9b0d004316263ac786a17e9c4edf075741200718cd32
"validator@npm:13.15.0":
version: 13.15.0
resolution: "validator@npm:13.15.0"
checksum: 10c0/0f13fd7031ac575e8d7828431da8ef5859bac6a38ee65e1d7fdd367dbf1c3d94d95182aecc3183f7fa7a30ff4474bf864d1aff54707620227a2cdbfd36d894c2
languageName: node
linkType: hard