Compare commits

..

61 Commits
0.1.4 ... 0.3.0

Author SHA1 Message Date
7cd24cd51d 🚀RELEASE v0.3.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-15 20:20:02 +01:00
c81b34c1d0 Merge branch 'dev' of https://git.odit.services/lfk/frontend into dev
Some checks failed
continuous-integration/drone/push Build was killed
2021-01-15 20:19:03 +01:00
7b1acc494d Merge pull request 'feature/16-org-management' (#32) from feature/16-org-management into dev
Some checks failed
continuous-integration/drone/push Build was killed
Reviewed-on: #32
 close #16
2021-01-15 19:18:52 +00:00
6ff90694e2 bump gridjs to 3.2.2 2021-01-15 20:17:36 +01:00
157c7c66b5 🧹 general component cleanup
Some checks failed
continuous-integration/drone/push Build was killed
2021-01-15 20:14:54 +01:00
93249258c6 🏁 finish basic functionality of AddOrgModal + OrgDetail
ref #16
2021-01-15 20:03:29 +01:00
01c01a46fa 🌎 i18n
ref #16
2021-01-15 19:25:42 +01:00
0e2a10fe94 basic functionality in OrgDetail
ref #16
2021-01-15 19:25:30 +01:00
0b9f3de47c improvements in OrgOverview
ref #16
2021-01-15 19:25:12 +01:00
bc239eead1 💬 AddOrgModal bindings
ref #16
2021-01-15 19:24:46 +01:00
7a09869b0c 🏬 OrgDetail ui
ref #16
2021-01-15 19:14:46 +01:00
bdc0de6ada added Org base components
ref #16
2021-01-15 18:49:45 +01:00
b497cebe76 Merge commit 'fcd657c10ea14290455cfb0bf2de89375a664143' into dev
All checks were successful
continuous-integration/drone/push Build is passing
close #31
2021-01-14 18:26:33 +01:00
0fa107a75b [tmp] - disable serviceworker 2021-01-14 18:25:01 +01:00
35b18d72fd Merge branch 'dev' of https://git.odit.services/lfk/frontend into dev
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-14 18:22:54 +01:00
4b80f30afb 🐳 Dockerfile - drop js sourcemaps 2021-01-14 18:22:33 +01:00
ad34e455ce new license file version [CI SKIP] 2021-01-14 17:18:21 +00:00
01fdd0bee2 Bump Dockerfile builder to 15.5.1-alpine3.12
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-14 18:17:29 +01:00
32ffa345cd 🔨 config compatibility for new Snowpack V3 bundler
Some checks failed
continuous-integration/drone/push Build is failing
2021-01-14 18:17:12 +01:00
6fc3c16073 basic dependency bump
Some checks failed
continuous-integration/drone/push Build is failing
lfk-library, snowpack@3.0.10 & svelte plugin
2021-01-14 18:16:46 +01:00
7d58657c80 🔨 reorder CI build order for correct license exporting
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-13 21:38:05 +01:00
fcd657c10e 🐞 fix sidebar mobile-md scaling
ref #31
2021-01-13 21:37:29 +01:00
4ab77c5557 Merge branch 'dev' of https://git.odit.services/lfk/frontend into dev
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-13 21:07:08 +01:00
2bbaa500f4 🚀RELEASE v0.2.1 2021-01-13 21:06:51 +01:00
722a20e141 🐞 fix package release script: locales directory 2021-01-13 21:06:39 +01:00
041c24a837 🙋‍♂️ UserDetails - group updating
ref #12
2021-01-13 21:05:03 +01:00
39a3baa00b 🐞 UserDetail - fix permission reactivity by assignments
ref #12
2021-01-13 18:17:34 +01:00
f7acbb1eaa shared state reactivity - AddUserModal-Users-UsersOverview
ref #12
2021-01-13 17:49:01 +01:00
e6fbf7aa5b UserDetail - fixed group updating
ref #12
2021-01-12 21:19:12 +01:00
87926e69db new license file version [CI SKIP] 2021-01-12 20:07:09 +00:00
36a084eab6 🔒 UserDetail - WIP on Permissions
ref #12
2021-01-12 21:04:12 +01:00
a9e319e0c0 👪 UserDetail - group edit support
ref #12
2021-01-12 20:16:16 +01:00
ea23b97231 💬 UserDetail - info Toasts
ref #12
2021-01-12 19:30:54 +01:00
7df76f9642 AddUserModal + UserDetail - optional username field
ref #12
2021-01-12 19:30:06 +01:00
f6db117a5e bump @odit/lfk-client-js to 0.0.11
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-11 21:21:49 +01:00
23c3cd605d 🔨 optimized release script 2021-01-11 21:21:12 +01:00
77690702c0 🚀RELEASE v0.2.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-11 21:17:35 +01:00
e0093480d9 Merge branch 'feature/12-user-management' into dev 2021-01-11 21:17:12 +01:00
c7679b7a67 [tmp] - disable darkmode + re-enable sw 2021-01-11 21:17:05 +01:00
e6ac34bde8 🐞 [tmp] - nginx.conf - disable .js file caching
Some checks failed
continuous-integration/drone/push Build was killed
2021-01-11 21:10:40 +01:00
8c4b595c30 Merge branch 'dev' into feature/12-user-management 2021-01-11 21:08:44 +01:00
be629e5c6b 🕕 set manual refresh time to 2min
Some checks failed
continuous-integration/drone/push Build was killed
2021-01-11 21:08:39 +01:00
63569684a3 ℹ update jwtinfo store on token refresh 2021-01-11 21:08:14 +01:00
5937a0d7ce 🔒 added rendering based on permission level
ref #12
2021-01-11 21:07:30 +01:00
4512272c1c UserDetail - delete
ref #12
2021-01-11 21:06:47 +01:00
ce1f3842e0 🖊 UserDetail - reactivity on edit + update functionality
ref #12
2021-01-11 20:41:57 +01:00
ee01c3a059 🚀RELEASE v0.1.6
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-10 18:19:45 +01:00
81c1537bad 🔒 UserDetail - added basic layout for permission change
ref #12
2021-01-10 18:14:11 +01:00
98ecfab032 UserDetail multiselect layout for groups
ref #12
2021-01-10 18:02:36 +01:00
b948b8c1a4 UserDetail - placeholder for permission picker 🔒
ref #12
2021-01-10 17:55:13 +01:00
f856c6ae37 📧 UserDetail - email input
ref #12
2021-01-10 17:54:50 +01:00
2dd2580530 Merge branch 'dev' into feature/12-user-management 2021-01-10 17:34:12 +01:00
330755c63e 🚀RELEASE v0.1.5
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-10 17:18:55 +01:00
9cf0174b41 Merge commit '16f572480ad55425890061f9dad65fe85f2f39ad' into dev
close #30
2021-01-10 17:18:33 +01:00
16f572480a add versionbuilder script to release hook
ref #30
2021-01-10 17:18:16 +01:00
b8a9e4f272 📅 dynamic copyright year in Footer component
ref #30
2021-01-10 17:17:07 +01:00
c089bb3929 ⤵ load dynamic build info in Footer component
ref #30
2021-01-10 17:16:51 +01:00
3caa1fc277 🔨 sample build of index.html with versionbuilder script
ref #30
2021-01-10 17:16:07 +01:00
43b406592e 👀 improved Footer layout + display on Login component
ref #30
2021-01-10 17:15:46 +01:00
1dd6674faa added versionbuilder.js script
ref #30
2021-01-10 17:15:01 +01:00
f0c100aee4 UsersOverview - user delete
ref #12
2021-01-10 15:16:02 +01:00
27 changed files with 1145 additions and 315 deletions

View File

@@ -4,18 +4,6 @@ type: docker
name: build:dev name: build:dev
steps: steps:
- name: build dev
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: DOCKER_REGISTRY_USER
password:
from_secret: DOCKER_REGISTRY_PASSWORD
repo: registry.odit.services/lfk/frontend
tags:
- dev
registry: registry.odit.services
- name: run full license export - name: run full license export
depends_on: ["clone"] depends_on: ["clone"]
image: node:alpine image: node:alpine
@@ -33,6 +21,18 @@ steps:
remote: git@git.odit.services:lfk/frontend.git remote: git@git.odit.services:lfk/frontend.git
ssh_key: ssh_key:
from_secret: GITLAB_SSHKEY from_secret: GITLAB_SSHKEY
- name: build dev
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: DOCKER_REGISTRY_USER
password:
from_secret: DOCKER_REGISTRY_PASSWORD
repo: registry.odit.services/lfk/frontend
tags:
- dev
registry: registry.odit.services
trigger: trigger:
branch: branch:

View File

@@ -2,11 +2,91 @@
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.3.0](https://git.odit.services/lfk/frontend/compare/0.2.1...0.3.0)
- Merge pull request 'feature/16-org-management' (#32) from feature/16-org-management into dev [`#16`](https://git.odit.services/lfk/frontend/issues/16)
- Merge commit 'fcd657c10ea14290455cfb0bf2de89375a664143' into dev [`#31`](https://git.odit.services/lfk/frontend/issues/31)
- ✨ added Org base components [`bdc0de6`](https://git.odit.services/lfk/frontend/commit/bdc0de6adab2db95e6075a993bd50317e9e36eb5)
- 🏬 OrgDetail ui [`7a09869`](https://git.odit.services/lfk/frontend/commit/7a09869b0ca9d5dd38cf0c0010b71ab9ce6c6f40)
- 🏁 finish basic functionality of AddOrgModal + OrgDetail [`9324925`](https://git.odit.services/lfk/frontend/commit/93249258c6b0f34da22f0ed5d290b437d221a8fd)
- ✨ basic functionality in OrgDetail [`0e2a10f`](https://git.odit.services/lfk/frontend/commit/0e2a10fe94075b3cda8ef3ebae6a6159a2e6bbf9)
- 🐞 fix sidebar mobile-md scaling [`fcd657c`](https://git.odit.services/lfk/frontend/commit/fcd657c10ea14290455cfb0bf2de89375a664143)
- 🔨 reorder CI build order for correct license exporting [`7d58657`](https://git.odit.services/lfk/frontend/commit/7d58657c800e9e494c1d1f098ad0dc34d1f0cd8d)
- 💬 AddOrgModal bindings [`bc239ee`](https://git.odit.services/lfk/frontend/commit/bc239eead1d1a29c9662d94db797c6bf23e43166)
- ✨ improvements in OrgOverview [`0b9f3de`](https://git.odit.services/lfk/frontend/commit/0b9f3de47c0c8b750c38da07e53927ba55ef3499)
- 🔨 config compatibility for new Snowpack V3 bundler [`32ffa34`](https://git.odit.services/lfk/frontend/commit/32ffa345cde67b1affe2750add620522c0a24577)
- 🧹 general component cleanup [`157c7c6`](https://git.odit.services/lfk/frontend/commit/157c7c66b57c3a5053c780682402d3615fbc046a)
- ⏫ basic dependency bump [`6fc3c16`](https://git.odit.services/lfk/frontend/commit/6fc3c16073555fffd55773218c5c2eed361f076b)
- 🌎 i18n [`01c01a4`](https://git.odit.services/lfk/frontend/commit/01c01a46faa9332a2e437861fdb42afe962da833)
- ⏫ bump gridjs to 3.2.2 [`6ff9069`](https://git.odit.services/lfk/frontend/commit/6ff90694e288356e16f5226a6e0a054e6fec8b3f)
- [tmp] - disable serviceworker [`0fa107a`](https://git.odit.services/lfk/frontend/commit/0fa107a75bc33046758bc42523262a566da9f60f)
- new license file version [CI SKIP] [`ad34e45`](https://git.odit.services/lfk/frontend/commit/ad34e455ceedc0e0ccca5ccd86f7f011a7667873)
- ⏫ Bump Dockerfile builder to 15.5.1-alpine3.12 [`01fdd0b`](https://git.odit.services/lfk/frontend/commit/01fdd0bee2199bb58373aecc9942591a2d45011a)
- new license file version [CI SKIP] [`87926e6`](https://git.odit.services/lfk/frontend/commit/87926e69dbd5b93b2c98cd68fb31913259e3cc00)
- 🐳 Dockerfile - drop js sourcemaps [`4b80f30`](https://git.odit.services/lfk/frontend/commit/4b80f30afbfb8c16b9395fb310f309c516c48a17)
#### [0.2.1](https://git.odit.services/lfk/frontend/compare/0.2.0...0.2.1)
> 13 January 2021
- 🔒 UserDetail - WIP on Permissions [`36a084e`](https://git.odit.services/lfk/frontend/commit/36a084eab6bd0c922da29ebb2d260ba803bf9675)
- 👪 UserDetail - group edit support [`a9e319e`](https://git.odit.services/lfk/frontend/commit/a9e319e0c0f2bfaba42bc3af875462e394489dc2)
- 🙋‍♂️ UserDetails - group updating [`041c24a`](https://git.odit.services/lfk/frontend/commit/041c24a837d58ff46362699b54e8088f22ba2daa)
- ⚡ shared state reactivity - AddUserModal-Users-UsersOverview [`f7acbb1`](https://git.odit.services/lfk/frontend/commit/f7acbb1eaa14ddf41e29ff1db631520123218289)
- ✨ AddUserModal + UserDetail - optional username field [`7df76f9`](https://git.odit.services/lfk/frontend/commit/7df76f9642b528586fd654f27148b5502400ffdf)
- UserDetail - fixed group updating [`e6fbf7a`](https://git.odit.services/lfk/frontend/commit/e6fbf7aa5b230733ffd92fdfe851b9f86001c859)
- 🚀RELEASE v0.2.1 [`2bbaa50`](https://git.odit.services/lfk/frontend/commit/2bbaa500f4ca56e41613cac12228f4e3327180ab)
- 💬 UserDetail - info Toasts [`ea23b97`](https://git.odit.services/lfk/frontend/commit/ea23b972315db39e1f800366d52e3bacf9eaf58b)
- 🔨 optimized release script [`23c3cd6`](https://git.odit.services/lfk/frontend/commit/23c3cd605db950a5620ea709748216f7ea034385)
- 🐞 fix package release script: locales directory [`722a20e`](https://git.odit.services/lfk/frontend/commit/722a20e141079302da8876be1ccc55026c588048)
- ⏫ bump @odit/lfk-client-js to 0.0.11 [`f6db117`](https://git.odit.services/lfk/frontend/commit/f6db117a5eca5c9692a4c5d83159917a712a0e63)
- 🐞 UserDetail - fix permission reactivity by assignments [`39a3baa`](https://git.odit.services/lfk/frontend/commit/39a3baa00b0575ee3150c7ae26f32995e2e857d9)
#### [0.2.0](https://git.odit.services/lfk/frontend/compare/0.1.6...0.2.0)
> 11 January 2021
- 🔒 added rendering based on permission level [`5937a0d`](https://git.odit.services/lfk/frontend/commit/5937a0d7ce970d38ddb0e4c6a02d11f8c8b53e9b)
- ❌ UserDetail - delete [`4512272`](https://git.odit.services/lfk/frontend/commit/4512272c1c2a5c861d8ac4c9908244df125dc3d9)
- 🖊 UserDetail - reactivity on edit + update functionality [`ce1f384`](https://git.odit.services/lfk/frontend/commit/ce1f3842e0f581d9e94ea6079cf223d945f7465d)
- 🚀RELEASE v0.2.0 [`7769070`](https://git.odit.services/lfk/frontend/commit/77690702c0461b71ff1b65a44bfdc331d5a42c3e)
- [tmp] - disable darkmode + re-enable sw [`c7679b7`](https://git.odit.services/lfk/frontend/commit/c7679b7a67b362a7fbf796f612892bdfac50731c)
- 🕕 set manual refresh time to 2min [`be629e5`](https://git.odit.services/lfk/frontend/commit/be629e5c6b076bf9a28dcc953e97478d244d8413)
- 🐞 [tmp] - nginx.conf - disable .js file caching [`e6ac34b`](https://git.odit.services/lfk/frontend/commit/e6ac34bde8d288a45e83fc6723a2bbe952f2622a)
- update jwtinfo store on token refresh [`6356968`](https://git.odit.services/lfk/frontend/commit/63569684a392bf0c24c9c2efd7945114d1a230a5)
#### [0.1.6](https://git.odit.services/lfk/frontend/compare/0.1.5...0.1.6)
> 10 January 2021
- ✨ UsersOverview - user delete [`f0c100a`](https://git.odit.services/lfk/frontend/commit/f0c100aee47d6a5aeb0995db79b268f33bf316e9)
- 🔒 UserDetail - added basic layout for permission change [`81c1537`](https://git.odit.services/lfk/frontend/commit/81c1537bada2c87127385d9110d48459cd1b505f)
- 🚀RELEASE v0.1.6 [`ee01c3a`](https://git.odit.services/lfk/frontend/commit/ee01c3a059c435add68938657955cbd2c5851c50)
- 📧 UserDetail - email input [`f856c6a`](https://git.odit.services/lfk/frontend/commit/f856c6ae3792c93aee148339d89e3978db6e9293)
- ✨ UserDetail multiselect layout for groups [`98ecfab`](https://git.odit.services/lfk/frontend/commit/98ecfab0325e35c5418775f7162049b56e5f332f)
- UserDetail - placeholder for permission picker 🔒 [`b948b8c`](https://git.odit.services/lfk/frontend/commit/b948b8c1a48e5b4bc6a083139d26100ef4499970)
#### [0.1.5](https://git.odit.services/lfk/frontend/compare/0.1.4...0.1.5)
> 10 January 2021
- Merge commit '16f572480ad55425890061f9dad65fe85f2f39ad' into dev [`#30`](https://git.odit.services/lfk/frontend/issues/30)
- 🚀RELEASE v0.1.5 [`330755c`](https://git.odit.services/lfk/frontend/commit/330755c63e3405533a5da79c84ef4f379eb43e1c)
- ⤵ load dynamic build info in Footer component [`c089bb3`](https://git.odit.services/lfk/frontend/commit/c089bb39298fb1067093c2fa81101130c214947c)
- 📅 dynamic copyright year in Footer component [`b8a9e4f`](https://git.odit.services/lfk/frontend/commit/b8a9e4f272f925999b9a032dd009f7498acbfae0)
- 👀 improved Footer layout + display on Login component [`43b4065`](https://git.odit.services/lfk/frontend/commit/43b406592ebe115cea04a8dbf36874c0a5bdd7e9)
- ✨ added versionbuilder.js script [`1dd6674`](https://git.odit.services/lfk/frontend/commit/1dd6674faad686c0048a62b4cd25ab21b5c8b04f)
- ⚡ add versionbuilder script to release hook [`16f5724`](https://git.odit.services/lfk/frontend/commit/16f572480ad55425890061f9dad65fe85f2f39ad)
- 🔨 sample build of index.html with versionbuilder script [`3caa1fc`](https://git.odit.services/lfk/frontend/commit/3caa1fc277b99ee767c1e1fc4a28fd247d98e659)
#### [0.1.4](https://git.odit.services/lfk/frontend/compare/0.1.3...0.1.4) #### [0.1.4](https://git.odit.services/lfk/frontend/compare/0.1.3...0.1.4)
> 10 January 2021
- Merge commit '45ec97066f425ac2ac66914be649cbd5a1038e10' into dev [`#20`](https://git.odit.services/lfk/frontend/issues/20) - Merge commit '45ec97066f425ac2ac66914be649cbd5a1038e10' into dev [`#20`](https://git.odit.services/lfk/frontend/issues/20)
- 🌎 add remaining translation keys for filepond [`45ec970`](https://git.odit.services/lfk/frontend/commit/45ec97066f425ac2ac66914be649cbd5a1038e10) - 🌎 add remaining translation keys for filepond [`45ec970`](https://git.odit.services/lfk/frontend/commit/45ec97066f425ac2ac66914be649cbd5a1038e10)
- add basic i18n logic to filepond [`b08c0f1`](https://git.odit.services/lfk/frontend/commit/b08c0f145a13d295b2a51c7a6da76faceb80a90c) - add basic i18n logic to filepond [`b08c0f1`](https://git.odit.services/lfk/frontend/commit/b08c0f145a13d295b2a51c7a6da76faceb80a90c)
- 🚀RELEASE v0.1.4 [`4674b52`](https://git.odit.services/lfk/frontend/commit/4674b52717e388122e113553b8a136c649ce030c)
- 🌎 About - i18n [`692c906`](https://git.odit.services/lfk/frontend/commit/692c906cd26bdb7f7d730b90734d23748e0ab451) - 🌎 About - i18n [`692c906`](https://git.odit.services/lfk/frontend/commit/692c906cd26bdb7f7d730b90734d23748e0ab451)
- ✨ About - change license modal icon to "legal" [`0e31ba2`](https://git.odit.services/lfk/frontend/commit/0e31ba212f99d90b133bc242e5b4d163aa99b93b) - ✨ About - change license modal icon to "legal" [`0e31ba2`](https://git.odit.services/lfk/frontend/commit/0e31ba212f99d90b133bc242e5b4d163aa99b93b)
- new license file version [CI SKIP] [`4f3837a`](https://git.odit.services/lfk/frontend/commit/4f3837ac45a5df9a7476fd68ec9c069dc6b128cd) - new license file version [CI SKIP] [`4f3837a`](https://git.odit.services/lfk/frontend/commit/4f3837ac45a5df9a7476fd68ec9c069dc6b128cd)

View File

@@ -1,4 +1,4 @@
FROM node:15.4.0-alpine3.12 FROM node:15.5.1-alpine3.12
WORKDIR /app WORKDIR /app
RUN npm i -g pnpm RUN npm i -g pnpm
COPY package.json ./ COPY package.json ./
@@ -11,6 +11,7 @@ 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

@@ -9,7 +9,7 @@ http {
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ { location ~* \.(?:ico|css|gif|jpe?g|png)$ {
expires 1y; expires 1y;
add_header Pragma public; add_header Pragma public;
add_header Cache-Control "public"; add_header Cache-Control "public";

View File

@@ -1,19 +1,18 @@
{ {
"name": "@odit/lfk-frontend", "name": "@odit/lfk-frontend",
"version": "0.1.4", "version": "0.3.0",
"scripts": { "scripts": {
"i18n-order": "node order.js", "i18n-order": "node order.js",
"dev": "snowpack dev", "dev": "snowpack dev",
"build": "snowpack build", "build": "snowpack build",
"build:sw": "workbox generateSW workbox-config.js", "build:sw": "workbox generateSW workbox-config.js",
"release": "release-it", "release": "release-it",
"changelog": "npx auto-changelog --commit-limit false --template https://raw.githubusercontent.com/release-it/release-it/master/templates/changelog-compact.hbs",
"licenses:export": "license-exporter --json -o public" "licenses:export": "license-exporter --json -o public"
}, },
"dependencies": { "dependencies": {
"@odit/lfk-client-js": "0.0.10", "@odit/lfk-client-js": "0.0.12",
"filepond": "4.25.1", "filepond": "4.25.1",
"gridjs": "3.2.1", "gridjs": "3.2.2",
"localforage": "1.9.0", "localforage": "1.9.0",
"lodash.isequal": "^4.5.0", "lodash.isequal": "^4.5.0",
"svelte-filepond": "0.0.1", "svelte-filepond": "0.0.1",
@@ -26,13 +25,13 @@
}, },
"devDependencies": { "devDependencies": {
"@odit/license-exporter": "0.0.9", "@odit/license-exporter": "0.0.9",
"@snowpack/plugin-svelte": "3.4.1", "@snowpack/plugin-svelte": "3.5.1",
"auto-changelog": "^2.2.1", "auto-changelog": "^2.2.1",
"autoprefixer": "10.2.1", "autoprefixer": "10.2.1",
"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.0-rc.2", "snowpack": "3.0.10",
"svelte": "3.31.2", "svelte": "3.31.2",
"svelte-preprocess": "4.6.1", "svelte-preprocess": "4.6.1",
"workbox-cli": "6.0.2" "workbox-cli": "6.0.2"
@@ -51,7 +50,7 @@
"publish": false "publish": false
}, },
"hooks": { "hooks": {
"after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md" "after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md && node versionbuilder.js && git add public/index.html && node order.js && git add src/locales"
} }
} }
} }

View File

@@ -13,6 +13,7 @@
</head> </head>
<body> <body>
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.3.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>

File diff suppressed because one or more lines are too long

View File

@@ -5,10 +5,11 @@ module.exports = {
src: '/_dist_' src: '/_dist_'
}, },
plugins: [ '@snowpack/plugin-svelte' ], plugins: [ '@snowpack/plugin-svelte' ],
install: [ routes: [
/* ... */ /* Enable an SPA Fallback in development: */
{ match: 'routes', src: '.*', dest: '/index.html' }
], ],
installOptions: { packageOptions: {
/* ... */ /* ... */
sourceMap: false sourceMap: false
}, },
@@ -18,13 +19,8 @@ module.exports = {
buildOptions: { buildOptions: {
/* ... */ /* ... */
}, },
proxy: {
/* ... */
},
alias: { alias: {
/* ... */ /* ... */
}, },
experiments: {
optimize: { bundle: true, minify: true } optimize: { bundle: true, minify: true }
}
}; };

View File

@@ -1,6 +1,7 @@
<script> <script>
import "./TailwindStyles.svelte"; import "./TailwindStyles.svelte";
import "toastify-js/src/toastify.css"; import "toastify-js/src/toastify.css";
import "gridjs/dist/theme/mermaid.css";
import { Route, router } from "tinro"; import { Route, router } from "tinro";
router.subscribe((routeInfo) => { router.subscribe((routeInfo) => {
window.scrollTo(0, 0); window.scrollTo(0, 0);

View File

@@ -0,0 +1,162 @@
<script>
import { _ } from "svelte-i18n";
import { clickOutside } from "./outsideclick";
import { focusTrap } from "svelte-focus-trap";
import { RunnerOrganisationService } from "@odit/lfk-client-js";
import Toastify from "toastify-js";
export let modal_open;
export let current_organizations;
let name_input_dom;
function focus(el) {
el.focus();
}
$: name = "";
$: processed_last_submit = true;
$: isOrgnameValid = name.trim().length !== 0;
$: createbtnenabled = isOrgnameValid;
(() => {
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: "Organization is being added...",
duration: -1,
}).showToast();
RunnerOrganisationService.runnerOrganisationControllerPost({
name,
address: undefined,
contact: undefined,
})
.then((result) => {
console.log(result);
name = "";
modal_open = false;
//
Toastify({
text: "Organization added",
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
current_organizations = current_organizations.concat([result]);
})
.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
class="h-6 w-6 text-blue-600"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"><path
d="M17 19h2v-8h-6v8h2v-6h2v6zM3 19V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v5h2v10h1v2H2v-2h1zm4-8v2h2v-2H7zm0 4v2h2v-2H7zm0-8v2h2V7H7z" /></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 Organization
</h3>
<div class="mt-2 mb-6">
<p class="text-sm text-gray-500">
Please provide the required information to add a new
organization.
</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">Name</label>
<input
use:focus
autocomplete="off"
placeholder="Name"
class:border-red-500={!isOrgnameValid}
class:focus:border-red-500={!isOrgnameValid}
class:focus:ring-red-500={!isOrgnameValid}
bind:value={name}
bind:this={name_input_dom}
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 !isOrgnameValid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
Organization name 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

@@ -2,20 +2,21 @@
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 { tracks as tracksstore } from "../store.js";
import { UserService } from "@odit/lfk-client-js"; import { UserService } from "@odit/lfk-client-js";
import isEmail from "validator/es/lib/isEmail"; import isEmail from "validator/es/lib/isEmail";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import "toastify-js/src/toastify.css";
export let modal_open; export let modal_open;
export let current_users;
let firstname_input; let firstname_input;
let lastname_input; let lastname_input;
let middlename_input; let middlename_input;
let username_input;
let password_input; let password_input;
let email_input; let email_input;
function focus(el) { function focus(el) {
el.focus(); el.focus();
} }
$: username_input_value = "";
$: middlename_input_value = ""; $: middlename_input_value = "";
$: password_input_value = ""; $: password_input_value = "";
$: email_input_value = ""; $: email_input_value = "";
@@ -49,17 +50,25 @@
text: "User is being added...", text: "User is being added...",
duration: -1, duration: -1,
}).showToast(); }).showToast();
UserService.userControllerPost({ let postdata={
firstname: firstname_input_value, firstname: firstname_input_value,
lastname: lastname_input_value, lastname: lastname_input_value,
middlename: middlename_input_value, middlename: middlename_input_value,
email: email_input_value, password: password_input_value
password: password_input_value, };
}) if(email_input_value!==""){
postdata.email=email_input_value;
}
if(username_input_value!==""){
postdata.username=username_input_value;
}
UserService.userControllerPost(postdata)
.then((result) => { .then((result) => {
firstname_input_value = ""; firstname_input_value = "";
lastname_input_value = ""; lastname_input_value = "";
middlename_input_value = ""; middlename_input_value = "";
email_input_value = "";
username_input_value = "";
modal_open = false; modal_open = false;
// //
Toastify({ Toastify({
@@ -67,12 +76,8 @@
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
let storeval = []; current_users.push(result);
tracksstore.subscribe((val) => { current_users=current_users;
storeval = val;
});
storeval.push(result);
tracksstore.set(storeval);
}) })
.catch((err) => { .catch((err) => {
// //
@@ -213,6 +218,19 @@
</span> </span>
{/if} {/if}
</div> </div>
<div class="col-span-6">
<label
for="trackname"
class="block text-sm font-medium text-gray-700">{$_('username')}</label>
<input
autocomplete="off"
placeholder={$_('username')}
bind:value={username_input_value}
bind:this={username_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"> <div class="col-span-6">
<label <label
for="email" for="email"

View File

@@ -24,19 +24,40 @@
) )
check = true; check = true;
})(navigator.userAgent || navigator.vendor || window.opera); })(navigator.userAgent || navigator.vendor || window.opera);
const aspectratio=window.innerWidth/window.innerHeight;
if(aspectratio<=0.765){
check=true;
}
return check; return check;
} }
$: mobile = ismobile(); $: mobile = ismobile();
window.addEventListener('resize', function(){
const aspectratio=window.innerWidth/window.innerHeight;
if(aspectratio<=0.765){
navOpen=false;
mobile=true;
}else{
navOpen=true;
mobile=false;
}
});
// $: if (mobile===true) {
// console.log("changed to mobile");
// }
// $: if (mobile===false) {
// console.log("changed to md");
// }
function logout() { function logout() {
localForage.clear(); localForage.clear();
location.replace("/"); location.replace("/");
} }
</script> </script>
<section class="min-h-screen bg-gray-50 dark:bg-black dark:text-gray-100"> <section class="min-h-screen bg-gray-50">
<nav <nav
class:hidden={!navOpen && mobile} class:hidden={!navOpen && mobile}
class="select-none fixed top-0 left-0 z-20 h-full pb-10 overflow-x-hidden overflow-y-auto transition origin-left transform border-r w-60 md:translate-x-0"> class="select-none fixed top-0 left-0 z-20 h-full pb-10 overflow-x-hidden overflow-y-auto transition origin-left transform border-r w-60 md:translate-x-0 bg-gray-50">
<a href="/" class="flex items-center px-4 py-5"> <a href="/" class="flex items-center px-4 py-5">
<img <img
src="/lfk-logo.png" src="/lfk-logo.png"

View File

@@ -2,7 +2,6 @@
import { _, json } from "svelte-i18n"; import { _, json } from "svelte-i18n";
import { getlang } from "./datatable_i18n"; import { getlang } from "./datatable_i18n";
import { Grid } from "gridjs"; import { Grid } from "gridjs";
import "gridjs/dist/theme/mermaid.css";
// //
let table; let table;
const datatable = new Grid({ const datatable = new Grid({

View File

@@ -1,15 +1,35 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
$: releaseinfo = "";
setTimeout(() => {
releaseinfo = document
.getElementById("buildinfo")
.textContent.replace("RELEASE_INFO-", "")
.replace("-RELEASE_INFO", "");
}, 1500);
const year = new Date().getFullYear();
</script> </script>
<footer class="container"> <footer class="p-5 w-full">
<hr class="mt-2 mb-4 border-b-1 border-gray-300" />
<p class="text-sm text-gray-500 mt-4"> <p class="text-sm text-gray-500 mt-4">
Lauf für Kaya! Läufersystem - Copyright © 2020 + proudly powered by Lauf für Kaya! Läufersystem - Copyright ©
{year}
+ proudly powered by
<a <a
class="underline" class="underline"
href="https://odit.services" href="https://odit.services"
rel="noopener,noreferrer" rel="noopener,noreferrer"
target="_blank">ODIT.Services</a> target="_blank">ODIT.Services</a>
</p> </p>
<p class="text-sm text-gray-500 mt-4">
<a
class="underline"
target="_blank"
rel="noopener, noreferrer"
href="https://git.odit.services/lfk/frontend/">LfK!Frontend</a>@<a
class="underline"
target="_blank"
rel="noopener, noreferrer"
href="https://git.odit.services/lfk/frontend/src/tag/{releaseinfo}">{releaseinfo}</a>
</p>
</footer> </footer>

View File

@@ -4,6 +4,7 @@
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
store.init(); store.init();
import { OpenAPI, AuthService } from "@odit/lfk-client-js"; import { OpenAPI, AuthService } from "@odit/lfk-client-js";
import Footer from "./Footer.svelte";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
// ------ // ------
let username = "demo"; let username = "demo";
@@ -140,3 +141,4 @@
</div> </div>
</div> </div>
</div> </div>
<Footer />

View File

@@ -1,14 +1,95 @@
<script> <script>
import { RunnerOrganisationService } from "@odit/lfk-client-js";
import { _ } from "svelte-i18n";
import Toastify from "toastify-js";
import store from "../store";
import PromiseError from "./PromiseError.svelte";
$: delete_triggered = false;
$: save_enabled = !data_changed;
export let params; export let params;
let orgdata = {};
let original = {};
$: data_loaded = false;
$: data_changed = JSON.stringify(orgdata) === JSON.stringify(original);
const promise = RunnerOrganisationService.runnerOrganisationControllerGetOne(
params.orgid
).then((value) => {
data_loaded = true;
orgdata = Object.assign(orgdata, value);
original = Object.assign(original, value);
});
function deleteOrganisation() {
RunnerOrganisationService.runnerOrganisationControllerRemove(
original.id,
true
)
.then((resp) => {
location.replace("./");
})
.catch((err) => {});
}
function submit() {
if (data_loaded === true && save_enabled) {
Toastify({
text: "updating organization",
duration: 2500,
}).showToast();
RunnerOrganisationService.runnerOrganisationControllerPut(
original.id,
orgdata
)
.then((resp) => {
Object.assign(original, orgdata);
original = orgdata;
Object.assign(original, orgdata);
//
Toastify({
text: "updated organization",
duration: 2500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
})
.catch((err) => {});
} else {
}
}
</script> </script>
<section class="container p-5"> {#if data_loaded}
<span class="mb-1 text-3xl font-extrabold leading-tight"> <section class="container p-5">
Orgs <div class="mb-8 text-3xl font-extrabold leading-tight">
{original.name}
<span data-id="org_actions_${orgdata.id}">
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
{#if delete_triggered}
<button
on:click={deleteOrganisation}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-delete')}</button>
<button
on:click={() => {
delete_triggered = !delete_triggered;
}}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm">{$_('cancel')}</button>
{/if}
{#if !delete_triggered}
<button
on:click={() => {
delete_triggered = true;
}}
type="button"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-organization')}</button>
{/if}
{/if}
{#if !delete_triggered}
<button
on:click={submit}
disabled={!save_enabled}
class:opacity-50={!save_enabled}
type="button"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('save-changes')}</button>
{/if}
</span> </span>
<p class="mb-8 text-lg text-gray-500"> </div>
configure the tracks & minimum lap times
</p>
<div class="flex flex-row mb-4"> <div class="flex flex-row mb-4">
<div class="w-full"> <div class="w-full">
<nav class="w-full flex"> <nav class="w-full flex">
@@ -80,4 +161,45 @@
</nav> </nav>
</div> </div>
</div> </div>
</section> <div class="text-sm w-full">
<label for="name" class="font-medium text-gray-700">Name</label>
<input
autocomplete="off"
placeholder="Name"
type="text"
bind:value={orgdata.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" />
</div>
<div class="text-sm w-full">
<label
for="contact"
class="font-medium text-gray-700">{$_('contact')}</label>
<input
autocomplete="off"
placeholder={$_('contact')}
type="text"
bind:value={orgdata.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" />
</div>
<div class="text-sm w-full">
<label
for="address"
class="font-medium text-gray-700">{$_('address')}</label>
<input
autocomplete="off"
placeholder={$_('address')}
type="text"
bind:value={orgdata.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" />
</div>
</section>
{:else}
{#await promise}
organization detail is being loaded...
{:catch error}
<PromiseError />
{/await}
{/if}

View File

@@ -0,0 +1,157 @@
<script>
import { _ } from "svelte-i18n";
import { RunnerOrganisationService } from "@odit/lfk-client-js";
import "gridjs/dist/theme/mermaid.css";
import store from "../store";
import OrgsEmptyState from "./OrgsEmptyState.svelte";
$: searchvalue = "";
$: active_deletes = [];
export let current_organizations = [];
const promise = RunnerOrganisationService.runnerOrganisationControllerGetAll().then(
(val) => {
current_organizations = val;
}
);
</script>
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:GET')}
{#await promise}
<div
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
role="alert">
<p class="font-bold">organizations are being loaded...</p>
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
</div>
{:then}
{#if current_organizations.length === 0}
<OrgsEmptyState />
{:else}
<input
type="search"
bind:value={searchvalue}
placeholder={$_('datatable.search')}
aria-label={$_('datatable.search')}
class="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">
Address
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Contact
</th>
<th scope="col" class="relative px-6 py-3">
<span class="sr-only">Action</span>
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
{#each current_organizations as o}
{#if Object.values(o)
.toString()
.toLowerCase()
.includes(searchvalue)}
<tr data-rowid="org_{o.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 dark:text-gray-100">
{o.name}
</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="ml-4">
<div
class="text-sm font-medium text-gray-900 dark:text-gray-100">
{#if o.address}
{JSON.stringify(o.address)}
{:else}no address specified{/if}
</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="ml-4">
<div
class="text-sm font-medium text-gray-900 dark:text-gray-100">
{#if o.contact}
{JSON.stringify(o.contact)}
{:else}no contact specified{/if}
</div>
</div>
</div>
</td>
{#if active_deletes[o.id] === true}
<td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
on:click={() => {
active_deletes[o.id] = false;
}}
tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
Delete</button>
<button
on:click={() => {
RunnerOrganisationService.runnerOrganisationControllerRemove(o.id, true)
.then((resp) => {
current_organizations = current_organizations.filter((obj) => obj.id !== o.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="./{o.id}"
class="text-indigo-600 hover:text-indigo-900">Edit</a>
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:DELETE')}
<button
on:click={() => {
active_deletes[o.id] = true;
}}
tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Delete</button>
{/if}
</td>
{/if}
</tr>
{/if}
{/each}
</tbody>
</table>
</div>
{/if}
{:catch error}
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
<span class="inline-block align-middle mr-8">
<b class="capitalize">{$_('general_promise_error')}</b>
{error}
</span>
</div>
{/await}
{/if}

View File

@@ -1,13 +1,31 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import store from "../store";
import AddOrgModal from "./AddOrgModal.svelte";
export let modal_open = false;
import OrgOverview from "./OrgOverview.svelte";
console.log(store.state.jwtinfo.userdetails.permissions);
let current_organizations = [];
</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">
Orgs {$_('organizations')}
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:CREATE')}
<button
on:click={() => {
modal_open = true;
}}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
{$_('create-organization')}
</button>
{/if}
</span> </span>
<p class="mb-8 text-lg text-gray-500"> <p class="mb-8 text-lg text-gray-500">manage runner organizations</p>
add, delete, edit organizations <OrgOverview bind:current_organizations />
</p>
<nav><a class="underline" href="./1">Org 1</a></nav>
</section> </section>
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:CREATE')}
<AddOrgModal bind:current_organizations bind:modal_open />
{/if}

View File

@@ -0,0 +1,15 @@
<script>
import { _ } from "svelte-i18n";
import AddOrgModal from "./AddOrgModal.svelte";
let modal_open = false;
let current_organizations = [];
</script>
<div class="text-center items-center justify-center">
<p class="mb-16 text-lg text-gray-500">
<span class="font-bold">There are no organizations added yet.</span><br />
<span>Add your first organization</span>
</p>
</div>
<AddOrgModal bind:modal_open bind:current_organizations />

View File

@@ -6,7 +6,6 @@
const tracks_promise = TrackService.trackControllerGetAll(); const tracks_promise = TrackService.trackControllerGetAll();
import { getlang } from "./datatable_i18n"; import { getlang } from "./datatable_i18n";
import { Grid, html } from "gridjs"; import { Grid, html } from "gridjs";
import "gridjs/dist/theme/mermaid.css";
import { tracks as tracksstore } from "../store.js"; import { tracks as tracksstore } from "../store.js";
$: trackscache = []; $: trackscache = [];
$: blocked = []; $: blocked = [];

View File

@@ -1,27 +1,91 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import lodashIsEqual from "lodash.isequal"; import lodashIsEqual from "lodash.isequal";
import { UserService } from "@odit/lfk-client-js"; import store from "../store";
import "gridjs/dist/theme/mermaid.css"; import {
UserService,
UserGroupService,
PermissionService,
} from "@odit/lfk-client-js";
import Toastify from "toastify-js";
import PromiseError from "./PromiseError.svelte"; import PromiseError from "./PromiseError.svelte";
export let params; export let params;
const user_promise = UserService.userControllerGetOne(params.userid); const user_promise = UserService.userControllerGetOne(params.userid);
let data_loaded = false; let data_loaded = false;
let original_data = undefined; $: delete_triggered = false;
$: editable_userdata = undefined; $: original_data = {};
$: editable_userdata = {};
$: allpermissions = [];
$: allgroups = [];
$: allgroups_ids = [];
$: usergroups_array_objects = [];
$: usergroups_array = [];
let usergroups_array_original = [];
user_promise.then((data) => { user_promise.then((data) => {
data_loaded = true; data_loaded = true;
original_data = data; original_data = Object.assign(original_data, data);
editable_userdata = data; editable_userdata = data;
data.groups.forEach((g) => {
usergroups_array=usergroups_array.concat([g.id]);
}); });
// $: changes_performed = lodashIsEqual(original_data, editable_userdata); usergroups_array_original = usergroups_array;
$: changes_performed = !lodashIsEqual({ test: 1 }, { test: 1 }); allgroups.forEach((g) => {
allgroups_ids.push(g.id);
});
});
UserGroupService.userGroupControllerGetAll().then((data) => {
allgroups = data;
});
const permissions_promise = PermissionService.permissionControllerGetAll();
permissions_promise.then((data) => {
data.forEach((p) => {
allpermissions=allpermissions.concat([p.target + ":" + p.action])
});
});
$: changes_performed = !lodashIsEqual(original_data, editable_userdata);
$: groups_changed = JSON.stringify(usergroups_array)===JSON.stringify(usergroups_array_original);
$: save_enabled = changes_performed||!groups_changed;
function submit() { function submit() {
if (data_loaded === true && changes_performed === true) { if (
console.log("ok, submitting..."); !lodashIsEqual(original_data.permissions, editable_userdata.permissions)
} else { ) {
console.log("no changes performed"); // TODO: add+delete permissions
} }
if (data_loaded === true && save_enabled) {
let tmp=[];
usergroups_array.forEach(g => {
const group=allgroups.find(obj=>obj.id===g);
tmp.push(group);
});
editable_userdata.groups=tmp;
Toastify({
text: $_("updating-user"),
duration: 2500,
}).showToast();
UserService.userControllerPut(original_data.id, editable_userdata)
.then((resp) => {
Object.assign(original_data, editable_userdata);
original_data = editable_userdata;
Object.assign(original_data, editable_userdata);
//
Toastify({
text: $_("user-updated"),
duration: 2500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
})
.catch((err) => {
});
} else {
}
}
function deleteUser() {
UserService.userControllerRemove(original_data.id, true)
.then((resp) => {
location.replace("./");
})
.catch((err) => {
});
} }
</script> </script>
@@ -63,51 +127,54 @@
<polyline points="12 5 19 12 12 19" /></svg> <polyline points="12 5 19 12 12 19" /></svg>
</li> </li>
<li class="flex items-center"> <li class="flex items-center">
<span class="mr-2">{user.firstname} <span class="mr-2">{original_data.firstname}
{user.middlename || ''} {original_data.middlename || ''}
{user.lastname}</span> {original_data.lastname}</span>
</li> </li>
</ol> </ol>
</nav> </nav>
</div> </div>
</div> </div>
<div class="mb-8 text-3xl font-extrabold leading-tight"> <div class="mb-8 text-3xl font-extrabold leading-tight">
{user.firstname} {original_data.firstname}
{user.middlename || ''} {original_data.middlename || ''}
{user.lastname} {original_data.lastname}
<span data-id="user_actions_${user.id}"> <span data-id="user_actions_${editable_userdata.id}">
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
{#if delete_triggered}
<button <button
class="hidden w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-400 text-base font-medium text-white sm:w-auto sm:text-sm" on:click={deleteUser}
data-userid="${user.id}" 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>
onclick="user__delete_cancel()">{$_('cancel')}</button>
<button <button
class="hidden w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-500 text-base font-medium text-white sm:w-auto sm:text-sm" on:click={() => {
data-userid="${user.id}" delete_triggered = !delete_triggered;
onclick="user__delete_confirm()">{$_('confirm-delete')}</button> }}
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 <button
on:click={() => {
delete_triggered = true;
}}
type="button" type="button"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-user')}</button> class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-user')}</button>
{/if}
{/if}
{#if !delete_triggered}
<button <button
disabled={!changes_performed} disabled={!save_enabled}
class:opacity-50={!changes_performed} class:opacity-50={!save_enabled}
type="button" type="button"
on:click={submit} 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> 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> </span>
</div> </div>
<!-- -->
<div class="mt-2 flex items-center"> <div class="mt-2 flex items-center">
<img <img
alt={$_('profile-picture')} alt={$_('profile-picture')}
class="inline-block h-20 w-20 rounded-full overflow-hidden bg-gray-100" class="inline-block h-20 w-20 rounded-full overflow-hidden bg-gray-100"
src={user.profilePic} /> src={editable_userdata.profilePic} />
<!-- <span
class="inline-block h-12 w-12 rounded-full overflow-hidden bg-gray-100"><svg
class="h-full w-full text-gray-300"
fill="currentColor"
viewBox="0 0 24 24"><path
d="M24 20.993V24H0v-2.996A14.977 14.977 0 0112.004 15c4.904 0 9.26 2.354 11.996 5.993zM16.002 8.999a4 4 0 11-8 0 4 4 0 018 0z" /></svg></span> -->
<button <button
type="button" type="button"
class="ml-5 bg-white py-2 px-3 border border-gray-300 rounded-md shadow-sm text-sm leading-4 font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Change</button> class="ml-5 bg-white py-2 px-3 border border-gray-300 rounded-md shadow-sm text-sm leading-4 font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Change</button>
@@ -165,6 +232,102 @@
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 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div> </div>
<div class="text-sm w-full">
<label
for="email"
class="font-medium text-gray-700">{$_('e-mail-adress')}</label>
<input
autocomplete="off"
placeholder={$_('e-mail-adress')}
type="email"
bind:value={editable_userdata.email}
name="email"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div>
<div class="text-sm w-full">
<label
for="username"
class="font-medium text-gray-700">{$_('username')}</label>
<input
autocomplete="off"
placeholder={$_('username')}
type="text"
bind:value={editable_userdata.username}
name="username"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div>
<div class="text-sm w-full">
<span class="font-medium">{$_('groups')}</span>
<!-- svelte-ignore a11y-no-onchange -->
<select
bind:value={usergroups_array}
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2"
multiple>
{#each allgroups as g}
{#if usergroups_array.includes(g.id)}
<option selected value={g.id}>{g.name}</option>
{:else}
<option value={g.id}>{g.name}</option>
{/if}
{/each}
</select>
</div>
<div class="text-sm w-full">
<span class="font-medium">Permissions</span>
<div class="border-4 border-dashed rounded mb-4 p-5 text-lg text-center">
<!-- -->
<div class="flex flex-wrap -mx-1 overflow-hidden">
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2">
verfügbare
</div>
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2">erteilte</div>
</div>
<!-- -->
<div class="flex flex-wrap -mx-1 overflow-hidden">
{#if allpermissions.length > 0}
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2">
<div
class="border-4 border-dashed rounded mb-4 p-5 text-lg text-center">
{#each allpermissions as p}
{#if !editable_userdata.permissions.includes(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">
{p}
<button
on:click={() => {
editable_userdata.permissions.push(p);
editable_userdata.permissions = editable_userdata.permissions;
}}
type="button"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-200 text-base font-medium text-black hover:bg-green-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:ml-3 sm:w-auto sm:text-sm">+</button>
</p>
{/if}
{/each}
</div>
</div>
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2">
<div
class="border-4 border-dashed rounded mb-4 p-5 text-lg text-center">
{#each allpermissions as p}
{#if editable_userdata.permissions.includes(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">
{p}
<button
on:click={() => {
editable_userdata.permissions = editable_userdata.permissions.filter((obj) => obj !== p);
}}
type="button"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-300 text-base font-medium text-black hover:bg-red-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm">-</button>
</p>
{/if}
{/each}
</div>
</div>
{/if}
</div>
</div>
</div>
</section> </section>
{:catch error} {:catch error}
<PromiseError {error} /> <PromiseError {error} />

View File

@@ -1,13 +1,17 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import store from "../store";
import AddUserModal from "./AddUserModal.svelte"; import AddUserModal from "./AddUserModal.svelte";
export let modal_open = false; export let modal_open = false;
import UsersOverview from "./UsersOverview.svelte"; import UsersOverview from "./UsersOverview.svelte";
console.log(store.state.jwtinfo.userdetails.permissions);
let current_users=[];
</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">
{$_('users')} {$_('users')}
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:CREATE')}
<button <button
on:click={() => { on:click={() => {
modal_open = true; modal_open = true;
@@ -16,8 +20,12 @@
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"> 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-user')} {$_('create-user')}
</button> </button>
{/if}
</span> </span>
<p class="mb-8 text-lg text-gray-500">{$_('manage-admin-users')}</p> <p class="mb-8 text-lg text-gray-500">{$_('manage-admin-users')}</p>
<UsersOverview /> <UsersOverview bind:current_users />
</section> </section>
<AddUserModal bind:modal_open />
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:CREATE')}
<AddUserModal bind:current_users bind:modal_open />
{/if}

View File

@@ -1,32 +1,33 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import Toastify from "toastify-js";
import { UserService } from "@odit/lfk-client-js"; import { UserService } from "@odit/lfk-client-js";
const users_promise = UserService.userControllerGetAll(); const users_promise = UserService.userControllerGetAll();
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 UsersEmptyState from "./UsersEmptyState.svelte"; import UsersEmptyState from "./UsersEmptyState.svelte";
$: searchvalue = ""; $: searchvalue = "";
$: userscache = []; $: active_deletes = [];
export let current_users=[];
$: advanced_search = false; $: advanced_search = false;
usersstore.subscribe((val) => { usersstore.subscribe((val) => {
userscache = val; userscache = val;
current_users=val;
}); });
users_promise.then((data) => { users_promise.then((data) => {
console.log(data);
usersstore.set(data); usersstore.set(data);
}); });
</script> </script>
{#await users_promise} {#if store.state.jwtinfo.userdetails.permissions.includes('USER:GET')}
{#await users_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"
role="alert"> role="alert">
<p class="font-bold">users are being loaded...</p> <p class="font-bold">users are being loaded...</p>
<p class="text-sm">{$_('this-might-take-a-moment')}</p> <p class="text-sm">{$_('this-might-take-a-moment')}</p>
</div> </div>
{:then users} {:then}
{#if userscache.length === 0} {#if current_users.length === 0}
<UsersEmptyState /> <UsersEmptyState />
{:else} {:else}
{#if advanced_search} {#if advanced_search}
@@ -75,12 +76,12 @@
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-gray-200"> <tbody class="divide-y divide-gray-200">
{#each users as u} {#each current_users as u}
{#if Object.values(u) {#if Object.values(u)
.toString() .toString()
.toLowerCase() .toLowerCase()
.includes(searchvalue)} .includes(searchvalue)}
<tr> <tr data-rowid="user_{u.id}">
<td class="px-6 py-4 whitespace-nowrap"> <td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center"> <div class="flex items-center">
{#if u.profilePic} {#if u.profilePic}
@@ -120,16 +121,46 @@
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{g.name}</a> class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{g.name}</a>
{/each} {/each}
</td> </td>
{#if active_deletes[u.id] === true}
<td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
on:click={() => {
active_deletes[u.id] = false;
}}
tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
Delete</button>
<button
on:click={() => {
UserService.userControllerRemove(u.id, true)
.then((resp) => {
current_users=current_users.filter(obj=>obj.id!==u.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 <td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<a <a
href="./{u.id}" href="./{u.id}"
class="text-indigo-600 hover:text-indigo-900">Edit</a> class="text-indigo-600 hover:text-indigo-900">Edit</a>
<span {#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
<button
on:click={() => {
active_deletes[u.id] = true;
}}
tabindex="0" tabindex="0"
href="#" class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Delete</button>
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Delete</span> {/if}
</td> </td>
{/if}
</tr> </tr>
{/if} {/if}
{/each} {/each}
@@ -137,11 +168,12 @@
</table> </table>
</div> </div>
{/if} {/if}
{:catch error} {:catch error}
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500"> <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"> <span class="inline-block align-middle mr-8">
<b class="capitalize">{$_('general_promise_error')}</b> <b class="capitalize">{$_('general_promise_error')}</b>
{error} {error}
</span> </span>
</div> </div>
{/await} {/await}
{/if}

View File

@@ -4,6 +4,7 @@
"about": "About", "about": "About",
"action": "Action", "action": "Action",
"add-your-first-track": "Add your first track", "add-your-first-track": "Add your first track",
"address": "Address",
"application_name": "Lauf für Kaya! - Admin", "application_name": "Lauf für Kaya! - Admin",
"author": "Author", "author": "Author",
"browse": "Browse", "browse": "Browse",
@@ -13,10 +14,12 @@
"changelog": "Changelog", "changelog": "Changelog",
"close": "Close", "close": "Close",
"confirm-delete": "Confirm Delete", "confirm-delete": "Confirm Delete",
"contact": "Contact",
"count_organizations": "# Organizations", "count_organizations": "# Organizations",
"count_teams": "# Teams", "count_teams": "# Teams",
"create": "Create", "create": "Create",
"create-a-new-track": "Create a new Track", "create-a-new-track": "Create a new Track",
"create-organization": "Create Organization",
"create-user": "Create User", "create-user": "Create User",
"credits": "Credits", "credits": "Credits",
"dashboard-greeting": "hello there", "dashboard-greeting": "hello there",
@@ -36,6 +39,7 @@
"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-organization": "Delete Organization",
"delete-user": "Delete User", "delete-user": "Delete User",
"dependency_name": "Name", "dependency_name": "Name",
"dont-have-your-email-connected": "Don't have your email connected?", "dont-have-your-email-connected": "Don't have your email connected?",
@@ -71,6 +75,7 @@
"general-stats": "General Stats", "general-stats": "General Stats",
"general_promise_error": "😢 Error", "general_promise_error": "😢 Error",
"goback": "Go Home", "goback": "Go Home",
"groups": "Groups",
"hallo": "hello", "hallo": "hello",
"installed-version": "Installed version", "installed-version": "Installed version",
"invalid-mail-reset": "the provided email is invalid", "invalid-mail-reset": "the provided email is invalid",
@@ -89,6 +94,7 @@
"minimum-lap-time-in-s": "minimum lap time in s", "minimum-lap-time-in-s": "minimum lap time in s",
"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.",
"organizations": "Organizations",
"orgs": "Orgs", "orgs": "Orgs",
"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",
@@ -116,6 +122,9 @@
"track-length-in-m": "Track Length in m", "track-length-in-m": "Track Length in m",
"track-name": "Track name", "track-name": "Track name",
"tracks": "Tracks", "tracks": "Tracks",
"updating-user": "updating user...",
"user-updated": "User updated",
"username": "Username",
"users": "Users", "users": "Users",
"valid-email-is-required": "valid email is required", "valid-email-is-required": "valid email is required",
"welcome_wavinghand": "Welcome 👋", "welcome_wavinghand": "Welcome 👋",

View File

@@ -27,6 +27,8 @@ const store = () => {
AuthService.authControllerRefresh({ token: state.auth.refresh_token }).then((auth) => { AuthService.authControllerRefresh({ token: state.auth.refresh_token }).then((auth) => {
console.log('got new auth'); console.log('got new auth');
OpenAPI.TOKEN = auth.access_token; OpenAPI.TOKEN = auth.access_token;
const jwtinfo = JSON.parse(atob(auth.access_token.split('.')[1]));
state.jwtinfo = jwtinfo;
localForage.setItem('logindata', auth); localForage.setItem('logindata', auth);
}); });
}, },
@@ -39,8 +41,8 @@ const store = () => {
// //
state.refreshInterval = setInterval(() => { state.refreshInterval = setInterval(() => {
this.refreshAuth(); this.refreshAuth();
// 4min // 2min
}, 4 * 60000); }, 2 * 60000);
// //
return state; return state;
}); });

View File

@@ -2,7 +2,7 @@ module.exports = {
purge: { purge: {
content: [ './src/**/*.svelte' ] content: [ './src/**/*.svelte' ]
}, },
darkMode: 'media', // darkMode: 'media',
variants: {}, variants: {},
plugins: [], plugins: [],
theme: { theme: {

5
versionbuilder.js Normal file
View File

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