Compare commits

...

61 Commits

Author SHA1 Message Date
4debab2636 Merge branch 'dev' into feature/13-runner-management
# Conflicts:
#	package.json
2021-01-24 20:39:11 +01:00
b30b6734a1 general dependency bump
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 20:38:29 +01:00
dadb80608a 💣 process breaking changes for lib v0.3.0
Some checks failed
continuous-integration/drone/push Build is failing
2021-01-24 20:37:56 +01:00
16c9969fb9 Merge branch 'feature/13-runner-management' of https://git.odit.services/lfk/frontend into feature/13-runner-management 2021-01-24 18:41:04 +01:00
dc1644ed25 🐞 ImportRunnerModal - table overflow fix
ref #13
2021-01-24 18:40:54 +01:00
2cc9b3e1ed 👀 ImportRunnerModal - layout cleanup
ref #13
2021-01-24 18:38:16 +01:00
415f340a68 i18n 🌍
ref #13
2021-01-24 18:20:48 +01:00
2d4869128d 🌎 i18n
ref #13
2021-01-24 17:54:45 +01:00
ae8bc01d9b 🌎 i18n
ref #13
2021-01-24 17:47:29 +01:00
e2552d9442 Merge branch 'dev' into feature/13-runner-management 2021-01-24 17:41:11 +01:00
5d1b5d80b6 Merge branch 'feature/13-runner-management' of https://git.odit.services/lfk/frontend into feature/13-runner-management 2021-01-24 17:31:31 +01:00
366804aa29 🌎 i18n
ref #13
2021-01-24 17:31:10 +01:00
9240e0c903 🧹 general runner cleanup
ref #13
2021-01-24 17:30:31 +01:00
7baaf2cff3 Merge branch 'feature/13-runner-management' of git.odit.services:lfk/frontend into feature/13-runner-management 2021-01-24 17:23:18 +01:00
9fbc1ba031 Added friles to ignore 2021-01-24 17:21:48 +01:00
6704c07db0 Deleted files to ignore 2021-01-24 17:21:39 +01:00
a87165148a 🧹 RunnerDetail cleanup + i18n 🌎
ref #13
2021-01-24 17:21:19 +01:00
ec4bcd093b 🐞 [bugfix] RunnerDetail update
ref #13
2021-01-24 17:16:49 +01:00
5552055b98 RunnerDetail - button text fixes
ref #13
2021-01-21 20:50:14 +01:00
03aa67034d basic RunnerDetail
ref #13
2021-01-21 19:07:43 +01:00
fc21427685 💻 updated VSCode recommended extensions
All checks were successful
continuous-integration/drone/push Build is passing
change i18n-ally scoping
2021-01-21 18:41:05 +01:00
819b02a204 ImportRunnerModal - hide team when loading from TeamDetail
ref #13
2021-01-20 20:25:41 +01:00
de0bd5fd57 ImportRunnerModal usage in TeamDetail
ref #13
2021-01-20 20:21:59 +01:00
8aa1d94a1a use ImportRunnerModal in OrgDetail + Orgs
ref #13
2021-01-20 19:59:53 +01:00
f8a59133a2 ImportRunnerModal - compatibility for multi-component access
ref #13
2021-01-20 19:59:31 +01:00
c382f770dc 👀 basic ui interaction for ImportRunnerModal
ref #13
2021-01-20 18:31:23 +01:00
cde4ec13ef basic cancel event dispatch from ImportRunnerModal
ref #13
2021-01-20 18:15:47 +01:00
ecad1ea839 ↙ added default fallback parsing to ImportRunnerModal
ref #13
2021-01-20 17:56:32 +01:00
6b91b22713 🚀 ImportRunnerModal - working demo
ref #13
2021-01-20 17:46:18 +01:00
e34c91b2cc 🌎 i18n in ImportRunnerModal headers
ref #13
2021-01-20 17:33:10 +01:00
822759a688 😦 added missing dependencies
ref #13
2021-01-19 21:45:00 +01:00
b606037890 🌎 added locale based csv/xlsx header parsing
ref #13
2021-01-19 21:44:41 +01:00
74d9b94119 basic xlsx + csv parsing
ref #13
2021-01-19 21:44:13 +01:00
b1e9f955b0 basic ImportRunnerModal with CSV input
ref #13
2021-01-19 18:19:21 +01:00
e0356fa360 fixed runner permissions
ref #13
2021-01-19 18:18:51 +01:00
fbc67eeb98 Merge branch 'dev' of https://git.odit.services/lfk/frontend into dev 2021-01-18 20:34:50 +01:00
09fd73b130 🐞 improved version builder from template 2021-01-18 20:34:47 +01:00
259a76f46b 🧹 darkmode classes cleanup 2021-01-18 20:29:44 +01:00
c6504c2eaf new license file version [CI SKIP] 2021-01-17 18:46:15 +00:00
7d104a1514 🚀RELEASE v0.4.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-17 19:45:28 +01:00
b3bd61c89e Merge branch 'feature/13-runner-management' into dev
Some checks failed
continuous-integration/drone/push Build was killed
2021-01-17 19:44:07 +01:00
e49dca0275 🐞 gitignore fix 2021-01-17 19:29:05 +01:00
03125b3a2d general dependency bumps 2021-01-17 19:24:57 +01:00
a523379b3a gitignore fix 2021-01-17 19:24:25 +01:00
aa6348a29a fix package:dev script
All checks were successful
continuous-integration/drone/push Build is passing
ref #37
2021-01-17 19:22:45 +01:00
b9f0f1a69a Merge commit 'a284806d3cb769030a4e28d0403190b746f8fc61' into dev
All checks were successful
continuous-integration/drone/push Build is passing
close #37
2021-01-17 19:18:42 +01:00
a284806d3c re-enable PWA functionality via serviceworker
ref #37
2021-01-17 19:15:22 +01:00
7e10c1db65 🔨 cleaned up build process + Dockerfile
ref #37
2021-01-17 19:14:14 +01:00
11790638d6 🔨 cleaned up build process + Dockerfile
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-17 19:01:11 +01:00
0583cbe266 improved serviceworker + PWA logic
Some checks failed
continuous-integration/drone/push Build was killed
2021-01-17 18:59:26 +01:00
2e6874c822 apply new gitignore config 2021-01-17 18:32:32 +01:00
2ce41990bf 🐞 fix cross-env logic for faster dev starts 2021-01-17 18:31:35 +01:00
c8aeba38ba Merge branch 'dev' of https://git.odit.services/lfk/frontend into dev
Some checks failed
continuous-integration/drone/push Build is failing
2021-01-17 18:22:57 +01:00
5e02502a5c 👩‍💻 developer configs/ recommendations for VSCode 2021-01-17 18:22:28 +01:00
382cc3d844 new license file version [CI SKIP] 2021-01-17 17:19:48 +00:00
dd74d9ee89 🧹 gitignore changes in public/index.html & svelte.config.js
Some checks failed
continuous-integration/drone/push Build is failing
2021-01-17 18:19:07 +01:00
383f82807f improved dev scripts for speed starts
Some checks failed
continuous-integration/drone/push Build was killed
2021-01-17 18:16:02 +01:00
d4579a9a41 dynamic contact info in AddRunnerModal
ref #13
2021-01-17 17:54:21 +01:00
66a07c6a51 RunnersOverview
ref #13
2021-01-17 17:51:03 +01:00
66ffd8e936 AddRunnerModal
ref #13
2021-01-17 17:50:52 +01:00
dccf7c6c8d PWA optimizations
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-17 15:59:28 +01:00
39 changed files with 1317 additions and 155 deletions

15
.gitignore vendored
View File

@@ -1,10 +1,11 @@
.vscode
.idea
node_modules node_modules
dist build
dist-ssr
public/env.js
/build
yarn.lock
package-lock.json package-lock.json
yarn.lock
*.map *.map
public/env.js
public/sw.js
public/index.html
public/workbox-*.js
svelte.config.js
public/index.html

13
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,13 @@
{
"recommendations": [
"2gua.rainbow-brackets",
"christian-kohler.npm-intellisense",
"remimarsal.prettier-now",
"svelte.svelte-vscode",
"lokalise.i18n-ally",
"fivethree.vscode-svelte-snippets"
],
"unwantedRecommendations": [
"antfu.i18n-ally"
]
}

4
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"i18n-ally.localesPaths": "src/locales",
"i18n-ally.keystyle": "nested"
}

View File

@@ -2,8 +2,32 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC. All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [0.4.0](https://git.odit.services/lfk/frontend/compare/0.3.1...0.4.0)
- Merge commit 'a284806d3cb769030a4e28d0403190b746f8fc61' into dev [`#37`](https://git.odit.services/lfk/frontend/issues/37)
- ✨ AddRunnerModal [`66ffd8e`](https://git.odit.services/lfk/frontend/commit/66ffd8e936010960766e7f9021319d549e1d3e6b)
- ✨ RunnersOverview [`66a07c6`](https://git.odit.services/lfk/frontend/commit/66a07c6a51674a92d5e8459f250de2ab5ff6d902)
- ⚡ improved dev scripts for speed starts [`383f828`](https://git.odit.services/lfk/frontend/commit/383f82807f4090bdd2c3dcdc695b75093b854031)
- ✨ dynamic contact info in AddRunnerModal [`d4579a9`](https://git.odit.services/lfk/frontend/commit/d4579a9a410a27676e0ed0285bd124696153aae4)
- 🐞 fix cross-env logic for faster dev starts ⚡ [`2ce4199`](https://git.odit.services/lfk/frontend/commit/2ce41990bf9911db11eb556ce4c9aa3b3e5ca16c)
- 👩‍💻 developer configs/ recommendations for VSCode [`5e02502`](https://git.odit.services/lfk/frontend/commit/5e02502a5c2b8ebf798cbc21856b4425f8510041)
- ⚡ re-enable PWA functionality via serviceworker [`a284806`](https://git.odit.services/lfk/frontend/commit/a284806d3cb769030a4e28d0403190b746f8fc61)
- 🔨 cleaned up build process + Dockerfile [`7e10c1d`](https://git.odit.services/lfk/frontend/commit/7e10c1db659c21cd737b5d1e10bf3e61c4e0de94)
- 🔨 cleaned up build process + Dockerfile [`1179063`](https://git.odit.services/lfk/frontend/commit/11790638d68e8c43f91448bd0c35f910a3d9e446)
- ⚡ improved serviceworker + PWA logic [`0583cbe`](https://git.odit.services/lfk/frontend/commit/0583cbe2664f8832c5eaa7fb155b3e6deccb2ed3)
- apply new gitignore config [`2e6874c`](https://git.odit.services/lfk/frontend/commit/2e6874c822f2f8e9a8a7b74b4765631ba08f0255)
- ⚡ PWA optimizations [`dccf7c6`](https://git.odit.services/lfk/frontend/commit/dccf7c6c8de0da0f25ad77e20822fb4fbf68a61a)
- ⏫ general dependency bumps [`03125b3`](https://git.odit.services/lfk/frontend/commit/03125b3a2d0ad4b12cffdec98f27da14f3f45f77)
- 🐞 gitignore fix [`e49dca0`](https://git.odit.services/lfk/frontend/commit/e49dca02754aa57cbe464066f11505db4a9b5ca9)
- gitignore fix [`a523379`](https://git.odit.services/lfk/frontend/commit/a523379b3a5f7f3cffecca82c0c066167da046ca)
- fix package:dev script [`aa6348a`](https://git.odit.services/lfk/frontend/commit/aa6348a29a6e9ecb9789681b7195527c4eef19e4)
- new license file version [CI SKIP] [`382cc3d`](https://git.odit.services/lfk/frontend/commit/382cc3d844bf0af7c46492907f8a9a78fadc25d0)
- 🧹 gitignore changes in public/index.html & svelte.config.js [`dd74d9e`](https://git.odit.services/lfk/frontend/commit/dd74d9ee89b80c46ce3d3347a3c7cbe34373019c)
#### [0.3.1](https://git.odit.services/lfk/frontend/compare/0.3.0...0.3.1) #### [0.3.1](https://git.odit.services/lfk/frontend/compare/0.3.0...0.3.1)
> 16 January 2021
- Merge pull request 'feature/16-org-management' (#35) from feature/16-org-management into dev [`#16`](https://git.odit.services/lfk/frontend/issues/16) - Merge pull request 'feature/16-org-management' (#35) from feature/16-org-management into dev [`#16`](https://git.odit.services/lfk/frontend/issues/16)
- 🏃‍♂️🏃‍♂️🏃‍♂️ basic UI components for team management [`d87b879`](https://git.odit.services/lfk/frontend/commit/d87b879cc3d6c771a8a9932409e39068e1b2acdb) - 🏃‍♂️🏃‍♂️🏃‍♂️ basic UI components for team management [`d87b879`](https://git.odit.services/lfk/frontend/commit/d87b879cc3d6c771a8a9932409e39068e1b2acdb)
- ✨ TeamDetail with edit,delete [`ccf09f9`](https://git.odit.services/lfk/frontend/commit/ccf09f97d5fb476113f24a9559a48bccd75fd0a5) - ✨ TeamDetail with edit,delete [`ccf09f9`](https://git.odit.services/lfk/frontend/commit/ccf09f97d5fb476113f24a9559a48bccd75fd0a5)
@@ -11,14 +35,15 @@ All notable changes to this project will be documented in this file. Dates are d
- 🔒 ConfirmOrgDeletion in OrgDetail [`d890112`](https://git.odit.services/lfk/frontend/commit/d8901126d0cc91cabe3b94a30a83f36e6288126d) - 🔒 ConfirmOrgDeletion in OrgDetail [`d890112`](https://git.odit.services/lfk/frontend/commit/d8901126d0cc91cabe3b94a30a83f36e6288126d)
- ✨ basic TeamsOverview [`597e9e1`](https://git.odit.services/lfk/frontend/commit/597e9e1ea9da7c73bdcb8ef1ae1a13dfa68ff5a3) - ✨ basic TeamsOverview [`597e9e1`](https://git.odit.services/lfk/frontend/commit/597e9e1ea9da7c73bdcb8ef1ae1a13dfa68ff5a3)
- ✨ UX - ConfirmOrgDeletion cancel event reflection in datatable [`84a9cf0`](https://git.odit.services/lfk/frontend/commit/84a9cf069a4aa0940eaacc87ea67e745deabe939) - ✨ UX - ConfirmOrgDeletion cancel event reflection in datatable [`84a9cf0`](https://git.odit.services/lfk/frontend/commit/84a9cf069a4aa0940eaacc87ea67e745deabe939)
- 🧹 Dashboard - drop header bar [`f1833f1`](https://git.odit.services/lfk/frontend/commit/f1833f13d57595c23abf29bce1a2795cbb05a116)
- 🤝 attribution/ credits for icons and illustrations [`eb0dd3f`](https://git.odit.services/lfk/frontend/commit/eb0dd3f781f739c6511588a8e153c14a39096025)
- ✨ added new empty states [`66e6cd8`](https://git.odit.services/lfk/frontend/commit/66e6cd80d39ef18a29fd8ac80fbac929bd0c4f8c)
- Merge pull request 'feature/14-team-management' (#36) from feature/14-team-management into dev [`4285168`](https://git.odit.services/lfk/frontend/commit/42851686caae69e6672f48cd7df77ee4c2e49092)
- 🐞 fix Dashboard sidebar responsiveness [`6a81e36`](https://git.odit.services/lfk/frontend/commit/6a81e369fa20f0bb2846365a45f96e91e95fe2e7) - 🐞 fix Dashboard sidebar responsiveness [`6a81e36`](https://git.odit.services/lfk/frontend/commit/6a81e369fa20f0bb2846365a45f96e91e95fe2e7)
- 🧹 Dashboard - drop header bar [`f1833f1`](https://git.odit.services/lfk/frontend/commit/f1833f13d57595c23abf29bce1a2795cbb05a116)
- ✨ AddTeamModal working [`9bb027e`](https://git.odit.services/lfk/frontend/commit/9bb027ec4c73483907d396180f739dc3a11b2404) - ✨ AddTeamModal working [`9bb027e`](https://git.odit.services/lfk/frontend/commit/9bb027ec4c73483907d396180f739dc3a11b2404)
- 🧹 TeamDetail cleanup [`7654b79`](https://git.odit.services/lfk/frontend/commit/7654b795c756ca198bad77068823032714408535) - 🧹 TeamDetail cleanup [`7654b79`](https://git.odit.services/lfk/frontend/commit/7654b795c756ca198bad77068823032714408535)
- 🚀RELEASE v0.3.1 [`64ade90`](https://git.odit.services/lfk/frontend/commit/64ade901ded75fa738c713446343a209eca89ce6)
- 🤝 attribution/ credits for icons and illustrations [`eb0dd3f`](https://git.odit.services/lfk/frontend/commit/eb0dd3f781f739c6511588a8e153c14a39096025)
- 🔒 re-enable confirmation in OrgOverview [`ce6002a`](https://git.odit.services/lfk/frontend/commit/ce6002a631dd3c140f3892c750d052e89c135653) - 🔒 re-enable confirmation in OrgOverview [`ce6002a`](https://git.odit.services/lfk/frontend/commit/ce6002a631dd3c140f3892c750d052e89c135653)
- ✨ added new empty states [`66e6cd8`](https://git.odit.services/lfk/frontend/commit/66e6cd80d39ef18a29fd8ac80fbac929bd0c4f8c)
- Merge pull request 'feature/14-team-management' (#36) from feature/14-team-management into dev [`4285168`](https://git.odit.services/lfk/frontend/commit/42851686caae69e6672f48cd7df77ee4c2e49092)
- 🧹 TeamsOverview - formatting [`6870a7f`](https://git.odit.services/lfk/frontend/commit/6870a7f9b1fce2f06182dafa502f6dc4bb818bd3) - 🧹 TeamsOverview - formatting [`6870a7f`](https://git.odit.services/lfk/frontend/commit/6870a7f9b1fce2f06182dafa502f6dc4bb818bd3)
- 🔒 ConfirmOrgDeletion in OrgOverview [`83f19a7`](https://git.odit.services/lfk/frontend/commit/83f19a7572255b5c095c68d688a963dbe3cf4a75) - 🔒 ConfirmOrgDeletion in OrgOverview [`83f19a7`](https://git.odit.services/lfk/frontend/commit/83f19a7572255b5c095c68d688a963dbe3cf4a75)
- 🧹 Team cleanups [`07f2e65`](https://git.odit.services/lfk/frontend/commit/07f2e65fc722c0328ee5a8dc4d01fc89c906fa86) - 🧹 Team cleanups [`07f2e65`](https://git.odit.services/lfk/frontend/commit/07f2e65fc722c0328ee5a8dc4d01fc89c906fa86)

View File

@@ -3,15 +3,13 @@ WORKDIR /app
RUN npm i -g pnpm RUN npm i -g pnpm
COPY package.json ./ COPY package.json ./
RUN pnpm i RUN pnpm i
COPY package.json *.config.js workbox-config.js ./ COPY package.json *.config.js workbox-config.js template-copy.js index.template.html s-config.template.js ./
COPY src ./src COPY src ./src
COPY public ./public COPY public ./public
RUN pnpm run build:sw
RUN pnpm run build RUN pnpm run build
# final image # final image
FROM alpine FROM alpine
COPY --from=0 /app/build /app COPY --from=0 /app/build /app
RUN rm -rf build/sw.js.map build/workbox-*.js.map
RUN rm -rf /app/build/_dist_/components RUN rm -rf /app/build/_dist_/components
RUN rm -rf /app/build/_dist_/locales RUN rm -rf /app/build/_dist_/locales
RUN rm -rf /app/build-manifest.json RUN rm -rf /app/build-manifest.json

View File

@@ -10,10 +10,11 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Lauf Für Kaya! - Admin" /> <meta name="description" content="Lauf Für Kaya! - Admin" />
<title>Lauf für Kaya! - Admin</title> <title>Lauf für Kaya! - Admin</title>
__TAILWIND_INSERT__
</head> </head>
<body> <body>
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.3.1-RELEASE_INFO</span> <span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.4.0-RELEASE_INFO</span>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/env.js"></script> <script src="/env.js"></script>
<script defer type="module" src="/_dist_/index.js"></script> <script defer type="module" src="/_dist_/index.js"></script>

View File

@@ -1,16 +1,19 @@
{ {
"name": "@odit/lfk-frontend", "name": "@odit/lfk-frontend",
"version": "0.3.1", "version": "0.4.0",
"scripts": { "scripts": {
"i18n-order": "node order.js", "i18n-order": "node order.js",
"dev": "snowpack dev", "dev:all": "yarn prebuild && snowpack dev",
"build": "snowpack build", "dev": "cross-env NODE_ENV_ODIT=development_fast node template-copy.js && yarn build:sw && snowpack dev",
"build": "yarn prebuild && snowpack build",
"prebuild": "cross-env NODE_ENV_ODIT=production node template-copy.js && yarn build:sw",
"build:sw": "workbox generateSW workbox-config.js", "build:sw": "workbox generateSW workbox-config.js",
"release": "release-it", "release": "release-it",
"licenses:export": "license-exporter --json -o public" "licenses:export": "license-exporter --json -o public"
}, },
"dependencies": { "dependencies": {
"@odit/lfk-client-js": "0.0.12", "@odit/lfk-client-js": "0.3.0",
"csvtojson": "^2.0.10",
"filepond": "4.25.1", "filepond": "4.25.1",
"gridjs": "3.2.2", "gridjs": "3.2.2",
"localforage": "1.9.0", "localforage": "1.9.0",
@@ -19,21 +22,23 @@
"svelte-focus-trap": "1.0.1", "svelte-focus-trap": "1.0.1",
"svelte-i18n": "3.3.0", "svelte-i18n": "3.3.0",
"tailwindcss": "2.0.2", "tailwindcss": "2.0.2",
"tinro": "0.5.6", "tinro": "0.5.8",
"toastify-js": "1.9.3", "toastify-js": "1.9.3",
"validator": "13.5.2" "validator": "13.5.2",
"xlsx": "^0.16.9"
}, },
"devDependencies": { "devDependencies": {
"@odit/license-exporter": "0.0.9", "@odit/license-exporter": "0.0.9",
"@snowpack/plugin-svelte": "3.5.1", "@snowpack/plugin-svelte": "3.5.2",
"auto-changelog": "^2.2.1", "auto-changelog": "^2.2.1",
"autoprefixer": "10.2.1", "autoprefixer": "10.2.3",
"cross-env": "^7.0.3",
"postcss": "8.2.4", "postcss": "8.2.4",
"postcss-load-config": "3.0.0", "postcss-load-config": "3.0.0",
"release-it": "^14.2.2", "release-it": "^14.2.2",
"snowpack": "3.0.10", "snowpack": "3.0.11",
"svelte": "3.31.2", "svelte": "3.31.2",
"svelte-preprocess": "4.6.1", "svelte-preprocess": "4.6.3",
"workbox-cli": "6.0.2" "workbox-cli": "6.0.2"
}, },
"release-it": { "release-it": {

File diff suppressed because one or more lines are too long

View File

@@ -1,11 +1,18 @@
{ {
"name": "Lauf für Kaya! - Admin", "name": "Lauf für Kaya! - Admin",
"short_name": "LfK!Admin", "short_name": "LfK!Admin",
"start_url": ".", "start_url": "/?utm_source=pwa",
"orientation": "portrait-primary",
"display": "standalone", "display": "standalone",
"background_color": "#fff", "background_color": "#fff",
"theme_color": "#fff", "theme_color": "#fff",
"description": "Lauf für Kaya! - Admin", "description": "Lauf für Kaya! - Admin",
"shortcuts": [
{
"name": "Users",
"url": "/users/?utm_source=pwa"
}
],
"icons": [ "icons": [
{ {
"src": "/favicon.png", "src": "/favicon.png",

View File

@@ -1,2 +0,0 @@
if(!self.define){const e=e=>{"require"!==e&&(e+=".js");let r=Promise.resolve();return i[e]||(r=new Promise((async r=>{if("document"in self){const i=document.createElement("script");i.src=e,document.head.appendChild(i),i.onload=r}else importScripts(e),r()}))),r.then((()=>{if(!i[e])throw new Error(`Module ${e} didnt register its module`);return i[e]}))},r=(r,i)=>{Promise.all(r.map(e)).then((e=>i(1===e.length?e[0]:e)))},i={require:Promise.resolve(r)};self.define=(r,s,o)=>{i[r]||(i[r]=Promise.resolve().then((()=>{let i={};const c={uri:location.origin+r.slice(1)};return Promise.all(s.map((r=>{switch(r){case"exports":return i;case"module":return c;default:return e(r)}}))).then((e=>{const r=o(...e);return i.default||(i.default=r),i}))})))}}define("./sw.js",["./workbox-c8ead010"],(function(e){"use strict";self.addEventListener("message",(e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()})),e.precacheAndRoute([{url:"favicon.ico",revision:"ba44f340afba5bb1a07f14decc15dd04"},{url:"favicon.png",revision:"07a9941cec62319578fa2a1734db9959"},{url:"favicon.svg",revision:"689d6c6fda51e359c0e5725d9e905064"},{url:"index.html",revision:"931c34f3675364dcc09411aa0f223776"},{url:"logo.svg",revision:"4c9e31a1f4268d7e36e22cda7656e561"},{url:"manifest.webmanifest",revision:"75c93eb352c4877216e77b1d7f73445f"},{url:"robots.txt",revision:"61c27d2cd39a713f7829422c3d9edcc7"}],{})}));
//# sourceMappingURL=sw.js.map

File diff suppressed because one or more lines are too long

6
s-config.template.js Normal file
View File

@@ -0,0 +1,6 @@
const sveltePreprocess = require('svelte-preprocess');
const preprocess = sveltePreprocess(__insert__);
module.exports = {
preprocess
};

View File

@@ -31,7 +31,6 @@
import Login from "./components/Login.svelte"; import Login from "./components/Login.svelte";
import Dashboard from "./components/Dashboard.svelte"; import Dashboard from "./components/Dashboard.svelte";
import store from "./store.js"; import store from "./store.js";
import NotFound from "./components/NotFound.svelte";
import ForgotPassword from "./components/ForgotPassword.svelte"; import ForgotPassword from "./components/ForgotPassword.svelte";
import MainDashContent from "./components/MainDashContent.svelte"; import MainDashContent from "./components/MainDashContent.svelte";
import Users from "./components/Users.svelte"; import Users from "./components/Users.svelte";
@@ -41,17 +40,17 @@
import Orgs from "./components/Orgs.svelte"; import Orgs from "./components/Orgs.svelte";
import Runners from "./components/Runners.svelte"; import Runners from "./components/Runners.svelte";
import Footer from "./components/Footer.svelte"; import Footer from "./components/Footer.svelte";
import Tracks from "./components/Tracks.svelte";
import TracksOverview from "./components/TracksOverview.svelte"; import TracksOverview from "./components/TracksOverview.svelte";
import OrgDetail from "./components/OrgDetail.svelte"; import OrgDetail from "./components/OrgDetail.svelte";
import Teams from "./components/Teams.svelte"; import Teams from "./components/Teams.svelte";
import { OpenAPI, AuthService } from "@odit/lfk-client-js"; import { OpenAPI } from "@odit/lfk-client-js";
import UserDetail from "./components/UserDetail.svelte"; import UserDetail from "./components/UserDetail.svelte";
OpenAPI.BASE = config.baseurl; OpenAPI.BASE = config.baseurl;
import { register as registerSW } from "./swmodule"; import { register as registerSW } from "./swmodule";
import TeamDetail from "./components/TeamDetail.svelte"; import TeamDetail from "./components/TeamDetail.svelte";
import RunnerDetail from "./components/RunnerDetail.svelte";
store.init(); store.init();
// registerSW(); registerSW();
</script> </script>
<Route> <Route>
@@ -83,8 +82,13 @@
</Route> </Route>
<Route path="/:trackid" let:params /> <Route path="/:trackid" let:params />
</Route> </Route>
<Route path="/runners"> <Route path="/runners/*">
<Runners /> <Route path="/">
<Runners />
</Route>
<Route path="/:runnerid" let:params>
<RunnerDetail {params} />
</Route>
</Route> </Route>
<Route path="/teams/*"> <Route path="/teams/*">
<Route path="/"> <Route path="/">

View File

@@ -2,7 +2,7 @@
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { clickOutside } from "./outsideclick"; import { clickOutside } from "./outsideclick";
import { focusTrap } from "svelte-focus-trap"; import { focusTrap } from "svelte-focus-trap";
import { RunnerOrganisationService } from "@odit/lfk-client-js"; import { RunnerOrganizationService } from "@odit/lfk-client-js";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
export let modal_open; export let modal_open;
export let current_organizations; export let current_organizations;
@@ -35,7 +35,7 @@
text: "Organization is being added...", text: "Organization is being added...",
duration: -1, duration: -1,
}).showToast(); }).showToast();
RunnerOrganisationService.runnerOrganisationControllerPost({ RunnerOrganizationService.runnerOrganizationControllerPost({
name, name,
address: undefined, address: undefined,
contact: undefined, contact: undefined,

View File

@@ -0,0 +1,298 @@
<script>
import { _ } from "svelte-i18n";
import { clickOutside } from "./outsideclick";
import { focusTrap } from "svelte-focus-trap";
import { RunnerService, RunnerTeamService } from "@odit/lfk-client-js";
import isEmail from "validator/es/lib/isEmail";
import isMobilePhone from "validator/es/lib/isMobilePhone";
import Toastify from "toastify-js";
export let modal_open;
export let current_runners;
$: selected_team = undefined;
let firstname_input;
let lastname_input;
let middlename_input;
let phone_input;
let email_input;
let groups = [];
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
groups = val;
});
function focus(el) {
el.focus();
}
$: middlename_input_value = "";
$: phone_input_value = "";
$: email_input_value = "";
$: lastname_input_value = "";
$: firstname_input_value = "";
$: processed_last_submit = true;
$: isPhoneValidOrEmpty =
isMobilePhone(
phone_input_value
.replaceAll("(", "")
.replaceAll(")", "")
.replaceAll("-", "")
.replaceAll(" ", "")
) || phone_input_value === "";
$: isEmailValidOrEmpty =
isEmail(email_input_value) || email_input_value === "";
$: isLastnameValid = lastname_input_value.trim().length !== 0;
$: isFirstnameValid = firstname_input_value.trim().length !== 0;
$: createbtnenabled =
isFirstnameValid &&
isLastnameValid &&
isEmailValidOrEmpty &&
isPhoneValidOrEmpty;
(() => {
document.onkeydown = (e) => {
e = e || window.event;
if (e.key === "Escape") {
modal_open = false;
}
if (e.keyCode === 13) {
if (createbtnenabled === true) {
createbtnenabled = false;
submit();
}
}
};
})();
function submit() {
if (processed_last_submit === true) {
processed_last_submit = false;
const toast = Toastify({
text: "Runner is being added...",
duration: -1,
}).showToast();
let postdata = {
group: selected_team,
firstname: firstname_input_value,
lastname: lastname_input_value,
};
if (middlename_input_value) {
postdata.middlename = middlename_input_value;
}
if (phone_input_value) {
postdata.phone = phone_input_value;
}
if (email_input_value) {
postdata.email = email_input_value;
}
RunnerService.runnerControllerPost(postdata)
.then((result) => {
firstname_input_value = "";
lastname_input_value = "";
middlename_input_value = "";
email_input_value = "";
modal_open = false;
//
Toastify({
text: "Runner added",
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
current_runners.push(result);
current_runners = current_runners;
})
.catch((err) => {
//
})
.finally(() => {
processed_last_submit = true;
//
toast.hideToast();
});
}
}
</script>
{#if modal_open}
<div
class="fixed z-10 inset-0 overflow-y-auto"
use:focusTrap
use:clickOutside
on:click_outside={() => {
modal_open = false;
}}>
<div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 opacity-75"
data-id="modal_backdrop" />
</div>
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span>
<div
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class="h-6 w-6 text-blue-600"
fill="currentColor"
width="24"
height="24"><path fill="none" d="M0 0h24v24H0z" />
<path
d="M9.83 8.79L8 9.456V13H6V8.05h.015l5.268-1.918c.244-.093.51-.14.782-.131a2.616 2.616 0 0 1 2.427 1.82c.186.583.356.977.51 1.182A4.992 4.992 0 0 0 19 11v2a6.986 6.986 0 0 1-5.402-2.547l-.581 3.297L15 15.67V23h-2v-5.986l-2.05-1.987-.947 4.298-6.894-1.215.348-1.97 4.924.868L9.83 8.79zM13.5 5.5a2 2 0 1 1 0-4 2 2 0 0 1 0 4z" /></svg>
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900">
Create a new Runner
</h3>
<div class="mt-2 mb-6">
<p class="text-sm text-gray-500">
Please provide the required information to add a new runner.
</p>
</div>
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6">
<label
for="firstname"
class="block text-sm font-medium text-gray-700">{$_('first-name')}</label>
<input
use:focus
autocomplete="off"
placeholder={$_('first-name')}
class:border-red-500={!isFirstnameValid}
class:focus:border-red-500={!isFirstnameValid}
class:focus:ring-red-500={!isFirstnameValid}
bind:value={firstname_input_value}
bind:this={firstname_input}
type="text"
name="firstname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
{#if !isFirstnameValid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
{$_('first-name-is-required')}
</span>
{/if}
</div>
<div class="col-span-6">
<label
for="trackname"
class="block text-sm font-medium text-gray-700">{$_('middle-name')}</label>
<input
autocomplete="off"
placeholder={$_('middle-name')}
bind:value={middlename_input_value}
bind:this={middlename_input}
type="text"
name="trackname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div>
<div class="col-span-6">
<label
for="lastname"
class="block text-sm font-medium text-gray-700">Last Name</label>
<input
autocomplete="off"
placeholder="Last Name"
class:border-red-500={!isLastnameValid}
class:focus:border-red-500={!isLastnameValid}
class:focus:ring-red-500={!isLastnameValid}
bind:value={lastname_input_value}
bind:this={lastname_input}
type="text"
name="lastname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
{#if !isLastnameValid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
{$_('last-name-is-required')}
</span>
{/if}
</div>
<div class="col-span-6">
<label
for="team"
class="block text-sm font-medium text-gray-700">Team</label>
<select
name="team"
bind:value={selected_team}
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
{#each groups as g}
<option value={g.id}>{g.name}</option>
{/each}
</select>
</div>
<div class="col-span-6">
<label
for="phone"
class="block text-sm font-medium text-gray-700">Phone</label>
<input
autocomplete="off"
placeholder="Phone"
class:border-red-500={!isPhoneValidOrEmpty}
class:focus:border-red-500={!isPhoneValidOrEmpty}
class:focus:ring-red-500={!isPhoneValidOrEmpty}
bind:value={phone_input_value}
bind:this={phone_input}
type="tel"
name="phone"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
{#if !isPhoneValidOrEmpty}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
the provided phone number is invalid.<br />please enter a
valid international number...
</span>
{/if}
</div>
<div class="col-span-6">
<label
for="email"
class="block text-sm font-medium text-gray-700">{$_('e-mail-adress')}</label>
<input
autocomplete="off"
placeholder={$_('e-mail-adress')}
class:border-red-500={!isEmailValidOrEmpty}
class:focus:border-red-500={!isEmailValidOrEmpty}
class:focus:ring-red-500={!isEmailValidOrEmpty}
bind:value={email_input_value}
bind:this={email_input}
type="email"
name="email"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
{#if !isEmailValidOrEmpty}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
{$_('valid-email-is-required')}
</span>
{/if}
</div>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button
disabled={!createbtnenabled}
class:opacity-50={!createbtnenabled}
on:click={submit}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
{$_('create')}
</button>
<button
on:click={() => {
modal_open = false;
}}
type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
{$_('cancel')}
</button>
</div>
</div>
</div>
</div>
{/if}

View File

@@ -3,7 +3,7 @@
import { clickOutside } from "./outsideclick"; import { clickOutside } from "./outsideclick";
import { focusTrap } from "svelte-focus-trap"; import { focusTrap } from "svelte-focus-trap";
import { import {
RunnerOrganisationService, RunnerOrganizationService,
RunnerTeamService, RunnerTeamService,
} from "@odit/lfk-client-js"; } from "@odit/lfk-client-js";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
@@ -33,7 +33,7 @@
})(); })();
$: parentGroup = undefined; $: parentGroup = undefined;
$: orgs = []; $: orgs = [];
RunnerOrganisationService.runnerOrganisationControllerGetAll().then((val) => { RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
orgs = val; orgs = val;
}); });
function submit() { function submit() {
@@ -147,7 +147,7 @@
class="block text-sm font-medium text-gray-700">{$_('organization')}</label> class="block text-sm font-medium text-gray-700">{$_('organization')}</label>
<select <select
bind:value={parentGroup} bind:value={parentGroup}
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2"> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
{#each orgs as t} {#each orgs as t}
<option value={t.id}>{t.name}</option> <option value={t.id}>{t.name}</option>
{/each} {/each}

View File

@@ -30,7 +30,7 @@
<Table /> <Table />
</div> </div>
<div <div
class="widget w-full p-4 mb-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> class="widget w-full p-4 mb-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between mb-6"> <div class="flex flex-row items-center justify-between mb-6">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-sm font-light text-grey-500">Regular</div> <div class="text-sm font-light text-grey-500">Regular</div>

View File

@@ -2,7 +2,7 @@
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { clickOutside } from "./outsideclick"; import { clickOutside } from "./outsideclick";
import { focusTrap } from "svelte-focus-trap"; import { focusTrap } from "svelte-focus-trap";
import { RunnerOrganisationService } from "@odit/lfk-client-js"; import { RunnerOrganizationService } from "@odit/lfk-client-js";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
export let modal_open; export let modal_open;
@@ -13,7 +13,7 @@
dispatch("cancelDelete", { id: delete_org.id }); dispatch("cancelDelete", { id: delete_org.id });
} }
function deleteOrg() { function deleteOrg() {
RunnerOrganisationService.runnerOrganisationControllerRemove( RunnerOrganizationService.runnerOrganizationControllerRemove(
delete_org.id, delete_org.id,
true true
) )

View File

@@ -1,4 +1,4 @@
<div class="w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> <div class="w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between mb-6"> <div class="flex flex-row items-center justify-between mb-6">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-sm font-light text-grey-500">Conversions</div> <div class="text-sm font-light text-grey-500">Conversions</div>
@@ -18,16 +18,16 @@
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<ul class="list-none"> <ul class="list-none">
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">Today</a></li> href="/">Today</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This week</a></li> href="/">This week</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This month</a></li> href="/">This month</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This year</a></li> href="/">This year</a></li>
</ul> </ul>
</div> </div>

View File

@@ -323,7 +323,7 @@
</li> </li>
</ul> </ul>
</div> </div>
<div class="main w-full bg-grey-50 text-grey-900 dark:bg-grey-900 dark:text-white"> <div class="main w-full bg-grey-50 text-grey-900">
<div class="navbar navbar-1 border-b"> <div class="navbar navbar-1 border-b">
<div class="navbar-inner w-full flex items-center justify-start"><button class="mx-4"><svg stroke="currentColor" <div class="navbar-inner w-full flex items-center justify-start"><button class="mx-4"><svg stroke="currentColor"
fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" size="20" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" size="20"
@@ -733,7 +733,7 @@
<div class="flex flex-col lg:flex-row w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4"> <div class="flex flex-col lg:flex-row w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4">
<div class="w-full lg:w-1/4"> <div class="w-full lg:w-1/4">
<div <div
class="widget w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-xs uppercase font-light text-grey-500">Users</div> <div class="text-xs uppercase font-light text-grey-500">Users</div>
@@ -751,7 +751,7 @@
</div> </div>
<div class="w-full lg:w-1/4"> <div class="w-full lg:w-1/4">
<div <div
class="widget w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-xs uppercase font-light text-grey-500">Sessions</div> <div class="text-xs uppercase font-light text-grey-500">Sessions</div>
@@ -766,7 +766,7 @@
</div> </div>
<div class="w-full lg:w-1/4"> <div class="w-full lg:w-1/4">
<div <div
class="widget w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-xs uppercase font-light text-grey-500">Bounce rate</div> <div class="text-xs uppercase font-light text-grey-500">Bounce rate</div>
@@ -783,7 +783,7 @@
</div> </div>
<div class="w-full lg:w-1/4"> <div class="w-full lg:w-1/4">
<div <div
class="widget w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-xs uppercase font-light text-grey-500">Session duration</div> <div class="text-xs uppercase font-light text-grey-500">Session duration</div>
@@ -803,7 +803,7 @@
<ConversionsChart /> <ConversionsChart />
</div> </div>
<div class="w-full lg:w-1/3"> <div class="w-full lg:w-1/3">
<div class="w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> <div class="w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between mb-6"> <div class="flex flex-row items-center justify-between mb-6">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-sm font-light text-grey-500">Sessions</div> <div class="text-sm font-light text-grey-500">Sessions</div>
@@ -823,16 +823,16 @@
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<ul class="list-none"> <ul class="list-none">
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">Today</a></li> href="/">Today</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This week</a></li> href="/">This week</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This month</a></li> href="/">This month</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This year</a></li> href="/">This year</a></li>
</ul> </ul>
</div> </div>
@@ -923,7 +923,7 @@
</div> </div>
</div> </div>
<div class="w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4"> <div class="w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4">
<div class="w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> <div class="w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between mb-6"> <div class="flex flex-row items-center justify-between mb-6">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-sm font-light text-grey-500">Users</div> <div class="text-sm font-light text-grey-500">Users</div>
@@ -1211,15 +1211,15 @@
</table> </table>
<div class="flex flex-row w-full items-center justify-around lg:justify-between my-4"> <div class="flex flex-row w-full items-center justify-around lg:justify-between my-4">
<div class="flex flex-wrap items-center justify-start space-x-2 pagination"><button <div class="flex flex-wrap items-center justify-start space-x-2 pagination"><button
class="btn btn-default bg-transparent hover:bg-grey-200 text-grey-900 dark:text-white">Next</button><button class="btn btn-default bg-transparent hover:bg-grey-200 text-grey-900">Next</button><button
class="btn btn-default bg-transparent hover:bg-grey-200 text-grey-900 dark:text-white">Last</button> class="btn btn-default bg-transparent hover:bg-grey-200 text-grey-900">Last</button>
</div><span class="hidden lg:block">Page </div><span class="hidden lg:block">Page
<!-- --> <b>1 <!-- --> <b>1
<!-- --> of <!-- --> of
<!-- -->11 <!-- -->11
</b> </b>
</span><select </span><select
class="hidden lg:block form-select text-sm bg-white dark:bg-grey-800 dark:border-grey-800 outline-none shadow-none focus:shadow-none"> class="hidden lg:block form-select text-sm bg-white outline-none shadow-none focus:shadow-none">
<option selected="" value="10">Show 10</option> <option selected="" value="10">Show 10</option>
<option value="25">Show 25</option> <option value="25">Show 25</option>
<option value="50">Show 50</option> <option value="50">Show 50</option>
@@ -1232,7 +1232,7 @@
</div> </div>
<div class="flex flex-col lg:flex-row w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4"> <div class="flex flex-col lg:flex-row w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4">
<div class="w-full lg:w-1/2"> <div class="w-full lg:w-1/2">
<div class="w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> <div class="w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between mb-6"> <div class="flex flex-row items-center justify-between mb-6">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-sm font-light text-grey-500">Project status</div> <div class="text-sm font-light text-grey-500">Project status</div>
@@ -1252,16 +1252,16 @@
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<ul class="list-none"> <ul class="list-none">
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">Today</a></li> href="/">Today</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This week</a></li> href="/">This week</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This month</a></li> href="/">This month</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This year</a></li> href="/">This year</a></li>
</ul> </ul>
</div> </div>
@@ -1336,7 +1336,7 @@
</div> </div>
</div> </div>
<div class="w-full lg:w-1/2"> <div class="w-full lg:w-1/2">
<div class="w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> <div class="w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between mb-6"> <div class="flex flex-row items-center justify-between mb-6">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-sm font-light text-grey-500">Sales</div> <div class="text-sm font-light text-grey-500">Sales</div>
@@ -1356,16 +1356,16 @@
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<ul class="list-none"> <ul class="list-none">
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">Today</a></li> href="/">Today</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This week</a></li> href="/">This week</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This month</a></li> href="/">This month</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This year</a></li> href="/">This year</a></li>
</ul> </ul>
</div> </div>
@@ -1578,7 +1578,7 @@
</div> </div>
<div class="flex flex-col lg:flex-row w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4"> <div class="flex flex-col lg:flex-row w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4">
<div class="w-full lg:w-1/3"> <div class="w-full lg:w-1/3">
<div class="w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> <div class="w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between mb-6"> <div class="flex flex-row items-center justify-between mb-6">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-sm font-light text-grey-500">Activities</div> <div class="text-sm font-light text-grey-500">Activities</div>
@@ -1598,16 +1598,16 @@
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<ul class="list-none"> <ul class="list-none">
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">Today</a></li> href="/">Today</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This week</a></li> href="/">This week</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This month</a></li> href="/">This month</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This year</a></li> href="/">This year</a></li>
</ul> </ul>
</div> </div>
@@ -1619,7 +1619,7 @@
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<div class="flex relative justify-start items-start"> <div class="flex relative justify-start items-start">
<div class="h-full w-6 absolute inset-0 flex items-center justify-center"> <div class="h-full w-6 absolute inset-0 flex items-center justify-center">
<div class="h-full w-1 bg-grey-200 dark:bg-grey-800 pointer-events-none"></div> <div class="h-full w-1 bg-grey-200 pointer-events-none"></div>
</div> </div>
<div <div
class="flex-shrink-0 w-6 h-6 rounded-full inline-flex items-center justify-center bg-blue-500 text-white relative z-10 font-medium text-sm"> class="flex-shrink-0 w-6 h-6 rounded-full inline-flex items-center justify-center bg-blue-500 text-white relative z-10 font-medium text-sm">
@@ -1636,7 +1636,7 @@
</div> </div>
<div class="flex relative justify-start items-start"> <div class="flex relative justify-start items-start">
<div class="h-full w-6 absolute inset-0 flex items-center justify-center"> <div class="h-full w-6 absolute inset-0 flex items-center justify-center">
<div class="h-full w-1 bg-grey-200 dark:bg-grey-800 pointer-events-none"></div> <div class="h-full w-1 bg-grey-200 pointer-events-none"></div>
</div> </div>
<div <div
class="flex-shrink-0 w-6 h-6 rounded-full inline-flex items-center justify-center bg-blue-500 text-white relative z-10 font-medium text-sm"> class="flex-shrink-0 w-6 h-6 rounded-full inline-flex items-center justify-center bg-blue-500 text-white relative z-10 font-medium text-sm">
@@ -1653,7 +1653,7 @@
</div> </div>
<div class="flex relative justify-start items-start"> <div class="flex relative justify-start items-start">
<div class="h-full w-6 absolute inset-0 flex items-center justify-center"> <div class="h-full w-6 absolute inset-0 flex items-center justify-center">
<div class="h-full w-1 bg-grey-200 dark:bg-grey-800 pointer-events-none"></div> <div class="h-full w-1 bg-grey-200 pointer-events-none"></div>
</div> </div>
<div <div
class="flex-shrink-0 w-6 h-6 rounded-full inline-flex items-center justify-center bg-blue-500 text-white relative z-10 font-medium text-sm"> class="flex-shrink-0 w-6 h-6 rounded-full inline-flex items-center justify-center bg-blue-500 text-white relative z-10 font-medium text-sm">
@@ -1670,7 +1670,7 @@
</div> </div>
<div class="flex relative justify-start items-start"> <div class="flex relative justify-start items-start">
<div class="h-full w-6 absolute inset-0 flex items-center justify-center"> <div class="h-full w-6 absolute inset-0 flex items-center justify-center">
<div class="h-full w-1 bg-grey-200 dark:bg-grey-800 pointer-events-none"></div> <div class="h-full w-1 bg-grey-200 pointer-events-none"></div>
</div> </div>
<div <div
class="flex-shrink-0 w-6 h-6 rounded-full inline-flex items-center justify-center bg-blue-500 text-white relative z-10 font-medium text-sm"> class="flex-shrink-0 w-6 h-6 rounded-full inline-flex items-center justify-center bg-blue-500 text-white relative z-10 font-medium text-sm">
@@ -1690,7 +1690,7 @@
</div> </div>
</div> </div>
<div class="w-full lg:w-2/3"> <div class="w-full lg:w-2/3">
<div class="w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> <div class="w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between mb-6"> <div class="flex flex-row items-center justify-between mb-6">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-sm font-light text-grey-500">To do</div> <div class="text-sm font-light text-grey-500">To do</div>
@@ -1710,16 +1710,16 @@
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<ul class="list-none"> <ul class="list-none">
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">Today</a></li> href="/">Today</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This week</a></li> href="/">This week</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This month</a></li> href="/">This month</a></li>
<li><a <li><a
class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100 dark:bg-grey-895 dark:hover:bg-grey-890" class="flex flex-row items-center justify-start h-10 w-full px-2 bg-white hover:bg-grey-100"
href="/">This year</a></li> href="/">This year</a></li>
</ul> </ul>
</div> </div>
@@ -1831,7 +1831,7 @@
</div> </div>
<form> <form>
<div class="form-element"><input type="text" value="" name="todo" <div class="form-element"><input type="text" value="" name="todo"
class="form-input text-sm bg-white dark:bg-grey-800 dark:border-grey-800" class="form-input text-sm bg-white"
placeholder="Add new..."></div> placeholder="Add new..."></div>
</form> </form>
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">

View File

@@ -0,0 +1,286 @@
<script>
import csv from "csvtojson";
import { read as readXlsx, utils as xlsx_utils } from "xlsx";
import { _ } from "svelte-i18n";
import { clickOutside } from "./outsideclick";
import { focusTrap } from "svelte-focus-trap";
import Toastify from "toastify-js";
import { ImportService } from "@odit/lfk-client-js";
import { createEventDispatcher } from "svelte";
export let opened_from;
export let passed_org;
export let passed_orgs;
export let passed_team;
export let import_modal_open;
$: searchvalue = "";
const dispatch = createEventDispatcher();
function cancelModal() {
import_modal_open = false;
dispatch("cancel");
}
(() => {
document.onkeydown = (e) => {
e = e || window.event;
if (e.key === "Escape") {
import_modal_open = false;
}
if (e.keyCode === 13) {
//
}
};
})();
let selected_org;
let files;
let recent_processed = true;
$: json_output = [];
$: {
if (files) {
if (
files[0].type ===
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
) {
const reader = new FileReader();
reader.addEventListener("load", async (e) => {
const data = new Uint8Array(e.target.result);
const out = readXlsx(data, { type: "array" });
json_output = xlsx_utils.sheet_to_json(
out.Sheets[Object.keys(out.Sheets)[0]]
);
});
reader.readAsArrayBuffer(files[0]);
} else {
const reader = new FileReader();
reader.addEventListener("load", async (e) => {
json_output = await csv({
delimiter: [";", ","],
trim: true,
}).fromString(e.target.result);
});
reader.readAsText(files[0]);
}
}
}
function importAction() {
if (recent_processed === true) {
const toast = Toastify({
text: "Runners are being imported...",
duration: -1,
}).showToast();
recent_processed = false;
const mapped = json_output.map(function (runner) {
return {
firstname: runner[`${$_("csv_import__firstname")}`],
middlename: runner[`${$_("csv_import__middlename")}`],
lastname: runner[`${$_("csv_import__lastname")}`],
team:
runner[`${$_("csv_import__team")}`] ||
runner[`${$_("csv_import__class")}`],
};
});
let org = 0;
if (opened_from === "OrgDetail") {
org = passed_org.id;
}
if (opened_from === "OrgOverview") {
org = parseInt(selected_org);
}
if (opened_from === "OrgOverview" || opened_from === "OrgDetail") {
ImportService.importControllerPostOrgsJson(org, mapped)
.then((resp) => {
toast.hideToast();
recent_processed = true;
Toastify({
text: "Import finished",
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
cancelModal();
})
.catch((err) => {
toast.hideToast();
recent_processed = true;
});
}
if (opened_from === "TeamDetail") {
ImportService.importControllerPostTeamsJson(passed_team.id, mapped)
.then((resp) => {
toast.hideToast();
recent_processed = true;
Toastify({
text: "Import finished",
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
cancelModal();
})
.catch((err) => {
toast.hideToast();
recent_processed = true;
});
}
}
}
</script>
{#if import_modal_open}
<div
class="fixed z-10 inset-0 overflow-y-auto"
use:focusTrap
use:clickOutside
on:click_outside={() => {
import_modal_open = false;
}}>
<div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 opacity-75"
data-id="modal_backdrop" />
</div>
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span>
<div
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class="h-6 w-6 text-blue-600"
fill="currentColor"
width="24"
height="24"><path fill="none" d="M0 0h24v24H0z" />
<path
d="M9.83 8.79L8 9.456V13H6V8.05h.015l5.268-1.918c.244-.093.51-.14.782-.131a2.616 2.616 0 0 1 2.427 1.82c.186.583.356.977.51 1.182A4.992 4.992 0 0 0 19 11v2a6.986 6.986 0 0 1-5.402-2.547l-.581 3.297L15 15.67V23h-2v-5.986l-2.05-1.987-.947 4.298-6.894-1.215.348-1.97 4.924.868L9.83 8.79zM13.5 5.5a2 2 0 1 1 0-4 2 2 0 0 1 0 4z" /></svg>
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-2 sm:text-left w-full">
<h3 class="text-lg leading-6 font-bold mt-2 text-gray-900">
{$_('runner-import')}
</h3>
</div>
</div>
<div class="mt-5 text-center sm:mt-0 sm:ml-2 sm:text-left w-full">
{#if json_output.length === 0}
<div class="mt-2 mb-6">
<p class="text-sm text-gray-500">
{$_('please-provide-the-required-csv-xlsx-file')}
</p>
</div>
<div class="overflow-hidden relative mt-4 mb-4">
<input
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
bind:files
type="file" />
</div>
{/if}
{#if json_output.length > 0}
{#if opened_from === 'OrgOverview'}
<p>{$_('import__target-organization')}</p>
<select
name="team"
bind:value={selected_org}
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
{#each passed_orgs as o}
<option value={o.id}>{o.name}</option>
{/each}
</select>
<p>{$_('bitte-bestaetige-diese-laeufer-fuer-den-import')}</p>
{/if}
{#if opened_from === 'OrgDetail'}
<p>
{$_('runnerimport_verify_runners_org', {
values: { org_name: passed_org.name },
})}
</p>
{/if}
<input
type="search"
bind:value={searchvalue}
placeholder={$_('datatable.search')}
aria-label={$_('datatable.search')}
class="p-2 w-full" />
<div class="relative w-full mt-4 mb-4">
<div class="w-full overflow-x-auto">
<table class="divide-y divide-gray-200 w-full">
<thead class="bg-gray-50">
<tr>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('csv_import__firstname')}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('csv_import__middlename')}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('csv_import__lastname')}
</th>
{#if opened_from !== 'TeamDetail'}
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('csv_import__team')}
</th>
{/if}
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
{#each json_output as runner}
{#if Object.values(runner)
.toString()
.toLowerCase()
.includes(searchvalue)}
<tr>
<td class="px-6 py-4 whitespace-nowrap">
{runner[`${$_('csv_import__firstname')}`]}
</td>
<td class="px-6 py-4 whitespace-nowrap">
{runner[`${$_('csv_import__middlename')}`] || ''}
</td>
<td class="px-6 py-4 whitespace-nowrap">
{runner[`${$_('csv_import__lastname')}`]}
</td>
{#if opened_from !== 'TeamDetail'}
<td class="px-6 py-4 whitespace-nowrap">
{runner[`${$_('csv_import__team')}`] || runner[`${$_('csv_import__class')}`] || '---'}
</td>
{/if}
</tr>
{/if}
{/each}
</tbody>
</table>
</div>
<button
on:click={importAction}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
{$_('import-runners')}
</button>
<button
on:click={() => {
json_output = [];
cancelModal();
}}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
{$_('cancel')}
</button>
</div>
{/if}
</div>
</div>
</div>
</div>
</div>
{/if}

View File

@@ -1,9 +1,10 @@
<script> <script>
import { RunnerOrganisationService } from "@odit/lfk-client-js"; import { RunnerOrganizationService } from "@odit/lfk-client-js";
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import store from "../store"; import store from "../store";
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte"; import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
import ImportRunnerModal from "./ImportRunnerModal.svelte";
import PromiseError from "./PromiseError.svelte"; import PromiseError from "./PromiseError.svelte";
$: delete_triggered = false; $: delete_triggered = false;
$: save_enabled = !data_changed; $: save_enabled = !data_changed;
@@ -12,7 +13,7 @@
let original = {}; let original = {};
$: data_loaded = false; $: data_loaded = false;
$: data_changed = JSON.stringify(orgdata) === JSON.stringify(original); $: data_changed = JSON.stringify(orgdata) === JSON.stringify(original);
const promise = RunnerOrganisationService.runnerOrganisationControllerGetOne( const promise = RunnerOrganizationService.runnerOrganizationControllerGetOne(
params.orgid params.orgid
).then((value) => { ).then((value) => {
data_loaded = true; data_loaded = true;
@@ -21,8 +22,8 @@
}); });
let modal_open = false; let modal_open = false;
let delete_org = {}; let delete_org = {};
function deleteOrganisation() { function deleteOrganization() {
// RunnerOrganisationService.runnerOrganisationControllerRemove( // RunnerOrganizationService.runnerOrganizationControllerRemove(
// original.id, // original.id,
// false // false
// ) // )
@@ -45,7 +46,7 @@
text: "updating organization", text: "updating organization",
duration: 2500, duration: 2500,
}).showToast(); }).showToast();
RunnerOrganisationService.runnerOrganisationControllerPut( RunnerOrganizationService.runnerOrganizationControllerPut(
original.id, original.id,
orgdata orgdata
) )
@@ -64,18 +65,37 @@
} else { } else {
} }
} }
export let import_modal_open = false;
</script> </script>
<ImportRunnerModal
on:cancelDelete={(event) => {
import_modal_open = false;
}}
passed_orgs={[]}
passed_org={orgdata}
opened_from="OrgDetail"
bind:import_modal_open />
<ConfirmOrgDeletion bind:modal_open bind:delete_org /> <ConfirmOrgDeletion bind:modal_open bind:delete_org />
{#if data_loaded} {#if data_loaded}
<section class="container p-5"> <section class="container p-5">
<div class="mb-8 text-3xl font-extrabold leading-tight"> <div class="mb-8 text-3xl font-extrabold leading-tight">
{original.name} {original.name}
<span data-id="org_actions_${orgdata.id}"> <span data-id="org_actions_${orgdata.id}">
{#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:ml-3 sm:w-auto sm:text-sm">
{$_('import-runners')}
</button>
{/if}
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')} {#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
{#if delete_triggered} {#if delete_triggered}
<button <button
on:click={deleteOrganisation} on:click={deleteOrganization}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-delete')}</button> class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-delete')}</button>
<button <button
on:click={() => { on:click={() => {
@@ -181,7 +201,7 @@
type="text" type="text"
bind:value={orgdata.name} bind:value={orgdata.name}
name="name" name="name"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div> </div>
<div class="text-sm w-full"> <div class="text-sm w-full">
<label <label
@@ -193,7 +213,7 @@
type="text" type="text"
bind:value={orgdata.contact} bind:value={orgdata.contact}
name="contact" name="contact"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div> </div>
<div class="text-sm w-full"> <div class="text-sm w-full">
<label <label
@@ -205,7 +225,7 @@
type="text" type="text"
bind:value={orgdata.address} bind:value={orgdata.address}
name="address" name="address"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div> </div>
</section> </section>
{:else} {:else}

View File

@@ -2,8 +2,7 @@
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
let modal_open = false; let modal_open = false;
let delete_org = {}; let delete_org = {};
import { RunnerOrganisationService } from "@odit/lfk-client-js"; import { RunnerOrganizationService } from "@odit/lfk-client-js";
import "gridjs/dist/theme/mermaid.css";
import store from "../store"; import store from "../store";
import OrgsEmptyState from "./OrgsEmptyState.svelte"; import OrgsEmptyState from "./OrgsEmptyState.svelte";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
@@ -12,7 +11,7 @@
$: active_deletes = []; $: active_deletes = [];
export let current_organizations = []; export let current_organizations = [];
const promise = RunnerOrganisationService.runnerOrganisationControllerGetAll().then( const promise = RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
(val) => { (val) => {
current_organizations = val; current_organizations = val;
} }
@@ -26,7 +25,7 @@
}} }}
bind:modal_open bind:modal_open
bind:delete_org /> bind:delete_org />
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:GET')} {#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:GET')}
{#await promise} {#await promise}
<div <div
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
@@ -80,7 +79,7 @@
<div class="flex items-center"> <div class="flex items-center">
<div class="ml-4"> <div class="ml-4">
<div <div
class="text-sm font-medium text-gray-900 dark:text-gray-100"> class="text-sm font-medium text-gray-900">
{o.name} {o.name}
</div> </div>
</div> </div>
@@ -90,7 +89,7 @@
<div class="flex items-center"> <div class="flex items-center">
<div class="ml-4"> <div class="ml-4">
<div <div
class="text-sm font-medium text-gray-900 dark:text-gray-100"> class="text-sm font-medium text-gray-900">
{#if o.address} {#if o.address}
{JSON.stringify(o.address)} {JSON.stringify(o.address)}
{:else}no address specified{/if} {:else}no address specified{/if}
@@ -102,7 +101,7 @@
<div class="flex items-center"> <div class="flex items-center">
<div class="ml-4"> <div class="ml-4">
<div <div
class="text-sm font-medium text-gray-900 dark:text-gray-100"> class="text-sm font-medium text-gray-900">
{#if o.contact} {#if o.contact}
{JSON.stringify(o.contact)} {JSON.stringify(o.contact)}
{:else}no contact specified{/if} {:else}no contact specified{/if}
@@ -122,7 +121,7 @@
Delete</button> Delete</button>
<button <button
on:click={() => { on:click={() => {
RunnerOrganisationService.runnerOrganisationControllerRemove(o.id, false) RunnerOrganizationService.runnerOrganizationControllerRemove(o.id, false)
.then((resp) => { .then((resp) => {
current_organizations = current_organizations.filter((obj) => obj.id !== o.id); current_organizations = current_organizations.filter((obj) => obj.id !== o.id);
Toastify({ Toastify({
@@ -147,7 +146,7 @@
<a <a
href="./{o.id}" href="./{o.id}"
class="text-indigo-600 hover:text-indigo-900">Edit</a> class="text-indigo-600 hover:text-indigo-900">Edit</a>
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:DELETE')} {#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:DELETE')}
<button <button
on:click={() => { on:click={() => {
active_deletes[o.id] = true; active_deletes[o.id] = true;

View File

@@ -4,14 +4,15 @@
import AddOrgModal from "./AddOrgModal.svelte"; import AddOrgModal from "./AddOrgModal.svelte";
export let modal_open = false; export let modal_open = false;
import OrgOverview from "./OrgOverview.svelte"; import OrgOverview from "./OrgOverview.svelte";
console.log(store.state.jwtinfo.userdetails.permissions); import ImportRunnerModal from "./ImportRunnerModal.svelte";
let current_organizations = []; let current_organizations = [];
export let import_modal_open = false;
</script> </script>
<section class="container p-5"> <section class="container p-5">
<span class="mb-1 text-3xl font-extrabold leading-tight"> <span class="mb-1 text-3xl font-extrabold leading-tight">
{$_('organizations')} {$_('organizations')}
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:CREATE')} {#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:CREATE')}
<button <button
on:click={() => { on:click={() => {
modal_open = true; modal_open = true;
@@ -21,11 +22,29 @@
{$_('create-organization')} {$_('create-organization')}
</button> </button>
{/if} {/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:ml-3 sm:w-auto sm:text-sm">
{$_('import-runners')}
</button>
{/if}
</span> </span>
<p class="mb-8 text-lg text-gray-500">manage runner organizations</p> <p class="mb-8 text-lg text-gray-500">manage runner organizations</p>
<OrgOverview bind:current_organizations /> <OrgOverview bind:current_organizations />
</section> </section>
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:CREATE')} {#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:CREATE')}
<AddOrgModal bind:current_organizations bind:modal_open /> <AddOrgModal bind:current_organizations bind:modal_open />
<ImportRunnerModal
on:cancelDelete={(event) => {
import_modal_open = false;
}}
passed_org={{}}
passed_orgs={current_organizations}
opened_from="OrgOverview"
bind:import_modal_open />
{/if} {/if}

View File

@@ -8,7 +8,7 @@
</div> </div>
</div> </div>
<div <div
class="w-full p-4 mb-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890"> class="w-full p-4 mb-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-start p-4"> <div class="flex flex-row items-center justify-start p-4">
<div class="flex-shrink-0 w-24"> <div class="flex-shrink-0 w-24">
<img <img

View File

@@ -0,0 +1,235 @@
<script>
import { _ } from "svelte-i18n";
import lodashIsEqual from "lodash.isequal";
import store from "../store";
import { RunnerService } from "@odit/lfk-client-js";
import Toastify from "toastify-js";
import PromiseError from "./PromiseError.svelte";
import isEmail from "validator/es/lib/isEmail";
let data_loaded = false;
export let params;
const runner_promise = RunnerService.runnerControllerGetOne(params.runnerid);
$: delete_triggered = false;
$: original_data = {};
$: editable = {};
$: changes_performed = !lodashIsEqual(original_data, editable);
$: isEmailValid =
(editable.email || "") === "" ||
(editable.email && isEmail(editable.email || ""));
$: isFirstnameValid = editable.firstname !== "";
$: isLastnameValid = editable.lastname !== "";
$: save_enabled =
changes_performed && isFirstnameValid && isLastnameValid && isEmailValid;
runner_promise.then((data) => {
data_loaded = true;
original_data = Object.assign(original_data, data);
editable = data;
});
function submit() {
if (data_loaded === true && save_enabled) {
Toastify({
text: "Updating runner...",
duration: 2500,
}).showToast();
editable.group = editable.group.id;
RunnerService.runnerControllerPut(original_data.id, editable)
.then((resp) => {
Object.assign(original_data, editable);
original_data = editable;
Object.assign(original_data, editable);
//
Toastify({
text: "Runner updated!",
duration: 2500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
})
.catch((err) => {});
} else {
}
}
function deleteRunner() {
RunnerService.runnerControllerRemove(original_data.id, true)
.then((resp) => {
location.replace("./");
})
.catch((err) => {});
}
</script>
{#await runner_promise}
<!-- -->
{:then}
<section class="container p-5 select-none">
<div class="flex flex-row mb-4">
<div class="w-full">
<nav class="w-full flex">
<ol class="list-none flex flex-row items-center justify-start">
<li class="flex items-center">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class="flex-shrink-0 w-5 h-5 mr-2"
fill="currentColor"
width="24"
height="24"><path fill="none" d="M0 0h24v24H0z" />
<path
d="M9.83 8.79L8 9.456V13H6V8.05h.015l5.268-1.918c.244-.093.51-.14.782-.131a2.616 2.616 0 0 1 2.427 1.82c.186.583.356.977.51 1.182A4.992 4.992 0 0 0 19 11v2a6.986 6.986 0 0 1-5.402-2.547l-.581 3.297L15 15.67V23h-2v-5.986l-2.05-1.987-.947 4.298-6.894-1.215.348-1.97 4.924.868L9.83 8.79zM13.5 5.5a2 2 0 1 1 0-4 2 2 0 0 1 0 4z" /></svg>
</li>
<li class="flex items-center">
<a class="mr-2" href="./">{$_('runners')}</a><svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="h-3 w-3 mr-2 stroke-current"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"><line
x1="5"
y1="12"
x2="19"
y2="12" />
<polyline points="12 5 19 12 12 19" /></svg>
</li>
<li class="flex items-center">
<span class="mr-2">{original_data.firstname}
{original_data.middlename || ''}
{original_data.lastname}</span>
</li>
</ol>
</nav>
</div>
</div>
<div class="mb-8 text-3xl font-extrabold leading-tight">
{original_data.firstname}
{original_data.middlename || ''}
{original_data.lastname}
<span data-id="runner_actions_${editable.id}">
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
{#if delete_triggered}
<button
on:click={deleteRunner}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-deletion')}</button>
<button
on:click={() => {
delete_triggered = !delete_triggered;
}}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm">{$_('cancel')}</button>
{/if}
{#if !delete_triggered}
<button
on:click={() => {
delete_triggered = true;
}}
type="button"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-runner')}</button>
{/if}
{/if}
{#if !delete_triggered}
<button
disabled={!save_enabled}
class:opacity-50={!save_enabled}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('save-changes')}</button>
{/if}
</span>
</div>
<!-- -->
<div class="text-sm w-full">
<label
for="firstname"
class="font-medium text-gray-700">{$_('first-name')}</label>
<input
autocomplete="off"
placeholder={$_('first-name')}
type="text"
class:border-red-500={!isFirstnameValid}
class:focus:border-red-500={!isFirstnameValid}
class:focus:ring-red-500={!isFirstnameValid}
bind:value={editable.firstname}
name="firstname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
{#if !isFirstnameValid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
{$_('first-name-is-required')}
</span>
{/if}
</div>
<div class="text-sm w-full">
<label
for="middlename"
class="font-medium text-gray-700">{$_('middle-name')}</label>
<input
autocomplete="off"
placeholder={$_('middle-name')}
type="text"
bind:value={editable.middlename}
name="middlename"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div>
<div class="text-sm w-full">
<label
for="lastname"
class="font-medium text-gray-700">{$_('last-name')}</label>
<input
autocomplete="off"
placeholder={$_('last-name')}
type="text"
bind:value={editable.lastname}
class:border-red-500={!isLastnameValid}
class:focus:border-red-500={!isLastnameValid}
class:focus:ring-red-500={!isLastnameValid}
name="lastname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
{#if !isLastnameValid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
{$_('last-name-is-required')}
</span>
{/if}
</div>
<div class="text-sm w-full">
<label
for="email"
class="font-medium text-gray-700">{$_('e-mail-adress')}</label>
<input
autocomplete="off"
placeholder={$_('e-mail-adress')}
type="email"
bind:value={editable.email}
class:border-red-500={!isEmailValid}
class:focus:border-red-500={!isEmailValid}
class:focus:ring-red-500={!isEmailValid}
name="email"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
{#if !isEmailValid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
{$_('valid-email-is-required')}
</span>
{/if}
</div>
<div class="text-sm w-full">
<label for="phone" class="font-medium text-gray-700">{$_('phone')}</label>
<input
autocomplete="off"
placeholder={$_('phone')}
type="tel"
bind:value={editable.phone}
name="phone"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div>
<div class="text-sm w-full">
<span class="font-medium text-gray-700">{$_('distance')}</span>
<br />
<span class="text-gray-700">{original_data.distance} km</span>
</div>
</section>
{:catch error}
<PromiseError {error} />
{/await}

View File

@@ -1,12 +1,48 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import RunnersEmptyState from "./RunnersEmptyState.svelte"; import store from "../store";
import AddRunnerModal from "./AddRunnerModal.svelte";
import ImportRunnerModal from "./ImportRunnerModal.svelte";
import RunnersOverview from "./RunnersOverview.svelte";
let current_runners = [];
export let modal_open = false;
export let import_modal_open = false;
</script> </script>
<section class="container p-5"> <section class="container p-5">
<span class="mb-1 text-3xl font-extrabold leading-tight"> <span class="mb-1 text-3xl font-extrabold leading-tight">
{$_('runners')} {$_('runners')}
{#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:ml-3 sm:w-auto sm:text-sm">
Läufer hinzufügen
</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:ml-3 sm:w-auto sm:text-sm">
Läufer importieren
</button>
{/if}
</span> </span>
<p class="mb-8 text-lg text-gray-500">läuft bei ihnen</p> <RunnersOverview bind:current_runners />
</section> </section>
<RunnersEmptyState />
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:CREATE')}
<AddRunnerModal bind:current_runners bind:modal_open />
<ImportRunnerModal
on:cancelDelete={(event) => {
import_modal_open = false;
}}
passed_team={{}}
passed_orgs={[]}
passed_org={{}}
opened_from="RunnerOverview"
bind:import_modal_open />
{/if}

View File

@@ -0,0 +1,146 @@
<script>
import { _ } from "svelte-i18n";
import { RunnerService } from "@odit/lfk-client-js";
import store from "../store";
import RunnersEmptyState from "./RunnersEmptyState.svelte";
$: searchvalue = "";
$: active_deletes = [];
export let current_runners = [];
const runners_promise = RunnerService.runnerControllerGetAll().then((val) => {
current_runners = val;
});
</script>
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')}
{#await runners_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">runners are being loaded...</p>
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
</div>
{:then}
{#if current_runners.length === 0}
<RunnersEmptyState />
{:else}
<input
type="search"
bind:value={searchvalue}
placeholder={$_('datatable.search')}
aria-label={$_('datatable.search')}
class="gridjs-input gridjs-search-input mb-4" />
<div
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
<table class="divide-y divide-gray-200 w-full">
<thead class="bg-gray-50">
<tr>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('name')}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('contact-information')}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('group')}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('distance-in-km')}
</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_runners as runner}
{#if Object.values(runner)
.toString()
.toLowerCase()
.includes(searchvalue)}
<tr data-rowid="user_{runner.id}">
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="ml-4">
<div class="text-sm font-medium text-gray-900">
{runner.firstname}
{runner.middlename || ''}
{runner.lastname}
</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
{#if runner.email}
<div class="text-sm text-gray-500">{runner.email}</div>
{/if}
{#if runner.phone}
<div class="text-sm text-gray-500">{runner.phone}</div>
{/if}
</td>
<td class="px-6 py-4 whitespace-nowrap">
{runner.group.name}
</td>
<td class="px-6 py-4 whitespace-nowrap">{runner.distance}</td>
{#if active_deletes[runner.id] === true}
<td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
on:click={() => {
active_deletes[runner.id] = false;
}}
tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
Delete</button>
<button
on:click={() => {
RunnerService.runnerControllerRemove(runner.id, true)
.then((resp) => {
current_runners = current_runners.filter((obj) => obj.id !== runner.id);
})
.catch((err) => {
// error deleting user
});
}}
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="./{runner.id}"
class="text-indigo-600 hover:text-indigo-900">Edit</a>
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
<button
on:click={() => {
active_deletes[runner.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

@@ -18,7 +18,7 @@
class="flex flex-col lg:flex-row w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4"> class="flex flex-col lg:flex-row w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4">
<a href="/runners/" class="w-full lg:w-1/4"> <a href="/runners/" class="w-full lg:w-1/4">
<div <div
class="widget w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890 dark:bg-gray-900 dark:text-white"> class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-xs uppercase font-light text-grey-500"> <div class="text-xs uppercase font-light text-grey-500">
@@ -39,7 +39,7 @@
</a> </a>
<div class="w-full lg:w-1/4"> <div class="w-full lg:w-1/4">
<div <div
class="widget w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890 dark:bg-gray-900 dark:text-white"> class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-xs uppercase font-light text-grey-500"> <div class="text-xs uppercase font-light text-grey-500">
@@ -64,7 +64,7 @@
</div> </div>
<div class="w-full lg:w-1/4"> <div class="w-full lg:w-1/4">
<div <div
class="widget w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890 dark:bg-gray-900 dark:text-white"> class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-xs uppercase font-light text-grey-500"> <div class="text-xs uppercase font-light text-grey-500">
@@ -83,7 +83,7 @@
</div> </div>
<div class="w-full lg:w-1/4"> <div class="w-full lg:w-1/4">
<div <div
class="widget w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890 dark:bg-gray-900 dark:text-white"> class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-xs uppercase font-light text-grey-500"> <div class="text-xs uppercase font-light text-grey-500">
@@ -106,7 +106,7 @@
</div> </div>
<a href="/teams/" class="w-full lg:w-1/4"> <a href="/teams/" class="w-full lg:w-1/4">
<div <div
class="widget w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890 dark:bg-gray-900 dark:text-white"> class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-xs uppercase font-light text-grey-500"> <div class="text-xs uppercase font-light text-grey-500">
@@ -135,7 +135,7 @@
</a> </a>
<a href="/orgs/" class="w-full lg:w-1/4"> <a href="/orgs/" class="w-full lg:w-1/4">
<div <div
class="widget w-full p-4 rounded-lg bg-white border border-grey-100 dark:bg-grey-895 dark:border-grey-890 dark:bg-gray-900 dark:text-white"> class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-xs uppercase font-light text-grey-500"> <div class="text-xs uppercase font-light text-grey-500">

View File

@@ -1,11 +1,12 @@
<script> <script>
import { import {
RunnerOrganisationService, RunnerOrganizationService,
RunnerTeamService, RunnerTeamService,
} from "@odit/lfk-client-js"; } from "@odit/lfk-client-js";
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import store from "../store"; import store from "../store";
import ImportRunnerModal from "./ImportRunnerModal.svelte";
import PromiseError from "./PromiseError.svelte"; import PromiseError from "./PromiseError.svelte";
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte"; import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
export let params; export let params;
@@ -16,6 +17,7 @@
[], [],
false, false,
]; ];
export let import_modal_open = false;
$: delete_triggered = false; $: delete_triggered = false;
$: save_enabled = !data_changed; $: save_enabled = !data_changed;
$: data_loaded = false; $: data_loaded = false;
@@ -28,7 +30,7 @@
teamdata = Object.assign(teamdata, value); teamdata = Object.assign(teamdata, value);
original = Object.assign(original, value); original = Object.assign(original, value);
}); });
RunnerOrganisationService.runnerOrganisationControllerGetAll().then((val) => { RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
orgs = val; orgs = val;
}); });
function deleteTeam() { function deleteTeam() {
@@ -71,12 +73,31 @@
} }
</script> </script>
<ImportRunnerModal
on:cancelDelete={(event) => {
import_modal_open = false;
}}
passed_team={teamdata}
passed_orgs={[]}
passed_org={{}}
opened_from="TeamDetail"
bind:import_modal_open />
<ConfirmTeamDeletion bind:modal_open bind:delete_team /> <ConfirmTeamDeletion bind:modal_open bind:delete_team />
{#if data_loaded} {#if data_loaded}
<section class="container p-5"> <section class="container p-5">
<div class="mb-8 text-3xl font-extrabold leading-tight"> <div class="mb-8 text-3xl font-extrabold leading-tight">
{original.name} {original.name}
<span data-id="org_actions_${teamdata.id}"> <span data-id="org_actions_${teamdata.id}">
{#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:ml-3 sm:w-auto sm:text-sm">
{$_('import-runners')}
</button>
{/if}
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')} {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')}
{#if delete_triggered} {#if delete_triggered}
<button <button
@@ -188,7 +209,7 @@
type="text" type="text"
bind:value={teamdata.name} bind:value={teamdata.name}
name="name" name="name"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div> </div>
<div class="text-sm w-full"> <div class="text-sm w-full">
<label <label
@@ -200,14 +221,14 @@
type="text" type="text"
bind:value={teamdata.contact} bind:value={teamdata.contact}
name="contact" name="contact"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div> </div>
<div class="text-sm w-full"> <div class="text-sm w-full">
<label for="org" class="font-medium text-gray-700">Parent Organization</label> <label for="org" class="font-medium text-gray-700">Parent Organization</label>
<select <select
name="org" name="org"
bind:value={teamdata.parentGroup} bind:value={teamdata.parentGroup}
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2"> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2">
{#each orgs as o} {#each orgs as o}
<option value={o.id}>{o.name}</option> <option value={o.id}>{o.name}</option>
{/each} {/each}

View File

@@ -3,7 +3,6 @@
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import { RunnerTeamService } from "@odit/lfk-client-js"; import { RunnerTeamService } from "@odit/lfk-client-js";
const teams_promise = RunnerTeamService.runnerTeamControllerGetAll(); const teams_promise = RunnerTeamService.runnerTeamControllerGetAll();
import "gridjs/dist/theme/mermaid.css";
import { users as usersstore } from "../store.js"; import { users as usersstore } from "../store.js";
import store from "../store"; import store from "../store";
import TeamsEmptyState from "./TeamsEmptyState.svelte"; import TeamsEmptyState from "./TeamsEmptyState.svelte";
@@ -82,7 +81,7 @@
<div class="flex items-center"> <div class="flex items-center">
<div class="ml-4"> <div class="ml-4">
<div <div
class="text-sm font-medium text-gray-900 dark:text-gray-100"> class="text-sm font-medium text-gray-900">
{t.name} {t.name}
</div> </div>
</div> </div>
@@ -92,7 +91,7 @@
<div class="flex items-center"> <div class="flex items-center">
<div class="ml-4"> <div class="ml-4">
<div <div
class="text-sm font-medium text-gray-900 dark:text-gray-100"> class="text-sm font-medium text-gray-900">
{#if t.parentGroup} {#if t.parentGroup}
{t.parentGroup.name} {t.parentGroup.name}
{:else}no organization specified{/if} {:else}no organization specified{/if}
@@ -104,7 +103,7 @@
<div class="flex items-center"> <div class="flex items-center">
<div class="ml-4"> <div class="ml-4">
<div <div
class="text-sm font-medium text-gray-900 dark:text-gray-100"> class="text-sm font-medium text-gray-900">
{#if t.contact} {#if t.contact}
{JSON.stringify(t.contact)} {JSON.stringify(t.contact)}
{:else}no contact specified{/if} {:else}no contact specified{/if}

View File

@@ -206,7 +206,7 @@
type="text" type="text"
bind:value={editable_userdata.firstname} bind:value={editable_userdata.firstname}
name="firstname" name="firstname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div> </div>
<div class="text-sm w-full"> <div class="text-sm w-full">
<label <label
@@ -218,7 +218,7 @@
type="text" type="text"
bind:value={editable_userdata.middlename} bind:value={editable_userdata.middlename}
name="middlename" name="middlename"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div> </div>
<div class="text-sm w-full"> <div class="text-sm w-full">
<label <label
@@ -230,7 +230,7 @@
type="text" type="text"
bind:value={editable_userdata.lastname} bind:value={editable_userdata.lastname}
name="lastname" name="lastname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div> </div>
<div class="text-sm w-full"> <div class="text-sm w-full">
<label <label
@@ -242,7 +242,7 @@
type="email" type="email"
bind:value={editable_userdata.email} bind:value={editable_userdata.email}
name="email" name="email"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div> </div>
<div class="text-sm w-full"> <div class="text-sm w-full">
<label <label
@@ -254,14 +254,14 @@
type="text" type="text"
bind:value={editable_userdata.username} bind:value={editable_userdata.username}
name="username" name="username"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
</div> </div>
<div class="text-sm w-full"> <div class="text-sm w-full">
<span class="font-medium">{$_('groups')}</span> <span class="font-medium">{$_('groups')}</span>
<!-- svelte-ignore a11y-no-onchange --> <!-- svelte-ignore a11y-no-onchange -->
<select <select
bind:value={usergroups_array} bind:value={usergroups_array}
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
multiple> multiple>
{#each allgroups as g} {#each allgroups as g}
{#if usergroups_array.includes(g.id)} {#if usergroups_array.includes(g.id)}
@@ -291,7 +291,7 @@
{#each allpermissions as p} {#each allpermissions as p}
{#if !editable_userdata.permissions.includes(p)} {#if !editable_userdata.permissions.includes(p)}
<p <p
class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 bg-gray-200 p-2 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"> class="block w-full mt-1 text-sm bg-gray-200 p-2 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple form-input">
{p} {p}
<button <button
on:click={() => { on:click={() => {
@@ -311,7 +311,7 @@
{#each allpermissions as p} {#each allpermissions as p}
{#if editable_userdata.permissions.includes(p)} {#if editable_userdata.permissions.includes(p)}
<p <p
class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 bg-gray-200 p-2 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"> class="block w-full mt-1 text-sm bg-gray-200 p-2 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple form-input">
{p} {p}
<button <button
on:click={() => { on:click={() => {

View File

@@ -93,7 +93,7 @@
{/if} {/if}
<div class="ml-4"> <div class="ml-4">
<div <div
class="text-sm font-medium text-gray-900 dark:text-gray-100"> class="text-sm font-medium text-gray-900">
{u.firstname} {u.firstname}
{u.middlename || ''} {u.middlename || ''}
{u.lastname} {u.lastname}

View File

@@ -2,10 +2,17 @@
"404message": "Die gesuchte Seite wurde leider nicht gefunden.", "404message": "Die gesuchte Seite wurde leider nicht gefunden.",
"404title": "Fehler 404", "404title": "Fehler 404",
"about": "Über", "about": "Über",
"application_name": "Lauf für Kaya! \n- Admin", "application_name": "Lauf für Kaya! - Admin",
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer für den import bestätigen.",
"by": "von", "by": "von",
"cancel": "Abbrechen",
"cannot-reset-your-password-directly": "Schade. \nWir können das Passwort leider nicht direkt zurücksetzen.\nBitte sende uns eine Mail in der du deine Identität bestätigst.", "cannot-reset-your-password-directly": "Schade. \nWir können das Passwort leider nicht direkt zurücksetzen.\nBitte sende uns eine Mail in der du deine Identität bestätigst.",
"credits": "", "credits": "",
"csv_import__class": "Klasse",
"csv_import__firstname": "Vorname",
"csv_import__lastname": "Nachname",
"csv_import__middlename": "Mittelname",
"csv_import__team": "Team",
"dashboard-greeting": "Moin", "dashboard-greeting": "Moin",
"datatable": { "datatable": {
"search": "🔍 Suche ...", "search": "🔍 Suche ...",
@@ -27,6 +34,8 @@
"goback": "Zur Startseite", "goback": "Zur Startseite",
"hallo": "hallo", "hallo": "hallo",
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:", "icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
"import-runners": "Läufer importieren",
"import__target-organization": "Ziel Organisation",
"invalid-mail-reset": "Das ist keine gültige E-Mail", "invalid-mail-reset": "Das ist keine gültige E-Mail",
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.", "lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
"log_in": "Anmelden", "log_in": "Anmelden",
@@ -34,8 +43,11 @@
"login_is_checked": "Login wird überprüft", "login_is_checked": "Login wird überprüft",
"oss_credit_description": "Wir verwenden eine Menge Open Source-Software bei diesen Projekten und möchten uns bei den folgenden Projekten und Mitwirkenden bedanken, die dazu beitragen, Open Source großartig zu machen!", "oss_credit_description": "Wir verwenden eine Menge Open Source-Software bei diesen Projekten und möchten uns bei den folgenden Projekten und Mitwirkenden bedanken, die dazu beitragen, Open Source großartig zu machen!",
"password": "Passwort", "password": "Passwort",
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
"register": "Registrieren", "register": "Registrieren",
"reset-my-password": "Passwort zurücksetzen", "reset-my-password": "Passwort zurücksetzen",
"runner-import": "Läufer Import",
"runnerimport_verify_runners_org": "Bitte die Läufer für den Import in die Organisation \"{org_name}\" bestätigen",
"runners": "Läufer", "runners": "Läufer",
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services", "send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
"settings": "Einstellungen", "settings": "Einstellungen",

View File

@@ -7,6 +7,7 @@
"address": "Address", "address": "Address",
"application_name": "Lauf für Kaya! - Admin", "application_name": "Lauf für Kaya! - Admin",
"author": "Author", "author": "Author",
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import",
"browse": "Browse", "browse": "Browse",
"by": "by", "by": "by",
"cancel": "Cancel", "cancel": "Cancel",
@@ -14,7 +15,9 @@
"changelog": "Changelog", "changelog": "Changelog",
"close": "Close", "close": "Close",
"confirm-delete": "Confirm Delete", "confirm-delete": "Confirm Delete",
"confirm-deletion": "Confirm Deletion",
"contact": "Contact", "contact": "Contact",
"contact-information": "Contact Information",
"count_organizations": "# Organizations", "count_organizations": "# Organizations",
"count_teams": "# Teams", "count_teams": "# Teams",
"create": "Create", "create": "Create",
@@ -22,6 +25,11 @@
"create-organization": "Create Organization", "create-organization": "Create Organization",
"create-user": "Create User", "create-user": "Create User",
"credits": "Credits", "credits": "Credits",
"csv_import__class": "Class",
"csv_import__firstname": "Firstname",
"csv_import__lastname": "Lastname",
"csv_import__middlename": "Middlename",
"csv_import__team": "Team",
"dashboard-greeting": "hello there", "dashboard-greeting": "hello there",
"dashboard-title": "Dashboard", "dashboard-title": "Dashboard",
"datatable": { "datatable": {
@@ -39,10 +47,14 @@
"no_matching_records_found": "No matching records found", "no_matching_records_found": "No matching records found",
"an_error_happened_while_fetching_the_data": "An error happened while fetching the data" "an_error_happened_while_fetching_the_data": "An error happened while fetching the data"
}, },
"delete": "Delete",
"delete-organization": "Delete Organization", "delete-organization": "Delete Organization",
"delete-runner": "Delete Runner",
"delete-team": "Delete Team", "delete-team": "Delete Team",
"delete-user": "Delete User", "delete-user": "Delete User",
"dependency_name": "Name", "dependency_name": "Name",
"distance": "Distance",
"distance-in-km": "Distance in km",
"dont-have-your-email-connected": "Don't have your email connected?", "dont-have-your-email-connected": "Don't have your email connected?",
"dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌", "dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌",
"drag-and-drop-your-files-or": "Drag & Drop your files or", "drag-and-drop-your-files-or": "Drag & Drop your files or",
@@ -76,9 +88,12 @@
"general-stats": "General Stats", "general-stats": "General Stats",
"general_promise_error": "😢 Error", "general_promise_error": "😢 Error",
"goback": "Go Home", "goback": "Go Home",
"group": "Group",
"groups": "Groups", "groups": "Groups",
"hallo": "hello", "hallo": "hello",
"icon-image-credits": "We also want to thank these projects for illustrations and icons:", "icon-image-credits": "We also want to thank these projects for illustrations and icons:",
"import-runners": "Import runners",
"import__target-organization": "Target Organization",
"installed-version": "Installed version", "installed-version": "Installed version",
"invalid-mail-reset": "the provided email is invalid", "invalid-mail-reset": "the provided email is invalid",
"last-name": "Last name", "last-name": "Last name",
@@ -94,6 +109,7 @@
"manage-admin-users": "manage admin users", "manage-admin-users": "manage admin users",
"middle-name": "Middle name", "middle-name": "Middle name",
"minimum-lap-time-in-s": "minimum lap time in s", "minimum-lap-time-in-s": "minimum lap time in s",
"name": "Name",
"no-license-text-could-be-found": "No license text could be found 😢", "no-license-text-could-be-found": "No license text could be found 😢",
"no-tracks-added-yet": "there are no tracks added yet.", "no-tracks-added-yet": "there are no tracks added yet.",
"organization": "Organization", "organization": "Organization",
@@ -102,12 +118,16 @@
"oss_credit_description": "We use a lot of open source software on these projects, and would like to thank the following projects and contributors who help make open source great!", "oss_credit_description": "We use a lot of open source software on these projects, and would like to thank the following projects and contributors who help make open source great!",
"password": "Password", "password": "Password",
"password-is-required": "Password is required", "password-is-required": "Password is required",
"phone": "Phone",
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
"please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.", "please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.",
"profile-picture": "Profile Picture", "profile-picture": "Profile Picture",
"read-license": "Read License", "read-license": "Read License",
"register": "Register", "register": "Register",
"repo_link": "Link", "repo_link": "Link",
"reset-my-password": "Reset my password", "reset-my-password": "Reset my password",
"runner-import": "Runner Import",
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
"runners": "Runners", "runners": "Runners",
"save-changes": "Save Changes", "save-changes": "Save Changes",
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services", "send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",

View File

@@ -1,11 +0,0 @@
const sveltePreprocess = require('svelte-preprocess');
const preprocess = sveltePreprocess({
postcss: {
plugins: [ require('tailwindcss'), require('autoprefixer') ]
}
});
module.exports = {
preprocess
};

19
template-copy.js Normal file
View File

@@ -0,0 +1,19 @@
const fs = require('fs');
let content_svelteconfig = fs.readFileSync('./s-config.template.js', { encoding: 'utf8' });
let content_html = fs.readFileSync('./index.template.html', { encoding: 'utf8' });
if (process.env.NODE_ENV_ODIT == 'development_fast') {
content_html = content_html.replace(
'__TAILWIND_INSERT__',
'<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tailwindcss@2.0.2/dist/tailwind.min.css">'
);
content_svelteconfig = content_svelteconfig.replace('__insert__', '{postcss:{}}');
} else {
content_html = content_html.replace('__TAILWIND_INSERT__', '');
content_svelteconfig = content_svelteconfig.replace(
'__insert__',
"{postcss:{plugins:[require('tailwindcss'),require('autoprefixer')]}}"
);
}
fs.writeFileSync('./public/index.html', content_html);
fs.writeFileSync('./svelte.config.js', content_svelteconfig);
console.info('dev setup script done');

View File

@@ -1,5 +1,5 @@
const fs = require('fs'); const fs = require('fs');
const package = JSON.parse(fs.readFileSync(`./package.json`, { encoding: 'utf-8' })); const package = JSON.parse(fs.readFileSync(`./package.json`, { encoding: 'utf-8' }));
const original = fs.readFileSync(`./public/index.html`, { encoding: 'utf-8' }); const original = fs.readFileSync(`./index.template.html`, { encoding: 'utf-8' });
let out = original.replace(/RELEASE_INFO-(\S)+-RELEASE_INFO/gi, 'RELEASE_INFO-' + package.version + '-RELEASE_INFO'); let out = original.replace(/RELEASE_INFO-(\S)+-RELEASE_INFO/gi, 'RELEASE_INFO-' + package.version + '-RELEASE_INFO');
fs.writeFileSync(`./public/index.html`, out); fs.writeFileSync(`./index.template.html`, out);

View File

@@ -1,6 +1,9 @@
module.exports = { module.exports = {
globDirectory: 'public', globDirectory: 'public',
globPatterns: [ '**/*.{js,ico,png,svg,html,webmanifest,txt}' ], globPatterns: [ '**/*.{js,ico,png,svg,html,webmanifest,txt,json}' ],
globIgnores: [ 'env.js', 'env.sample.js', 'licenses.json' ], globIgnores: [ 'env.js', 'env.sample.js' ],
swDest: 'public/sw.js' swDest: 'public/sw.js',
cleanupOutdatedCaches: true,
mode: 'production',
sourcemap: false
}; };