Merge branch 'master' into test
This commit is contained in:
commit
fc2aa31d77
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,6 +5,7 @@ node_modules/
|
||||
assets/icons
|
||||
assets/favicons
|
||||
bin/
|
||||
assets/fonts/
|
||||
*.hi
|
||||
*.o
|
||||
*.sqlite3
|
||||
|
||||
948
CHANGELOG.md
948
CHANGELOG.md
@ -2,881 +2,6 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [v27.4.59-test-h0.0.18](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-h0.0.17...v27.4.59-test-h0.0.18) (2025-02-19)
|
||||
|
||||
## [v27.4.59-test-h0.0.17](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-g0.0.17...v27.4.59-test-h0.0.17) (2025-02-19)
|
||||
|
||||
## [v27.4.59-test-g0.0.17](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-f0.0.17...v27.4.59-test-g0.0.17) (2025-02-18)
|
||||
|
||||
## [v27.4.59-test-f0.0.17](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-g0.0.16...v27.4.59-test-f0.0.17) (2025-02-17)
|
||||
|
||||
## [v27.4.59-test-g0.0.16](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-f0.0.16...v27.4.59-test-g0.0.16) (2025-02-16)
|
||||
|
||||
## [v27.4.59-test-f0.0.16](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-f0.0.15...v27.4.59-test-f0.0.16) (2025-02-16)
|
||||
|
||||
## [v27.4.59-test-f0.0.15](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.15...v27.4.59-test-f0.0.15) (2025-02-15)
|
||||
|
||||
## [v27.4.59-test-e0.0.15](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-f0.0.14...v27.4.59-test-e0.0.15) (2025-02-14)
|
||||
|
||||
## [v27.4.59-test-f0.0.14](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.14...v27.4.59-test-f0.0.14) (2025-02-14)
|
||||
|
||||
## [v27.4.59-test-e0.0.14](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.13...v27.4.59-test-e0.0.14) (2025-02-13)
|
||||
|
||||
## [v27.4.59-test-e0.0.13](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.12...v27.4.59-test-e0.0.13) (2025-02-12)
|
||||
|
||||
## [v27.4.59-test-e0.0.12](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-d0.0.12...v27.4.59-test-e0.0.12) (2025-02-12)
|
||||
|
||||
## [v27.4.59-test-d0.0.12](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-d0.0.11...v27.4.59-test-d0.0.12) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-d0.0.11](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-c0.0.11...v27.4.59-test-d0.0.11) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-c0.0.11](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-b0.0.11...v27.4.59-test-c0.0.11) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-b0.0.11](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-c0.0.10...v27.4.59-test-b0.0.11) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-c0.0.10](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-b0.0.10...v27.4.59-test-c0.0.10) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-b0.0.10](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.10...v27.4.59-test-b0.0.10) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-a0.0.10](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.9...v27.4.59-test-a0.0.10) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-a0.0.9](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.8...v27.4.59-test-a0.0.9) (2025-02-10)
|
||||
|
||||
## [v27.4.59-test-a0.0.8](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.7...v27.4.59-test-a0.0.8) (2025-02-10)
|
||||
|
||||
## [v27.4.59-test-a0.0.7](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.6...v27.4.59-test-a0.0.7) (2025-02-10)
|
||||
|
||||
## [v27.4.59-test-a0.0.6](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.5...v27.4.59-test-a0.0.6) (2025-02-08)
|
||||
|
||||
## [v27.4.59-test-a0.0.5](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.4...v27.4.59-test-a0.0.5) (2025-02-07)
|
||||
|
||||
## [v27.4.59-test-a0.0.4](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.3...v27.4.59-test-a0.0.4) (2025-02-07)
|
||||
|
||||
## [v27.4.59-test-a0.0.3](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.2...v27.4.59-test-a0.0.3) (2025-02-06)
|
||||
|
||||
## [v27.4.59-test-a0.0.2](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.1...v27.4.59-test-a0.0.2) (2025-02-05)
|
||||
|
||||
## [v27.4.59-test-a0.0.1](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.0...v27.4.59-test-a0.0.1) (2025-02-05)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ghci:** ghci works now as expected ([c3117db](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/c3117dbdcd1de9ef9f0751afa45018e2ebce2c42))
|
||||
|
||||
## [v27.4.59-test-a0.0.0](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59...v27.4.59-test-a0.0.0) (2024-10-25)
|
||||
|
||||
### Features
|
||||
|
||||
* **util script:** Util script for renaming of files added. ([caf8fec](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/caf8fec5acb94df16293bf9aa0cdab766f8829e8))
|
||||
* **frontend:** load icons from svg files ([22781e1](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/22781e1565e890cf6c5b40973146b0334cb667aa))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **stack.yaml:** move to uniworx.de gitlab ([55484e6](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/55484e631b786ea3710d322282019baf5292c243))
|
||||
* **utils/renamer:** Mehr outputs nur im verbose-Fall. ([ac30cb9](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/ac30cb9e6712d0ee3f204da4863d1e2509af8a76))
|
||||
* **utils:** Verboseparameter -v hinzugefuegt; rekursives makedir; genauere Meldungen. ([1806d9f](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/1806d9f01fc4a0746d2f9df42ef1ee6827c7fa09))
|
||||
* **Dockerfile:** change rights of source dir to env user ([e7a8183](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/e7a8183656ae419cfee2942543045c6fa6a9caa3))
|
||||
* **Makefile:** add missing dependency on well-known for backend-builds ([a09dc59](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/a09dc59f260843f8815c382576bb5254d21104bf))
|
||||
* **frontend:** fixed icon colour in table headers ([4c4571d](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/4c4571d2d0879e89f2572eba6015d34a7f4794c8))
|
||||
* **doc:** minor haddock problems ([d4f8a6c](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/d4f8a6c77b2a4a4540935f7f0beca0d0605508c8))
|
||||
|
||||
## [28.1.1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/t28.1.0...t28.1.1) (2024-04-22)
|
||||
|
||||
## [28.1.0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/t28.0.10...t28.1.0) (2024-04-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **middleware:** allow Cross Origin Resource Sharing (CORS) ([e1a25cd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e1a25cdd311c3d606404f7f94549875a2a15e2b3))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** use appsettings for azure tenant id; refactor azure lookup url methods ([7a510b3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7a510b315d62131e5fb47da8c1398144c57d4587))
|
||||
|
||||
## [28.0.10](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/t28.0.9...t28.0.10) (2024-04-18)
|
||||
|
||||
## [28.0.9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/t28.0.8...t28.0.9) (2024-04-08)
|
||||
|
||||
## [28.0.8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/t28.0.0...t28.0.8) (2024-04-06)
|
||||
|
||||
## [28.0.7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/d28.0.10...d28.0.7) (2024-03-22)
|
||||
|
||||
## [28.0.6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/d28.0.7...d28.0.6) (2024-01-13)
|
||||
|
||||
## [28.0.5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/d28.0.4...d28.0.5) (2024-01-10)
|
||||
|
||||
## [28.0.4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/d28.0.3...d28.0.4) (2024-01-09)
|
||||
|
||||
## [28.0.3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/d28.0.2...d28.0.3) (2024-01-07)
|
||||
|
||||
## [28.0.2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/d28.0.1...d28.0.2) (2024-01-07)
|
||||
|
||||
## [28.0.1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/d28.0.0...d28.0.1) (2024-01-07)
|
||||
|
||||
## 28.0.0 (2024-01-06)
|
||||
## [28.0.0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/t27.4.49...t28.0.0) (2024-03-21)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* remove applications and allocations
|
||||
* **auth:** additional authorisation caching
|
||||
* **jobs:** Job offloading
|
||||
* **migration:** ManualMigration
|
||||
* **html-field:** StoredMarkup
|
||||
* **course:** AccessPredicates now take continuation
|
||||
* **workflows:** digests now json encode via base64
|
||||
|
||||
Also improve efficiency of marking workflow files as referenced
|
||||
* **files:** files now chunked
|
||||
* split foundation
|
||||
* **db:** transactions need to be retryable, now
|
||||
* **dry-run:** runDBRead
|
||||
* **course-participants:** CourseParticipantState
|
||||
* **system-messages:** names of cookies & configuration changed
|
||||
* **allocations:** influence of grades on allocation priority now
|
||||
relative when priorities are ordinal
|
||||
* major version bumps
|
||||
* markdown based HTML input
|
||||
* **exams:** ExamResult now contains ExamResultPassedGrade
|
||||
* major navigation refactor
|
||||
* **hide-columns:** StorageManager version numbers
|
||||
* **frontend:** Major frontend refactor
|
||||
* **sub-study-fields:** superStudyField
|
||||
* Bumped esqueleto
|
||||
* yesod >=1.6
|
||||
* **exams:** examPartName no longer required
|
||||
* **exams:** Introduces ExamPartNumbers
|
||||
* **users:** Remove UserLecturer and UserAdmin
|
||||
* **courses:** auditing for course registrations and deregistrations, more
|
||||
tightly couple exam results, exam registration, and course registration (delete
|
||||
them together now)
|
||||
* **csv:** CsvColumnsExplained now required
|
||||
* **exams:** examOccurrenceName
|
||||
* **exams:** examStart and examPublishOccurrenceAssignments now optional
|
||||
* **exams:** E.isInfixOf and E.hasInfix
|
||||
* **standard-version:** Start of new versioning schema
|
||||
|
||||
### Features
|
||||
|
||||
* add user-system-function ([abc37ac](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/abc37aca9c2aa5eafe7eea9333886b43189d5591))
|
||||
* **add-users:** add page-action to add users from TUsersR ([9c62c9e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9c62c9ee8ca365ceea206c696d3596e46927391c))
|
||||
* **add-users:** connect confirmation form with handler ([c013ae9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c013ae9efcd7df812b26ae32ce04ba3da4e6aef4))
|
||||
* **add-users:** correctly add users and reroute ([fecc752](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fecc752d6ce3aa952efabdac2ff17064f4091050))
|
||||
* **add-users:** more page-actions for convenience ([a882a3c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a882a3c0d03ffc57902cbec779621fb58617ed3b))
|
||||
* additional exam functions on show page ([214e895](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/214e8951e49bada7081b35cdf4a570eba3890f87))
|
||||
* additional general purpose caching tier (memcachedLocal) ([939ab37](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/939ab37588bb71b14b8a9f3ab58d7440f598faf9))
|
||||
* admin interface to issue tokens ([738ab7b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/738ab7b738bf2264d74023aa90fa23461b21ac2c))
|
||||
* admin-crontab-r ([460c133](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/460c133aac316fb9317c5f08823e04c22eb63fe9))
|
||||
* **admin-crontab:** export as json ([bbd4916](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bbd4916f3a556ce4c05eb3b2b5268c9c072fdfdd))
|
||||
* **admin-test:** download test ([daaeb09](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/daaeb09de82ec5758cba564cb4bc5db7948f5476))
|
||||
* **admin-users:** allow adding users ([67f1201](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/67f120120f616377c8b5ab34b63941475195fcac))
|
||||
* **admin-workflows:** allow uploading graph spec as file ([48208c9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/48208c9105ba49feb784ea3143b610ed5b11b517))
|
||||
* admins can efficiently generate many tokens for random users ([600bbe5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/600bbe5d7e9051e4a4eac540b01ff358666ebc9c))
|
||||
* **alert-icons:** add custom icons for alerts ([bc67500](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bc675006d8c72a2994be832236036447ebe1efc1))
|
||||
* **alerticons:** allow alerts to have custom icons ([d70a958](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d70a9585f093c0701adf724ffe84cbaf3f1a592d))
|
||||
* **alerts js:** support custom icons in Alerts HTTP-Header ([8833cb5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8833cb5090738c351b8a47af558dfcb91040cf77))
|
||||
* **allocation-list:** show numbers of avail. and applied-to courses ([a3f236c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a3f236cb5f174c82924255f438861b8bdb320f8b))
|
||||
* **allocations:** add application form(s) ([ef625cd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ef625cd901bddc1e770bdae82ffb420b434087c1))
|
||||
* **allocations:** add courses to allocations ([14a9a45](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/14a9a4567491253cb220c51a458e029e6d75e00a))
|
||||
* **allocations:** add info page for allocations ([689b85a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/689b85ad0868087d5f5163f9020ba035a557fe82))
|
||||
* **allocations:** add registration form ([c5b18fc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c5b18fcfcf3b970039d2d72eab6d6f7e646d72ef))
|
||||
* **allocations:** additional info and explanation for participants ([38949cf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/38949cfe0d3957c261b79b448a7fd17c20af1d25))
|
||||
* **allocations:** admin-interface registrations ([5e38f03](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5e38f03a85992964d4c9cf5100c4c8a4a8762aaf)), closes [#677](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/677)
|
||||
* **allocations:** allocation-course-accept-substitutes ([8abcd65](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8abcd65edf2a1bf5b6de62103af7427fa7ed7db3))
|
||||
* **allocations:** allow additional notifications ([cc20559](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cc205596ae55826dcefe51ebaef3227ad72bb3d8))
|
||||
* **allocations:** allow changing course capacity during allocation ([83e1c94](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/83e1c9418a0461baebd6da8e0d835738d611f188))
|
||||
* **allocations:** auxilliaries for allocation-algo ([47bfd8d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/47bfd8d4ea3e5ef9f5270c08c70346cd29aa44aa))
|
||||
* **allocations:** compute & accept allocations ([20ef95c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/20ef95c142e0026b9a8bbe63fb60209b285509c6))
|
||||
* **allocations:** create & edit, list & download matching logs ([5320a4f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5320a4fe98f26576e6b72a1411107f410333009a))
|
||||
* **allocations:** create model for allocations ([82e3bf9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/82e3bf95c49a024f3afdbca4ce4c2744dda3303f))
|
||||
* **allocations:** csv-export new-assigned ([a4114a7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a4114a79f1bfd968bb9d300f0c39400a8904ee7c))
|
||||
* **allocations:** delete allocation-users ([6a1a64a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6a1a64a6113fcae3a654e472fabdf5a3f622f549))
|
||||
* **allocations:** display new allocations in user table ([bb20062](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bb20062d9f8fd7169b7dd6f7d14e82d244af83b2))
|
||||
* **allocations:** display number of ratings and vetos to admins ([6da8ad3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6da8ad348182185f773ab08a10ff59a6a1e89b85))
|
||||
* **allocations:** display participant counts to admins ([b79bac7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b79bac777c6d349a626ea4efa6c43141b7f669d0))
|
||||
* **allocations:** edit allocation-user and their applications ([4daf33a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4daf33a1a0c2c621e295aef50aae9e2dc5d5a7e8))
|
||||
* **allocations:** explanations & introduce grade-ordinal-proportion ([ee2e504](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ee2e504ffad276fbb0adc189175d29adb3e31e03))
|
||||
* **allocations:** fingerprints & ordinal ratings ([60603cb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/60603cb6ec43738bdbd98b5a2620366b20bf98bf))
|
||||
* **allocations:** highlight app's of users without alloc'-user ([300c378](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/300c3787867622a7fe3580b63cbbfba86a8b21f3))
|
||||
* **allocations:** implement application interface ([4dcc82a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4dcc82a7709ae4e145a666d170286e3f9f939d41))
|
||||
* **allocations:** improve accept ui and logging ([3422fd7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3422fd70a73bf005622f4e9b94caa503eb92f553))
|
||||
* **allocations:** improve acceptance display ([cf03277](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cf0327787417e025e21f96f824893f85e6fdad57))
|
||||
* **allocations:** improve display ([26f8f39](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/26f8f392a96893bc3c97f1c2212a9c71f0a610f7))
|
||||
* **allocations:** include study features in users table ([7f7d2c7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7f7d2c795767fd6fac1fa4a10a304e3e3d2280c3))
|
||||
* **allocations:** link allocations from home ([c759364](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c759364ab1d43a4e796cd92a494cafb939dd2568))
|
||||
* **allocations:** merge notifications ([9e9e53e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9e9e53e76abb471309494e36fc23b5a8ec4a09a8))
|
||||
* **allocations:** notification about finished allocation ([9323220](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/93232201f2b62b61ed6f543d84f6373a13bd1ca5))
|
||||
* **allocations:** notifications ([6d52ed5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6d52ed5c4caba9e164cc30e2affada85c7ddcf7f))
|
||||
* **allocations:** notify about new courses ([18921e0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/18921e06d1deeb41d705eabacc2d348bac76197f))
|
||||
* **allocations:** prevent course (de)registrations ([94a1208](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/94a120808dad0bea3b74ecb17f17e7daad5cb3f1))
|
||||
* **allocations:** properly save allocation-relevant course-deregs ([7a759b1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7a759b192fff62bc8e7608f58f861f4c2e313534))
|
||||
* **allocations:** prototype assignment-algorithm ([0fcf48c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0fcf48ce666b4828a33592e234ad2265d7f22952))
|
||||
* **allocations:** refine model for allocations ([069eb1e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/069eb1e0b7a1285ae925f95ae1be71befe65fc12))
|
||||
* **allocations:** serve archive of all application files by course ([5e393c5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5e393c53c6a702a88e053e585c1d38cb5fea15bf))
|
||||
* **allocations:** set up routes ([c2df01c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c2df01c2f710eef3ec8ba8bd0a745f393169832c))
|
||||
* **allocations:** show & export priority ([7462e03](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7462e03e7073e73d298ee98cb2403c7221c2ea6a))
|
||||
* **allocations:** show bounds on assignments due to allocation ([91b249e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/91b249e58ba4d839bf3c9324548c4f44caa4be7b))
|
||||
* **allocations:** show more information ([b7c54df](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b7c54df9132b3759b3957dec4f09f6250b2f4623))
|
||||
* **allocations:** show staff descriptions ([b359468](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b35946859309fbb526043194c8620c5fc0844809))
|
||||
* **allocations:** show table of all allocations ([d621e61](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d621e61b11b1ddb85ba3c2611a24b0c28fe841c2))
|
||||
* **allocations:** show table of course applications ([f5da3be](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f5da3bebba8d5ef6ee9b665c73eba0ea24dd50dd))
|
||||
* **allocations:** switch to csprng ([3ea7371](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3ea7371465194decf072bf038c6d05b4790b6520))
|
||||
* **allocations:** table of allocation users ([2735d46](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2735d465eb6b91b5c6373171f9f93f751be120e9))
|
||||
* **allocations:** tooltips listing courses in users table ([6bca64c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6bca64cf5f50f5c0ce7f43575930902e46dd1b1d))
|
||||
* **allocations:** ui for adding applicants ([7b7f11e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7b7f11e72853e11717c671d434397c707eff3b7f))
|
||||
* **allocations:** upload of priorities ([a590f45](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a590f45cc150dfac5d786963dbec351ff53a5b63))
|
||||
* allow editing of course applications outside of allocation ([e816a30](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e816a30b353f6451f48c97cc9a315f9b3aebb3a5))
|
||||
* allow examFinished before examEnd ([21bbb92](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/21bbb92d4c5bca8e175d2be97515e14f67ad696b))
|
||||
* allow separating user generated content into separate domain ([707b41d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/707b41d4ec9fa92238eaeb4e77f32d8bd8052c46))
|
||||
* **applicants:** disclose applicant emails & allow communication ([6711173](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/67111736875f22e636b8abdb48c869ad06909875))
|
||||
* **applications-list:** add warning regarding features of study ([cdbe12c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cdbe12c7268ee923cf0ed8c5609584a0f5193dc0))
|
||||
* **async-table:** history api ([c348b7c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c348b7cb035b2c48a8d85e1fe394116bba45f36e)), closes [#426](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/426)
|
||||
* **async-table:** no submit on locked inputs ([22b3780](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/22b3780efdabdc572d6c5a08b282bb65448bf3f1))
|
||||
* **audit:** automatic transaction log truncation ([248482b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/248482b1bb791023fa7226e303a143996192d9c8))
|
||||
* **audit:** introduce id-based format ([f602b79](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f602b79e7a72c2dced293d5218a4f7bea98c610c))
|
||||
* **audit:** take IP from header ([fb027de](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fb027dee588d709662556874ba22af44af2183bd))
|
||||
* **authorisation:** cookie-active-auth-tags ([0d372c6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0d372c636a735b4003448ab2518f6354b08ca042))
|
||||
* **auth:** record student ldap role ([50455e6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/50455e68a1e89e16a5905b976a09d265afa08bba))
|
||||
* **auth:** user independent authorisation caching ([63f0d3c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/63f0d3c37ad4a02a5cbdf76398d4a9c74a0a0b59))
|
||||
* automatically sync system functions from ldap ([297ff4f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/297ff4f02591339dda7f3270cc9cd332e18febb7))
|
||||
* **avs:** add extraction functions for avs datatypes and tests ([f8afca0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f8afca0598d03073e4200ba9c7946eec2b509d04))
|
||||
* **avs:** add page-action and form handler for registering avs participants ([747d619](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/747d6198c4efdafab009012dc46ed65b02303a38))
|
||||
* **avs:** add SetRampDrivingLicence and InfoRampDrivingLicence to AVS interface ([a1272e3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a1272e38b72d146b881492341a86e1fc544ab0ff))
|
||||
* **avs:** disable certificate validation for avs api ([66dd1a8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/66dd1a8b70468a51aca0eba82369833acc8dcb3d))
|
||||
* **avs:** register course participants for day groups per default ([64d3ceb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/64d3ceb56d4a7ce09d7760c7452f48e12b182070))
|
||||
* better explain behaviour of submittorForm ([b973495](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b9734953cfb0a63922e52b828c3b47cd32d2834e))
|
||||
* **bot-mitigations:** only logged in table sorting ([fb6ae08](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fb6ae089c63174edc1d84512ea35378ab8cd0e0e))
|
||||
* bump changelog ([3bd7520](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3bd75200874c812afc425d9652318b57336c31fb))
|
||||
* bump changelog ([bc674af](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bc674af936550d518e1d427ca86205a3a1e8c5d5))
|
||||
* **caching:** aggressively cache nav items ([b9b0909](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b9b090992fd83fa4db1c408727d4c8c582b447e4))
|
||||
* **caching:** introduce cache prewarming ([8d1f216](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8d1f216b5b6ee2a59c3fb80f5dd4a701d9dad5ef))
|
||||
* **changelog:** bump ([3d1636f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3d1636ffe8b1b24b5f6e4a679bb1fbcdf9de5fa6))
|
||||
* **changelog:** bump ([a684b90](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a684b90e5ec0545c571b72cab6336dd07f1e42aa))
|
||||
* **changelog:** implement changelog like faq ([d9d353f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d9d353fcb7652c46a15016b5d2f400162c8271ef))
|
||||
* **changelog:** prettify date formatting ([2b3aef7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2b3aef7a490ca2fbabd474069d3406ebb9403e4b))
|
||||
* **communication:** send test emails ([d90da85](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d90da85df353da63794eeb95b79b87f485bb6908))
|
||||
* **config:** improve configurability of VerpMode ([a7c3fe7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a7c3fe76f23f9bd5ba15adcb8a469faf53ad3769))
|
||||
* **copyright:** add english translation ([dbb0a57](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/dbb0a5708613d350843247b7ed55a96992db9772))
|
||||
* **correction-interface:** wire up ECorrectR ([d8801a3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d8801a3435088648cc490f71ec08eba91c4a68c3))
|
||||
* **correction-interface:** wire up ECorrectR ([df66c9b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/df66c9b58dd1ea6119d428470d2d089edd70e2d0))
|
||||
* **correction:** allow lecturers to set corrector ([f74581c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f74581c35648788a39d46c5a72acda4f2c2fa7b9)), closes [#414](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/414)
|
||||
* **corrections assignment:** add convenience to table header ([56c2fcc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/56c2fccb84ff71163ccc22291cf42c0cea88b2de))
|
||||
* **corrections-grade:** additional column for sheetType ([4cb2d4f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4cb2d4f07ddc0d873601ae43636a76adfd5a481a))
|
||||
* **corrections-grade:** basic filter UI with pseudonyms ([d03fd4b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d03fd4bee6d645624c30297907c91bf4697aa2f8))
|
||||
* **corrections-grade:** sorting by sheetType ([702fb1d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/702fb1dfdb0bc9d9124d824efef56620b6666d33))
|
||||
* **corrections-grade:** working additional filters ([c4eb2c0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c4eb2c0f04adc6c7193b602b6bfa570c1ba3483b))
|
||||
* **corrections-r:** allow csv exporting one line per submittor ([7aadb66](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7aadb6662bc8db76436f8d41ded7156acb98418e))
|
||||
* **corrections-r:** authorship statement state ([51522ef](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/51522efc7c9915115e0d8791320a03e35d2933c8))
|
||||
* **corrections-r:** csv export ([2a6248e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2a6248e3d5d4f4de5f1c7d6c6bcf092dc9873a2e)), closes [#705](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/705)
|
||||
* **corrections-r:** filter/sort by pseudonym ([153af8c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/153af8c6b4042430bb4bc120fa5c24a5d114e4c1))
|
||||
* **corrections-r:** json export ([fe8e4bb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fe8e4bbd4f6a8b1b1c54808ebc96ee675a078648))
|
||||
* **corrections:** added missing titles; small message fixes ([018082e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/018082ec4a8d1fb90fb5fa874a9b971f6162716b))
|
||||
* **corrections:** better highlight corrected files ([46ce477](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/46ce477235fa488986728a7f42ec6a402cd01a98)), closes [#602](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/602)
|
||||
* **corrections:** non-anonymous download w/ registered groups ([9032f80](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9032f80f59532a0d26a1d67de50765dbb1c2e0e0))
|
||||
* **corrections:** override rating_done & documentation ([bbbfa94](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bbbfa946e1e2bd3cce6d30cffc672460ec5125bf)), closes [#525](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/525) [#274](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/274)
|
||||
* **corrections:** submission filter ([38dbfe7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/38dbfe73b25ef9cce15b4fdd7a529bb2a3abd9c7))
|
||||
* **corrector-assignment:** show load/submission percentages ([228cd50](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/228cd507498a74f92978c2c9082d91348e68c564))
|
||||
* **course admin:** application restore ([cb4ed8d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cb4ed8d9887e521f47689c118baf439846cd4514))
|
||||
* **course admin:** done ([15689c5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/15689c597ef407583b01dabc9f7631e9dc90b009))
|
||||
* **course admin:** no new-line ([0a6a174](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0a6a1749d351e626383e513293af280f78552009))
|
||||
* course applications study features ([44eeffc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/44eeffcc70a8b4c119e1a88a9ef01c687fe2e10a))
|
||||
* **course enrolement:** show proper icons in alerts ([b2b3895](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b2b3895aa97d19580987d4b7f845798d6603c44a))
|
||||
* **course material:** auto vorschläge für materialtype ([decdda3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/decdda359d16cce429a7e7a07d4674840e5fe6af))
|
||||
* **course material:** first two filters ([90e4a62](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/90e4a620f0c1671ff332db1910c176e58ccbac06))
|
||||
* **course material:** materialDescription in progress ([89e9887](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/89e9887fe1112cbc21517e4b501ead33f5a969ba))
|
||||
* **course material:** materialdescription search implemented ([3a9622d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3a9622dfb8474d9f3764f5870197e317a96d9de3))
|
||||
* **course material:** merge-request suggestions ([dc5fc3f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/dc5fc3f710363f0644c43866505e32095b41ce92))
|
||||
* **course material:** runDB für cid nur einmal ([c09acbb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c09acbbf8a7b95176b3d52449b3b9d26e315ccd6))
|
||||
* **course material:** small empty-bug fixed ([d8b1f97](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d8b1f9788c74ea5d7dc4f1f45432649d9601106a))
|
||||
* **course-applications:** automatic acceptance of direct applicants ([620950d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/620950df83e3dc4d1f0050af4bb207d25883800e))
|
||||
* **course-applications:** csv transport ([cf0ec1a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cf0ec1aec4267b99cf549b8ae5a0cd1762c45884))
|
||||
* **course-comm:** recipient categories for sheets and exams ([2fd060d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2fd060d55b7f027fa731dcb5b7d706e71d9ba413))
|
||||
* **course-communication:** one recipient group per tutorial ([99f23f2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/99f23f25582429e276f513f58677fe6676657ac3)), closes [#428](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/428)
|
||||
* **course-edit:** warn about long shorthands ([80cb16a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/80cb16a40f49564ad98395e4e0d16f405103a9d2))
|
||||
* **course-events:** add HideColumns for course events ([1138f9e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1138f9e32712eb879f76792a68a870e7a48c4b90))
|
||||
* **course-events:** add optional note to course events ([6ad8f2e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6ad8f2ee290d5b9166b07ba3be329483a769e097))
|
||||
* **course-events:** course event note text -> html ([c8904d1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c8904d10b679e77bd7d4adaf80cd37bb3288275f))
|
||||
* **course-events:** hide note column if there are no notes to display ([1ac7f4e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1ac7f4e8811d9272a10aa28420b4e3fb0c976009))
|
||||
* **course-events:** show notes in course events table ([b2c4125](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b2c4125ca3f76e65aa4eb4390e6d1e7013d1eb0d))
|
||||
* **course-list:** filter by allocation ([de39686](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/de39686d89f6ec410bc50eaca058082dc727547d)), closes [#715](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/715)
|
||||
* course-participant-lists ([88dd5a9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/88dd5a90b91be365878f9424a3ab304c3ae7c339))
|
||||
* **course-participants:** course-deregister-no-show ([bf64eaf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bf64eafd0877a686e3129f1da3ac352fda90e5d0)), closes [#499](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/499)
|
||||
* **course-participants:** csv export exercise sheets ([06f47c5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/06f47c59b434f1d97afc8afbcb1d47737a85c1d5))
|
||||
* **course-participants:** csv export first name/surname separately ([1036926](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1036926470792bf3409ba3a224886d48b7e1d314))
|
||||
* **course-participants:** introduce CourseParticipantState ([d5b65a1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d5b65a1b06c6fdad2df537e270cba06e967f7ef7)), closes [#499](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/499) [#371](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/371)
|
||||
* **course-participants:** show exercise sheets (first cornice) ([26cc8e4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/26cc8e4b53261c64e2f23ab17a8f6ddcbb6fcd63))
|
||||
* **course-registration:** allow independent course application ([a00698e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a00698e99e915fd9771d236ed5796bdfcad5b5c7))
|
||||
* **course-show:** show "not registered" ([96e1a30](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/96e1a30eb64c8f18094ab5f3149bb675e9b8f14c))
|
||||
* **course-show:** show allocation name ([3c80235](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3c8023569bb3d8ce91ab6626b5a93763532a0d10))
|
||||
* **course-teaser-css:** removed description label ([a25efb3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a25efb3be4743f8667b106d4b00399a33d1ef605))
|
||||
* **course-teaser-filter:** filter for lecturers ([e96e17f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e96e17ff9f6701263e189fac6c6718e0a7ea0971))
|
||||
* **course-teaser-filter:** working filters for semester and institute ([3b419b3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3b419b336670f94a2f5f024ded4abdb9c7d977fa))
|
||||
* **course-teaser:** checkbox field for open registration filter ([e4f150d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e4f150d0d536c36294abe6df27ba56a7ca5c16a9))
|
||||
* **course-teaser:** display sorting "pills" for course teasers ([d964e1f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d964e1f705bb2fd9f9f4a220c6871f829b7b6ca3))
|
||||
* **course-teaser:** filter by open registration ([c2c12b9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c2c12b9643e81efd5f16e18e4fca4dcbd581db11))
|
||||
* **course-teaser:** final version of course-teaser for course list ([66b97d6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/66b97d6729c4feb94b0be50da43fcd3aa6c8c488))
|
||||
* **course-teaser:** hide lecturer entry if empty ([f7fb3c1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f7fb3c12198e29b653f93e9d9ef2f6fce23b1b85))
|
||||
* **course-teaser:** incomplete course teaser for course list ([9a97925](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9a9792578d98453ba0928d504ebbffd9ae7ccfda))
|
||||
* **course-teaser:** moved course teaser functionality to util ([c99a3c7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c99a3c7009fd44f15248b8b71abe07b5ba763c64))
|
||||
* **course-teaser:** no display of chevron without description ([5c88c13](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5c88c13cf835425a7ecbd9a0ed054b1ed5c67a12))
|
||||
* **course-teaser:** no page reload on sorting ([68b8d24](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/68b8d2468175509533fc86ab4458268baa30ecb3))
|
||||
* **course-teaser:** only true lecturers without assistants ([7926f29](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7926f29da1565ce27600115d0030246cb1bf4ba0))
|
||||
* **course-teaser:** redirecting to course/ ([aa20389](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/aa20389e05bbf683e0b998444f4b52af3e52327a))
|
||||
* **course-teaser:** reintroduced courseId and course-teaser.julius ([3b6e700](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3b6e700531205b8b8a3e9b319c4f7a9c6868bc95))
|
||||
* **course-teaser:** show openCourses also to logged in users ([8cca548](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8cca54897036e5959d8c06497f5a28bbbea888ed))
|
||||
* **course-teaser:** unpolished version of course-teaser for course list ([ea5d54b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ea5d54b2135820820aa24adab2807cb1bd03b8ec))
|
||||
* **course-teaser:** working link to course pages ([8a49979](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8a49979ecc26a54d3c2aff7056136f920abe13d8))
|
||||
* **course-user:** authorisation checks ([d15792c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d15792cd7da8ce8038472af1afa721d4e99349dc))
|
||||
* **course-user:** i18n ([da629a8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/da629a81d28aeec37d53ef9a21ed959c73dd7e67))
|
||||
* **course-user:** major improvements ([ced6ef2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ced6ef287451cc59ef32f5454fc23e5cbf0f70eb)), closes [#126](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/126)
|
||||
* **course-users-table:** json export ([6f291b2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6f291b2e6893554193732b059758794fe2b7fa51))
|
||||
* **course-users:** allow for exam registration on CUsersR ([b8acc9b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b8acc9b5da701bd0d17d9578ee2c9d4e835fc2d7))
|
||||
* **course-users:** allow registering tutorial users manually ([d507d9b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d507d9bbdea035d2d83050e5a0bbf61a73ae3161))
|
||||
* **course-users:** exams in dbtable and csv ([c23becc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c23becceb1ef994a39204ab3df083f1bbc857c27))
|
||||
* **course-users:** filter by exam registrations ([1d7d0ab](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1d7d0ab55422670d53425061961faa27829fba7c))
|
||||
* **course-users:** fuse avs register form with CAddUserR ([4a00907](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4a00907bdad26208329080ad87fe52daa33775ff))
|
||||
* **course-users:** include tutorial in csv-export ([1d5ddd1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1d5ddd102ce49c83ab0b45cf2be590f76ca0f0d0))
|
||||
* **course-users:** match filter titles with column titles ([ecd7bec](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ecd7bec9aa36591854ee42e3feba3d8186f872b7))
|
||||
* **course-users:** register avs-upserted users ([cba73bf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cba73bf2ca6825e9d4d00e51440354aba4cf57f0))
|
||||
* **course-users:** register exam action with optional occurrence ([34ad1df](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/34ad1dfae2d265c2dd63325b2c742777a58eb699))
|
||||
* **course-users:** set new tutorials to Schulung ([69de448](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/69de44893c9e37a809cde350d404f60a14e5052b))
|
||||
* **course-visibility:** account for visibility in routes ([cb0bf15](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cb0bf151212fd4ecba0eda7b1ef69a640fd6d35b))
|
||||
* **course-visibility:** account for visibility on AllocationListR ([4185742](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4185742f380f7625cac2bbc8df5952157ec0ba63))
|
||||
* **course-visibility:** account for visibility on AShowR ([df7a784](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/df7a784a9daebbfb5ca61606cd38352662824131))
|
||||
* **course-visibility:** account for visibility on TShowR ([0ff07a5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0ff07a5fad5504bff5adfdce278a6256f6bc8711))
|
||||
* **course-visibility:** add invisible icon to CShowR title ([6c0adde](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6c0adde5db117e6ad12167ebbb05a948e5c857c9))
|
||||
* **course-visibility:** add visibleFrom,visibleTo ([222d566](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/222d566bdaa84382b24299d6e9179eb2ebb09564))
|
||||
* **course-visibility:** allow access for exam correctors ([dfa70ee](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/dfa70ee7fea2020065699e2d4f0608195a1a0228))
|
||||
* **course-visibility:** display icon in course list for lecturers ([17dbccf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/17dbccf2a343cf1571ef0aaf07d6064bf3a2a216))
|
||||
* **course-visibility:** error on visibleFrom > visibleTo ([9494019](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/94940196949014d6a99cb183514e855c37575fa5))
|
||||
* **course-visibility:** hide invisible courses from favourites + icon ([d86fed7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d86fed7a32badfe75ef124145e1c59086771c164))
|
||||
* **course-visibility:** more precise description on CShowR ([6fbb2ea](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6fbb2eabf1c90d3ab4e321773506ff8aebbb761d))
|
||||
* **course-visibility:** no invisible courses in course list ([24f1289](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/24f12896e084e9180800a0080077d90005801642))
|
||||
* **course-visibility:** now as default visibleFrom for new courses ([7bdf8ca](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7bdf8cac8865743752401ee561355df466407223))
|
||||
* **course-visibility:** redirect to NewsR after deregister (WIP!) ([183aa8d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/183aa8d2227091054f8409bd81f40031a8c2066d))
|
||||
* **course-visibility:** reorder course form ([7af82bc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7af82bcb67d0ec6ae33aa82067b3d1f4de0d74de))
|
||||
* **course-visibility:** rework visibility check for ZA courses ([a16eb1a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a16eb1ab91747e19f61fd1dfaa5ae7db5800bad0))
|
||||
* **course-visibility:** warn on deregister from invisible course ([16ad72d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/16ad72d87638a195afbfbc390f23182dc705f7fd))
|
||||
* **course-visibility:** warn on invisibility during registration ([23aca1c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/23aca1caa43f24b38aa22d3cac3f2289b1cbe8f3))
|
||||
* **course:** additional crosslinking ([5eaba78](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5eaba7830f052fac42a0ce387619a09cefea48f8))
|
||||
* **course:** allow csv-export of all features-of-study ([e60f1b2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e60f1b2bfcc7c914d202c30e9a5f155d28fae20a))
|
||||
* **course:** associate qualifications with courses ([ffaaf9c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ffaaf9c86d5caa7eaec2d2bcd06bc6963310a7eb))
|
||||
* **course:** csv export of course participants ([9a28dc8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9a28dc851cd4d8023ca3638b325b6b9575974a89))
|
||||
* **course:** introduce CourseNews ([aa93b75](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/aa93b75e00cb28d3092c0ee4b538e21e543eb7d4))
|
||||
* **courses:** add NotificationCourseRegistered ([3750da8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3750da81dc27fb104d4ad3765921af2e08915c4d))
|
||||
* **courses:** course events ([fa7f771](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fa7f7712f77a9e801a2c9fa040b1d97d0ae1f8bd))
|
||||
* **course:** show direct registration dates ([8f284ac](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8f284acde8229144f54d63464168b7b82f87c69e))
|
||||
* **courses:** rework couse registration ([79d4ae2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/79d4ae20ee7aaebf9b55005730383fe46ff84e12))
|
||||
* **course:** warning if re-registration is not possible ([4451cee](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4451ceedf7bde0da7f3bb4c0818b79d7c5df1cbd)), closes [#646](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/646)
|
||||
* **crontab:** cronjob for pruning expired invitations ([a9c5276](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a9c527621ec17287b119617573e22ca918d20d9d))
|
||||
* **csv import:** add explanation text ([6d0a4c1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6d0a4c156bd8c792a9a01f05f6a41fe631da5517))
|
||||
* **csv-export:** .xlsx ([5c51394](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5c513946c15ed215f6958be1c7a435f03314f115))
|
||||
* **csv-import:** automagically determine csv delimiters ([3555322](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3555322f2a14ebdaeeab557d7c885e1179f0a90a))
|
||||
* **csv:** add column explanations ([c8dca94](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c8dca945cfac12453bcc74bdfea321d7b4cb3053))
|
||||
* **csv:** allow customisation of csv-export-options ([95ceedd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/95ceeddc83ff79dad6f2dc494015e85f2996c40d))
|
||||
* **csv:** don't limit number of exported rows ([e62d7a3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e62d7a34e68b79ae52450dcd9e1c5814933d33d1))
|
||||
* **csv:** encoding ([81415e1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/81415e1afb02126a40bb1979ad4c039fd9cccb58))
|
||||
* **csv:** export example data & improve zoned-time parsing ([49d9ab9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/49d9ab9dba70423431e6e68892825c8e29309739))
|
||||
* **csv:** finish implementing csv import ([e35fed6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e35fed6b85fd5734834e4a4590276c6d3df34f83))
|
||||
* **csv:** implement csv import ([996bc2a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/996bc2ac27bf8fccadcd5d30876dbd3263963cc1))
|
||||
* **csv:** introduce csv export ([631bbef](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/631bbef0b8d202e3127de602ad1b5f30b896cd0a))
|
||||
* **data-protection:** data protection statement contd ([c3c533f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c3c533f6a89eeb387abbd4ca17b56c0024c64b5d))
|
||||
* **data-prot:** extend info on data saved ([2599e86](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2599e86a59ccb58d0f18295475fd14fe95fe83f3))
|
||||
* **datepicker:** add option to change the position of the datepicker ([85f46ef](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/85f46ef23075104346aba33861f8c170757a3c09))
|
||||
* **datepicker:** also parse manual input in internal format ([8a3ac72](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8a3ac72cbeffd467d3a64832621dae7666005a6f))
|
||||
* **datepicker:** close datepicker on click outside ([88a6b85](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/88a6b85a7e83896beefa477b244b44c348a012f6))
|
||||
* **datepicker:** close datepicker on escape keydown ([0e5707a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0e5707ac9fe69e80240b22c4f727170766cb7bea))
|
||||
* **datepicker:** currently broken version using tail.datetime instead ([4282554](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4282554d82d36c20f4887fdba8396a708dd794e9))
|
||||
* **datepicker:** define instance collection singleton ([f5636b8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f5636b81d157f1b5df2bc4053aaf0efc3d1ba47a))
|
||||
* **datepicker:** display datepicker on the right ([cbb7e95](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cbb7e952769ef5208103766f4b32217819deed8e))
|
||||
* **datepicker:** do not replace value if input is no valid date ([ecab0ac](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ecab0ac93ca28233457297e285f1a431232f8ace))
|
||||
* **datepicker:** format according to input type; position datepicker ([db345ee](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/db345eed55a049b540f30802e77db33705349945))
|
||||
* **datepicker:** format any dates before submission ([1eccb0e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1eccb0ee4aba99a4ea05c15e6a898e44cc75b207))
|
||||
* **datepicker:** format time on submit ([9f8749c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9f8749c4cee73b43eb58d34eb18051f3b1753d31))
|
||||
* **datepicker:** formatting dates for mass-inputs ([b9fd4d7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b9fd4d7d285eb3779cff79de69dd3ebf7481c51a))
|
||||
* **datepicker:** helper functions and updated tail.datetime fork ([2512d69](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2512d69e675c31192c6de96f14d07306e82ff64c))
|
||||
* **datepicker:** more sane datetime config ([5a44263](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5a4426300abe83de223f6180039ced92722d2fb7))
|
||||
* **datepicker:** new approach stub for formatting dates in formdata ([9ea7b2e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9ea7b2e3f7db4111acf914354968824161ddd86c))
|
||||
* **datepicker:** only update datepicker date if date is valid ([d857af3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d857af3812f3810628c4837a8c7a74e8cd4bd1a9))
|
||||
* **datepicker:** switch to tail.datetime fork to fix time selection ([863971f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/863971fbde19a39bd7fc2a16457f03463a41fdb0))
|
||||
* **datepicker:** update dependencies ([427ffbf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/427ffbf0d8acecc71446dd0250b2f6fc3ff20da3))
|
||||
* **db:** automatic retry of database transactions upon system error ([e7a5162](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e7a5162ec9560a20eaffdc24f143ab765f3f0238))
|
||||
* **db:** optionally disable some db connection pooling ([35ac503](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/35ac503bf971ace21c49646aa15e8b94b7a3e823))
|
||||
* **db:** provide our own implementation of connection pooling ([50fdcb4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/50fdcb4540e6bfbc8da9ed10ed06d6f6ce443cf9))
|
||||
* **dbtable:** add support for Cornice ([fdeb251](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fdeb2514c0faae19604b578358806aeb4677a95e))
|
||||
* **dbtable:** extra representations ([2c0fc63](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2c0fc63be1de02e8acffbc6a9c5ee83b061c5825))
|
||||
* **db:** track source of database accesses ([23ff9d9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/23ff9d9222d7a75b2931827a6cc0335aafe753a1))
|
||||
* **default-layout:** save handler ident to main content ([ba846be](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ba846be5aa99278ca00b64150165ccb825eb9ba0))
|
||||
* demand authorship statements ([34b3e6a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/34b3e6ae21b38a5b8389deade5deeb77b0981ead))
|
||||
* **development:** add commitlint to ensure proper commit msgs ([dd528c1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/dd528c13aa28ecf882ee311aa2a22389b24c9585))
|
||||
* **development:** add standard-version for automatic changelog generation ([c495ef5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c495ef577231ac0db6b8c467cf4b0a69c3cf961c))
|
||||
* **docker:** wrap within tini ([c86f36b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c86f36b2f67a014352b043397c32b6d8ca1642fe))
|
||||
* document CourseEvents ([db224cf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/db224cf58e6025c89174bfa1eab09e03fbec2f07))
|
||||
* don't redirect monitoring routes & crontab tokens ([3a106d1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3a106d1ee5998ddeea852b3b0398c2f330664a63))
|
||||
* **dry-run:** implement dry-run ([002775e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/002775e19296bd75cf016146e594df2f6101948b))
|
||||
* **eecorrectr:** add handlers and navigation ([be2eb3c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/be2eb3c38d6539056456978b37c47c049d1cd683))
|
||||
* **eecorrectr:** basic handler structure (WIP) ([de02895](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/de02895ed0ddc7ed119b76fded1d3eaec24448ba))
|
||||
* **eecorrectr:** more appropriate error messages ([3b4c7fe](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3b4c7fed3658cf3abe731fe45f24fe9c18b52b54))
|
||||
* **eeusers:** fix form & finish implementation ([7d3e9a3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7d3e9a3de359a2775e2a2941cd807dd51dc07f0f))
|
||||
* **eeusersr:** audit external exam result delete ([baa3fd8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/baa3fd82e1642e5527b94cf71bc6e96dc0f81455))
|
||||
* **eeusersr:** audit external exam result result and occurrence edits ([ed3f761](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ed3f761b24f98527ca0b26b09db7a75f1c98142e))
|
||||
* **eeusersr:** audit external exam result result edit ([0d54757](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0d54757d16bebadaeceeb0947df65f15d86ac3e0))
|
||||
* **eeusersr:** more on actions, TODO audit ([d4b784a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d4b784afba450019d34a7c70eff7992dbad3b9bf))
|
||||
* **eeusersr:** stubs for new actions ([4d48730](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4d48730abd7b1c4d4d9faab08734289fc6d6afb8))
|
||||
* ensure cached study feature relevance is up to date ([8798f54](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8798f547a60a7fa7c0849e20e1b0e9d012ac9312))
|
||||
* **errors:** redirect errors back to ApprootDefault ([fbf21d7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fbf21d7313d7c2795c171b85a621ad2235eb68c9))
|
||||
* exam auto-occurrence nudging ([a91fd7f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a91fd7fd6387e82331d881ec32e830fd59634d9d))
|
||||
* **exam users:** course notes ([1e756be](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1e756be7784101c7be80395efea988785a0b0d1d))
|
||||
* **exam-correct:** accept grades besides exam part results ([be187ae](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/be187ae90727eba0966de59a3b6945080515b3db))
|
||||
* **exam-correct:** add basic interface stub ([623becf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/623becf59751f988411cb0fa39654d4fac214d0b))
|
||||
* **exam-correct:** add basic interface stub ([cb7c9ac](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cb7c9ac6dad5e248e9cf0748a871947369cd39af))
|
||||
* **exam-correct:** add hasMore to no-op reponse ([e941083](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e941083a44ae817f8ad301afdcf57ebdb9a1742d))
|
||||
* **exam-correct:** add sortable style and date column ([87bda16](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/87bda1607e23fd44ac32279b9f36088554cdf56f))
|
||||
* **exam-correct:** add sortable style and date column ([9fa4245](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9fa4245607a1e31e915c67a3840dad291a9d284b))
|
||||
* **exam-correct:** display backend error messages ([6fc0262](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6fc0262d2dbf9e6a72b0db94c0a46cfb9ffeba15))
|
||||
* **exam-correct:** display more info ([ef52f02](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ef52f02d78d8dfc75c48c1ad65b329d68c3361a5))
|
||||
* **exam-correct:** examResult interface, no styling or functionality ([970076e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/970076e7307d18424837957133e0086aa78bbafb))
|
||||
* **exam-correct:** explanation & length restriction ([1bf19a7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1bf19a76bd6c03ff23ab417fcfc0e86596dc896f))
|
||||
* **exam-correct:** general improvement ([23044b2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/23044b28dbcfdc82d5f1e934ab18fba034d60e4a))
|
||||
* **exam-correct:** hide result grade select ([edacc20](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/edacc2016d6bbd5c25d62f13d8609b41ee5814ac))
|
||||
* **exam-correct:** limit number of matching users (BE) ([d4d27f8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d4d27f8ef63bf5374eab9e3a8e1d1bea6e2e5b3e))
|
||||
* **exam-correct:** more on frontend name resolving ([905d445](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/905d445479f846edf724452832e6e9659c07fbbf))
|
||||
* **exam-correct:** more on frontend name resolving ([daf9eee](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/daf9eee1d3203da5cd7893431a3358a12e41941a))
|
||||
* **exam-correct:** more stub ([cbe6495](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cbe6495609dd762f86d13638684496a1822b048a))
|
||||
* **exam-correct:** more stub ([6727dff](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6727dff2ef5de6cf3d4c302165c1c04302d41b68))
|
||||
* **exam-correct:** overwrite request cells from response ([c8edbb3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c8edbb395b1dbcd704864e640bce1354d1774c40))
|
||||
* **exam-correct:** persist results and more ([a7cc24b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a7cc24be90cb13985d0faf8c8464c921054f0345))
|
||||
* **exam-correct:** persist results and more ([53ff629](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/53ff6298e2a5f12b2453dd6d9e2bedec6494ecda))
|
||||
* **exam-correct:** postECorrectR stub ([5f9a176](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5f9a176bc68116757237b499da26bb34e8aae32b))
|
||||
* **exam-correct:** postECorrectR stub ([a525cab](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a525cab356427514c49348929a362a52fd6edc8b))
|
||||
* **exam-correct:** request refactor and handling of sent uuids ([f06ca00](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f06ca00d752ba0034055f8031e17d1f56594e007))
|
||||
* **exam-correct:** request refactor and handling of sent uuids ([4a36a01](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4a36a010f4bc0ea326f263c0ee77132843f03c73))
|
||||
* **exam-correct:** resend option on ambiguous entries (TODO refactor) ([512f4d9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/512f4d907095087688774bc6adf8619cda3b9142))
|
||||
* **exam-correct:** resend option on ambiguous entries (TODO refactor) ([e252be2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e252be2fef3732f04b333a909860df985b786fd5))
|
||||
* **exam-correct:** return user lookup result even for failure ([8e41820](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8e41820c9dbe812530a6a5844c0f4baa0aa73027))
|
||||
* **exam-correct:** server date handling in frontend and refactor ([77e39be](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/77e39be56c68af9bbf0fdce98508e4d10401dd06))
|
||||
* **exam-correct:** server date handling in frontend and refactor ([d8a080d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d8a080d74d4d8ebe78c864daedcd0d4b0b6114d4))
|
||||
* **exam-correct:** setup basic session storage manager, add util stub ([9cb64f2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9cb64f2a8f5c86d5b5ef5ad65fd7f3c9f0ef7a13))
|
||||
* **exam-correct:** setup basic session storage manager, add util stub ([9a79156](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9a791562b6809b54b6d45699566e0f369e14c627))
|
||||
* **exam-correct:** single runDB in POST handler; more response handling ([4cb62f8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4cb62f8f91505c40364b51339072545173f1a569))
|
||||
* **exam-correct:** single runDB in POST handler; more response handling ([6837c44](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6837c44b7f40bd4544e75a91a70f6722dc3d5ea7))
|
||||
* **exam-correct:** status icons (wip) ([3cc6814](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3cc6814ff5e337d24841fc25797ca92e38c5bf3a))
|
||||
* **exam-correct:** status icons (wip) ([eefff9f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/eefff9f719aa44a544f3eea25ba29b987d085365))
|
||||
* **exam-correct:** stub ([90359c8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/90359c83b75e52e369ad6a3df8022ed3cdb50e72))
|
||||
* **exam-correct:** stub ([0467194](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0467194e3df2da569bd2a4bd8c63bc2d23f44c30))
|
||||
* **exam-correct:** submit on enter ([10de1a7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/10de1a7de7e6855c6c84933618aa84d20f7f07b9))
|
||||
* **exam-correct:** upsert exam part results (TODO) ([c0f91bc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c0f91bccdd48dc0c99e3b8ef133cfedd890866cf))
|
||||
* **exam-correct:** upsert exam part results (TODO) ([650598f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/650598fc22cf33d9eafb97a988db672d94cc3a48))
|
||||
* **exam-correct:** use examId instead as uw-exam-correct value ([2d9a877](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2d9a8771efb5bd8d3c22c799ad21bc1f750a4837))
|
||||
* **exam-correct:** use examId instead as uw-exam-correct value ([5d7427a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5d7427ad463f114648f6d5b958e5ecba519f0abe))
|
||||
* **exam-correct:** validate user input stub ([7f04862](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7f04862a6f0726a7b721d8bbf1cc6c81b2ced5f8))
|
||||
* **exam-correct:** validate user input stub ([431d004](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/431d0046658f6f096fb3bf4c11acba0337f10629))
|
||||
* **exam-correct:** work on delete ([014036e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/014036e4e31f17267e0ad2c82faff163f6064d6c))
|
||||
* **exam-office:** course/user opt-outs ([484fa1c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/484fa1cc632b16d21e694426ae6552dc9098a8f1))
|
||||
* **exam-office:** exam-office permissions by courseSchool ([5841a7b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5841a7b5d2c9ee1b291a003f3d03b41d5e0b5d95))
|
||||
* **exam-office:** exams list ([651f0bc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/651f0bc4d47477f5f60ed1f91b038cfe6c74cf92))
|
||||
* **exam-office:** grade export ([72a7f6e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/72a7f6e8a8edfacc6aa8ae477a8da46f6f88c551))
|
||||
* **exam-office:** notifications ([52e1844](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/52e1844d5e5f5c38cdf639f58ba682af5cfc678a))
|
||||
* **exam-office:** show exam(Occurrence) end-time ([b638783](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b638783f1262f8ea7817618f70474a114b182fda))
|
||||
* **exam-office:** subscription management for users & fields ([f75cc64](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f75cc641e22b6f00bc494f85aa64cd365ac19ad5))
|
||||
* **exam-office:** user invitations ([123970a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/123970a7833d4a10474bbdcc4dfa6102795d331d))
|
||||
* **exam-users:** allow missing columns in csv import ([e242013](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e2420130874728ad1e98ee5c590d0a20d5f2da5e))
|
||||
* **exam-users:** document part-* family of columns ([fe07a22](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fe07a226e9d5ee3195067e45d9c41d730218c7a2))
|
||||
* **exam-users:** provide better table defaults ([a689d19](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a689d19bfa314ae7e559232c0c3d23948c211ebd))
|
||||
* **exam:** audit exam registrations ([31931e7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/31931e708e998116d112fb8a29a1434769ff9d1c))
|
||||
* **exams:** accept/reset computed results ([72342f1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/72342f13936f9e4056e3825ba872a3c5a3726e11))
|
||||
* **exams:** add extremely rudimentary registration table ([31e6b72](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/31e6b72c463e7f638a2cc2ff6f19b67f2d49db73))
|
||||
* **exams:** add warning about multiple automatic distributions ([7fc9fef](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7fc9fefb0a255dcf627320e89802fa5b6869c542))
|
||||
* **exams:** allow assigning exam participants to occurrences ([e1996ac](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e1996ac2e51d74db09c833b6c57a80fcdcb9f6bf))
|
||||
* **exams:** allow forced deregistration ([1b532c4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1b532c4e4d2aa90da93a08dd4f1dbaf8626e8077))
|
||||
* **exams:** allow mixed ExamGradingMode ([acffe04](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/acffe0435037b10cabdeffebd1cdcafa03b74d0c))
|
||||
* **exams:** auth ExamResults by ExamExamOfficeSchools ([29a3e24](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/29a3e24bcf01cd9c893857eda00dcd249e6cbbe2))
|
||||
* **exams:** automatic exam occurrence assignment ([e994faf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e994fafe28a32022c06c2cce123181525061f24e))
|
||||
* **exams:** automatically compute examResults ([ea5a398](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ea5a398bab2ca0a63af06e167129c2656e887c74))
|
||||
* **exam:** save registration timestamp ([78e4369](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/78e4369afb1f76c1a6a30580a2ae35273f495e43))
|
||||
* **exams:** basic required optional action for authorship statements ([5cc41ae](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5cc41aeef94993a24538b2f88af1fb75625036a8))
|
||||
* **exams:** better display exam-result-information ([0ebda4d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0ebda4d38243d54bf2638e4ce7808bbc084d10dd))
|
||||
* **exams:** better explain "enlist directly" ([f07eb3d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f07eb3dcc33fffb823fb490e36576a202328a0f4))
|
||||
* **exams:** check exam_discouraged_modes ([f9c50c8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f9c50c80f22770f5376396923b8921eaac3e7216))
|
||||
* **exams:** convenience for automatic grade calculation ([ec6a8ae](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ec6a8ae463ca42fd80538da782a864b739f6ba3e))
|
||||
* **exams:** CRU (no D) for exams ([67a50c9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/67a50c9e87d3368aafe7f52a3b81e580713e6c24))
|
||||
* **exams:** csv-based grade upload ([932145c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/932145ccf794cffce396ddb2d85f01e74d1c7c75))
|
||||
* **exams:** csv-export exercise data ([2218103](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2218103cbd6a021fd24629f9215c71dd115f08e4))
|
||||
* **exams:** csv-import of ExamPartResults ([29f4e28](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/29f4e2853667db251b48857bcb21d22482534f2f))
|
||||
* **exams:** disable and set use-custom field according to school setting ([22dfd33](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/22dfd33aca9b8ad797c2617bbc656cf8276edf38))
|
||||
* **exams:** display school default in form ([abd68ac](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/abd68ac0322a34afb62c416b60965e87ee6f10c2))
|
||||
* **exams:** do form validation ([bf7b25c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bf7b25ca9e9d11df94b91f7483ee339cefd3e0c9))
|
||||
* **exams:** exam design & school exam rules ([f7bab3b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f7bab3befc4c42cde430699681f8caf8a959ab39))
|
||||
* **exams:** exam finish button ([78d0f25](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/78d0f2522db759c2ee465e040939c92b2f9a1891))
|
||||
* **exams:** exam registration ([99184ff](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/99184ff05322573a6958f09e30fa0fdcdd3d665b))
|
||||
* **exams:** exam sheets ([500000b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/500000ba0f6f3b3c32cfd7593e5468796660d46b))
|
||||
* **exams:** exam staff & additional schools ([94436ee](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/94436ee0e1ce2cbf13a66f9ad81883d7286acb9b))
|
||||
* **exams:** filter on occurrence ([cf040ce](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cf040ce6863488f4708c1c2059f783413b1183d1))
|
||||
* **exams:** first do-nothing stub for exam-wide authorship statements ([0392297](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0392297ddbfccbb9a08e678696a9cedd1098121a))
|
||||
* **exams:** Form validation ([6fb1399](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6fb1399ef448eb1a6b92c652e644d6aaafe11673))
|
||||
* **exams:** implement exam registration invitations ([dd90fd0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/dd90fd04a3ebf43e35837d41ca14424f7568bc2c))
|
||||
* **exams:** implement rounding of exambonus ([e97cd56](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e97cd5616bfadb838d3ba279768f38fb536dd4fc))
|
||||
* **exams:** improve handling of exam results everywhere ([0e49bc1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0e49bc14e5a66f75f75612a57024dace0303f299))
|
||||
* **exams:** improve immediate exam table on home page ([93e718f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/93e718f32366b4f4b6cd083473f15b192aeb642f))
|
||||
* **exams:** improve occurrence display ([2b56f26](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2b56f26c45bb0c17bd2b4ad0a491b912c96e9acb))
|
||||
* **exams:** introduce examOccurrenceName ([379a7ed](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/379a7edd12b16ed55d39e99637de647a51fb4267))
|
||||
* **exams:** notifications wrt. registration ([ae27ff0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ae27ff0bb16e1daab034bdac7bfbf787f3a3a77d))
|
||||
* **exams:** optionally close on finish ([4b525ea](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4b525ea8246706d191fce109d4a9d1f5cc4c22d1)), closes [#652](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/652)
|
||||
* **exams:** re-introduce ExamBonusManual ([54e94a6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/54e94a667027548056a12139ac96512fc4609911))
|
||||
* **exams:** refine exam form ([014a17a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/014a17a3be8811586caea5d9f178c5cd318fae29))
|
||||
* **exams:** show exam bonus in webinterface ([2b23600](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2b23600a2287e96e5b482c4e53125a55b64bbb93))
|
||||
* **exams:** show exam results ([b8b308d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b8b308d608a6acb9e70a143157437038de1f92ac))
|
||||
* **exams:** show number of registrations to course admins ([ec020c5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ec020c5486eb0573fa35a710b8ed0752d0443ea6))
|
||||
* **exams:** show occurrenceRule in exam overview ([06673e0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/06673e00311d01dbc7b8844cf2ab2f049e045cf1))
|
||||
* **exams:** show study features of registered users ([04bea76](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/04bea764f4dcafda1a07ca3a98f290433c207bc5))
|
||||
* **exam:** start work on automatic exam-occurrence assignment ([282df86](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/282df86bc20b5ec884379c6c81f232abfb4631c3))
|
||||
* **exams:** use template authorship statement settings if applicable ([57a259d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/57a259d8a2822ac1c593663e99f6e41163909c91))
|
||||
* **exam:** working prototype of automatic occurrence assignment ([f89545f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f89545f36ec4b0d45a0607b04d4b0d86b5dd1caa))
|
||||
* external exam csv export ([553c117](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/553c1176269850048998ef1a0b8f580c0d4dc267))
|
||||
* external exam csv import & ldap lookup during csv import ([1d14b6a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1d14b6a69cc569e3924523d4270a897c7529281a))
|
||||
* external exams in exam office exams table ([3b739f7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3b739f751d195063665430fc144169e998c8fa55))
|
||||
* **external-exams:** add actions to EEUsers ([2cf4895](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2cf4895231e889711dc62896937e775b3d85fe79))
|
||||
* **external-exams:** auditing ([2b153c1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2b153c1863752ddaf7a8f476fc9696448fed17e6))
|
||||
* **external-exams:** create new exams ([94bb391](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/94bb3911cb7dc1d12544be5a644ff0b7ec25725a))
|
||||
* **external-exams:** display staff & add' schools ([c14d90f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c14d90fd531a9d391f90df3c27724c0d3219f2ee))
|
||||
* **external-exams:** edit existing exams ([1252a5f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1252a5fc79354df10bd0b8d17953fb306ae5024a))
|
||||
* **external-exams:** list ([fa3521d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fa3521d6dbebe1d07352bec2269b10e5eb3e31d5))
|
||||
* **external-exams:** open defaults wrt. external exam schools ([ef1411e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ef1411efdb644e300656403c071cfcdef9caf077)), closes [#651](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/651)
|
||||
* **external-exams:** plan for student grade access ([b7506a0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b7506a03b1de498c3231e81c3330994d55dbb54e))
|
||||
* **external-exams:** requisite routes ([f25b21a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f25b21aa4b9f4be71bf1afc7cdfae58f7f93c689))
|
||||
* **failover:** treat alternatives cyclically ([9213b75](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9213b7554a6da2a40ea0c82ad4601a951dd7ebb4))
|
||||
* **faq:** exam-points ([aebc05d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/aebc05d021dc27c6539373b7e30a1f97898bf15c)), closes [#595](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/595)
|
||||
* **faqs:** i18n ([a1a0fa3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a1a0fa3a448c75f83949eb9f3a5f681fcd6e5792))
|
||||
* **faqs:** initial ([7b53377](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7b5337723d6dd300dc18a0881c589f89dea0bdbf))
|
||||
* **faqs:** more faqs ([18766ed](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/18766edc7c9757d26a9d83f1b996fdc473f48f8a))
|
||||
* **faqs:** more links to faq ([10d44d1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/10d44d189bb7df852bdbc64466e31f09fe91f619))
|
||||
* **favourites:** usability improvements ([fccc2ea](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fccc2ea212fd5d780510ee6b59191cd1d615c8b4))
|
||||
* **fe-heatmap:** add css class heated for heatmap elements ([b09b876](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b09b876969f43cc0d21af9f9c0057c1285811e3c)), closes [#405](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/405)
|
||||
* **features-of-study:** record parent & standalone candidates ([2621d36](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2621d36b7d020e67b66e0371004634decc5208fd))
|
||||
* **file-uploads:** maximum file sizes ([9dee134](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9dee134b11adb7f72ecb66117c4373c08a664979))
|
||||
* **files:** avoid initial unnecessary rechunking ([e80f7d7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e80f7d7a89e205ce53a70178e0b44d9b0ddf5b97))
|
||||
* **files:** buffer uploads to minio ([d9e9179](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d9e9179a52d1c17633b6dedae7d2a263f3612ac2))
|
||||
* **files:** chunk prune-unreferenced-files finer ([58c2420](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/58c242045887673f69c368668803574d829cc823))
|
||||
* **files:** chunking ([8f608c1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8f608c19552ef7bd6ce61af92496b3d5f5bf61b1))
|
||||
* **files:** content dependent chunking ([d624a95](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d624a951c54bda86e04d440eba9901d2a65153b9))
|
||||
* **files:** further balance file jobs ([1926917](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1926917dd7463a4ed11b9e7ee64fab6c8167de6f))
|
||||
* **files:** monitor missing files ([fb0ae65](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fb0ae65ac5928443abc01de9b57c69849d6a6b21))
|
||||
* **files:** move uploads from buffer to database ([9a2cba5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9a2cba5c0acd0db489d5958938efcdbf6d2dcc63))
|
||||
* **files:** safer file deletion ([88a9239](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/88a92390d580d618b15081c87dabe51c7c5e0eca))
|
||||
* **footer:** add link to source code ([5a88d5c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5a88d5c41f39a45147b049985d2f59cf70daddec))
|
||||
* **forms:** allow customisation of user-facing datalist values ([412ce98](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/412ce98fa0efc2715a9ba75ba8e95786fef47450))
|
||||
* **forms:** improve field labeling & error reporting ([3820b45](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3820b45b3e87de3d7ba43a11d84666227f42582d)), closes [#588](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/588)
|
||||
* **forms:** Introduce more convenient form validation ([f8d0b02](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f8d0b021edcf254c161ff98e1183e9e4bfab0df9))
|
||||
* **forms:** show studyFeaturesField in studyFeaturesFieldFor ([b7496f9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b7496f994075836949a9f6f5c584fa34a2441d1d)), closes [#451](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/451)
|
||||
* **foundation:** move stuff out of Foundation ([e27beba](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e27bebac59e42857b82e567f07576167bafcf8e3))
|
||||
* **frontend:** password visibilty toggle ([f0e4547](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f0e45477fa85a1d82750597cdaf122e41e9c7764))
|
||||
* **frontend:** split up util registry ([67e472f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/67e472fa5e09ed2068d477ef12b12adb0ca98c4f))
|
||||
* **frontend:** use webpack more extensively ([5d8c2af](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5d8c2af51d69c5d33c84447b7baabc75e34d930a))
|
||||
* generate & include new favicon ([b78c484](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b78c48465a4f42366c9a8e8ba924b8d5c2315d71))
|
||||
* generated columns tooltip ([2c4080d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2c4080d0e0d7f59829238830a5200116a9d884ec))
|
||||
* **generic-file-field:** prevent multiple session files of same name ([98e1141](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/98e1141e602b08d422ae0db1d25b24b35e6e3238))
|
||||
* **glossary:** english glossary ([237c586](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/237c5868b708e6f5734eef19c63f1764eb3cbdfb))
|
||||
* **glossary:** more de-de-formal ([7daa42d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7daa42db983c815dbfc65b50c59a10dbc5054bda))
|
||||
* **glossary:** most glossary entries in de-de-formal ([ba7c60e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ba7c60ec1ce697e65a9a507073f03c540bb20d41))
|
||||
* **guess-user:** add option to limit query ([4154a39](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4154a395f44edb059225caa090bd3ba95a1451c2))
|
||||
* **guess-user:** replace guessUser and usages ([ca96518](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ca96518e0eb348b91964d21680b1e8e8d3600fa3))
|
||||
* **guess-user:** variant of guessUser ([58ae9dd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/58ae9dddbc994f17cc52cc0940d996dedf583ba5))
|
||||
* **health:** check for active job workers ([d1abe53](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d1abe530b60939f69289b60216f52eab7e7ba6a4))
|
||||
* **health:** timeout all health checks ([33338cd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/33338cdfe94754759e4aa8cbf5ccd9f9fc939fa6))
|
||||
* **help:** attach last error message ([fdd6b1a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fdd6b1a194fd2d4a1deb399cd3914e63e167d30a))
|
||||
* **hide-columns:** add hider label th attr ([6c05a8f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6c05a8f09fdd0d1679c3c5b33277829901d2e8c0))
|
||||
* **hide-columns:** add hider label th attr ([71e90a1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/71e90a18178dcab90ee68519b15e44e51ff79a91))
|
||||
* **hide-columns:** add hider labels for material list ([ccafd95](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ccafd955b9b9659d05e34aadd0bd8fdc15ac44d9))
|
||||
* **hide-columns:** add hider labels for tutorial list on course page ([3553df2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3553df23ca75eab3c324d9b67aa11ce01212c230))
|
||||
* **hide-columns:** add hider labels for tutorial list on course page ([03e4ac1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/03e4ac1ccac94dc815b9341fbd547ee548d5f839))
|
||||
* **hide-columns:** add more hider labels ([555c4ae](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/555c4aebebbd050ec00ad0b4369c196502301d7a))
|
||||
* **hide-columns:** add more hider labels ([eba58d8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/eba58d83a04009f712f46fb2a4b123081b8ead84))
|
||||
* **hide-columns:** better positioning of hiders ([761c6d3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/761c6d39a82a57e4bdddd193d25be459b12ca1f7))
|
||||
* **hide-columns:** correct storage keys ([610d13a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/610d13a7292f61e7892bc0f58a666011efbbbe71))
|
||||
* **hide-columns:** don't break on dom changes ([c519792](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c5197928b12861599338a87dda9562ff16782332))
|
||||
* **hide-columns:** fadein transformation ([506f94e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/506f94e5d4afd2e2a955dab654f9a566a4152728))
|
||||
* **hide-columns:** first stub of hide-column util with manual styling ([111821d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/111821dcad4d0ffde6dfebbb62fb21b9b76ab9c5))
|
||||
* **hide-columns:** get table wrapper ident for storage ident ([d55d3ef](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d55d3ef4847f089970982e9554365f8699f2f9e6))
|
||||
* **hide-columns:** hide empty columns per default ([d1232ce](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d1232ce72d45ddcabe14f9770a0f8117d8efe74d))
|
||||
* **hide-columns:** more (broken) styling; move hider elements in DOM ([e655bc6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e655bc6e700f1b9668633f6beaef7acf8db484f0))
|
||||
* **hide-columns:** more styling ([4908702](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/49087027b250a8ce1212d508e1c9028f5122a09e))
|
||||
* **hide-columns:** opt-out on select columns ([b03c10f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b03c10f09810796f43d313dd17b15f5c39c8e5a3))
|
||||
* **hide-columns:** refactor and auto-hide empty columns ([047c0a5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/047c0a5787657be7f810b20599bb1015a99b4e9b))
|
||||
* **hide-columns:** set attributes for hide-columns and extra-stuff div ([169a479](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/169a4799b4996c9474ee492e79dcd0a5040af04e))
|
||||
* **hide-columns:** styling stub with repositioning ([a9c17d7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a9c17d75fe2ec2aef65e4150d8f080797433fe0d))
|
||||
* **hide-columns:** support colspan & don't persist autohide ([0798d68](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0798d6870e7b4dfd0baf23940fe5d87b9c2d444c))
|
||||
* **home:** allow users to define exam warning time ([d23e222](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d23e222fd0b2eb45afd28a5cb96cd25c433cf0c2)), closes [#445](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/445)
|
||||
* **home:** clean up homepage ([a6e2f64](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a6e2f6491048186415546f5cbbd513b75c123026))
|
||||
* **homepage:** add convenience links to term and school ([83445c4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/83445c4e7707febc569f4bff271f995ece64dcd0))
|
||||
* **homepage:** add prime action new course to homepage ([2208368](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/22083685961ca0503cce168c97bba73beaec2ea7))
|
||||
* **home:** show immediate exams on home page ([242cff3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/242cff30600a857efa9b98a44b44cbb73a1b1001))
|
||||
* **http-client:** baseUrl and defaultUrl ([693189f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/693189fe8274fea64596d09f158a1121196c35eb))
|
||||
* i18n form ([2d95f35](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2d95f353c1209a4d3528c6aaf53c832bf5429a34))
|
||||
* **i18n:** 12h-clock for english locales ([331ba1f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/331ba1fed3ca5e25942c906b10f670e2ed03299b))
|
||||
* **i18n:** additional en-eu ([83a458d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/83a458ddf530941663108db705067fe129fb8bcc))
|
||||
* **i18n:** basic language switching ([352bdba](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/352bdba1a4377bbd3ecf76b72c6aee6fdd861316))
|
||||
* **i18n:** close language select on click anywhere ([97a29ec](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/97a29ec68cb64e4264afc1d6a95e73e608b33748))
|
||||
* **i18n:** english imprint ([7b3ed79](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7b3ed79ddd4c1d7d29c4830f7f5929662e9011aa))
|
||||
* **i18n:** english versions of imprint and data-protection ([4ee3ad0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4ee3ad01bab9b8d57ae266904a259130a5c039d4))
|
||||
* **i18n:** get started on en-eu ([75677dc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/75677dc171943cbdd4abb872dd813a9bea40e40e))
|
||||
* **i18n:** missing message translations; small fixes ([aec4b21](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/aec4b21757c4d38622db30d96faa95b4fcaa72c3))
|
||||
* **i18n:** missing translations ([153bb1f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/153bb1f62179e19e34f5c818544b86633a826e0a))
|
||||
* **i18n:** more en-eu ([67e40fd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/67e40fd3e71a90b13ce75be33cbad7c229b1899c))
|
||||
* **i18n:** more en-eu ([3058737](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3058737021a5f9f949d2da7a3ca608eb71f34cc8))
|
||||
* **i18n:** more en-eu ([7c8dbc9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7c8dbc9dcc0c79bb50f464eb565d1cebba83b4b5))
|
||||
* **i18n:** populate frontend datetime locale from backend settings ([498d616](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/498d6168a0f47b0f93bab75d65b87c34670535f1))
|
||||
* **i18n:** store language in user account ([f0f9411](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f0f94112f4d8b9af96c2048a046e43ce7ae7351b))
|
||||
* implement in-memory cache for file download ([36debd8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/36debd865f6e74856c74bd658dc4694140183fed))
|
||||
* implement system-exam-office ([42aee66](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/42aee66d1f9c189a6a6b13b1970c61e0299630ae))
|
||||
* **implementation:** add paragraph about license (AGPL-3.0-or-later) ([d4b341b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d4b341ba259e710a142d813ede83c209fe2fe45a))
|
||||
* improve logging/metrics wrt. batch jobs ([d21faf4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d21faf4de0d40a3683ff2a7a3020bc85717f827c))
|
||||
* improve navigation ([95ffda2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/95ffda25b6f1a6e9e8ae0b0be5e58a7260c4f5fa))
|
||||
* **info-lecturer:** add english translation; minor fixes in german ([a4fc555](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a4fc5551f1936a1e8fb5e7c28a2911fbc1ae8803))
|
||||
* **info-lecturer:** add expiry time for newFeat ([fa9e6b5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fa9e6b587b2143160ad2067923b55592c7db64ea))
|
||||
* **info-lecturer:** add inline newU2W icons ([5a49feb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5a49febf9c484bb0cf40007fee3197f206b5488e))
|
||||
* **info-lecturer:** add newU2W icons on info page ([9f02ef0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9f02ef02b3cfa2b4f7ee5ace2cda1a492f76ee5a))
|
||||
* **info-lecturer:** minor adjustments ([64b391a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/64b391a0feb8150c5a213a5ccf7e3eadddeaa714))
|
||||
* **info-lecturer:** more bullhorns ([4a5e7d9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4a5e7d9e7e1c5cc8f56169401693fea3f4c65a8a))
|
||||
* **info-lecturer:** remove "news" section ([cb1e3a6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cb1e3a604b305ca45584bc009f4bf0c027613e22))
|
||||
* **info:** info seiten überarbeitet ([7459fc3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7459fc34bc747fe7af31a4bc87930e1bea03c923))
|
||||
* **info:** start glossary ([73b0546](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/73b0546db674914ca24e0f69c0c17a309e88fc1e))
|
||||
* **inject-files:** additionally throttle by file count ([3cf0335](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3cf033560e90ddc104e4056c470459f92b6eb4ae))
|
||||
* **invitations:** additional explanation for new users ([bb9c34f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bb9c34fa4de6efc811e6a336a8e68f924ff37b56))
|
||||
* **invitations:** anonymous invitations ([1380d9d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1380d9d21ea457ad631998c64b63d6aa85b764ce))
|
||||
* **invitations:** save expiresAt to DB ([1c2f2b7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1c2f2b7221d2bb237f3f1da61ca1cd9cde791506))
|
||||
* **jobs:** batch job offloading ([09fb26f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/09fb26f1a892feba32185166223f8f95611ea9ef))
|
||||
* **jobs:** move held-up jobs to different workers ([284aae1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/284aae12135ad97b1cf85b45f1176da6930876ee))
|
||||
* **jobs:** queue by jobctl priority ([a27a553](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a27a553e0a9782eda6023ec0b8b1055757bb511f))
|
||||
* **ldap:** automatically synchronise user data from ldap ([b39ba8b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b39ba8b268ca705e93398175df55f8cb741c376a))
|
||||
* **ldap:** expose active directory errors ([51ed7e0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/51ed7e0a26a94d2178a4ca10ad7ea36b99076b54))
|
||||
* **ldap:** failover ([0e68b6c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0e68b6cf5348bbf5baa5014a86be321a7e5e4b49))
|
||||
* **ldap:** manually trigger ldap sync ([83afb6f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/83afb6f15fb107b5302958020dcba4018f98ba8d))
|
||||
* **lecturer type:** aenderung ([89e1d67](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/89e1d675c3be0fec106e84920184a8c95dfa6346))
|
||||
* **lecturer-info:** add planned features icon; update info ([a4068b4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a4068b4a82931f1bc40d0edceca53297e0e45120))
|
||||
* **lecturer-info:** fix typos, add info (adding tutorial participants) ([5139825](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5139825aad1a9ab602000e2d870e424da6b84e48))
|
||||
* **lecturer-info:** replaced icons with icon-tooltips; edited text ([2ca7085](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2ca7085ec95c981fd4721a952064b3df8dbccb58))
|
||||
* **legal:** fix translations and links ([cdc4053](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cdc405307613eae1ef30b19e417faf27d6aee4a5))
|
||||
* **legal:** move legal info to one single page ([565c6a4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/565c6a4f3d3faabaee7d52f6bdb701c703aae7a6))
|
||||
* **letter:** allow printing of multiple course certificates at once ([768f03f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/768f03f6727f54b7c7aa18ecef8bc67302ee27cd))
|
||||
* **link password time:** application restore ([6d536c3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6d536c39bd9f3117f18d2e52c93f178aea4a002d))
|
||||
* **link password time:** done ([4490e9a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4490e9ad20c55153e81a344c7dbf7813cb219108))
|
||||
* **link password time:** done ([2321216](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2321216b0f4f194c7cd8b47eb020819d6aa1f2e5))
|
||||
* **link password time:** new time format ([df2a9bc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/df2a9bc20fe9f958cbee98315b644ec2fcba0630))
|
||||
* **link password time:** restore application ([c5c5417](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c5c541709b5053c08d21bdd753bb99df574c6c5b))
|
||||
* **link password time:** restore application ([85006ff](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/85006ff389188b56a8b61943621c190c9a9503b7))
|
||||
* **lms:** configurable csv settings for lms direct import and export routes ([6159403](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6159403b27dab30178645dc37c99d41b4aaf610c))
|
||||
* **lms:** enable upload handlers for all upload routes ([a5121f0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a5121f0d3e7a77695a6198057afd23f5f86ff174))
|
||||
* **lms:** random ident pw generation without db ([21b74a5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/21b74a5d7ff3c03be466ef911fbb8ed2a1b67f4b))
|
||||
* load shedding ([9df0686](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9df0686086ff7b64d401a2302edd2fe7636db111))
|
||||
* **load:** allow creation of submissions without login (w/ token) ([2e826d3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2e826d3c4585b0dafe8ec7abbdd63e23f1d5d341))
|
||||
* log ldap error messages on invalid-credentials ([0b4fade](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0b4fadedd2d7ffbb58598d9844e1c7d97cabc447))
|
||||
* log sent notifications for analysis ([c5ef6bb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c5ef6bb5a5430a5f9b4dd4b2a5635332d1edfed7)), closes [#535](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/535)
|
||||
* **logging:** additional logging for inject-files ([cbf41b2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cbf41b2ea061aa276f455dde1e31464d106cd3d7))
|
||||
* **log:** remove container log setting in order to use stdout ([8f460bd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8f460bd0a3aba9013f2ee2d20a1465487ecfe629))
|
||||
* **lpr:** print center allows filtering by day now ([cac4870](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cac4870c95f5367536ee48644fea8a526a0da5a3))
|
||||
* **mail:** archive all sent mail & better verp ([1666081](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1666081fea0eec0bf5440a100db0e8cc69be8295))
|
||||
* make git revision accessable to nix build ([b37c2e6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b37c2e6aec125952c26156ad599f18496d5cea8e))
|
||||
* make pagesize changes load async ([6486120](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/64861205361bb6ee25b172528bbf939850ba3efd))
|
||||
* markdown help requests ([06f3ac6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/06f3ac656313dd751f8a758349f6151497dc4ddf))
|
||||
* **mass-input:** automatic add before submit ([7540a4f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7540a4fe5fe0f61d449bc7cc5f5aa7d3da034f55))
|
||||
* **massinput:** reduce size of ajax requests ([72838e2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/72838e2592f159ab79c9f245ac28a4f9bd807e19))
|
||||
* **memcached:** introduce general purpose memcached ([e8c2dc5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e8c2dc5aaa5baeeffef805752a7639c9e412dc21))
|
||||
* **messages:** implement custom parser for message files ([bb877eb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bb877eb81396211a801496061ea603b39753829b))
|
||||
* **messages:** mkMessageAddition ([ea33d84](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ea33d844cc4acb2503fc4780c7895299eb9d5ef5))
|
||||
* **messages:** rename subs grade ([534c32d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/534c32d9f90fc95a5cf7ff16056ffffeca8cf964))
|
||||
* **metrics:** basic collection & export of metrics ([b8f41ef](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b8f41ef0b36c092f734f9ee901b2f438ea21aab8))
|
||||
* **metrics:** measure file i/o ([4801d22](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4801d22cb360dcd936c57494ff2ff02655431409))
|
||||
* **metrics:** monitor job durations ([0da6c49](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0da6c493924ef544208a3a330bde7714a61fd835))
|
||||
* **metrics:** monitor job executor state ([b74bb53](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b74bb53041073546df1b45b03758b559c98b95c8))
|
||||
* **metrics:** observe login attempts ([0c7e56f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0c7e56f4054593eef757dffba49fdc27f7b060df))
|
||||
* **metrics:** report on health checks ([bec4023](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bec40236dbdedd022b968e83f563df75ab35c959))
|
||||
* migrate indexes ([dfe68d5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/dfe68d5924d37ea4d3fd0df0a8e68871bcd187d5))
|
||||
* **migration:** switch from versions to enum ([f2fb7d8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f2fb7d8c267fed96f0dbdb237f4984c8996fbce8))
|
||||
* **minio:** use separate bucket for temporary files ([1cd79d3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1cd79d35e2761d84bb904a77e74d5cacb0b2244c))
|
||||
* **monitoring:** observe database connection opening/closing ([d801a2f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d801a2f84ae42862dfc357a58ee47dd6dc39eef8))
|
||||
* more date & time formats ([936c366](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/936c3666fcc39e00ef1c868b3f23d4bb88336702))
|
||||
* more en-eu translations; minor fixes in de-de-formal ([870f1df](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/870f1df4d30182ef08d4c7b2f8bb15a6ea722925))
|
||||
* **multi-user-field:** improve placeholder ([2936eef](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2936eefbd1626fb69afa735df2d2dae5783ba842))
|
||||
* **multi-user-field:** multi-user-invitation-field ([c072b85](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c072b85299f87f6ddfcdf72ff3db4881a079af41))
|
||||
* navbar header containers ([1348c91](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1348c91c3c7a5c645decda9215c352fa2130aaaa))
|
||||
* **navigate-away-prompt:** prompt on actual value change only ([293ab6d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/293ab6dc62725a2b9785b18d7f06ff8efbf860ea))
|
||||
* **news:** active allocations for lecturers ([cde0122](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cde012252907c57506eef44868b3d25fae50a8f7))
|
||||
* **news:** show system messages ([0d39924](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0d399247773a0e4799602c49e6c06de906b43fec))
|
||||
* **news:** timeout sheets after a month ([31aa25a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/31aa25a1fd6acd0994e2af156b4b166b3717de13))
|
||||
* notification about externalExamResults to exam-office ([a304840](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a30484003ae75ccbb98a4d275423320bd9d09f33))
|
||||
* **notification triggers:** redesign interface ([84c12b5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/84c12b5fc7c875940900c2c38cf59b09c0d63fab)), closes [#410](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/410)
|
||||
* **notifications:** add NotificationExamResult ([a7e2921](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a7e2921a731d74eb4b79d60e8e1f34aa90161b60))
|
||||
* **notifications:** sheet-hint & sheet-solution ([f11b215](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f11b215773fb2af8cb400d5798029802768a631a))
|
||||
* optional ribbon ([c2e13cf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c2e13cf4df1fc8a6e0d919b5171a7eaf002fd381))
|
||||
* pageactions for exam correct interface ([0d4dcf8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0d4dcf8658d7b6d6f3fe692400c772425bbfb3b0))
|
||||
* **pageactions:** finish restoration ([e1cac76](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e1cac76f1518e2de0f9d7e9f0f80278ea07fac0d))
|
||||
* **pageactions:** restore pageactions ([4bc48a5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4bc48a50faf4fbecff14fd7e38a31503097d74d8))
|
||||
* **pageactions:** restore pageactions ([926bd44](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/926bd4473696a7d1524659895975749d7b4b3a79))
|
||||
* pandoc-markdown based htmlField ([c5848b2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c5848b24e850eb0bfc13db3ff68fd05df522b057))
|
||||
* partial support for lsf import ([37cdc77](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/37cdc775b5b2d3e4cd1cc22858b2c05e75de8a3c)), closes [#686](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/686)
|
||||
* partial/conditional downloads & video streaming ([5b28303](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5b28303539e28024b43addb413aedc4e5ee0e470))
|
||||
* participants intersection ([697c3e1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/697c3e11fc3bdd279c0df2d4fd9362bf2981ccae))
|
||||
* **participants:** basic funktions added ([b96327b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b96327b18dafcd020c94bb84c6aafffb53544076))
|
||||
* **participants:** corrections ([fd11121](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fd111215447aff817399db379a4ca8e90eb73cff))
|
||||
* **participants:** corrections 2 ([d6ce0c4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d6ce0c47d92fac76ccdc59805fcdbd3ad932d3e3))
|
||||
* **participants:** first finished verson ([0a3fd23](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0a3fd23e22a81b3636fb3ac224dce52df3f752f2))
|
||||
* **participants:** second version, Intersection added ([02354f0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/02354f0998e61c236bc982848b9d709c927690f5))
|
||||
* **participants:** small Name-change ([6f3243d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6f3243d90bdc137e7f2ea9fe8e271f1cdc32dfbd))
|
||||
* **participants:** small Name-change ([eced778](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/eced7781ae346e285b7f3949917f23883b4dfaa8))
|
||||
* persist bearer tokens in session ([d8040e7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d8040e7aa864e2078962ed2c938ae91408dd9e50))
|
||||
* **personalised-sheet-files:** collated ignore ([1fe63a2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1fe63a23a0b41dba3b87b97903eb58ced87f8b2d))
|
||||
* **personalised-sheet-files:** download from CUsersR ([93d0ace](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/93d0ace8ba97d19edba92a65b3f37a793165baab))
|
||||
* **personalised-sheet-files:** finish upload functionality ([ed5fb6e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ed5fb6e218097250f197b7795d448bbfe460bf99))
|
||||
* **personalised-sheet-files:** i18n ([f452b2b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f452b2b24f60e3d2cfefee0501d9833e2f7665db))
|
||||
* **personalised-sheet-files:** introduce routes & work on crypto ([9ee44aa](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9ee44aa2f1aaa91c898b216f0dba58017122c75f))
|
||||
* **personalised-sheet-files:** participant interaction ([db205f6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/db205f635d8c80b037f96f34488fde451140eda7))
|
||||
* **personalised-sheet-files:** restrict download by exam ([a8f2688](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a8f268852a256209f6ab187167c2a1c066618c4c))
|
||||
* **personalised-sheet-files:** seeds ([cf67945](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cf679452928c14200e1eb3877987ee299fbf9f6f))
|
||||
* pruning of unreferenced files ([ff161b2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ff161b2e045dcd1281aec21513ed1c818f2174aa))
|
||||
* **qualfications:** renewal actions and filtering by card and personal number ([4df0243](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4df024374d387fc85a833b3faffe1b6ef8edc7d9))
|
||||
* **rating:** pretty-print to new yaml based format ([2bf4846](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2bf484609e4efb905614ffddb3b8f0dee03f5483))
|
||||
* **ratings:** i18n rating file names ([1195231](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1195231bc3d3502fa4f77db64d30f2138cd7fa20))
|
||||
* **ratings:** parsing for new format ([af79473](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/af7947328d38ef6db4450bae177efdae7877ab56))
|
||||
* reduce number of study features for courses ([51a98f0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/51a98f067086bcef3daff601b53d5eb45f4a27f0))
|
||||
* refine presentation of exam-correct ([95c1755](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/95c17557107c3ff41ea85cd32d3e5ff435feebb9))
|
||||
* rename "Start" to "Beginn" in error messages ([66bd10e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/66bd10e4142cee5f1683e1252885f1b5a0a07fa6))
|
||||
* renamed "Bewertung abgeschlossen ab" to "Ergebnisse sichtbar ab" ([6b610e1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6b610e1e54cbca89bd957101723e9c79652d315a))
|
||||
* restore & improve navbar contents ([51fc6dc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/51fc6dc541ea729c049271d3f1d16afffd5ef6c0))
|
||||
* restore study features in all tables ([363f7ab](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/363f7abc192872ebd2a609b8bd89b58032bc9131))
|
||||
* **robots.txt:** disallow ahrefs ([9afee89](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9afee89a090030c31b6025eef22b5055a4251c0b))
|
||||
* **rooms:** different room types & hidden rooms ([319c75a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/319c75a85aa5e5f7e2f2af328d69960e1df3cb80))
|
||||
* **schools:** add school settings regarding authorship statements ([cb8e338](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cb8e3385889c0c4c13418bc69af091b9c8a3f22f))
|
||||
* **schools:** implement cru ([18ae28a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/18ae28abbcfcff6015b419f6791bc60fe6dd88f5))
|
||||
* **schools:** more school-wide configuration authorship statements ([960bd76](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/960bd76acafc9cd077b831b67a281eb7b20e703c))
|
||||
* **schools:** store school authorship statements as html ([09927ae](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/09927ae14004f7a27f816ad874704969641dad83))
|
||||
* **serversessions:** move session storage to dedicated memcached ([9960059](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/996005935df86cbbc48bd823cc8cba13aa2f8bca)), closes [#390](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/390)
|
||||
* **sheetlist:** sort sheet file types in db by haskell Ord ([643cc41](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/643cc4165fdec197ae8f744f193a731e731f537b))
|
||||
* **sheets:** add required flag and definition ([541dd76](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/541dd7688ffa36be8a968f26f920507ed5aae646))
|
||||
* **sheets:** better explain rating-done ([3944ce0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3944ce02615f8f4d3ec6a14ae4beaceb324c6104))
|
||||
* **sheets:** display authship req on SShowR ([44473b4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/44473b45756c5df20e6a81927867de191cf70366))
|
||||
* **sheets:** eliminate authship statement required Bool ([0735c05](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0735c05a7489957ed500bac1c006f4ecfdab74f3))
|
||||
* **sheets:** fetch school statement as statement default ([a39a0d7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a39a0d7c8763e158dae5750afac8a78bd953dcdf))
|
||||
* **sheets:** introduce sheet-specific statements for exam-unrelated sheets and as exam-statement overrides ([3f87f20](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3f87f20eb14e5db8a63c61885c4570689169ebed))
|
||||
* **sheets:** pass-always ([b2ebce4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b2ebce483658d74239b7a9dd5462b7c78371b896))
|
||||
* **sheets:** require exam registration ([d770afd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d770afd2c6ade597fa2b8ecf229c312f1ee6be56))
|
||||
* **sheets:** submission groups & rework sheet form ([57f1ce9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/57f1ce9265e2a122aa7a318b923df51ee9ead0a3))
|
||||
* **sheets:** upload-empty-ok ([ab1940c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ab1940cb09e824fbba03264b5451fa8b17c5c804))
|
||||
* **sheet:** warn about no submission without not graded ([9373266](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/937326639a02c576f278b79b8ebb441a2652bece)), closes [#342](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/342)
|
||||
* show authorship statement requirement for sheet ([5e96982](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5e969825ad0c84c240b5c17b011dacbb63f4bfdf))
|
||||
* **sort-table:** add basic SortTable util stub ([53131e2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/53131e2de891edc57d900a618aeadc31533f305b))
|
||||
* **sort-table:** add basic SortTable util stub ([11c0bd0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/11c0bd07e93a4a59d78226dbf3a2ca94d02a5883))
|
||||
* **sorting tutorial table:** application restore ([9dc12de](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9dc12de056e73736659c053b0eabef66ca524047))
|
||||
* **sorting tutorial table:** done ([482241d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/482241d033c32c52c31ea20920a4fec07ba975dd))
|
||||
* **standard-version:** allow adding additional changes to release ([7ed6fe4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7ed6fe4fedc2f0ee463680a0d3210d7a6f4ac7ab))
|
||||
* **standard-version:** complete release workflow ([605e62f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/605e62f4458238119eaf13b3e8151924d758e3a9))
|
||||
* **static pages:** touch ups ([d2c0043](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d2c0043debb0896446cefaef5f488e99470bbf39))
|
||||
* **status:** show instance running time ([8743719](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8743719183abfa10d089c6e7e765e49f6da3c50d))
|
||||
* **storage-key:** add breadcrumb and import ([8cf5d63](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8cf5d63cf2d63d3fa0017d3c555a2070431086f6))
|
||||
* **storage-key:** add breadcrumb and import ([1580d3f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1580d3f59bf4d716228ecc15c8af17b8af445250))
|
||||
* **storage-key:** add StorageKeyR to routes; minor Handler refactor ([2d1d58f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2d1d58f78f3bcdce5030da2eb2e67532f3ccff27))
|
||||
* **storage-key:** add StorageKeyR to routes; minor Handler refactor ([4d4dc8f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4d4dc8f58be9f0c705b52d6bbd42041d41b2749f))
|
||||
* **storage-key:** postStorageKeyR ([059efe5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/059efe5085967366df663ca531f1e4fb521ac9ab))
|
||||
* **storage-key:** postStorageKeyR ([b51c466](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b51c466a650743d9df9e954313e9c7501f66c4f0))
|
||||
* **storage-manager:** add en-/decryption stub (WIP) and restructure ([54d852f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/54d852f30823c59146d75d33f05f35f2c66a228f))
|
||||
* **storage-manager:** add en-/decryption stub (WIP) and restructure ([0016145](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/001614522e0ae3841b27086e9370c999c24a2963))
|
||||
* **storage-manager:** add storage manager library ([1023240](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/10232401369fa18fd7866a584b4f6d3eb1380e5c))
|
||||
* **storage-manager:** location hierarchy ([80ff4ac](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/80ff4ac2a734bf295a026aa68d5d881da9cca3bd))
|
||||
* **storage-manager:** store encryption info per location ([25a7c34](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/25a7c3420a68ef6a959506db27411dc363c1b839))
|
||||
* **storage-manager:** store encryption info per location ([8122ab1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8122ab10b0277069ec4a6de7f77dd34748df3fe5))
|
||||
* study feature filtering ([96d0ba8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/96d0ba8f7a1c8d8d4e895541b66e36d35392fb25))
|
||||
* **study-features:** add study-features-first-observed ([dcb83d9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/dcb83d96fc0e52c0c322e50d9467d9a2bed90359))
|
||||
* **study-features:** cache study features term relevance ([8f6d54d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8f6d54d0125e01f5c8a90843b54129d6412b79f1))
|
||||
* **study-features:** complete StudyFeatures admin-interface ([c4c82f5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c4c82f54396abd6cdb3c719079a6f87a883c4989))
|
||||
* **study-features:** further restriction by course ([f7a9bc8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f7a9bc831a3b0ef58fcbf7918be9f5e3b262641e))
|
||||
* **submission-groups:** invite w/ submission-group & audit ([7f10d44](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7f10d44aee0fea561e331e20d03ff814a6df9baa))
|
||||
* **submission-list:** bulk download submission originals ([d7f2d11](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d7f2d113929f9dc11291d6db916c8944ae158c3b)), closes [#707](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/707)
|
||||
* **submission-show:** display authorship statements ([cbd6d7d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cbd6d7d2b098f8e2c921fd7a56a458d62331d784))
|
||||
* **submission:** add correction to sub-show-r ([e060080](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e06008026160185103b9adf60b5cfbc6991d77df))
|
||||
* **submission:** allow restriction of submittors via token ([0fa8d37](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0fa8d370374ae8022faa0ebd7dfcc5a50afa4e4c))
|
||||
* **submission:** edit notifications ([98c0d69](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/98c0d6919e0e4ef4fca6eb451edbd8283829ebf6))
|
||||
* **submissions:** also warn correctors about multiple submissions ([8795edd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8795edd1fa452d012704146481c8318d206634a5))
|
||||
* **submissions:** display authorship statements ([7749238](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7749238e554b612a8bf69e6beb94efe3e5d02973))
|
||||
* **submissions:** display submittors more explicitly ([d2e2456](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d2e2456f6204245d933fb6abc87c44388ce3e339))
|
||||
* **submissions:** ignore additional filename components ([38f69c3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/38f69c3aedaf497753a5240d1d64970320f4f64e))
|
||||
* **submissions:** improve behaviour of sheet-type-exam-part ([91a5166](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/91a51664c32bd17e4c2d1cd496bf05338146291d)), closes [#676](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/676)
|
||||
* **submissions:** non-anonymized correction ([fd2c288](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fd2c2881ea5a465458eb3f64d7767be3a307dc46)), closes [#524](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/524) [#292](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/292)
|
||||
* **submissions:** optionally disable consideration for deficit ([c6a6ec7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c6a6ec721c2a863d324ddfb5d2b2c1e42e659067))
|
||||
* **submissions:** warn about multiple submissions for same user ([c19a00d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c19a00dcefb2dcae017026edb6e1c7cb6ce16841))
|
||||
* **submission:** warn about deleting co-submissions ([e87f607](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e87f6075d379eac84decaf0079cf62d8d5d0698d))
|
||||
* support exam registration including room (ExamRoomFifo) ([14bb020](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/14bb020fe9d8f7579269468c9fb55a1dc373d145))
|
||||
* support for ldap primary keys ([bbfd182](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bbfd182ed93d1e602229a2fd1ac1e0fa4c4439ef))
|
||||
* **system-messages:** hiding ([c81bc23](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c81bc2314e75d82ad2a246218b7e077d5cb02781))
|
||||
* **system-messages:** manual priority ([cf06f79](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cf06f798072a5c4cd1a7f6f92c035929f467ff30))
|
||||
* **system-messages:** refactor cookies & improve system messages ([ead6015](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ead6015dfef7e667e52116b26fd92ebfd4f908eb))
|
||||
* targets on InfoLecturerR ([5ffee38](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5ffee38979e239c40390c4c5e4ac8db1532bbede))
|
||||
* **terms:** better prediction of term dates ([e5732df](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e5732df1b62756aa267fbaad598f96478cba0220))
|
||||
* **terms:** improve term display/editing ([8b7e8e4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8b7e8e4bd541dec10e098485453b6a08c758bb68)), closes [#485](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/485)
|
||||
* **terms:** time based term activity ([df073ef](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/df073ef7947eb80dc35fe955b92e635881eb50fa))
|
||||
* **theses:** additional state explanation ([1e38734](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/1e3873485e3da81b25dd0a0eb5aed7b9e0fe42b2))
|
||||
* **tokens:** multiple authorities ([bc47dcf](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bc47dcf43f08fdc6e9b52dc205fbabea1893259f))
|
||||
* **tooltip:** added test warning to admin test page ([885efd3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/885efd364b5a59365b1594e33c5de8317e9f16fd))
|
||||
* **tooltips:** add auto unzip and multiFileField tooltips ([276dcb6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/276dcb6ad962b4ffca07e58b6231cebfaceb68c6))
|
||||
* **tooltips:** add option for inline tooltips ([0b2e931](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0b2e9319be2bec3546f2af2568b86ce39f114025))
|
||||
* **tooltips:** replace tooltips ([3b0e1d5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3b0e1d570d4000cf386def168400413fb0992753))
|
||||
* **tooltips:** tooltips from messages ([f85ab69](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f85ab69114f4947cf1b80469d3e75c2848bc8d5a))
|
||||
* **tou:** add english translation ([ce8b1a6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ce8b1a6c64a8f4f0e64f90367e23d0f85a7f1e8c))
|
||||
* **tou:** first stub of german tou ([74caeca](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/74caeca9676ae1c1a00fc22e16b6b47209499d88))
|
||||
* **tou:** implement Terms of Use (tou) route ([932cd5c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/932cd5cfdba309b1c70682c0f1731ac173298432))
|
||||
* **tou:** small fix in english translation ([aced70f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/aced70f8346cb9f2d4b7a58624dc865005f35a48))
|
||||
* **tou:** small fixes in german version ([246af70](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/246af702d2fc898fb012d448f36b9d509371a6f1))
|
||||
* **transaction-log:** more details about submission files ([b9cc5b9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b9cc5b9970cc0b1f61c9df03c54901d9d6e822d0))
|
||||
* **tutor tabel sorting:** dbt sorting tutors added ([b1787cd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b1787cd77e8a643accc0ef54cc18c87df215680c))
|
||||
* **tutorial-users:** replace study-fields column with qualifications column ([9850e1d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9850e1dd88a5371abe67fd5fb69458d7f52ea8e8))
|
||||
* **tutorial-users:** table action for granting qualifications ([fa0caba](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fa0caba55d05f080f5ed98b0b83dde3c6cebe7b7))
|
||||
* **tutorials:** delegate control to tutors ([261f3ed](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/261f3ed92f4ae689d0fbaf83a8070b619d3c2444))
|
||||
* use c++ library for json parsing from database ([f226751](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f22675189e19d1cce20362121ef8c8aebe3628f1))
|
||||
* use pandoc to convert html emails to markdown (plaintext) ([4879bb8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4879bb840482b6b81b0dee58a01f3f33c5c1c725))
|
||||
* **user-schools:** allow users to override automatic school assoc' ([7d927fd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7d927fdd5fe6e1e4abd315abf4b415c58f99e89b))
|
||||
* **user-schools:** automatically assign users to schools ([12067de](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/12067de2ff7e645f324ba266869d4ba1ca0ad064))
|
||||
* usergroups & metrics usergroup ([9204565](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9204565cac7b2c52f5d69ada066824e37ba6ae38)), closes [#538](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/538)
|
||||
* **users-add:** add error message for users not found in avs ([e273c60](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e273c60a2325f75033d2393725ce7a25368821bf))
|
||||
* **users-add:** redirect to different routes depending on tutorial ([93c6853](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/93c6853b082a5d2195bb55cbf7b792d2f4307254))
|
||||
* **users-add:** upsert tutorial participants ([662445e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/662445e8cc92cf9f5815851d7e9d0b559cef289e))
|
||||
* **users:** allow customisation of displayed email address ([2f38278](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2f38278ab141ac4db7d16a4b6d990c58067b200e)), closes [#459](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/459)
|
||||
* **users:** allow customisation of userDisplayName ([a85f317](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a85f317bf2de8c5038b406d6c5601d0ead8e4bd2)), closes [#346](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/346)
|
||||
* **users:** allow users to set postal address and email encryption password ([655fcf7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/655fcf756471a2dfc6380e4b63236ca8d5229e11))
|
||||
* **users:** assimilation ([ef51c6e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ef51c6e7c34effa691125e4313876d95feda96af))
|
||||
* **users:** generalise UserLecturer and UserAdmin to UserFunction ([76f8da5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/76f8da52e0f532ef08df5ad649aa3d2bb24159f5)), closes [#320](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/320)
|
||||
* **users:** ldap-synchronise arbitrary subsets of users ([0789536](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/07895368ddda85cf8d1ce9838d5cfe5db32c511d))
|
||||
* **users:** lecturer invitations ([e6c3be4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e6c3be4f7b1694420756ab194f0c607af427cfdd))
|
||||
* **users:** sex ([c2a8381](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c2a83812785e9f8f2ad948a551527df95e24d118))
|
||||
* **users:** store first names and titles ([ceed070](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ceed070e35f8ef4decc0afcfc338abbfdb8a46ac))
|
||||
* **users:** switching between AuthModes & password changing ([0d610cc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0d610ccf4459ab929d18ab7285dd080b51394ad2))
|
||||
* **util-registry:** ensure specific start ordering ([baf8b18](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/baf8b18dc3049559891647ab2ef43a23a982cbdb)), closes [#587](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/587)
|
||||
* **util-registry:** more debug info for setup util instances ([00584f9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/00584f95901786ce211f64e1edcfeedab2299c45))
|
||||
* **utils:** throwLeftWith to facilitate ldap code ([8417eb5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8417eb57c9b8324cee81cbd16ff72f6039757a8e))
|
||||
* warnings about multiple terms/schools ([91e1bf9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/91e1bf99966655b0a8f7ab99d0ddebe5642c627b))
|
||||
* well known files ([068632b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/068632b11753f58e8142608db3dc139d0c84f93f))
|
||||
* **workflows:** add missing instances; correct Int64 workaround ([8b32ede](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8b32edee64509ca5a3d5fc206192d4fa43cc1971))
|
||||
* **workflows:** additional work on WorkflowWorkflowWorkflow ([5108e14](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5108e1494aa8b2bc8b383a349d1d2a4e0249501f))
|
||||
* **workflows:** create new workflow definitions ([4d63d30](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/4d63d306347ed452822b6bea101cdf4391363ed1))
|
||||
* **workflows:** definition route stubs & i18n ([e3b5b93](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e3b5b93c71e49203e428382cfabb3d536f290cc4))
|
||||
* **workflows:** delete definitions ([bda4f81](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bda4f81702d94d81427a4980b217be8cae2b9152))
|
||||
* **workflows:** edge messages ([c22004e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c22004e1b2f3cd85297faaf41d76954c0625e308))
|
||||
* **workflows:** enum fields ([426c40f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/426c40f0a4f596804eca723e09894f9c5606af6e))
|
||||
* **workflows:** explanation text ([aba6737](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/aba673756e9e40057625c41da8b32d378e9b67c6))
|
||||
* **workflows:** further work on WorkflowWorkflowWorkflow ([5b897c7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5b897c7a42067d6a7918dc7bc9640b5c3d8a1367))
|
||||
* **workflows:** improve linter ([316097a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/316097a07ed89e40ecbf3dd8a7160eca95bd7a67))
|
||||
* **workflows:** initiate ([fd7c91f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fd7c91f5b8aa2645e0e072115d6a7da58323971a))
|
||||
* **workflows:** list & edit definitions ([ff370c6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ff370c68c735c492e8e588a8bb8e4055aa8cc0f4))
|
||||
* **workflows:** list involved users ([d8878a9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d8878a905e07f1b5fb5159ecdaf70f27e9c1dc37))
|
||||
* **workflows:** make admin or token sufficient for all roles ([7a7cd4d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/7a7cd4d07c907611cf72e5ebe3ae41c3a401ef64))
|
||||
* **workflows:** new field CaptureDateTime ([5944a17](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5944a174bc8a749c60718b58d656f44cd21e7ecf))
|
||||
* **workflows:** node messages ([6a7a892](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6a7a892c74ad7da906a841fbfd031cca59174a8c))
|
||||
* **workflows:** placeholder handlers ([baea302](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/baea302e48dd6c603eebba7040923f0c23266f40))
|
||||
* **workflows:** prepare for admin-workflow-instance-edit ([ee6fecb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ee6fecb79e4807beceadd15f19e41393f7707135))
|
||||
* **workflows:** proper workflow-workflow-tables ([ac08846](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ac08846c267f20fa053e3bd73bea72b224b636c6))
|
||||
* **workflows:** replace pages with warning if turned off ([8634d20](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8634d20e2ad2d3746cf7b6111b91db9e57e4863b))
|
||||
* **workflows:** restrict day field wrt. current time ([b742731](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b7427315119843e6b2cebad4f6f420d57c2efaf0))
|
||||
* **workflows:** update instances from definitions ([32efdae](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/32efdae839b1a3e43ed4161d20e598964970f15e))
|
||||
* **workflows:** wire up ws-school ([82b3a63](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/82b3a6364c77c64a653e927cd0242d64ffcf9d2a))
|
||||
=======
|
||||
* **model:** separate user authentication data from User table; add ExternalAuth and InternalAuth models
|
||||
* **model:** move user authentication data to new ExternalUser model
|
||||
* **settings:** rename userdb app settings
|
||||
@ -1749,6 +874,7 @@ them together now)
|
||||
* **model:** separate user authentication data from User table; add ExternalAuth and InternalAuth models ([54f2430](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/54f2430b3e79d3b7c396ac4cf1d4d0da860e3d02))
|
||||
* **settings:** rename userdb app settings ([9f299c8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9f299c854c9d2d2f1b1127c85a31b787f85fa210))
|
||||
|
||||
=======
|
||||
## [27.4.79](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v27.4.78...v27.4.79) (2024-09-10)
|
||||
|
||||
|
||||
@ -1963,6 +1089,78 @@ them together now)
|
||||
* **i18n:** fix some bad plurals ([890f8ad](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/890f8ad8b60115533faa6b99f4c4504243cbfb1d))
|
||||
* **lint:** remove minor superfluous dollar ([64a1233](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/64a123387f3539b73649d02a6ecd97de577097e6))
|
||||
* **qualification:** fix [#159](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/159) by removing an misleadingly named column for user qualification table ([fd6a538](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fd6a5384d3517958a3c7726e32eed3bad197a591))
|
||||
## [v27.4.59-test-g0.0.17](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-f0.0.17...v27.4.59-test-g0.0.17) (2025-02-18)
|
||||
|
||||
## [v27.4.59-test-f0.0.17](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-g0.0.16...v27.4.59-test-f0.0.17) (2025-02-17)
|
||||
|
||||
## [v27.4.59-test-g0.0.16](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-f0.0.16...v27.4.59-test-g0.0.16) (2025-02-16)
|
||||
|
||||
## [v27.4.59-test-f0.0.16](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-f0.0.15...v27.4.59-test-f0.0.16) (2025-02-16)
|
||||
|
||||
## [v27.4.59-test-f0.0.15](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.15...v27.4.59-test-f0.0.15) (2025-02-15)
|
||||
|
||||
## [v27.4.59-test-e0.0.15](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-f0.0.14...v27.4.59-test-e0.0.15) (2025-02-14)
|
||||
|
||||
## [v27.4.59-test-f0.0.14](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.14...v27.4.59-test-f0.0.14) (2025-02-14)
|
||||
|
||||
## [v27.4.59-test-e0.0.14](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.13...v27.4.59-test-e0.0.14) (2025-02-13)
|
||||
|
||||
## [v27.4.59-test-e0.0.13](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.12...v27.4.59-test-e0.0.13) (2025-02-12)
|
||||
|
||||
## [v27.4.59-test-e0.0.12](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-d0.0.12...v27.4.59-test-e0.0.12) (2025-02-12)
|
||||
|
||||
## [v27.4.59-test-d0.0.12](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-d0.0.11...v27.4.59-test-d0.0.12) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-d0.0.11](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-c0.0.11...v27.4.59-test-d0.0.11) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-c0.0.11](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-b0.0.11...v27.4.59-test-c0.0.11) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-b0.0.11](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-c0.0.10...v27.4.59-test-b0.0.11) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-c0.0.10](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-b0.0.10...v27.4.59-test-c0.0.10) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-b0.0.10](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.10...v27.4.59-test-b0.0.10) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-a0.0.10](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.9...v27.4.59-test-a0.0.10) (2025-02-11)
|
||||
|
||||
## [v27.4.59-test-a0.0.9](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.8...v27.4.59-test-a0.0.9) (2025-02-10)
|
||||
|
||||
## [v27.4.59-test-a0.0.8](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.7...v27.4.59-test-a0.0.8) (2025-02-10)
|
||||
|
||||
## [v27.4.59-test-a0.0.7](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.6...v27.4.59-test-a0.0.7) (2025-02-10)
|
||||
|
||||
## [v27.4.59-test-a0.0.6](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.5...v27.4.59-test-a0.0.6) (2025-02-08)
|
||||
|
||||
## [v27.4.59-test-a0.0.5](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.4...v27.4.59-test-a0.0.5) (2025-02-07)
|
||||
|
||||
## [v27.4.59-test-a0.0.4](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.3...v27.4.59-test-a0.0.4) (2025-02-07)
|
||||
|
||||
## [v27.4.59-test-a0.0.3](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.2...v27.4.59-test-a0.0.3) (2025-02-06)
|
||||
|
||||
## [v27.4.59-test-a0.0.2](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.1...v27.4.59-test-a0.0.2) (2025-02-05)
|
||||
|
||||
## [v27.4.59-test-a0.0.1](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.0...v27.4.59-test-a0.0.1) (2025-02-05)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ghci:** ghci works now as expected ([c3117db](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/c3117dbdcd1de9ef9f0751afa45018e2ebce2c42))
|
||||
|
||||
## [v27.4.59-test-a0.0.0](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59...v27.4.59-test-a0.0.0) (2024-10-25)
|
||||
|
||||
### Features
|
||||
|
||||
* **util script:** Util script for renaming of files added. ([caf8fec](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/caf8fec5acb94df16293bf9aa0cdab766f8829e8))
|
||||
* **frontend:** load icons from svg files ([22781e1](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/22781e1565e890cf6c5b40973146b0334cb667aa))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **stack.yaml:** move to uniworx.de gitlab ([55484e6](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/55484e631b786ea3710d322282019baf5292c243))
|
||||
* **utils/renamer:** Mehr outputs nur im verbose-Fall. ([ac30cb9](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/ac30cb9e6712d0ee3f204da4863d1e2509af8a76))
|
||||
* **utils:** Verboseparameter -v hinzugefuegt; rekursives makedir; genauere Meldungen. ([1806d9f](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/1806d9f01fc4a0746d2f9df42ef1ee6827c7fa09))
|
||||
* **Dockerfile:** change rights of source dir to env user ([e7a8183](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/e7a8183656ae419cfee2942543045c6fa6a9caa3))
|
||||
* **Makefile:** add missing dependency on well-known for backend-builds ([a09dc59](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/a09dc59f260843f8815c382576bb5254d21104bf))
|
||||
* **frontend:** fixed icon colour in table headers ([4c4571d](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/4c4571d2d0879e89f2572eba6015d34a7f4794c8))
|
||||
* **doc:** minor haddock problems ([d4f8a6c](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/d4f8a6c77b2a4a4540935f7f0beca0d0605508c8))
|
||||
|
||||
## [27.4.59](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v27.4.58...v27.4.59) (2024-02-13)
|
||||
|
||||
|
||||
44
Makefile
44
Makefile
@ -69,13 +69,19 @@ clean:
|
||||
-rm -rf .stack-work .stack-work.lock
|
||||
-rm -rf bin .Dockerfile develop
|
||||
-$(CONTAINER_COMMAND) container prune --force
|
||||
.PHONY: clean-images
|
||||
# HELP: stop all running containers and clean all images from local repositories
|
||||
clean-images:
|
||||
rm -rf develop
|
||||
sleep 5
|
||||
-$(CONTAINER_COMMAND) system prune --all --force --volumes
|
||||
-$(CONTAINER_COMMAND) image prune --all --force
|
||||
-$(CONTAINER_COMMAND) volume prune --force
|
||||
.PHONY: clean-all
|
||||
# HELP: like clean but with full container, image, and volume prune
|
||||
clean-all: clean
|
||||
-rm -rf .stack
|
||||
-$(CONTAINER_COMMAND) system prune --all --force --volumes
|
||||
-$(CONTAINER_COMMAND) image prune --all --force
|
||||
-$(CONTAINER_COMMAND) volume prune --force
|
||||
$(CONTAINER_COMMAND) system reset --force
|
||||
|
||||
.PHONY: release
|
||||
# HELP: create, commit and push a new release
|
||||
@ -89,16 +95,20 @@ release:
|
||||
git push origin $${VERSION}
|
||||
|
||||
.PHONY: compile
|
||||
# HELP: perform full compilation (frontend and backend)
|
||||
compile:
|
||||
$(MAKE) compile-frontend
|
||||
$(MAKE) compile-backend
|
||||
|
||||
.PHONY: start
|
||||
# HELP: start complete development environment with a fresh test database
|
||||
start:
|
||||
$(MAKE) start-postgres
|
||||
$(MAKE) start-memcached
|
||||
$(MAKE) start-minio
|
||||
$(MAKE) start-maildev
|
||||
$(MAKE) compile-frontend
|
||||
$(MAKE) compile-uniworxdb
|
||||
$(MAKE) start-backend
|
||||
|
||||
.PHONY: %-backend
|
||||
@ -135,7 +145,7 @@ start:
|
||||
%-postgres: SERVICE=postgres
|
||||
%-postgres: SERVICE_VARIANT=postgres
|
||||
%-postgres: BASE_PORTS = "PGPORT=5432"
|
||||
%-postgres: IMAGE=localhost/fradrive/postgres
|
||||
%-postgres: SET_IMAGE=localhost/fradrive/postgres
|
||||
|
||||
.PHONY: %-memcached
|
||||
%-memcached: SERVICE=memcached
|
||||
@ -143,6 +153,18 @@ start:
|
||||
%-memcached: SET_IMAGE=$$(MEMCACHED_IMAGE) --port=`cat $$(CONTAINER_FILE) | grep 'MEMCACHED_PORT=' | sed 's/MEMCACHED_PORT=//'`
|
||||
%-memcached: BASE_PORTS = "MEMCACHED_PORT=11211"
|
||||
|
||||
.PHONY: %-maildev
|
||||
%-maildev: SERVICE=maildev
|
||||
%-maildev: SERVICE_VARIANT=maildev
|
||||
%-maildev: SET_IMAGE=$$(MAILDEV_IMAGE) --port=`cat $$(CONTAINER_FILE) | grep 'MAILDEV_PORT=' | sed 's/MAILDEV_PORT=//'`
|
||||
%-maildev: BASE_PORTS = "MAILDEV_PORT=1025"
|
||||
|
||||
.PHONY: %-release
|
||||
%-release: PROD=true
|
||||
%-release: SERVICE=fradrive
|
||||
%-release: SERVICE_VARIANT=fradrive
|
||||
%-release: IMAGE=localhost/fradrive/fradrive
|
||||
|
||||
.PHONY: %-minio
|
||||
%-minio: SERVICE=minio
|
||||
%-minio: SERVICE_VARIANT=minio
|
||||
@ -234,6 +256,7 @@ endif
|
||||
IMAGE="$(SET_IMAGE)" ; \
|
||||
else \
|
||||
IMAGE=$(IMAGE) ; \
|
||||
MAKECALL="make -- --$(JOB)-$(SERVICE_VARIANT) IN_CONTAINER=true" ; \
|
||||
fi ; \
|
||||
CONTAINER_ID=`$(CONTAINER_BGRUN) \
|
||||
-v $(PWD):$(PROJECT_DIR):rw \
|
||||
@ -244,7 +267,7 @@ endif
|
||||
--env SRC=$(SRC) \
|
||||
--name $${CONTAINER_NAME} \
|
||||
$${IMAGE} \
|
||||
make -- --$(JOB)-$(SERVICE_VARIANT) IN_CONTAINER=true \
|
||||
$${MAKECALL} \
|
||||
` ; \
|
||||
printf "CONTAINER_ID=$${CONTAINER_ID}" >> "$(CONTAINER_FILE)" ; \
|
||||
if [[ "true" == "$(CONTAINER_ATTACHED)" ]] ; then \
|
||||
@ -253,7 +276,7 @@ endif
|
||||
|
||||
# For Reverse Proxy Problem see: https://groups.google.com/g/yesodweb/c/2EO53kSOuy0/m/Lw6tq2VYat4J
|
||||
# HELP(start-backend): start development instance
|
||||
--start-backend:
|
||||
--start-backend: --dependencies-backend
|
||||
export YESOD_IP_FROM_HEADER=true; \
|
||||
export DEV_PORT_HTTP=`cat $(CONTAINER_FILE) | grep 'DEV_PORT_HTTP=' | sed 's/DEV_PORT_HTTP=//'`; \
|
||||
export DEV_PORT_HTTPS=`cat $(CONTAINER_FILE) | grep 'DEV_PORT_HTTPS=' | sed 's/DEV_PORT_HTTPS=//'`; \
|
||||
@ -273,11 +296,12 @@ endif
|
||||
export AVSPASS=$${AVSPASS:-nopasswordset} ; \
|
||||
stack $(STACK_CORES) exec --local-bin-path $$(pwd)/bin --copy-bins -- yesod devel -p "$${DEV_PORT_HTTP}" -q "$${DEV_PORT_HTTPS}"
|
||||
# HELP(compile-backend): compile backend binaries
|
||||
--compile-backend:
|
||||
--compile-backend: --dependencies-backend
|
||||
stack build $(STACK_CORES) --fast --profile --library-profiling --executable-profiling --flag uniworx:-library-only $(--DEVELOPMENT) --local-bin-path $$(pwd)/bin --copy-bins
|
||||
# HELP(dependencies-backend): (re-)build backend dependencies
|
||||
--dependencies-backend: #uniworx.cabal
|
||||
chown -R `id -un`:`id -gn` "$(PROJECT_DIR)"; \
|
||||
stack install hpack; stack install yesod-bin; \
|
||||
stack build -j2 --only-dependencies
|
||||
# HELP(lint-backend): lint backend
|
||||
--lint-backend:
|
||||
@ -289,10 +313,10 @@ endif
|
||||
# stack exec -- hpack --force
|
||||
|
||||
# HELP(compile-frontend): compile frontend assets
|
||||
--compile-frontend: node_modules assets esbuild.config.mjs frontend/src/env.sass
|
||||
--compile-frontend: --dependencies-frontend
|
||||
npm run build
|
||||
--start-frontend: --compile-frontend;
|
||||
--dependencies-frontend: node_modules assets;
|
||||
--dependencies-frontend: node_modules assets esbuild.config.mjs frontend/src/env.sass;
|
||||
node_modules: package.json package-lock.json
|
||||
npm install --cache .npm --prefer-offline
|
||||
package-lock.json: package.json
|
||||
@ -306,7 +330,7 @@ assets/icons: node_modules assets/icons-src/fontawesome.json
|
||||
-cp assets/icons-src/*.svg assets/icons/fradrive
|
||||
frontend/src/env.sass:
|
||||
echo "\$$path: '$${PROJECT_DIR}'" > frontend/src/env.sass
|
||||
static: node_modules assets esbuild.config.mjs frontend/src/env.sass
|
||||
static: --dependencies-frontend
|
||||
npm run build
|
||||
well-known: static;
|
||||
--lint-frontend: --compile-frontend
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
"file-upload": "file-arrow-up",
|
||||
"file-zip": "file-zipper",
|
||||
"file-csv": "file-csv",
|
||||
"file-missing": "file-circle-minus",
|
||||
"sft-question": "circle-question",
|
||||
"sft-hint": "life-ring",
|
||||
"sft-solution": "circle-exclamation",
|
||||
@ -76,12 +77,13 @@
|
||||
"submission-no-users": "user-slash",
|
||||
"reset": "arrow-rotate-left",
|
||||
"blocked": "ban",
|
||||
"certificate": "certificate",
|
||||
"certificate": "car-side",
|
||||
"print-center": "envelopes-bulk",
|
||||
"letter": "envelopes-bulk",
|
||||
"at": "at",
|
||||
"supervisor": "person",
|
||||
"supervisor-foreign": "person-rays",
|
||||
"superior": "user-tie",
|
||||
"waiting-for-user": "user-gear",
|
||||
"expired": "hourglass-end",
|
||||
"locked": "lock",
|
||||
@ -89,9 +91,18 @@
|
||||
"trash": "trash",
|
||||
"reset-tries": "trash-can-arrow-up",
|
||||
"company": "building",
|
||||
"company-warning": "building-circle-exclamation",
|
||||
"edit": "pen-to-square",
|
||||
"user-edit": "user-pen",
|
||||
"loading": "spinner",
|
||||
"placeholder": "notdef"
|
||||
"placeholder": "notdef",
|
||||
"reroute": "diamond-turn-right",
|
||||
"top": "award",
|
||||
"wildcard": "asterisk",
|
||||
"user-unknown": "user-slash",
|
||||
"user-badge": "id-badge",
|
||||
"glasses": "glasses",
|
||||
"missing": "question",
|
||||
"pin-protect": "key"
|
||||
}
|
||||
|
||||
|
||||
32
config/develop-settings.yml
Normal file
32
config/develop-settings.yml
Normal file
@ -0,0 +1,32 @@
|
||||
# SPDX-FileCopyrightText: 2024 Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# Values formatted like "_env:ENV_VAR_NAME:default_value" can be overridden by the specified environment variable.
|
||||
# See https://github.com/yesodweb/yesod/wiki/Configuration#overriding-configuration-values-with-environment-variables
|
||||
# NB: If you need a numeric value (e.g. 123) to parse as a String, wrap it in single quotes (e.g. "_env:PGPASS:'123'")
|
||||
# See https://github.com/yesodweb/yesod/wiki/Configuration#parsing-numeric-values-as-strings
|
||||
|
||||
|
||||
# DEVELOPMENT ONLY, NOT TO BE USED IN PRODUCTION
|
||||
|
||||
avs-licence-synch:
|
||||
times: [12]
|
||||
level: 4
|
||||
reason-filter: "(firm|block)"
|
||||
max-changes: 999
|
||||
|
||||
mail-reroute-to:
|
||||
name: "FRADrive-QA-Umleitungen"
|
||||
email: "FRADrive-TEST-Umleitungen@fraport.de"
|
||||
|
||||
# Enqueue at specified hour, a few minutes later
|
||||
job-lms-qualifications-enqueue-hour: 16
|
||||
job-lms-qualifications-dequeue-hour: 4
|
||||
|
||||
# Using these setting kills the job-workers somehow
|
||||
# job-workers: 5
|
||||
# job-flush-interval: 600
|
||||
# job-stale-threshold: 3600
|
||||
# job-move-threshold: 60
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Wolfgang Witt <Wolfgang.Witt@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Wolfgang Witt <Wolfgang.Witt@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -91,10 +91,6 @@ synchronise-avs-users-interval: "_env:SYNCHRONISE_AVS_INTERVAL:21600" # alle 6
|
||||
study-features-recache-relevance-within: 172800
|
||||
study-features-recache-relevance-interval: 293
|
||||
|
||||
# Enqueue at specified hour, a few minutes later
|
||||
job-lms-qualifications-enqueue-hour: 16
|
||||
job-lms-qualifications-dequeue-hour: 4
|
||||
|
||||
log-settings:
|
||||
detailed: "_env:DETAILED_LOGGING:false"
|
||||
all: "_env:LOG_ALL:false"
|
||||
@ -173,12 +169,14 @@ user-sync-within: "_env:USER_SYNC_WITHIN:1209600" # 14 Tage in Sekunden
|
||||
user-sync-interval: "_env:USER_SYNC_INTERVAL:3600" # jede Stunde
|
||||
|
||||
lms-direct:
|
||||
upload-header: "_env:LMSUPLOADHEADER:true"
|
||||
upload-delimiter: "_env:LMSUPLOADDELIMITER:"
|
||||
download-header: "_env:LMSDOWNLOADHEADER:true"
|
||||
download-delimiter: "_env:LMSDOWNLOADDELIMITER:,"
|
||||
download-cr-lf: "_env:LMSDOWNLOADCRLF:true"
|
||||
deletion-days: "_env:LMSDELETIONDAYS:7"
|
||||
upload-header: "_env:LMSUPLOADHEADER:true"
|
||||
upload-delimiter: "_env:LMSUPLOADDELIMITER:"
|
||||
download-header: "_env:LMSDOWNLOADHEADER:true"
|
||||
download-delimiter: "_env:LMSDOWNLOADDELIMITER:,"
|
||||
download-cr-lf: "_env:LMSDOWNLOADCRLF:true"
|
||||
orphan-deletion-days: "_env:LMSORPHANDELETIONDAYS:33"
|
||||
orphan-deletion-batch: "_env:LMSORPHANDELETIONBATCH:12"
|
||||
orphan-deletion-repeat-hours: "_env:LMSORPHANDELETIONREPEATHOURS:24"
|
||||
|
||||
avs:
|
||||
host: "_env:AVSHOST:skytest.fra.fraport.de"
|
||||
@ -233,9 +231,6 @@ memcached:
|
||||
timeout: "_env:MEMCACHED_TIMEOUT:20"
|
||||
expiration: "_env:MEMCACHED_EXPIRATION:300"
|
||||
memcache-auth: true
|
||||
memcached-local:
|
||||
maximum-ghost: 512
|
||||
maximum-weight: 104857600 # 100MiB
|
||||
|
||||
upload-cache:
|
||||
host: "_env:UPLOAD_S3_HOST:localhost" # should be optional, but all file transfers will be empty without an S3 cache
|
||||
@ -347,17 +342,6 @@ fallback-personalised-sheet-files-keys-expire: 2419200
|
||||
|
||||
download-token-expire: 604801
|
||||
|
||||
file-source-arc:
|
||||
maximum-ghost: 512
|
||||
maximum-weight: 1073741824 # 1GiB
|
||||
file-source-prewarm:
|
||||
maximum-weight: 1073741824 # 1GiB
|
||||
start: 1800 # 30m
|
||||
end: 600 # 10m
|
||||
inhibit: 3600 # 60m
|
||||
steps: 20
|
||||
max-speedup: 3
|
||||
|
||||
bot-mitigations:
|
||||
- only-logged-in-table-sorting
|
||||
- unauthorized-form-honeypots
|
||||
|
||||
@ -16,5 +16,4 @@ log-settings:
|
||||
auth-dummy-login: true
|
||||
server-session-acid-fallback: true
|
||||
|
||||
job-cron-interval: null
|
||||
job-workers: 1
|
||||
job-workers: 20
|
||||
@ -17,22 +17,45 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
apt-get -y update && apt-get install -y --no-install-recommends locales locales-all
|
||||
|
||||
# run-time dependencies for uniworx binary
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
apt-get -y update && apt-get -y install fonts-roboto
|
||||
# RUN apt-get -y update && apt-get -y install pdftk
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
apt-get -y update && apt-get -y install texlive-latex-recommended texlive-luatex texlive-plain-generic texlive-lang-german texlive-lang-english
|
||||
# RUN apt-get -y update && apt-get -y install \
|
||||
# texlive texlive-latex-recommended texlive-luatex texlive-plain-generic texlive-lang-german texlive-lang-english
|
||||
RUN apt-get -y update && apt-get -y install \
|
||||
wget \
|
||||
perl \
|
||||
xz-utils \
|
||||
fonts-roboto \
|
||||
texlive \
|
||||
texlive-luatex \
|
||||
texlive-latex-extra \
|
||||
texlive-fonts-recommended \
|
||||
texlive-fonts-extra \
|
||||
&& apt-get clean
|
||||
# RUN ls /usr/local/texlive
|
||||
# RUN chown -hR root /usr/local/texlive/2018
|
||||
ENV PATH="/usr/local/texlive/2018/bin/x86_64-linux:${PATH}"
|
||||
ENV TEXLIVE_VERSION=2018
|
||||
RUN tlmgr init-usertree
|
||||
RUN tlmgr option repository ftp://tug.org/historic/systems/texlive/2018/tlnet-final
|
||||
RUN tlmgr update --self --all
|
||||
RUN tlmgr install \
|
||||
babel \
|
||||
babel-english \
|
||||
babel-german \
|
||||
booktabs \
|
||||
textpos \
|
||||
enumitem \
|
||||
# luatex lualatex luatexbase lualatex-math eurosym \
|
||||
# above line requires tlmgr to run in -sys mode (~root?! apparently -privileged is missing)
|
||||
koma-script \
|
||||
unicode-math \
|
||||
selnolig
|
||||
|
||||
|
||||
|
||||
ARG PROJECT_DIR=/fradrive
|
||||
ENV PROJECT_DIR=${PROJECT_DIR}
|
||||
RUN mkdir -p "${PROJECT_DIR}"; chmod -R 7777 "${PROJECT_DIR}"
|
||||
# RUN mkdir -p "${PROJECT_DIR}"; chmod -R 777 "${PROJECT_DIR}"
|
||||
WORKDIR ${PROJECT_DIR}
|
||||
ENV HOME=${PROJECT_DIR}
|
||||
ENV STACK_ROOT="${PROJECT_DIR}/.stack"
|
||||
|
||||
RUN if [ ! -z "${IN_CI}" ]; then \
|
||||
stack install yesod-bin; \
|
||||
stack install hpack; \
|
||||
fi
|
||||
ENV STACK_ROOT="${PROJECT_DIR}/.stack"
|
||||
@ -14,10 +14,12 @@ ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Etc/UTC
|
||||
RUN apt-get update && apt-get -y install libpq-dev
|
||||
RUN apt-get update && apt-get -y install libsodium-dev
|
||||
RUN apt-get update && apt-get -y install fonts-roboto
|
||||
# TODO: minimize texlive dependencies, switch to basic schemes where possible
|
||||
RUN apt-get update && apt-get -y install \
|
||||
texlive-latex-base \
|
||||
texlive-full \
|
||||
texlive-luatex \
|
||||
texlive-plain-generic \
|
||||
texlive-fonts-recommended \
|
||||
texlive-fonts-extra \
|
||||
texlive-lang-english \
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
if [[ ! -d .stack-work-test ]]; then
|
||||
mv -vT .stack-work .stack-work-test
|
||||
[[ -d .stack-work-build ]] && mv -vT .stack-work-build .stack-work
|
||||
else
|
||||
echo "Directory .stack-work-test exists already."
|
||||
fi
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
@import 'env';
|
||||
|
||||
$ico-width: 30px;
|
||||
$ico-width: 15px;
|
||||
|
||||
$icons: new,
|
||||
ok,
|
||||
@ -35,6 +35,7 @@ $icons: new,
|
||||
file-upload,
|
||||
file-zip,
|
||||
file-csv,
|
||||
file-missing,
|
||||
sft-question,
|
||||
sft-hint,
|
||||
sft-solution,
|
||||
@ -95,9 +96,15 @@ $icons: new,
|
||||
trash,
|
||||
reset-tries,
|
||||
company,
|
||||
company-warning,
|
||||
edit,
|
||||
user-edit,
|
||||
placeholder,
|
||||
glasses,
|
||||
user-badge,
|
||||
user-unknown,
|
||||
missing,
|
||||
pin-protect,
|
||||
loading;
|
||||
|
||||
|
||||
@ -133,6 +140,7 @@ $icons: new,
|
||||
|
||||
.large-ico {
|
||||
font-size: 2em;
|
||||
min-width: 1em;
|
||||
}
|
||||
|
||||
.ico-spin {
|
||||
|
||||
20
load/Load.hs
20
load/Load.hs
@ -96,7 +96,7 @@ sampleIntegral = sampleN scaleIntegral
|
||||
instance PathPiece DiffTime where
|
||||
toPathPiece = (toPathPiece :: Pico -> Text) . MkFixed . diffTimeToPicoseconds
|
||||
fromPathPiece t = fromPathPiece t <&> \(MkFixed ps :: Pico) -> picosecondsToDiffTime ps
|
||||
|
||||
|
||||
|
||||
data LoadSimulation
|
||||
= LoadSheetDownload
|
||||
@ -214,13 +214,13 @@ runSimulation sim = do
|
||||
delays <- replicateM (fromIntegral p) $ do
|
||||
d <- view $ _2 . _simDelay
|
||||
sampleNDiffTime d
|
||||
|
||||
|
||||
forConcurrently_ ([1..p] `zip` sort delays) $ \(n, d') -> do
|
||||
begin <- liftIO getCurrentTime
|
||||
|
||||
dur <- view $ _2 . _simDuration
|
||||
tDuration <- sampleNDiffTime dur
|
||||
|
||||
|
||||
let MkFixed us = realToFrac d' :: Micro
|
||||
threadDelay $ fromInteger us
|
||||
start <- liftIO getCurrentTime
|
||||
@ -268,7 +268,7 @@ runSimulation' LoadSheetSubmission = do
|
||||
-- Just formData <- return . getFormData FIDsubmission $ resp ^. responseBody
|
||||
-- Just addButtonData <- return . flip (runFormScraper FIDsubmission) (resp ^. responseBody) $ do
|
||||
-- let btnSel = "button" Scalpel.@: [Scalpel.hasClass "btn-mass-input-add"]
|
||||
|
||||
|
||||
-- name <- Scalpel.attr "name" btnSel
|
||||
-- value <- Scalpel.attr "value" btnSel
|
||||
-- guard $ value == "add__0__0"
|
||||
@ -305,7 +305,7 @@ runSimulation' LoadSheetSubmission = do
|
||||
procEnd <- join $ asks runtime
|
||||
|
||||
print ("proc", procEnd - procStart)
|
||||
|
||||
|
||||
resp3 <- liftIO . httpRetry $ Session.post session (uriToString id formURI mempty) subData
|
||||
void . evaluate $! resp3
|
||||
where
|
||||
@ -328,11 +328,11 @@ runSimulation' LoadSheetSubmission = do
|
||||
-> m ()
|
||||
logRetry shouldRetry err status = liftIO . putStrLn . pack $ Retry.defaultLogMsg shouldRetry err status
|
||||
|
||||
|
||||
|
||||
-- runSimulation' other = terror $ "Not implemented: " <> tshow other
|
||||
|
||||
runFormScraper :: FormIdentifier -> Scalpel.Scraper Lazy.ByteString a -> Lazy.ByteString -> Maybe a
|
||||
runFormScraper fid innerS = fmap join . flip Scalpel.scrapeStringLike $
|
||||
runFormScraper fid innerS = fmap join . flip Scalpel.scrapeStringLike $
|
||||
fmap listToMaybe . Scalpel.chroots "form" $ do
|
||||
fid' <- Scalpel.attr "value" $ "input" Scalpel.@: ["name" Scalpel.@= "form-identifier"]
|
||||
guard $ fid' == encodeUtf8 (fromStrict $ toPathPiece fid)
|
||||
@ -341,11 +341,11 @@ runFormScraper fid innerS = fmap join . flip Scalpel.scrapeStringLike $
|
||||
|
||||
getFormData :: FormIdentifier -> Lazy.ByteString -> Maybe [FormParam]
|
||||
getFormData = flip runFormScraper $
|
||||
Scalpel.chroots ("input") $ do
|
||||
Scalpel.chroots "input" $ do
|
||||
name <- Scalpel.attr "name" Scalpel.anySelector
|
||||
value <- Scalpel.attr "value" Scalpel.anySelector <|> pure ""
|
||||
return $ toStrict name := value
|
||||
|
||||
|
||||
|
||||
newLoadSession :: ReaderT SimulationContext IO Session
|
||||
newLoadSession = do
|
||||
@ -354,7 +354,7 @@ newLoadSession = do
|
||||
let withToken = case loadToken of
|
||||
Nothing -> id
|
||||
Just (Jwt bs) -> (:) (hAuthorization, "Bearer " <> bs) . filter ((/= hAuthorization) . fst)
|
||||
|
||||
|
||||
|
||||
liftIO . Session.newSessionControl (Just mempty) $ tlsManagerSettings
|
||||
{ managerModifyRequest = \req -> return $ req { requestHeaders = withToken $ requestHeaders req }
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>,Gregor Kleen <gregor.kleen@ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
# SPDX-FileCopyrightText: 2022-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>,Gregor Kleen <gregor.kleen@ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -109,9 +109,10 @@ ProblemsDriverSynch1up: Alle gültigen Vorfeld-Fahrberechtigungen 'F' sind im AV
|
||||
ProblemsDriverSynch2: Alle gültigen Rollfeld-Fahrberechtigungen 'R' sind im AVS eingetragen
|
||||
ProblemsRDriversHaveFs: Alle Inhaber einer Rollfeld-Fahrberechtigung besitzen auch eine gültige Vorfeld-Fahrberechtigung
|
||||
ProblemsDriversHaveAvsIds: Alle Inhaber einer Fahrberechtigung konnten einer AVS Identifikationsnummer zugeordnet werden
|
||||
ProblemsUsersAreReachable: Für alle Benutzer ist eine E-Mail oder postalische Adresse bekannt
|
||||
ProblemsUsersAreReachable: Für alle Benutzer ist eine E-Mail oder postalische Adresse bekannt
|
||||
ProblemsNoStalePrintJobs n@Integer: Alle Briefversandaufträge #{pluralDE n "des vergangenen Tages" ("der vergangenen "<> tshow n <> " Tage")} wurden von der Druckerei bestätigt
|
||||
ProblemsNoBadAPCIds: Alle kürzlich empfangenen Druckauftragsbestätigungen waren gültig
|
||||
ProblemsNoInsaneCompanySupervisions: Sind alle Firmen-bezogenen Ansprechpartnerbeziehungen zwischen passenden Firmenangehörigen?
|
||||
ProblemsUnreachableHeading: Unerreichbare Benutzer
|
||||
ProblemsUnreachableBody: Benutzer ohne E-Mail oder Postadresse, welche z.B. bei ablaufenden Berechtigungen nicht benachrichtigt werden können:
|
||||
ProblemsUnreachableButtons: Synchronisation für Unerreichbare starten
|
||||
@ -123,6 +124,7 @@ ProblemsAvsSynchHeading: Synchronisation AVS Fahrberechtigungen
|
||||
ProblemsAvsErrorHeading: Fehlermeldungen
|
||||
ProblemsInterfaceSince: Berücksichtigt werden nur Erfolge und Fehler seit
|
||||
ProblemAvsUsrHadR: Momentan gültiges R im AVS
|
||||
ProblemLastCheckTime t@Text: Letzte Prüfung vor #{t}
|
||||
|
||||
AdminProblemSolved: Erledigt
|
||||
AdminProblemSolver: Bearbeitet von
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
# SPDX-FileCopyrightText: 2022-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -112,6 +112,7 @@ ProblemsDriversHaveAvsIds: All driving licence holder could be matched with thei
|
||||
ProblemsUsersAreReachable: Either Email or postal address is known for all users
|
||||
ProblemsNoStalePrintJobs n: All requests for letter mailing within the last #{pluralENsN n "day"} were acknowledged as printed by the airport printing center
|
||||
ProblemsNoBadAPCIds: All recently received print job ids from Airport Print Center were legit
|
||||
ProblemsNoInsaneCompanySupervisions: All company related supervisions are between company-associated users
|
||||
ProblemsUnreachableHeading: Unreachable Users
|
||||
ProblemsUnreachableBody: Users without Email nor postal address, who thus cannot be notified about expiring qualifications:
|
||||
ProblemsUnreachableButtons: Start synchronisation for unreachable users only
|
||||
@ -123,6 +124,7 @@ ProblemsAvsSynchHeading: Synchronisation AVS Driving Licences
|
||||
ProblemsAvsErrorHeading: Error Log
|
||||
ProblemsInterfaceSince: Only considering successes and errors since
|
||||
ProblemAvsUsrHadR: Currenlt R valid in AVS
|
||||
ProblemLastCheckTime t: Last checked #{t} ago
|
||||
|
||||
AdminProblemSolved: Done
|
||||
AdminProblemSolver: Solved by
|
||||
|
||||
@ -26,30 +26,30 @@ UnauthorizedSiteAdmin: You are no system-wide administrator.
|
||||
UnauthorizedSchoolAdmin: You are no administrator for this department.
|
||||
UnauthorizedAdminEscalation: You aren't an administrator for all departments for which this user is an administrator.
|
||||
UnauthorizedExamOffice: You are not part of an exam office.
|
||||
UnauthorizedEvaluation: You are not charged with course type evaluation.
|
||||
UnauthorizedEvaluation: You are not charged with course category evaluation.
|
||||
UnauthorizedExamExamOffice: You are not part of the appropriate exam office for any of the participants of this exam.
|
||||
UnauthorizedSchoolExamOffice: You are not part of an exam office for this school.
|
||||
UnauthorizedSystemExamOffice: You are not charged with system wide exam administration.
|
||||
UnauthorizedSystemPrinter: You are not charged with system wide letter printing.
|
||||
UnauthorizedExternalExamExamOffice: You are not part of the appropriate exam office for any of the participants of this exam.
|
||||
UnauthorizedSchoolLecturer: You are no course administrator for this department.
|
||||
UnauthorizedLecturer: You are no administrator for this course type.
|
||||
UnauthorizedCorrector: You are no sheet corrector for this course type.
|
||||
UnauthorizedLecturer: You are no administrator for this course category.
|
||||
UnauthorizedCorrector: You are no sheet corrector for this course category.
|
||||
UnauthorizedSheetCorrector: You are no corrector for this sheet.
|
||||
UnauthorizedExamCorrector: You are no corrector for this exam.
|
||||
UnauthorizedCorrectorAny: You are no corrector for any course type.
|
||||
UnauthorizedRegistered: You are no participant in this course type.
|
||||
UnauthorizedCorrectorAny: You are no corrector for any course category.
|
||||
UnauthorizedRegistered: You are no participant in this course category.
|
||||
UnauthorizedRegisteredExam: You are not registered for this exam.
|
||||
UnauthorizedRegisteredAnyExam: You are not registered for an exam.
|
||||
UnauthorizedExamResult: You have no results in this exam.
|
||||
UnauthorizedExamOccurrenceRegistration: Registration for exam is not done including occurrence/room.
|
||||
UnauthorizedExternalExamResult: You have no results in this exam.
|
||||
UnauthorizedParticipant: The specified user is no participant of this course type.
|
||||
UnauthorizedParticipantSelf: You are no participant of this course type.
|
||||
UnauthorizedCourseTime: This course type is not currently available.
|
||||
UnauthorizedCourseRegistrationTime: This course type does not currently allow enrollment.
|
||||
UnauthorizedParticipant: The specified user is no participant of this course category.
|
||||
UnauthorizedParticipantSelf: You are no participant of this course category.
|
||||
UnauthorizedCourseTime: This course category is not currently available.
|
||||
UnauthorizedCourseRegistrationTime: This course category does not currently allow enrollment.
|
||||
UnauthorizedSheetTime: This sheet is not currently available.
|
||||
UnauthorizedMaterialTime: This course type material is not currently available.
|
||||
UnauthorizedMaterialTime: This course category material is not currently available.
|
||||
UnauthorizedTutorialTime: This course does not currently allow registration.
|
||||
UnauthorizedCourseNewsTime: This news item is not currently available.
|
||||
UnauthorizedExamTime: This exam is not currently available.
|
||||
@ -61,7 +61,7 @@ UnauthorizedUserSubmission: Users may not directly submit for this exercise shee
|
||||
UnauthorizedCorrectorSubmission: Correctors may not create submissions for this exercise sheet.
|
||||
UnauthorizedCorrectionAnonymous: Correction is not anonymised.
|
||||
DeprecatedRoute: This view is deprecated and will be removed.
|
||||
UnfreeMaterials: Course type material are not publicly accessable.
|
||||
UnfreeMaterials: Course category material are not publicly accessable.
|
||||
UnauthorizedWrite: You do not have the write permission necessary to perform this action
|
||||
UnauthorizedSystemMessageTime: This system-message is not currently available.
|
||||
UnauthorizedSystemMessageAuth: This system-message is only available to logged in users.
|
||||
@ -94,7 +94,7 @@ WorkflowRoleAlreadyInitiated: This workflow was already initiated
|
||||
WorkflowRoleNoSuchWorkflowWorkflow: The given workflow could not be found
|
||||
WorkflowRoleNoPayload: This workflow does not contain any data
|
||||
|
||||
CourseNoCapacity: Course type has reached maximum capacity
|
||||
CourseNoCapacity: Course category has reached maximum capacity
|
||||
TutorialNoCapacity: Course has reached maximum capacity
|
||||
ExamOccurrenceNoCapacity: Occurrence/Room has reached maximum capacity
|
||||
CourseNotEmpty: There are currently no participants enrolled for this course.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25 Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
AvsPersonInfo: AVS Personendaten
|
||||
@ -54,10 +54,14 @@ AvsUserUnassociated user@UserDisplayName: AVS Id unbekannt für Nutzer #{user}
|
||||
AvsUserUnknownByAvs api@AvsPersonId: AVS kennt Id #{tshow api} nicht (mehr)
|
||||
AvsUserAmbiguous api@AvsPersonId: AVS Id #{tshow api} ist nicht eindeutig
|
||||
AvsStatusSearchEmpty: AVS lieferte keine Ausweisinformationen
|
||||
AvsPersonSearchEmpty: AVS Suche lieferte leeres Ergebnis
|
||||
AvsPersonSearchAmbiguous: AVS Suche lieferte mehrere uneindeutige Ergebnisse
|
||||
AvsPersonSearchEmpty: Suche im AVS lieferte kein Ergebnis
|
||||
AvsPersonSearchAmbiguous: Suche im AVS lieferte mehrere uneindeutige Ergebnisse
|
||||
AvsSetLicencesFailed reason@Text: Setzen der Fahrlizenz im AVS fehlgeschlagen. Grund: #{reason}
|
||||
AvsIdMismatch api1@AvsPersonId api2@AvsPersonId: AVS Suche für Id #{tshow api1} lieferte stattdessen Id #{tshow api2}
|
||||
AvsUserCreationFailed api@AvsPersonId: Für AVS Id #{tshow api} konnte kein neuer Benutzer angelegt werden, da es eine gemeinsame Id (z.B. Personalnummer) mit einem existierenden, aber verschiedenen Nutzer gibt.
|
||||
AvsCardsEmpty: AVS Suche lieferte keinerlei Ausweiskarten
|
||||
AvsCurrentData: Alle angezeigte Daten wurden kürzlich direkt über die AVS Schnittstelle abgerufen.
|
||||
AvsCardsEmpty: Suche im AVS lieferte keinerlei Ausweiskarten
|
||||
AvsCurrentData: Alle angezeigte Daten wurden kürzlich direkt über die AVS Schnittstelle abgerufen.
|
||||
AvsUpdateDayCheck: Zusätzlich wird im Hintergrund ein AVS Datenabgleich für alle in der Tagesansicht vorkommenden Personen angestoßen (einmal pro Tag).
|
||||
|
||||
AvsNoApronCard: Kein gültiger Ausweis mit Vorfeld-Zugang vorhanden
|
||||
AvsNoCompanyCard mcn@(Maybe CompanyName): Für buchende Firma #{maybeEmpty mcn ciOriginal} liegt kein gültiger Ausweis vor
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25 Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
AvsPersonInfo: AVS person info
|
||||
@ -61,4 +61,8 @@ AvsSetLicencesFailed reason: Set driving licence within AVS failed. Reason: #{re
|
||||
AvsIdMismatch api1 api2: AVS search for id #{tshow api1} returned id #{tshow api2} instead
|
||||
AvsUserCreationFailed api@AvsPersonId: No new user could be created for AVS Id #{tshow api}, since an existing user shares at least one id presumed as unique
|
||||
AvsCardsEmpty: AVS search returned no id cards
|
||||
AvsCurrentData: All shown data has been recently received via the AVS interface.
|
||||
AvsCurrentData: All shown data has been recently received via the AVS interface.
|
||||
AvsUpdateDayCheck: In addition, a background AVS update has been scheduled for all persons occrring within the day agenda (once per Day).
|
||||
|
||||
AvsNoApronCard: No valid card granting apron access found
|
||||
AvsNoCompanyCard mcn@(Maybe CompanyName): No valid card for booking company #{maybeEmpty mcn ciOriginal} found
|
||||
|
||||
@ -70,9 +70,9 @@ CourseInvalidInput: Eingaben bitte korrigieren.
|
||||
CourseEditTitle: Kursart editieren/anlegen
|
||||
CourseEditOk tid@TermId ssh@SchoolId csh@CourseShorthand: Kursart #{tid}-#{ssh}-#{csh} wurde erfolgreich geändert.
|
||||
CourseEditDupShort tid@TermId ssh@SchoolId csh@CourseShorthand: Kursart #{tid}-#{ssh}-#{csh} konnte nicht geändert werden: Es gibt bereits einen andere Kursart mit dem selben Kürzel oder Titel in diesem Jahr und Bereich.
|
||||
CourseEditQualificationFail: Eine Qualifikation konnte uas unbekanntem Grund nicht mit diesem Kurs assoziert werden.
|
||||
CourseEditQualificationFailRights qsh@QualificationShorthand ssh@SchoolId: Qualifikation #{qsh} konnte nicht mit diesem Kurs assoziert werden, da Ihre Berechtigungen für Bereich #{ssh} dazu nicht ausreichen.
|
||||
CourseEditQualificationFailExists: Diese Qualifikation ist bereits assoziert
|
||||
CourseEditQualificationFail: Eine Qualifikation konnte uas unbekanntem Grund nicht mit diesem Kurs assoziiert werden.
|
||||
CourseEditQualificationFailRights qsh@QualificationShorthand ssh@SchoolId: Qualifikation #{qsh} konnte nicht mit diesem Kurs assoziiert werden, da Ihre Berechtigungen für Bereich #{ssh} dazu nicht ausreichen.
|
||||
CourseEditQualificationFailExists: Diese Qualifikation ist bereits assoziiert
|
||||
CourseEditQualificationFailOrder: Diese Sortierpriorität existiert bereits
|
||||
CourseLecturer: Kursverwalter:in
|
||||
MailSubjectParticipantInvitation tid@TermId ssh@SchoolId csh@CourseShorthand: [#{tid}-#{ssh}-#{csh}] Einladung zur Kursartteilnahme
|
||||
@ -94,6 +94,8 @@ CourseParticipantsRegisterTutorialFieldTip: Ist aktuell keine Kurs mit diesem Na
|
||||
CourseParticipantsRegisterNoneGiven: Es wurden keine anzumeldenden Personen angegeben!
|
||||
CourseParticipantsRegisterNotFoundInAvs n@Int: Zu #{n} #{pluralDE n "Angabe konnte keine übereinstimmende Person" "Angaben konnten keine übereinstimmenden Personen"} im AVS gefunden werden
|
||||
CourseParticipantsRegisterTutorialFirstDayTip: Wenn ein neuer Kurs gemäß einer Vorlage erstellt wird, werden die Zeiten gemäß dem Starttag angepasst
|
||||
CourseParticipantsTutorialType: Typ der Vorlage
|
||||
CourseParticipantsTutorialTypeTooltip: Ein neuer Kurs wird wie ein Kurs namens "Vorlage_[typ]" erstellt, wobei zuerst in der aktuellen Kursart, danach in Kursarten gleichen Namens und möglichst neuem Datum gesucht wird.
|
||||
|
||||
CourseParticipantsInvited n@Int: #{n} #{pluralDE n "Einladung" "Einladungen"} per E-Mail verschickt
|
||||
CourseParticipantsAlreadyRegistered n@Int: #{n} #{pluralDE n "Teinehmer:in" "Teilnehmer:innen"} #{pluralDE n "ist" "sind"} bereits zur Kursart angemeldet
|
||||
@ -135,6 +137,9 @@ CourseUserTutorialsDeregistered count@Int64: Teilnehmer:in von #{show count} #{p
|
||||
CourseUserNoTutorialsDeregistered: Teilnehmer:in ist zu keinem der gewählten Kurse angemeldet
|
||||
CourseUserTutorials: Angemeldete Kurse
|
||||
CourseUserExams: Angemeldete Prüfungen
|
||||
CourseUserExamOccurrences: Prüfungstermin
|
||||
CourseUserExamOccurrenceOverride: Ggf. vorhandenen Prüfungstermin überschreiben
|
||||
CourseUserExamOccurrenceAgainExaminer: Ggf. vorherige Prüfer erneut erlauben
|
||||
CourseUserSheets: Übungsblätter
|
||||
CsvColumnUserName: Voller Name des/der Teilnehmers/Teilnehmerin
|
||||
CsvColumnUserMatriculation: AVS Nummer des/der Teilnehmers/Teilnehmerin
|
||||
@ -239,7 +244,7 @@ UtilEditedBy name@Text time@Text: #{time} durch #{name}
|
||||
CourseDate: Datum
|
||||
MailSubjectLecturerInvitation tid@TermId ssh@SchoolId csh@CourseShorthand: [#{tid}-#{ssh}-#{csh}] Einladung als Kursverwalter:in
|
||||
LecturerInvitationAccepted lType@Text csh@CourseShorthand: Sie wurden als #{lType} für #{csh} eingetragen
|
||||
CourseExamRegistrationTime: Angemeldet seit
|
||||
CourseExamRegistrationTime: Angemeldet am
|
||||
CourseParticipantStateIsActiveFilter: Ansicht
|
||||
CourseApply: Zur Kursart bewerben
|
||||
CourseAdministrator: Kursadministrator:in
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
FilterCourse: Course
|
||||
FilterCourse: Course category
|
||||
FilterCourseShort: Shorthand
|
||||
FilterTerm: Year
|
||||
FilterCourseSchoolShort: Department
|
||||
@ -15,7 +15,7 @@ FilterCourseRegisterOpen: Enrolment is allowed
|
||||
CourseRegistered: Enrolled
|
||||
CourseRegistration: Enrolment
|
||||
CourseDescription: Description
|
||||
CommCourseHeading: Course type message
|
||||
CommCourseHeading: Course category message
|
||||
CourseLecturers: Course administrators
|
||||
CourseLecturerEmail: Email
|
||||
CourseLecturerAlreadyAdded: This user is already configured as a course administrator
|
||||
@ -25,12 +25,12 @@ CourseLecturerRightsIdentical: All sorts of course administrators have the same
|
||||
CourseAcceptSubstitutesUntil: Accept substitute registrations until
|
||||
CourseAcceptSubstitutesUntilTip: Until which time should substitute registrations through the central allocation be accepted to fill free places in the course? If left empty no substitute registrations will be made. This deadline should not arbitrarily be set early or ommitted so as to not be an unneccesarily restrictive for students. For a seminar a valid choice might be a few hours before the first meeting in which topics will be assigned.
|
||||
CourseDeregisterNoShow: Record “no show” when deregistering
|
||||
CourseDeregisterNoShowTip: Should “no show” be recorded as the exam achievement for all exams associated with this course type automatically whenever a course type participant deregisters themselves? This would be done once upon deregistration (if no other achievement exists for the given exam) and automatically whenever a new exam is created.
|
||||
CourseDeregisterNoShowTip: Should “no show” be recorded as the exam achievement for all exams associated with this course category automatically whenever a course category participant deregisters themselves? This would be done once upon deregistration (if no other achievement exists for the given exam) and automatically whenever a new exam is created.
|
||||
CourseSchool: Department
|
||||
CourseSchoolMultipleTip: You may select from among multiple departments. Please ensure that you select the appropriate department for your course.
|
||||
CourseName: Title
|
||||
CourseShorthand: Shorthand
|
||||
CourseShorthandUnique: Needs to be unique within school and year. Will be used verbatim within the url of the course type page.
|
||||
CourseShorthandUnique: Needs to be unique within school and year. Will be used verbatim within the url of the course category page.
|
||||
CourseSemester: Year
|
||||
CourseDescriptionPlaceholder: Please include the module description
|
||||
CourseHomepageExternalPlaceholder: Optional external URL
|
||||
@ -38,14 +38,14 @@ CourseHomepageExternal: External homepage
|
||||
CourseSemesterMultipleTip: You are currently allowed to select from among multiple years. Please ensure that you select the appropriate year for your course.
|
||||
CourseVisibleFrom: Visible from
|
||||
CourseVisibleTo: Visible to
|
||||
CourseVisibleFromTip: The course type will be visible to others from this date onward. When left empty the course type will never be visible to other users. This does not affect course administrators, assistants, instructors, correctors, enrolled participants and applicants of/to this course. If the course type participates in a central allocation, the course type visibility will be forced during the application phase.
|
||||
CourseVisibleToTip: Other users will be able to see the course type from "Visible From" up to this date. When left empty visible courses will remain visible indefinitely.
|
||||
CourseMaterialFree: Course type material is publicly accessible
|
||||
CourseVisibleFromTip: The course category will be visible to others from this date onward. When left empty the course category will never be visible to other users. This does not affect course administrators, assistants, instructors, correctors, enrolled participants and applicants of/to this course. If the course category participates in a central allocation, the course category visibility will be forced during the application phase.
|
||||
CourseVisibleToTip: Other users will be able to see the course category from "Visible From" up to this date. When left empty visible courses will remain visible indefinitely.
|
||||
CourseMaterialFree: Course category material is publicly accessible
|
||||
CourseFormSectionRegistration: Registration
|
||||
CourseFormSectionAdministration: Administration
|
||||
CourseCapacity: Capacity
|
||||
CourseCapacityTip: Maximum permissable number of enrolments for this course; leave empty for unlimited capacity
|
||||
CourseSecretTip: Enrollment for this course type will require the password, if set
|
||||
CourseSecretTip: Enrollment for this course category will require the password, if set
|
||||
CourseSecretFormat: Arbitrary string
|
||||
CourseSecretWrong: Wrong password
|
||||
CourseSecret: Access password
|
||||
@ -59,17 +59,17 @@ CourseVisibilityEndMustBeAfterStart: The end of the visibility period must be af
|
||||
CourseRegistrationEndMustBeAfterStart: The end of the registration period must be after its start
|
||||
CourseDeregistrationEndMustBeAfterStart: The end of the deregistration period must be after the start of the registration period
|
||||
CourseUserMustBeLecturer: The current user needs to be a course administrator
|
||||
CourseShorthandTooLong: Long course type shorthands may lead to display issues and might complicate communication with students. Please choose a more concise shorthand if possible.
|
||||
CourseNotAlwaysVisibleDuringRegistration: To allow for students to register, the course type should also be visible during the entire registration period (which is currently not the case).
|
||||
CourseShorthandTooLong: Long course category shorthands may lead to display issues and might complicate communication with students. Please choose a more concise shorthand if possible.
|
||||
CourseNotAlwaysVisibleDuringRegistration: To allow for students to register, the course category should also be visible during the entire registration period (which is currently not the case).
|
||||
NoSuchTerm tid: Year #{tid} does not exist.
|
||||
NoSuchSchool ssh: Department #{ssh} does not exist.
|
||||
NoSuchCourseShorthand csh: There is no course type with shorthand #{csh}.
|
||||
NoSuchCourse: No such course type found.
|
||||
CourseNewDupShort tid ssh csh: Could not create course type #{tid}-#{ssh}-#{csh}. Another course type with the same shorthand or title already exists for the given year and school.
|
||||
NoSuchCourseShorthand csh: There is no course category with shorthand #{csh}.
|
||||
NoSuchCourse: No such course category found.
|
||||
CourseNewDupShort tid ssh csh: Could not create course category #{tid}-#{ssh}-#{csh}. Another course category with the same shorthand or title already exists for the given year and school.
|
||||
CourseInvalidInput: Invalid input
|
||||
CourseEditTitle: Edit/Create course
|
||||
CourseEditOk tid ssh csh: Successfully edited course type #{tid}-#{ssh}-#{csh}
|
||||
CourseEditDupShort tid ssh csh: Could not edit course type #{tid}-#{ssh}-#{csh}. Another course type with the same shorthand or title already exists for the given year and school.
|
||||
CourseEditOk tid ssh csh: Successfully edited course category #{tid}-#{ssh}-#{csh}
|
||||
CourseEditDupShort tid ssh csh: Could not edit course category #{tid}-#{ssh}-#{csh}. Another course category with the same shorthand or title already exists for the given year and school.
|
||||
CourseEditQualificationFail: A qualifikation could not be associated with this course for unknown reasons.
|
||||
CourseEditQualificationFailRights qsh ssh: Qualification #{qsh} could not be associated with this course, due to your insufficient rights for department #{ssh}.
|
||||
CourseEditQualificationFailExists: This qualification is already associated
|
||||
@ -83,21 +83,23 @@ CourseParticipantInvitationAccepted courseName: You were enrolled in #{courseNam
|
||||
CourseParticipantEnlistDirectly: Enrol known users directly
|
||||
CourseSubmissionGroup: Registered submission group
|
||||
SubmissionGroupEmptyIsUnsetTip: Leave empty to remove users from their respective submission groups
|
||||
CourseParticipantsRegisterHeading: Add course type participants
|
||||
CourseParticipantsRegisterActionAddParticipants: Add course type participants
|
||||
CourseParticipantsRegisterHeading: Add course category participants
|
||||
CourseParticipantsRegisterActionAddParticipants: Add course category participants
|
||||
CourseParticipantsRegisterActionAddTutorialMembers: Add course participants
|
||||
CourseParticipantsRegisterUsersField: Persons to register for course
|
||||
CourseParticipantsRegisterUsersFieldTip: Please enter id card no (including dot), Fraport personnel number or email. Please separate multiple entries with comma or space.
|
||||
CourseParticipantsRegisterTutorialOption: Register course type participants for course?
|
||||
CourseParticipantsRegisterTutorialOption: Register course category participants for course?
|
||||
CourseParticipantsRegisterTutorialField: Course
|
||||
CourseParticipantsRegisterTutorialFieldTip: If there is no course with this name, a new one will be created. If there is a course with this name, the course type participants will be registered for it.
|
||||
CourseParticipantsRegisterTutorialFieldTip: If there is no course with this name, a new one will be created. If there is a course with this name, the course category participants will be registered for it.
|
||||
CourseParticipantsRegisterNoneGiven: No persons given to register!
|
||||
CourseParticipantsRegisterNotFoundInAvs n: For #{n} #{pluralEN n "entry no corresponding person" "entries no corresponding persons"} could be found in AVS
|
||||
CourseParticipantsRegisterTutorialFirstDayTip: If a new course is created and a template exists, its dates are adjusted according to the start date
|
||||
CourseParticipantsRegisterUnnecessary: All requested registrations have already been saved. No actions have been performed.
|
||||
CourseParticipantsTutorialType: Template type
|
||||
CourseParticipantsTutorialTypeTooltip: A new course creation copies a course named "Template_[typ]", preferably from the same course category or another having the same name, the most recent being preferred.
|
||||
|
||||
CourseParticipantsInvited n: #{n} #{pluralEN n "invitation" "invitations"} sent via email
|
||||
CourseParticipantsAlreadyRegistered n: #{n} #{pluralEN n "participant is" "participants are"} already course type #{pluralEN n "member" "members"}
|
||||
CourseParticipantsAlreadyRegistered n: #{n} #{pluralEN n "participant is" "participants are"} already course category #{pluralEN n "member" "members"}
|
||||
CourseParticipantsAlreadyTutorialMember n: #{n} #{pluralEN n "participant is" "participants are"} already registered for this course
|
||||
CourseParticipantsRegistered n: Successfully registered #{n} #{pluralEN n "participant" "participants"} for course
|
||||
CourseParticipantsRegisteredTutorial n: Successfully registered #{n} #{pluralEN n "participant" "participants"} for course
|
||||
@ -110,9 +112,9 @@ CourseRegistrationFiles: Registration file(s)
|
||||
CourseRegistrationFilesNeedReupload: Registration files need to be reuploaded every time the registration is changed
|
||||
CourseRegistrationFile: Registration file
|
||||
CourseRegistrationArchive: Zip archive of registration files
|
||||
CourseDeregistrationNoShow: If you deregister from this course type “no show” will be recorded as your exam achievement for all exams associated with this course. If you have good reasons why you shold not be held accountable for leaving the course, please contact a course administrator. Course administrators can deregister you without incurring a permanent record.
|
||||
CourseDeregistrationFromInvisibleCourse: This course type is only visible to enrolled participants and applicants. If you deregister now, you will not be able to access the course type again!
|
||||
CourseDeregistrationNoReRegistration: If you deregister from the course type now, you will not be able to re-register yourself.
|
||||
CourseDeregistrationNoShow: If you deregister from this course category “no show” will be recorded as your exam achievement for all exams associated with this course. If you have good reasons why you shold not be held accountable for leaving the course, please contact a course administrator. Course administrators can deregister you without incurring a permanent record.
|
||||
CourseDeregistrationFromInvisibleCourse: This course category is only visible to enrolled participants and applicants. If you deregister now, you will not be able to access the course category again!
|
||||
CourseDeregistrationNoReRegistration: If you deregister from the course category now, you will not be able to re-register yourself.
|
||||
LoginNecessary: Please log in first!
|
||||
RegisterRetry: You haven't been enrolled. Press "Enrol for course" to enrol
|
||||
CourseRegisterOk: Successfully enrolled for course
|
||||
@ -135,6 +137,9 @@ CourseUserTutorialsDeregistered count: Sucessfully deregistered participant from
|
||||
CourseUserNoTutorialsDeregistered: Participant is not registered for any of the selected courses
|
||||
CourseUserTutorials: Registered courses
|
||||
CourseUserExams: Registered exams
|
||||
CourseUserExamOccurrences: Exam occurrence
|
||||
CourseUserExamOccurrenceOverride: Override other registrations for this exam, if any
|
||||
CourseUserExamOccurrenceAgainExaminer: Possibly allow previous examiners again
|
||||
CourseUserSheets: Exercise sheets
|
||||
CsvColumnUserName: Participant's full name
|
||||
CsvColumnUserMatriculation: Participant's AVS number
|
||||
@ -148,7 +153,7 @@ CsvColumnUserExam: Exams which the user is registered for, separated by semicolo
|
||||
CsvColumnUserSubmissionGroup: Registered submission group
|
||||
CsvColumnUserSurname: Participant's surname
|
||||
CsvColumnUserFirstName: Participant's given name
|
||||
CsvColumnUserNote: Course type notes for the participant
|
||||
CsvColumnUserNote: Course category notes for the participant
|
||||
CourseUserCsvName tid ssh csh: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-participants
|
||||
CourseUserTutorial: Registered course
|
||||
CourseUserExam: Registered exam
|
||||
@ -175,21 +180,21 @@ AssistantsFor: Assistants
|
||||
CourseAdminFor: Course administration
|
||||
TutorsFor n: #{pluralENs n "Instructor" }
|
||||
CorrectorsFor n: #{pluralEN n "Corrector" "Correctors"}
|
||||
CourseParticipantsHeading: Course type participants
|
||||
CourseParticipantsHeading: Course category participants
|
||||
CourseParticipantsCount n: #{n}
|
||||
CourseParticipantsCountOf n m: #{n} of #{m}
|
||||
CourseVisibility: Visibility
|
||||
CourseInvisible: This course type is currently only visible to course administrators, assistants, instructors, correctors, enrolled participants and applicants.
|
||||
CourseInvisible: This course category is currently only visible to course administrators, assistants, instructors, correctors, enrolled participants and applicants.
|
||||
CourseRegistrationInterval: Enrolment
|
||||
CourseDirectRegistrationInterval: Direct enrolment
|
||||
CourseDeregisterUntil time: Deregistration only until #{time}
|
||||
NotRegistered: Note enrolled for this course
|
||||
CourseMaterial: Material
|
||||
CourseMaterialNotFree: Course type material is only accessible to members of the course, e.g. for participants, instructors, correctors or administratiors.
|
||||
CourseMaterialsFoundHere: Material for this course type is available here
|
||||
CourseMaterialsNoneVisible: Currently there is no material for this course type or only material to which you don't have access (e.g. because of visibility settings)
|
||||
CourseSheetsFoundHere: Exercise sheets for this course type are available here
|
||||
CourseSheetsNoneVisible: Currently there are no exercise sheets for this course type or only exercise sheets to which you don't have access (e.g. because of visibility settings)
|
||||
CourseMaterialNotFree: Course category material is only accessible to members of the course, e.g. for participants, instructors, correctors or administratiors.
|
||||
CourseMaterialsFoundHere: Material for this course category is available here
|
||||
CourseMaterialsNoneVisible: Currently there is no material for this course category or only material to which you don't have access (e.g. because of visibility settings)
|
||||
CourseSheetsFoundHere: Exercise sheets for this course category are available here
|
||||
CourseSheetsNoneVisible: Currently there are no exercise sheets for this course category or only exercise sheets to which you don't have access (e.g. because of visibility settings)
|
||||
SheetListCourse: Exercise sheets
|
||||
CourseExams: Exams
|
||||
CourseTutorials: Courses
|
||||
@ -232,13 +237,13 @@ TutorialRegisterFrom: Register from
|
||||
TutorialRegisterTo: Register to
|
||||
|
||||
CourseDeleteQuestion: Are you sure you want to delete the below-mentioned course?
|
||||
CourseDeleted: Course type deleted
|
||||
CourseDeleted: Course category deleted
|
||||
|
||||
UtilEditedBy name time: #{time} by #{name}
|
||||
CourseDate: Date
|
||||
MailSubjectLecturerInvitation tid ssh csh: [#{tid}-#{ssh}-#{csh}] Invitation to be a course administrator
|
||||
LecturerInvitationAccepted lType csh: You were registered as #{lType} for #{csh}
|
||||
CourseExamRegistrationTime: Registered since
|
||||
CourseExamRegistrationTime: Registered on
|
||||
CourseParticipantStateIsActiveFilter: View
|
||||
CourseApply: Apply for course
|
||||
CourseAdministrator: Course administrator
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
CourseEvents: Termine
|
||||
CourseEventType: Art
|
||||
CourseEventType: Kategorie
|
||||
CourseEventTypePlaceholder: Vorlesung, Zentralübung, ...
|
||||
CourseEventTime: Zeit
|
||||
CourseEventRoom: Regulärer Raum
|
||||
|
||||
@ -8,17 +8,17 @@ CourseEventTypePlaceholder: Lecture, Exercise discussion, ...
|
||||
CourseEventTime: Time
|
||||
CourseEventRoom: Regular room
|
||||
CourseEventRoomHidden: Room only for participants
|
||||
CourseEventRoomHiddenTip: Should the room only be displayde to course type participants?
|
||||
CourseEventRoomHiddenTip: Should the room only be displayde to course category participants?
|
||||
CourseEventRoomIsUnset: —
|
||||
CourseEventRoomIsHidden: Room is only displayed to course type associated persons (participants, instructors, correctors, etc.)
|
||||
CourseEventRoomIsHidden: Room is only displayed to course category associated persons (participants, instructors, correctors, etc.)
|
||||
CourseEventNote: Note
|
||||
CourseEventActions: Actions
|
||||
CourseEventsActionEdit: Edit
|
||||
CourseEventsActionDelete: Delete
|
||||
CourseEventsActionCreate: New occurrence
|
||||
CourseEventCreated: Successfully created course type occurrence
|
||||
CourseEventEdited: Successfully edited course type occurrence
|
||||
CourseEventDeleteQuestion: Are you sure you want to delete the course type occurrence mentioned below?
|
||||
CourseEventDeleted: Successfully deleted course type occurrence
|
||||
CourseEventEdit: Edit course type occurrence
|
||||
CourseEventNew: New course type occurrence
|
||||
CourseEventCreated: Successfully created course category occurrence
|
||||
CourseEventEdited: Successfully edited course category occurrence
|
||||
CourseEventDeleteQuestion: Are you sure you want to delete the course category occurrence mentioned below?
|
||||
CourseEventDeleted: Successfully deleted course category occurrence
|
||||
CourseEventEdit: Edit course category occurrence
|
||||
CourseEventNew: New course category occurrence
|
||||
@ -9,17 +9,17 @@ CourseNewsLastEdited time: Last changed: #{time}
|
||||
CourseNewsActionEdit: Edit
|
||||
CourseNewsActionDelete: Delete
|
||||
CourseNewsActionCreate: Create new item
|
||||
CourseNewsVisibleFromEditWarning: This item of course type news has already been published and should no longer be changed sind this might confuse participants.
|
||||
CourseNewsVisibleFromEditWarning: This item of course category news has already been published and should no longer be changed sind this might confuse participants.
|
||||
CourseNewsVisibleFromTip: If left empty this item is never visible. Leave empty for unfinished items
|
||||
CourseNewsTitle: Title
|
||||
CourseNewsSummary: Summary
|
||||
CourseNewsSummaryTip: If specified this only the summary will be shown on the course type page, saving space. The content will be shown in a popup
|
||||
CourseNewsSummaryTip: If specified this only the summary will be shown on the course category page, saving space. The content will be shown in a popup
|
||||
CourseNewsContent: Content
|
||||
CourseNewsParticipantsOnly: Only for course type participants
|
||||
CourseNewsParticipantsOnly: Only for course category participants
|
||||
CourseNewsVisibleFrom: Visible from
|
||||
CourseNewsCreated: Successfully created item of course type news
|
||||
CourseNewsEdited: Successfully edited item of course type news
|
||||
CourseNewsDeleteQuestion: Are you sure you want to delete the item of course type news listed below?
|
||||
CourseNewsDeleted: Successfully deleted item of course type news
|
||||
CourseNewsNew: Add course type news
|
||||
CourseNewsEdit: Edit item of course type news
|
||||
CourseNewsCreated: Successfully created item of course category news
|
||||
CourseNewsEdited: Successfully edited item of course category news
|
||||
CourseNewsDeleteQuestion: Are you sure you want to delete the item of course category news listed below?
|
||||
CourseNewsDeleted: Successfully deleted item of course category news
|
||||
CourseNewsNew: Add course category news
|
||||
CourseNewsEdit: Edit item of course category news
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -35,7 +35,7 @@ ExamEditHeading examn@ExamName: #{examn} bearbeiten
|
||||
ExamNameTip: Muss innerhalb der Veranstaltung eindeutig sein
|
||||
ExamDescription: Beschreibung
|
||||
ExamFormTimes: Zeiten
|
||||
ExamFormOccurrences: Prüfungstermine/Räume
|
||||
ExamFormOccurrences: Prüfungstermine / Räume
|
||||
ExamFormAutomaticFunctions: Automatische Funktionen
|
||||
ExamFormCorrection: Korrektur
|
||||
ExamFormParts: Teile
|
||||
@ -43,12 +43,13 @@ ExamFormMode: Ausgestaltung der Prüfung
|
||||
ExamFormGrades: Prüfungsleistungen
|
||||
ExamStart: Beginn
|
||||
ExamEnd: Ende
|
||||
ExamTimeTip: Nur zur Information der Studierenden, die tatsächliche Zeitangabe erfolgt pro Prüfungstermin/Raum
|
||||
ExamTimeTip: Nur zur Information, die tatsächliche Zeitangabe erfolgt pro Prüfungstermin/Raum.
|
||||
ExamTimeFilterTip: In der Kursansicht für Kursverwaltende wird diese Zeit zur Filterung verwendet.
|
||||
ExamVisibleFrom: Sichtbar ab
|
||||
ExamVisibleFromTip: Ohne Datum nie sichtbar und keine Anmeldung möglich
|
||||
ExamRegisterFrom: Anmeldung ab
|
||||
ExamRegisterTo: Anmeldung bis
|
||||
ExamRegisterFromTip: Zeitpunkt ab dem sich Kursartteilnehmer:innen selbständig zur Prüfung anmelden können; ohne Datum ist keine Anmeldung möglich
|
||||
ExamRegisterFromTip: Zeitpunkt ab dem sich Kursartteilnehmer:innen selbständig zur Prüfung anmelden können; ohne Datum ist keine selbständige Anmeldung möglich
|
||||
ExamDeregisterUntil: Abmeldung bis
|
||||
ExamPublishOccurrenceAssignments: Termin- bzw. Raumzuteilung den Teilnehmer:innen mitteilen um
|
||||
ExamPublishOccurrenceAssignmentsTip: Ab diesem Zeitpunkt können Teilnehmer:innen einsehen zu welcher Teilprüfung bzw. welchen Raum sie angemeldet sind
|
||||
@ -64,14 +65,15 @@ ExamAutomaticGradingTip: Sollen die Gesamtleistungen der Teilnehmer:innen automa
|
||||
ExamBonus: Bonuspunkte-System
|
||||
ExamGradingMode: Bewertungsmodus
|
||||
ExamGradingModeTip: In welcher Form werden Prüfungsleistungen für diese Prüfung eingetragen?
|
||||
ExamStaff: Prüfer:innen/Verantwortliche Hochschullehrer:innen
|
||||
ExamStaffTip: Geben Sie bitte in jedem Fall einen Namen an, der Prüfer:in/Veranstalter:in/Hochschullehrer:in eindeutig identifiziert! Sollte der Name des Prüfers/der Prüferin allein womöglich nicht eindeutig sein, so geben Sie bitte eindeutig identifizierende Zusatzinfos, wie beispielsweise den Lehrstuhl bzw. die LFE o.Ä., an.
|
||||
ExamStaff: Hauptverantworliche:r
|
||||
ExamStaffTip: Hauptverantwortliche:r Prüfer:in, Textfeld zur reinen Information der Teilnehmenden.
|
||||
ExamExamOfficeSchools: Zusätzliche Bereiche
|
||||
ExamExamOfficeSchoolsTip: Prüfungsbeauftragte von Bereichen, die Sie hier angeben, erhalten im System (zusätzlich zum primären Bereich der zugehörigen Kursart) volle Einsicht in sämtliche für diese Prüfung hinterlegten Leistungen, unabhängig von den Studiendaten der Teilnehmer:innen.
|
||||
ExamCorrectorEmail: E-Mail
|
||||
ExamCorrectors: Korrektor:innen
|
||||
ExamCorrectorsTip: Hier eingetragene Korrektor:innen können zwischen Beginn der Prüfung und "Bewertung abgeschlossen ab" Ergebnisse für alle Teilprüfungen und alle Teilnehmer:innen im System hinterlegen.
|
||||
ExamCorrectorAlreadyAdded: Ein Korrektor/eine Korrektorin mit dieser E-Mail ist bereits für diese Prüfung eingetragen
|
||||
ExamCorrectors: Prüfer:innen
|
||||
ExamCorrectorsTip: Hier eingetragene Prüfer:innen können zwischen Beginn der Prüfung und "Bewertung abgeschlossen ab" Ergebnisse für alle Teilprüfungen und alle Teilnehmer:innen im System hinterlegen.
|
||||
ExamCorrectorAlreadyAdded: Ein Prüfer:innen mit dieser E-Mail ist bereits für diese Prüfung eingetragen
|
||||
ExamParticipant: Prüfungsteilnehmer:in
|
||||
ExamRoom: Raum
|
||||
ExamRoomManual': Keine automatische bzw. selbstständige Zuteilung
|
||||
ExamRoomSurname': Nach Nachname
|
||||
@ -86,6 +88,7 @@ ExamRoomAlreadyExists: Prüfung ist bereits eingetragen
|
||||
ExamRoomName: Interne Bezeichnung
|
||||
ExamRoomCapacity: Kapazität
|
||||
ExamRoomCapacityNegative: Kapazität darf nicht negativ sein
|
||||
ExamRoomCapacityInsufficient n@Int: Kapazität reicht nicht aus, #{noneOneMoreDE n "keine Plätze" "nur noch ein Platz" ("nur noch " <> tshow n <> " Plätze")} verfügbar
|
||||
ExamRoomTime: Termin
|
||||
ExamRoomStart: Beginn
|
||||
ExamRoomEnd: Ende
|
||||
@ -123,6 +126,8 @@ ExamOccurrenceStartMustBeAfterExamStart eoName@ExamOccurrenceName: Beginn des Te
|
||||
ExamOccurrenceEndMustBeBeforeExamEnd eoName@ExamOccurrenceName: Ende des Termins #{eoName} liegt nach dem Ende der Prüfung
|
||||
ExamOccurrenceDuplicate eoRoom@Text eoRange@Text: Raum #{eoRoom}, Termin #{eoRange} kommt mehrfach mit der selben Beschreibung vor
|
||||
ExamOccurrenceDuplicateName eoName@ExamOccurrenceName: Interne Terminbezeichnung #{eoName} kommt mehrfach vor
|
||||
ExamOccurrenceExaminerIsUnset !ident-ok: —
|
||||
ExamOccurrenceExaminerIsHidden: Prüfer wird nur Teilnehmer:innen angezeigt
|
||||
ExamOccurrenceRoomIsUnset !ident-ok: —
|
||||
ExamOccurrenceRoomIsHidden: Raum wird nur Teilnehmer:innen angezeigt
|
||||
ExamOccurrenceCannotBeDeletedDueToRegistrations eoName@ExamOccurrenceName: Termin #{eoName} kann nicht gelöscht werden, da noch Teilnehmer:innen diesem Termin zugewiesen sind. Über die Liste von Prüfungsteilnehmern können Sie zunächst die entsprechenden Terminzuweisungen entfernen.
|
||||
@ -217,6 +222,13 @@ ExamOccurrenceRuleParticipant: Termin- bzw. Raumzuteilungsverfahren
|
||||
ExamRegisteredCount: Anmeldungen
|
||||
ExamRegisteredCountOf num@Int64 count@Int64 !ident-ok: #{num}/#{count}
|
||||
ExamOccurrences: Termine
|
||||
ExamOccurrencesCopied num@Int: #{pluralDEeN num "Prüfungstermin"} kopiert
|
||||
ExamOccurrencesEdited num@Int del@Int: #{pluralENsN num "Prüfungstermin"} geändert #{guardMonoid (del > 0) ("und " <> pluralENsN num "Prüfungstermin" <> " gelöscht")}
|
||||
ExamOccurrenceCopyNoStartDate: Dieser Kurs hat noch keine eigene Termine um Prüfungstermine zeitlich damit zu assoziieren
|
||||
ExamOccurrenceCopyFail: Keine passenden Prüfungstermine zum Kopieren gefunden
|
||||
ExaminerReocurrence examiner@Text: Mehrfache Prüfung durch #{examiner}!
|
||||
ExamProblemReoccurrence: Prüfungen mit wiederholt gleichem Prüfer
|
||||
ExamNoProblemReoccurrence: Heute keine Prüfungen mit wiederholtem Prüfer.
|
||||
GradingFrom: Ab
|
||||
ExamNoShow: Nicht erschienen
|
||||
ExamVoided: Entwertet
|
||||
@ -264,6 +276,7 @@ ExamAutoOccurrenceExceptionRoomTooSmall: Automatische Verteilung gescheitert. Ei
|
||||
ExamBonusInfoPoints: Zur Berechnung von Bonuspunkten werden nur jene Blätter herangezogen, deren Aktivitätszeitraum vor Start des jeweiligen Termin/Prüfung begonnen hat
|
||||
ExamUserCsvSheetName tid@TermId ssh@SchoolId csh@CourseShorthand examn@ExamName: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase examn} Teilnehmer
|
||||
|
||||
ExamRoomExaminerTip: Nur bereits eingetragene Prüfer:innen sind hier erlaubt
|
||||
ExamRoomCapacityTip: Maximale Anzahl an Prüfungsteilnehmern für diesen Termin/Raum; leer lassen für unbeschränkte Teilnehmeranzahl
|
||||
ExamRoomMappingRandom: Verteilung
|
||||
ExamFinishHeading: Prüfungsergebnisse sichtbar schalten
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
# SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
ExamRegistrationInviteDeadline: Invitation valid until
|
||||
ExamRegistrationEnlistDirectly: Register known users directly
|
||||
ExamRegistrationEnlistDirectlyTip: Should users whose email addresses are known to the system be registered for the exam directly? Otherwise invitations will be sent to alle users, which they will have to accept first in order to be registered. Unknown users always receive an invitation.
|
||||
ExamRegistrationRegisterCourse: Also enroll users in course type
|
||||
ExamRegistrationRegisterCourse: Also enroll users in course category
|
||||
ExamRegistrationRegisterCourseTip: Users that aren't enrolled already won't be registered for the exam otherwise.
|
||||
ExamRegistrationInviteField: Email addresses
|
||||
ExamParticipantsRegisterHeading: Add exam participants
|
||||
@ -35,7 +35,7 @@ ExamEditHeading examn: Edit #{examn}
|
||||
ExamNameTip: Needs to be unique within the course
|
||||
ExamDescription: Description
|
||||
ExamFormTimes: Times
|
||||
ExamFormOccurrences: Occurrences/rooms
|
||||
ExamFormOccurrences: Occurrences / Rooms
|
||||
ExamFormAutomaticFunctions: Automatic functions
|
||||
ExamFormCorrection: Correction
|
||||
ExamFormParts: Exam parts
|
||||
@ -43,12 +43,13 @@ ExamFormMode: Exam design
|
||||
ExamFormGrades: Exam achievements
|
||||
ExamStart: Start
|
||||
ExamEnd: End
|
||||
ExamTimeTip: Only for informational purposes. The actual times are set for each occurrence/room
|
||||
ExamTimeTip: Only for informational purposes. The actual times are set for each occurrence/room.
|
||||
ExamTimeFilterTip: Also used for Filtering in the course administrator course view.
|
||||
ExamVisibleFrom: Visible from
|
||||
ExamVisibleFromTip: If left empty the exam is never visible and course type participants may not register.
|
||||
ExamVisibleFromTip: If left empty the exam is never visible and course category participants may not register.
|
||||
ExamRegisterFrom: Register from
|
||||
ExamRegisterTo: Register to
|
||||
ExamRegisterFromTip: Start of the period in which course type participants may register themselves for the exam. If left empty participants are never allowed to register.
|
||||
ExamRegisterFromTip: Start of the period in which course category participants may register themselves for the exam. If left empty participants are never allowed to register themselves.
|
||||
ExamDeregisterUntil: Deregister until
|
||||
ExamPublishOccurrenceAssignments: Publish occurrence/room-assignments
|
||||
ExamPublishOccurrenceAssignmentsTip: At this time participants can find out to which occurrence/room they are assigned
|
||||
@ -64,14 +65,15 @@ ExamAutomaticGradingTip: Should the exam achievement be automatically computed f
|
||||
ExamBonus: Bonus point system
|
||||
ExamGradingMode: Grading mode
|
||||
ExamGradingModeTip: In which format should grades for this exam be entered?
|
||||
ExamStaff: Examiner/Responsible university teacher
|
||||
ExamStaffTip: Please always specify a name that uniquely identifies the examiner/organiser/repsonsible university teacher! If there is a possibility that the name alone is ambiguous please also specify some additional information e.g. the professorial chair or the educational and research unit.
|
||||
ExamStaff: Chief examiner
|
||||
ExamStaffTip: Primary responsible examiner, arbirary text field for pure informational purposes.
|
||||
ExamExamOfficeSchools: Additional departments
|
||||
ExamExamOfficeSchoolsTip: Exam offices of departments you specify here will also have full access to all results for this exam disregarding the individual participants' features of study.
|
||||
ExamCorrectorEmail: Email
|
||||
ExamCorrectors: Correctors
|
||||
ExamCorrectorsTip: Correctors configured here may, after the start of the exam and until "Results visible from", enter exam part results for all exam parts and participants.
|
||||
ExamCorrectorAlreadyAdded: A corrector with this email address already exists
|
||||
ExamCorrectors: Examiner
|
||||
ExamCorrectorsTip: Examiners configured here may, after the start of the exam and until "Results visible from", enter exam part results for all exam parts and participants.
|
||||
ExamCorrectorAlreadyAdded: An examiner with this email address already exists
|
||||
ExamParticipant: Examinee
|
||||
ExamRoom: Room
|
||||
ExamRoomManual': No automatic or autonomous assignment
|
||||
ExamRoomSurname': By surname
|
||||
@ -86,6 +88,7 @@ ExamRoomAlreadyExists: Occurrence already configured
|
||||
ExamRoomName: Internal name
|
||||
ExamRoomCapacity: Capacity
|
||||
ExamRoomCapacityNegative: Capacity may not be negative
|
||||
ExamRoomCapacityInsufficient n@Int: Insufficient capacity, #{noneOneMoreEN n "none" "just one" ("only " <> tshow n)} remaining
|
||||
ExamRoomTime: Time
|
||||
ExamRoomStart: Start
|
||||
ExamRoomEnd: End
|
||||
@ -123,8 +126,10 @@ ExamOccurrenceStartMustBeAfterExamStart eoName: Start of the occurrence #{eoName
|
||||
ExamOccurrenceEndMustBeBeforeExamEnd eoName: End of the occurrence #{eoName} must be before the exam end
|
||||
ExamOccurrenceDuplicate eoRoom eoRange: Combination of room #{eoRoom} and occurrence #{eoRange} occurs multiple times
|
||||
ExamOccurrenceDuplicateName eoName: Internal name #{eoName} occurs multiple times
|
||||
ExamOccurrenceExaminerIsUnset !ident-ok: —
|
||||
ExamOccurrenceExaminerIsHidden: Examiner only displayed to participants registered for this occurrence
|
||||
ExamOccurrenceRoomIsUnset: —
|
||||
ExamOccurrenceRoomIsHidden: Room is only displayed to participants registered for this occurrence/room
|
||||
ExamOccurrenceRoomIsHidden: Room only displayed to participants registered for this occurrence
|
||||
ExamOccurrenceCannotBeDeletedDueToRegistrations eoName: Occurrence #{eoName} cannot be deleted because participants are registered for it. You can remove the offending registrations via the list of exam participants.
|
||||
ExamRegistrationMustFollowSchoolSeparationFromStart dayCount: As per school rules there #{pluralEN dayCount "needs" "need"} to be at least #{dayCount} #{pluralEN dayCount "day" "days"} between "Register from" and "Start".
|
||||
ExamRegistrationMustFollowSchoolDuration dayCount: As per school rules there #{pluralEN dayCount "needs" "need"} to be at least #{dayCount} #{pluralEN dayCount "day" "days"} between "Register from" and "Register to".
|
||||
@ -159,7 +164,7 @@ CsvColumnExamUserExercisePassesMax: Maximum number of exercise sheets the partic
|
||||
CsvColumnExamUserBonus: Exam bonus points
|
||||
CsvColumnExamUserParts: Number of points the participant achieved per exam part. One column per exam part if applicable.
|
||||
CsvColumnExamUserResult: Exam achievement; "passed", "failed", "no-show", "voided", or any number grade ("1.0", "1.3", "1.7", ..., "4.0", "5.0")
|
||||
CsvColumnExamUserCourseNote: Course type notes for the participant
|
||||
CsvColumnExamUserCourseNote: Course category notes for the participant
|
||||
CsvColumnExamOfficeExamUserOccurrenceStart: Exam occurrence (ISO 8601)
|
||||
CsvColumnUserStudyFeatures: All relevant features of study for the participant, separated by semicolon (;)
|
||||
ExamUserCsvName tid ssh csh examn: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase examn}-participants
|
||||
@ -176,7 +181,7 @@ ExamAction: Action
|
||||
ExamUsersExamDataRequiresRegistration: If exam data (part-/result, occurrence/room, bonus) is to be modified/set, the relenvant participant needs to be registered for the exam.
|
||||
ExamNoOccurrence: No occurrence/room
|
||||
ExamBonusNone: No bonus points
|
||||
ExamUserCsvCourseNoteDeleted: Course type note will be deleted
|
||||
ExamUserCsvCourseNoteDeleted: Course category note will be deleted
|
||||
ExamUsersDeregistered count: Successfully deregistered #{show count} #{pluralEN count "participant" "participants"}
|
||||
ExamUsersOccurrenceUpdated count: Successfully assigned occurrence/room for #{show count} #{pluralEN count "participant" "participants"}
|
||||
ExamUsersResultsAccepted count: Successfully accepted computed result for #{show count} #{pluralEN count "participant" "participants"}
|
||||
@ -217,6 +222,13 @@ ExamOccurrenceRuleParticipant: Occurrence/room assignment procedure
|
||||
ExamRegisteredCount: Registrations
|
||||
ExamRegisteredCountOf num count: #{num}/#{count}
|
||||
ExamOccurrences: Exams
|
||||
ExamOccurrencesCopied num: #{pluralENsN num "exam occurrence"} copied
|
||||
ExamOccurrencesEdited num del: #{pluralENsN num "exam occurrence"} edited #{guardMonoid (del > 0) ("and " <> pluralENsN num "exam occurrence" <> " deleted")}
|
||||
ExamOccurrenceCopyNoStartDate: This course needs its own occurrence to copy associated exam occurrences.
|
||||
ExamOccurrenceCopyFail: No suitable exam occurrences found to copy from.
|
||||
ExaminerReocurrence examiner: Multiple examinations by #{examiner}!
|
||||
ExamProblemReoccurrence: Exams with reoccurring examiner
|
||||
ExamNoProblemReoccurrence: Today there are no exams with a reoccurring examiner.
|
||||
GradingFrom: From
|
||||
|
||||
#templates widgets/bonus-rule
|
||||
@ -262,6 +274,8 @@ ExamAutoOccurrenceExceptionNoUsers: No participants can be distributed with the
|
||||
ExamAutoOccurrenceExceptionRoomTooSmall: Automatic distribution failed. A different distribution procedure might succeed. Alternatively, minimizing rooms or removing small rooms might help.
|
||||
ExamBonusInfoPoints: When calculating an exam bonus only those sheets will be considered, for which the submission period started before the start of the relevant occurrence/room
|
||||
ExamUserCsvSheetName tid ssh csh examn: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase examn} Participants
|
||||
|
||||
ExamRoomExaminerTip: Only examiners allowed here, add beforehand
|
||||
ExamRoomCapacityTip: Maximum number of participants for this occurrence/room; leave empty for unlimited capacity
|
||||
ExamRoomMappingRandom: Distribution
|
||||
ExamFinishHeading: Make results visible
|
||||
@ -302,9 +316,9 @@ ExamUserCsvOverrideResult: Override exam result in contradiction of computed val
|
||||
ExamUserCsvSetBonus: Set bonus points
|
||||
ExamUserCsvSetResult: Set exam result
|
||||
ExamUserCsvSetPartResult: Set result for exam part
|
||||
ExamUserCsvSetCourseNote: Modify course type participant notes
|
||||
ExamUserCsvExceptionNoMatchingUser: Course type participant could not be identified uniquely. All identifiers (given name(s), surname, display name, matriculation, ..) must match exactly. You can try to remove some of the identifiers for the given line (i.e. all but matriculation). Uni2work will then search for users using only the remaining identifiers. In this case special care should be taken that Uni2work correctly identifies the intended user.
|
||||
ExamUserCsvExceptionMultipleMatchingUsers: Course type participant could not be identified uniquely. There are multiple users that match the given identifiers. You can try to add more identifiers for the given line to ensure that only the intended user can be identified with them.
|
||||
ExamUserCsvSetCourseNote: Modify course category participant notes
|
||||
ExamUserCsvExceptionNoMatchingUser: Course category participant could not be identified uniquely. All identifiers (given name(s), surname, display name, matriculation, ..) must match exactly. You can try to remove some of the identifiers for the given line (i.e. all but matriculation). Uni2work will then search for users using only the remaining identifiers. In this case special care should be taken that Uni2work correctly identifies the intended user.
|
||||
ExamUserCsvExceptionMultipleMatchingUsers: Course category participant could not be identified uniquely. There are multiple users that match the given identifiers. You can try to add more identifiers for the given line to ensure that only the intended user can be identified with them.
|
||||
ExamUserCsvExceptionNoMatchingStudyFeatures: The specified field did not match with any of the participant's fields of study. You can try to remove the field of study for the given line. Uni2work will then automatically choose a field of study.
|
||||
ExamUserCsvExceptionNoMatchingOccurrence: Occurrence/room could not be identified uniquely. Please ensure that the given line only contains internal room identifiers exactly as they have been configured for this exam.
|
||||
ExamUserCsvExceptionMismatchedGradingMode expectedGradingMode actualGradingMode: The imported data contained an exam achievement which does not match the grading mode for this exam. The expected grading mode can be changed at "Edit exam" ("Passed/Failed", "Numeric grades", or "Mixed").
|
||||
|
||||
@ -15,8 +15,8 @@ ExternalExamCorrectErrorNeedleTooShort: This identifier is too short.
|
||||
UnauthorizedExternalExamCorrectorGrade: You may not enter overall exam achievements for this exam.
|
||||
ExternalExamCorrectErrorMultipleMatchingUsers: This identifier matches on multiple students.
|
||||
ExternalExamCorrectErrorNoMatchingUsers: This identifier does not match any student.
|
||||
ExternalExamEdited coursen@CourseName examn@ExamName: Succesfully edited exam “#{examn}” for course type “#{coursen}”.
|
||||
ExternalExamExists coursen@CourseName examn@ExamName: Exam “#{examn}” already exists for course type “#{coursen}”.
|
||||
ExternalExamEdited coursen@CourseName examn@ExamName: Succesfully edited exam “#{examn}” for course category “#{coursen}”.
|
||||
ExternalExamExists coursen@CourseName examn@ExamName: Exam “#{examn}” already exists for course category “#{coursen}”.
|
||||
ExternalExamEdit coursen examn: Edit: #{coursen}, #{examn}
|
||||
ExternalExamSemester: Year
|
||||
ExternalExamSchool: Department
|
||||
@ -41,10 +41,10 @@ ExternalExamStaffTip: The list of ssociated persons is shown to exam offices and
|
||||
ExternalExamStaffAlreadyAdded: Person is already associated with the exam.
|
||||
ExternalExamStaffEmail: Email
|
||||
ExternalExamUserMustBeStaff: You yourself must always be an associated person for exams you create.
|
||||
ExternalExamCourseExists: This course type already exists with FRADrive. Exams for courses that exist within FRADrive should be associated with the course type directly instead of being created as an external exam.
|
||||
ExternalExamCourseExists: This course category already exists with FRADrive. Exams for courses that exist within FRADrive should be associated with the course category directly instead of being created as an external exam.
|
||||
HeadingExternalExamList: External exams
|
||||
HeadingExternalExamNew: New external exam
|
||||
ExternalExamCreated coursen@CourseName examn@ExamName: Succesfully created exam “#{examn}” for course type “#{coursen}”.
|
||||
ExternalExamCreated coursen@CourseName examn@ExamName: Succesfully created exam “#{examn}” for course category “#{coursen}”.
|
||||
MailSubjectExternalExamStaffInvitation coursen examn: Invitation to act as examiner for “#{examn}” of “#{coursen}”
|
||||
ExternalExamOccurrenceEdited count: Successfully edited #{count} #{pluralEN count "occurrence" "occurrences"}
|
||||
ExternalExamResultEdited count: Successfully edited #{count} #{pluralEN count "exam result" "exam results"}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
MaterialList !ident-ok: Material
|
||||
MaterialName !ident-ok: Name
|
||||
MaterialType: Art
|
||||
MaterialType: Typ
|
||||
MaterialTypePlaceholder: Folien, Code, Beispiel, ...
|
||||
MaterialTypeSlides: Folien
|
||||
MaterialTypeCode !ident-ok: Code
|
||||
|
||||
@ -11,27 +11,27 @@ MaterialTypeCode: Code
|
||||
MaterialTypeExample: Example
|
||||
MaterialDescription: Description
|
||||
MaterialVisibleFrom: Visible to participants from
|
||||
MaterialVisibleFromTip: Never visible to participants if left empty; leaving the date empty is only sensible for unfinished course type material or when course type material should be provided only to sheet correctors
|
||||
MaterialVisibleFromEditWarning: This course type material has already been published and should not be edited. Doing so might confuse the participants.
|
||||
MaterialInvisible: This course type material is currently invisible to participants!
|
||||
MaterialVisibleFromTip: Never visible to participants if left empty; leaving the date empty is only sensible for unfinished course category material or when course category material should be provided only to sheet correctors
|
||||
MaterialVisibleFromEditWarning: This course category material has already been published and should not be edited. Doing so might confuse the participants.
|
||||
MaterialInvisible: This course category material is currently invisible to participants!
|
||||
MaterialFiles: Files
|
||||
MaterialHeading materialName: #{materialName}
|
||||
MaterialListHeading: Course type materials
|
||||
MaterialNewHeading: Publish new course type material
|
||||
MaterialNewTitle: New course type material
|
||||
MaterialEditHeading materialName: Edit course type material “#{materialName}”
|
||||
MaterialEditTitle materialName: Edit course type material “#{materialName}”
|
||||
MaterialSaveOk tid ssh csh materialName: Successfully saved “#{materialName}” for course type #{tid}-#{ssh}-#{csh}
|
||||
MaterialNameDup tid ssh csh materialName: Course type material with the name “#{materialName}” already exists for course type #{tid}-#{ssh}-#{csh}
|
||||
MaterialDeleteCaption: Do you really want to delete the course type material mentioned below?
|
||||
MaterialListHeading: Course category materials
|
||||
MaterialNewHeading: Publish new course category material
|
||||
MaterialNewTitle: New course category material
|
||||
MaterialEditHeading materialName: Edit course category material “#{materialName}”
|
||||
MaterialEditTitle materialName: Edit course category material “#{materialName}”
|
||||
MaterialSaveOk tid ssh csh materialName: Successfully saved “#{materialName}” for course category #{tid}-#{ssh}-#{csh}
|
||||
MaterialNameDup tid ssh csh materialName: Course category material with the name “#{materialName}” already exists for course category #{tid}-#{ssh}-#{csh}
|
||||
MaterialDeleteCaption: Do you really want to delete the course category material mentioned below?
|
||||
MaterialDelHasFiles count: including #{count} #{pluralEN count "file" "files"}
|
||||
MaterialIsVisible: Caution, this course type material has already been published.
|
||||
MaterialDeleted materialName: Successfully deleted course type material “#{materialName}”
|
||||
MaterialIsVisible: Caution, this course category material has already been published.
|
||||
MaterialDeleted materialName: Successfully deleted course category material “#{materialName}”
|
||||
MaterialArchiveName tid ssh csh materialName: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase materialName}
|
||||
MaterialVideo materialName: #{materialName} - Video
|
||||
MaterialVideoUnsupported: Your browser does not seem to support embedded video
|
||||
MaterialVideoDownload: Download
|
||||
MaterialFree: Course type material is publicly available.
|
||||
MaterialFree: Course category material is publicly available.
|
||||
AccessibleSince: Accessible since
|
||||
VisibleFrom: Published
|
||||
FilterMaterialNameSearch !ident-ok: Name
|
||||
|
||||
@ -2,16 +2,16 @@
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
ParticipantsList: Lists of course type participants
|
||||
ParticipantsIntersect: Common course type participants
|
||||
ParticipantsList: Lists of course category participants
|
||||
ParticipantsIntersect: Common course category participants
|
||||
ParticipantsCsvName tid ssh: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-participants
|
||||
ParticipantsIntersectCourseOption tid@TermId ssh@SchoolId coursen@CourseName: #{tid} - #{ssh} - #{coursen}
|
||||
ParticipantsIntersectCourses: Courses
|
||||
CourseParticipantsRegisteredWithoutField n: #{n} #{pluralEN n "participant was" "participants were"} registered without #{pluralEN n "an associated field of study" "associated fields of study"}, because #{pluralEN n "it" "they"} could not be determined uniquely.
|
||||
ParticipantsCsvSheetName tid ssh: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)} Participants
|
||||
CourseParticipants n: Currently #{n} course type #{pluralEN n "participant" "participants"}
|
||||
CourseParticipants n: Currently #{n} course category #{pluralEN n "participant" "participants"}
|
||||
ParticipantsIntersectNotOne: Intersection
|
||||
AllUsersUnion: Union of all participants
|
||||
AllUsersIntersection: Intersection of all participants
|
||||
CourseDeleteActiveParticipants: This course type still has active participants. Remove all active participants first if you really want to delete this course.
|
||||
CourseDeleteExistExams: This course type cannot be deleted, for as long as associated exams exist.
|
||||
CourseDeleteActiveParticipants: This course category still has active participants. Remove all active participants first if you really want to delete this course.
|
||||
CourseDeleteExistExams: This course category cannot be deleted, for as long as associated exams exist.
|
||||
@ -13,8 +13,8 @@ SheetDeleteQuestion: Do you really want to delete the below-mentioned exercise s
|
||||
SheetDeleted: Successfully deleted exercise sheet
|
||||
SheetArchiveName tid ssh csh shn: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase shn}
|
||||
SheetTypeArchiveName tid ssh csh shn renderedSft: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase shn}-#{foldCase renderedSft}
|
||||
SheetEditOk tid ssh csh sheetName: Successfully saved exercise sheet #{sheetName} in course type #{tid}-#{ssh}-#{csh}
|
||||
SheetNameDup tid ssh csh sheetName: There already is an exercise sheet #{sheetName} in course type #{tid}-#{ssh}-#{csh}
|
||||
SheetEditOk tid ssh csh sheetName: Successfully saved exercise sheet #{sheetName} in course category #{tid}-#{ssh}-#{csh}
|
||||
SheetNameDup tid ssh csh sheetName: There already is an exercise sheet #{sheetName} in course category #{tid}-#{ssh}-#{csh}
|
||||
SheetVisibleFrom: Visible from (for participants)
|
||||
SheetVisibleFromTip: Always invisible for participants and no submission possible if left empty; only leave this field empty for temporary/unfinished sheets
|
||||
SheetActiveFrom: Active from/Submission period start
|
||||
@ -24,7 +24,7 @@ SheetSolutionFromTip: Always invisible for participants if left empty; corrector
|
||||
SheetName: Name
|
||||
SheetDescription: Description
|
||||
SheetRequireExam: Require registration for an exam?
|
||||
SheetRequireExamTip: If registration for an exam is required, only course type participants that are registered for that exam at the time of submission will be allowed to create submission. Download of sheet files will also be restricted to course type participants registered for the exam.
|
||||
SheetRequireExamTip: If registration for an exam is required, only course category participants that are registered for that exam at the time of submission will be allowed to create submission. Download of sheet files will also be restricted to course category participants registered for the exam.
|
||||
SheetRequiredExam: Exam
|
||||
SheetFormType: Valuation & submission
|
||||
SheetFormTimes: Times
|
||||
@ -37,15 +37,15 @@ SheetMarkingFiles: Correction
|
||||
SheetMarkingTip: Instructions for correction, visible only to correctors
|
||||
SheetPersonalisedFilesDownload: Download personalised sheet files
|
||||
SheetPersonalisedFiles: Personalised sheet files
|
||||
SheetPersonalisedFilesTip: Should course type participants be assigned personalised sheet files in addition to the files configured above? Only the user to which a file has been assigned may view it.
|
||||
SheetPersonalisedFilesTip: Should course category participants be assigned personalised sheet files in addition to the files configured above? Only the user to which a file has been assigned may view it.
|
||||
SheetPersonalisedFilesUpload: Personalised sheet files
|
||||
SheetPersonalisedFilesUploadTip: Download the template for a ZIP-archive of personalised sheet files, move files into the directories corresponding to the desired users and upload the archive again. If the name of a personalised file matches the name of an unpersonalised file, the personalised file replaces the unpersonalised one from the respective participants' point of view.
|
||||
SheetPersonalisedFilesKeepExisting: Keep existing files
|
||||
SheetPersonalisedFilesKeepExistingTip: Should the personalised files you upload be added to the already existing ones, if applicable? Otherwise the files you upload will completely replace any existing files.
|
||||
SheetPersonalisedFilesAllowNonPersonalisedSubmission: Allow non-personalised submission
|
||||
SheetPersonalisedFilesAllowNonPersonalisedSubmissionTip: Should course type participants with no assigned personalised files be allowed to submit anyway?
|
||||
SheetPersonalisedFilesAllowNonPersonalisedSubmissionTip: Should course category participants with no assigned personalised files be allowed to submit anyway?
|
||||
SheetPersonalisedFilesDownloadTemplateHere: You can download a template for a ZIP-archive of personalised sheet files with the structure that Uni2work expects here:
|
||||
SheetPersonalisedFilesUsersList: List of course type participants who have personalised sheet files
|
||||
SheetPersonalisedFilesUsersList: List of course category participants who have personalised sheet files
|
||||
SheetPersonalisedFilesMetaYAMLSeedComment: This string was generated cryptographically from data uniquely identifying the user and exercise sheet. You can use it as a seed for a pseudorandom generator for generating (parts of) the personalised files.
|
||||
SheetPersonalisedFilesMetaYAMLNoSeedComment: There is not enough information available to generate a seed. You will have to create the exercise sheet in Uni2work first. Once seeds can be generated they will be generated cryptographically and you may use them to generate (parts of) the personalised files.
|
||||
SheetActiveFromTip: The exercise sheet's assignment will only be available for download and submission starting at this time. If left empty no submission or download of assignment is ever allowed
|
||||
@ -63,7 +63,7 @@ SheetErrDeadlineEarly: "Submission period end" must be after "Submission period
|
||||
SheetErrHintEarly: "Hint from" must be after "Submission period start"
|
||||
SheetErrSolutionEarly: "Solution from" must be after "Submission period end"
|
||||
SheetErrVisibleWithoutActive: If “Visible from (for participants)” is specified “Active from/Submission period start” must also be specified
|
||||
SheetSubmissionModeNoneWithoutNotGraded: The sheet was configured to be "No submission" but not "Not marked". Course type participants will not be able to submit.
|
||||
SheetSubmissionModeNoneWithoutNotGraded: The sheet was configured to be "No submission" but not "Not marked". Course category participants will not be able to submit.
|
||||
SheetWarnNoActiveTo: “Active to/Submission period end” should always be specified
|
||||
CountTutProp: Courses count against proportion
|
||||
CountTutPropTip: If submissions are assigned by course, do those assignments count with regard to the set proportion?
|
||||
@ -82,13 +82,13 @@ RatingPercent: Achieved
|
||||
IsRated: Marked
|
||||
SheetTypeIsExam: Rating „as an exam part“
|
||||
SheetGradingSummaryTitle intgr: #{intgr} #{pluralEN intgr "sheet" "sheets"}
|
||||
PersonalisedSheetFilesIgnored count: #{count} uploaded #{pluralEN count "file was" "files were"} ignored because #{pluralEN count "it" "they"} could not be associated with both a sheet file type and a course type participant.
|
||||
PersonalisedSheetFilesIgnored count: #{count} uploaded #{pluralEN count "file was" "files were"} ignored because #{pluralEN count "it" "they"} could not be associated with both a sheet file type and a course category participant.
|
||||
PersonalisedSheetFilesIgnoredIntro: The following files were ignored:
|
||||
PersonalisedSheetFilesDownloadRestrictByExamNone: No restriction
|
||||
PersonalisedSheetFilesDownloadRestrictByExam: Restrict to exam participants
|
||||
PersonalisedSheetFilesDownloadRestrictByExamTip: Only download personalised sheet files for participants also registered to a certain exam?
|
||||
PersonalisedSheetFilesDownloadAnonymousField: Anonymisation
|
||||
PersonalisedSheetFilesDownloadAnonymousFieldTip: Should the ZIP-archive of personalised files be anonymised (it would then contain no immediately identifiable information regard the course type participants) or should directory names be decorated with an identifiable feature of the user and the files of meta information contain additional personal data?
|
||||
PersonalisedSheetFilesDownloadAnonymousFieldTip: Should the ZIP-archive of personalised files be anonymised (it would then contain no immediately identifiable information regard the course category participants) or should directory names be decorated with an identifiable feature of the user and the files of meta information contain additional personal data?
|
||||
PersonalisedSheetFilesMetaFilename uid: meta-information_#{toPathPiece uid}.yaml
|
||||
PersonalisedSheetFilesArchiveName tid ssh csh shn: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase shn}-personalised_files
|
||||
SheetGeneratePseudonym: Generate
|
||||
|
||||
@ -49,10 +49,10 @@ SubmissionArchive: Zip-archive of submission files
|
||||
SubmissionArchiveCorrected: Zip-archive of submission files including corrections
|
||||
SubmissionFile: Submission file
|
||||
SubmissionFiles: Submitted files
|
||||
EmailInvitationWarningPrevCoSubmittors: This address could not be matched to any course type participant with whom you have submitted for this course type before. An Invitation will be sent via email.
|
||||
EmailInvitationWarningCourseParticipants: This address coulde not be matched to any course type participant. An Invitation will be sent via email.
|
||||
MultiUserFieldExplanationPrevCoSubmittors: This input searches through the addresses of all course type participants for whom it could be determined, that you have already submitted with that person for this course.
|
||||
MultiUserFieldExplanationCourseParticipants: This input searches through the addresses of all course type participants.
|
||||
EmailInvitationWarningPrevCoSubmittors: This address could not be matched to any course category participant with whom you have submitted for this course category before. An Invitation will be sent via email.
|
||||
EmailInvitationWarningCourseParticipants: This address coulde not be matched to any course category participant. An Invitation will be sent via email.
|
||||
MultiUserFieldExplanationPrevCoSubmittors: This input searches through the addresses of all course category participants for whom it could be determined, that you have already submitted with that person for this course.
|
||||
MultiUserFieldExplanationCourseParticipants: This input searches through the addresses of all course category participants.
|
||||
SubmissionAlreadyExistsFor email: #{email} already has a submission for this sheet.
|
||||
SubmissionUsersEmpty: Submissions may not be created without submittors.
|
||||
SubmissionUserAlreadyAdded: This user is already configured as a submittor
|
||||
@ -155,7 +155,7 @@ SubmissionSomeUsersDuplicateWarning: Some submittors are also submittors for a d
|
||||
|
||||
EMailUnknown email: Email #{email} does not belong to any known user.
|
||||
CorDeficitProportion: Deficit (proportion)
|
||||
CosubmittorTip: Invitations are sent via email to exactly those addresses for which it cannot be determined, that you have already submitted for this course type with the associated person, at least once. If one of the specified addresses can be matched to a person with whom you have submitted at least once for this course type already, the name of that person will be shown and the submission will immediately be made in their name as well.
|
||||
CosubmittorTip: Invitations are sent via email to exactly those addresses for which it cannot be determined, that you have already submitted for this course category with the associated person, at least once. If one of the specified addresses can be matched to a person with whom you have submitted at least once for this course category already, the name of that person will be shown and the submission will immediately be made in their name as well.
|
||||
CorrDownload: Download
|
||||
SubmissionDownloadAnonymous: Anonymized
|
||||
SubmissionDownloadSurnames: With surnames
|
||||
@ -237,9 +237,9 @@ SubmissionFilterAuthorshipStatementCurrent: Current wording
|
||||
|
||||
SubmissionNoUsers: This submission has no associated users!
|
||||
|
||||
CsvColumnCorrectionTerm: Term of the course type of the submission
|
||||
CsvColumnCorrectionSchool: School of the course type of the submission
|
||||
CsvColumnCorrectionCourse: Shorthand of the course type of the submission
|
||||
CsvColumnCorrectionTerm: Term of the course category of the submission
|
||||
CsvColumnCorrectionSchool: School of the course category of the submission
|
||||
CsvColumnCorrectionCourse: Shorthand of the course category of the submission
|
||||
CsvColumnCorrectionSheet: Name of the sheet of the submission
|
||||
CsvColumnCorrectionSubmission: Number of the submission (uwa…)
|
||||
CsvColumnCorrectionSurname: Submittor's surnames, separated by semicolon (;)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25 Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -36,6 +36,7 @@ TutorialDelete: Löschen
|
||||
TutorialsHeading: Kurse
|
||||
TutorialNew: Neuer Kurs
|
||||
TutorialRegisteredSuccess tutn@TutorialName: Erfolgreich zum Kurs #{tutn} angemeldet
|
||||
TutorialRegisteredFail tutn@TutorialName: Anmeldung zum Kurs #{tutn} fehlgeschlagen. Existiert bereits eine Anmeldung?
|
||||
TutorialDeregisteredSuccess tutn@TutorialName: Erfolgreich vom Kurs #{tutn} abgemeldet
|
||||
MailSubjectTutorInvitation tid@TermId ssh@SchoolId csh@CourseShorthand tutn@TutorialName: [#{tid}-#{ssh}-#{csh}] Einladung zum Ausbilder für #{tutn}
|
||||
TutorInviteHeading tutn@TutorialName: Einladung zum Ausbilder/zur Ausbilderin für #{tutn}
|
||||
@ -49,4 +50,21 @@ TutorialUserGrantQualification: Qualifikation vergeben
|
||||
TutorialUserRenewQualification: Qualifikation regulär verlängern
|
||||
TutorialUserRenewedQualification n@Int: Qualifikation für #{tshow n} Kurs-#{pluralDE n "Teilnehmer:in" "Teilnehmer:innen"} regulär verlängert
|
||||
TutorialUserGrantedQualification n@Int: Qualifikation erfolgreich an #{tshow n} Kurs-#{pluralDE n "Teilnehmer:in" "Teilnehmer:innen"} vergeben
|
||||
CommTutorial: Kursmitteilung
|
||||
TutorialUserAssignExam: Zur Prüfung einteilen
|
||||
TutorialUserExamAssignedFor n@Int m@Int p@Text: #{n}/#{m} zur Prüfung #{p} eingeteilt
|
||||
CommTutorial: Kursmitteilung
|
||||
TutorialDrivingPermit: Führerschein
|
||||
TutorialEyeExam: Sehtest
|
||||
TutorialNote: Kursnotiz
|
||||
TutorialDayAttendance day@Text: Anwesenheit #{day}
|
||||
TutorialDayNote day@Text: Anwesenheitsnotiz #{day}
|
||||
TutorialParticipantsDayEdits day@Text: Kursteilnehmer-Tagesnotizen aktualisiert für #{day}
|
||||
|
||||
PossibleCheckResults: Mögliche Prüfungsergebnisse
|
||||
CheckEyePermitMissing: Sehtest oder Führerschein fehlen noch
|
||||
CheckEyePermitIncompatible: Sehtest und Führerschein passen nicht zusammen
|
||||
|
||||
GenTutActOccCopyLast: Prüfungstermine von früherem Kurs kopieren
|
||||
GenTutActOccCopyWeek: Prüfungstermine von früherer Woche kopieren
|
||||
GenTutActOccEdit: Relevante Prüfungstermine bearbeiten
|
||||
GenTutActShowExam: Prüfungsergebnisse der Kursteilnehmer anzeigen
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25 Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -12,16 +12,16 @@ TutorialEdited tutn: Successfully edited course #{tutn}
|
||||
TutorialEditHeading tutn: Edit #{tutn}
|
||||
TutorEmail: Email
|
||||
TutorialTutorAlreadyAdded: An user with this email address is already registered as instructor
|
||||
TutorialNameTip: Needs to be unique within the course type
|
||||
TutorialNameTip: Needs to be unique within the course category
|
||||
TutorialTypePlaceholder: Tutorial, Driving lesson, ...
|
||||
TutorialTypeTip: Only for informational purposes
|
||||
TutorialRegGroupTip: Course type participants may only register for a maximum of one course per registration group. Courses that do not have a registration group are treated as being in different registration groups
|
||||
TutorialRegGroupTip: Course category participants may only register for a maximum of one course per registration group. Courses that do not have a registration group are treated as being in different registration groups
|
||||
TutorialRegGroup: Registration group
|
||||
TutorialTutorControlled: Instructors may edit course
|
||||
TutorialTutorControlledTip: Should instructors be allowed to edit arbitrary aspects of this course (name, registration group, room, time, other instructors, ...) at will?
|
||||
TutorialCapacity: Capacity
|
||||
TutorialCapacityNonPositive: Capacity may not be negative
|
||||
TutorialCapacityTip: Limits how many course type participants may register for this course
|
||||
TutorialCapacityTip: Limits how many course category participants may register for this course
|
||||
TutorialRoomHiddenTip: Should the room only be displayed to course participants?
|
||||
RegisterFrom: Enrolment starts
|
||||
RegisterTo: Enrolment ends
|
||||
@ -36,6 +36,7 @@ TutorialDelete: Delete
|
||||
TutorialsHeading: Courses
|
||||
TutorialNew: New course
|
||||
TutorialRegisteredSuccess tutn: Successfully registered for the course #{tutn}
|
||||
TutorialRegisteredFail tutn: Registering for the course #{tutn} failed. Probably already registered?
|
||||
TutorialDeregisteredSuccess tutn: Successfully de-registered for the course #{tutn}
|
||||
MailSubjectTutorInvitation tid ssh csh tutn: [#{tid}-#{ssh}-#{csh}] Invitation to be a instructor for #{tutn}
|
||||
TutorInviteHeading tutn: Invitation to be instructor for #{tutn}
|
||||
@ -50,4 +51,21 @@ TutorialUserGrantQualification: Grant qualification
|
||||
TutorialUserRenewQualification: Renew qualification
|
||||
TutorialUserRenewedQualification n@Int: Successfully renewed qualification #{tshow n} course #{pluralEN n "user" "users"}
|
||||
TutorialUserGrantedQualification n: Successfully granted qualification #{tshow n} course #{pluralEN n "user" "users"}
|
||||
TutorialUserAssignExam: Register for examination
|
||||
TutorialUserExamAssignedFor n@Int m@Int p@Text: #{n}/#{m} enrolled for exam #{p}
|
||||
CommTutorial: Course message
|
||||
TutorialDrivingPermit: Driving permit
|
||||
TutorialEyeExam: Eye exam
|
||||
TutorialNote: Course note
|
||||
TutorialDayAttendance day: Attendance #{day}
|
||||
TutorialDayNote day: Attendance note #{day}
|
||||
TutorialParticipantsDayEdits day: course participant day notes updated for #{day}
|
||||
|
||||
PossibleCheckResults: Possible results
|
||||
CheckEyePermitMissing: Eye exam or driving permit missing
|
||||
CheckEyePermitIncompatible: Eye exam and driving permit are incompatible
|
||||
|
||||
GenTutActOccCopyLast: Copy exam occurrences from previous course
|
||||
GenTutActOccCopyWeek: Copy exam occurrences from course on previous week
|
||||
GenTutActOccEdit: Edit relevant exam occurrences
|
||||
GenTutActShowExam: Show exam results for course participants
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2023-24 Steffen Jost <s.jost@fraport.de>
|
||||
# SPDX-FileCopyrightText: 2023-25 Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -21,8 +21,11 @@ FirmActResetSupersKeepAll: Alle behalten
|
||||
FirmActResetSupersRemoveAps: Nur Standardansprechpartner entfernen
|
||||
FirmActResetSupersRemoveAll: Alle entfernen
|
||||
FirmActAddSupervisors: Ansprechpartner hinzufügen
|
||||
FirmActAddSupersEmpty: Es konnten keine Ansprechpartner hinzugefügt werden
|
||||
FirmActAddAssociates: Firmenangehörige hinzufügen
|
||||
FirmActAddSupersEmpty: Es konnten keine neuen Ansprechpartner hinzugefügt werden!
|
||||
FirmActAddSupersSet n@Int64 postal@(Maybe Bool): #{n} Standardansprechpartner geändert #{maybeBoolMessage postal "" "und auf Briefversand geschaltet" "und Benachrichtigungen per Email gesetzt"}, aber nicht nicht aktiviert.
|
||||
FirmActAddAssocsEmpty: Es konnten keine neuen Firmenangehörige hinzugefügt werden!
|
||||
FirmActAddAssocs n@Int64: #{n} Firmenangehörige hinzugefügt.
|
||||
RemoveSupervisors ndef@Int64: #{ndef} Standardansprechpartner entfernt.
|
||||
FirmActChangeContactUser: Kontaktinformationen von allen Firmenangehörigen ändern
|
||||
FirmActChangeContactFirm: Kontaktinformationen der Firma ändern
|
||||
@ -38,7 +41,7 @@ FirmUserActMkSuper: Zum Firmenansprechpartner ernennen
|
||||
FirmUserActChangeDetailsResult n@Int64 t@Int64: Firmenassoziation von #{n}/#{t} #{pluralDE n "Firmenangehörigen" "Firmenangehörige"} wurden aktualisiert
|
||||
FirmUserActChangeResult n@Int64 t@Int64: Benachrichtigungseinstellung für #{n}/#{t} #{pluralDE n "Firmenangehörigen" "Firmenangehörige"} wurden geändert
|
||||
FirmUserActRemoveResult uc@Int64: #{uc} #{pluralDE uc "Firmenassoziation" "Firmenassoziationen"} entfernt.
|
||||
FirmRemoveSupervision sup@Int64 sub@Int64: #{noneMoreDE sup "" (tshow sup <> " Ansprechpartnerbeziehungen wegen entferntem Ansprechpartner gelöscht. ")} #{noneOneMoreDE sub "Keine Ansprechpartnerbeziehung" "Eine Ansprechpartnerbeziehung" (tshow sup <> " Ansprechpartnerbeziehungen")} wegen entferntem Angesprochenem gelöscht.
|
||||
FirmRemoveSupervision sup@Int64 sub@Int64: #{noneMoreDE sup "" (tshow sup <> " Ansprechpartnerbeziehungen wegen entferntem Ansprechpartner gelöscht. ")} #{noneOneMoreDE sub "Keine Ansprechpartnerbeziehung" "Eine Ansprechpartnerbeziehung" (tshow sup <> " Ansprechpartnerbeziehungen")} wegen entferntem Klienten gelöscht.
|
||||
FirmNewSupervisor: Neue individuelle Ansprechpartner hinzufügen
|
||||
FirmSetSupervisor: Existierende Ansprechpartner hinzufügen
|
||||
FirmSetSupersReport nusr@Int64 nspr@Int64 nrem@Int64: Für #{nusr} Firmenangehörige wurden #{nspr} individuelle Ansprechpartner eingetragen#{bool "." (" und " <> tshow nrem <> " individuelle Ansprechpartnerbeziehungen gelöscht.") (nrem >0)}
|
||||
@ -70,9 +73,25 @@ TableSuperior: Vorgesetzter
|
||||
TableIsDefaultReroute: Standardumleitung
|
||||
FormFieldPostal: Benachrichtigungseinstellung
|
||||
FormFieldPostalTip: Gilt für alle Benachrichtigungen an diese Person, nicht nur für Umleitungen an diesen Ansprechpartner
|
||||
FormFieldPinPass: Sensible PDF-E-Mail-Anhänge mit Passwort schützen?
|
||||
FormFieldPinPassRemove: Passwortschutz für PDF-E-Mail-Anhänge entfernen?
|
||||
FirmSupervisionKeyData: Kennzahlen Ansprechpartner
|
||||
CompanyUserPriority: Firmenpriorität
|
||||
CompanyUserPriorityTip: Firmenpriorität ist lediglich relativ zu anderen Firmenassoziation der Person
|
||||
CompanyUserUseCompanyAddress: Verwendet Firmenkontaktaddresse
|
||||
CompanyUserUseCompanyAddressTip: sofern im Benutzer keine Postanschrift hinterlegt ist
|
||||
CompanyUserUseCompanyPostalError: Postalische Adresse muss leer bleiben, damit die Firmenanschrift genutzt wird!
|
||||
CompanySupervisorCompanyMissing fsh@CompanyShorthand: Empfänger ist nicht mit Firma #{fsh} aus Ansprechpartnerbeziehung assoziiert
|
||||
CompanySuperviseeCompanyMissing fsh@CompanyShorthand: Klient ist nicht mit Firma #{fsh} aus Ansprechpartnerbeziehung assoziiert
|
||||
FirmSupervisionRInfo: In folgenden Ansprechpartnerbeziehungen gehören entweder der Ansprechpartner oder der Klient nicht mehr der Firma an, welche als Begründung für die Beziehung eingetragen ist.
|
||||
SupervisionViolationChoice: Firmenassoziation fehlt für
|
||||
SupervisionViolationEither: Egal
|
||||
SupervisionViolationSupervisor: Ansprechpartner
|
||||
SupervisionViolationClient: Klient
|
||||
SupervisionViolationBoth: Beide
|
||||
SupervisionsRemoved n@Int64 m@Int64: #{n}/#{m} #{pluralDE n "Ansprechpartnerbeziehung" "Ansprechpartnerbeziehungen"} entfernt.
|
||||
SupervisionsEdited n@Int64 m@Int64: #{n}/#{m} #{pluralDE n "Ansprechpartnerbeziehung" "Ansprechpartnerbeziehungen"} geändert.
|
||||
ASChangeCompany: Begründungen für Ansprechpartnerbeziehung abändern
|
||||
ASRemoveAssociation: Ansprechpartnerbeziehung löschen
|
||||
FirmNameNotFound: Keine Firma mit diesen Namen/Kürzel/AVS-Nr gefunden.
|
||||
FirmNameAmbiguous: Firmenname/-kürzel oder AVS-Nr ist nicht eindeutig.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2023-24 Steffen Jost <s.jost@fraport.de>
|
||||
# SPDX-FileCopyrightText: 2023-25 Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -15,14 +15,17 @@ FirmActionInfo: Affects alle company associates under your supervision.
|
||||
FirmActNotify: Send message
|
||||
FirmActResetSupervision: Reset supervisors for all company associates
|
||||
FirmActResetSuperKeep: Additionally keep existing supervisors of company associates?
|
||||
FirmActRemoveSupers: Terminate all company related supervisonships?
|
||||
FirmActRemoveSupers: Terminate all company related supervisionships?
|
||||
FirmActResetMutualSupervision: Supervisors supervise each other
|
||||
FirmActResetSupersKeepAll: Keep all
|
||||
FirmActResetSupersRemoveAps: Remove default supervisors only
|
||||
FirmActResetSupersRemoveAll: Remove all
|
||||
FirmActAddSupervisors: Add supervisors
|
||||
FirmActAddSupersEmpty: No supervisors added
|
||||
FirmActAddAssociates: Associate users with company
|
||||
FirmActAddSupersEmpty: No new supervisors added!
|
||||
FirmActAddSupersSet n postal: #{n} default company supervisors changed #{maybeBoolMessage postal "" "and switched to postal notifications" "and switched to email notifications"}, but not yet activated.
|
||||
FirmActAddAssocsEmpty: No new company associated users added!
|
||||
FirmActAddAssocs n: #{pluralENsN n "company associated user"} added.
|
||||
RemoveSupervisors ndef: #{ndef} default supervisors removed.
|
||||
FirmActChangeContactUser: Change contact data for all company associates
|
||||
FirmActChangeContactFirm: Change company contact data
|
||||
@ -70,9 +73,25 @@ TableSuperior: Superior
|
||||
TableIsDefaultReroute: Default reroute
|
||||
FormFieldPostal: Notification type
|
||||
FormFieldPostalTip: Affects all notifications to this person, not just reroutes to this supervisor
|
||||
FormFieldPinPass: Protect sensitive PDF e-mail attachments by password?
|
||||
FormFieldPinPassRemove: Remove password protection for PDF e-mail attachments?
|
||||
FirmSupervisionKeyData: Supervision key data
|
||||
CompanyUserPriority: Company priority
|
||||
CompanyUserPriorityTip: Company priority is relative to other company associations for a user
|
||||
CompanyUserUseCompanyAddress: Use company postal address
|
||||
CompanyUserUseCompanyAddressTip: if and only if the postal address of the user is empty
|
||||
CompanyUserUseCompanyPostalError: Individual postal address must left empty for the company address to be used!
|
||||
CompanySupervisorCompanyMissing fsh: Receiver is not associated with #{fsh} given as reroute reason
|
||||
CompanySuperviseeCompanyMissing fsh: Supervisee is not associated with #{fsh} detailed as supervisionship reason
|
||||
FirmSupervisionRInfo: Shown are supervisionships where either supervisor or supervisee no longer belong to the company associated with the supervisionship.
|
||||
SupervisionViolationChoice: Company association missing for
|
||||
SupervisionViolationEither: anyone
|
||||
SupervisionViolationSupervisor: Supervisor
|
||||
SupervisionViolationClient: Supervisee
|
||||
SupervisionViolationBoth: both
|
||||
SupervisionsRemoved n m: #{n}/#{m} #{pluralENs n "Supervisionship"} removed.
|
||||
SupervisionsEdited n m: #{n}/#{m} #{pluralENs n "Supervisionship"} edited.
|
||||
ASChangeCompany: Change supervisionship annotations
|
||||
ASRemoveAssociation: Delete supervisionship
|
||||
FirmNameNotFound: No company found with this name/shorthand or AVS number.
|
||||
FirmNameAmbiguous: Company name/shorthand or AVS number is amiguous.
|
||||
@ -6,7 +6,7 @@ HeadingLegal: Legal
|
||||
InfoSupervisorTitle: Information for supervisors
|
||||
InfoLecturerTitle: Information for course administrators
|
||||
InfoLecturerCourses: Courses
|
||||
InfoLecturerExercises: Course type exercises
|
||||
InfoLecturerExercises: Course category exercises
|
||||
InfoLecturerTutorials: Courses
|
||||
InfoLecturerExams: Exams
|
||||
LecturerInfoTooltipNew: New feature
|
||||
@ -20,8 +20,8 @@ KnownBugs: Known bugs
|
||||
ImplementationDetails: Implementation
|
||||
Clone: Cloning
|
||||
Administrator: Administrator
|
||||
CommCourse: Course type message
|
||||
CommCourse: Course category message
|
||||
Corrector: Corrector
|
||||
DefinitionCourseEvents: Course type occurrences
|
||||
DefinitionCourseNews: Course type news
|
||||
DefinitionCourseEvents: Course category occurrences
|
||||
DefinitionCourseNews: Course category news
|
||||
Invitations: Invitations
|
||||
|
||||
@ -17,7 +17,7 @@ PrintJobReprint n@Int m@Int: #{n}/#{m} #{pluralDE n "Druckauftrag" "Druckaufräg
|
||||
PrintJobAcknowledgeFailed: Keine Druckaufträge bestätigt aufgrund zwischenzeitlicher Änderungen. Bitte die Seite im Browser aktualisieren!
|
||||
PrintJobAcknowledgeQuestion n@Int d@Text: #{n} #{pluralDE n "Druckauftrag" "Druckaufräge"} vom #{d} als gedruckt und versendet bestätigen?
|
||||
PrintJobAcknowledgements: Versanddatum von Briefen an
|
||||
PrintRecipient: Empfänger
|
||||
PrintRecipient: Empfänger:innen
|
||||
PrintAffected: Betroffener
|
||||
PrintSender !ident-ok: Sender
|
||||
PrintCourse: Kursarten
|
||||
@ -28,5 +28,8 @@ PrintLmsUser: E‑Learning Id
|
||||
PrintJobs: Druckaufräge
|
||||
PrintLetterType: Brieftypkürzel
|
||||
|
||||
MCActDummy: Platzhalter
|
||||
MCActResendEmail: E‑Mail Kopie versenden
|
||||
MCActResendEmailTooltip: Eine unveränderte Kopie der E‑Mail erneut versenden. Nur die vorherigen Empfänger werden offiziell aufgeführt, sie erhalten jedoch keine neue Kopie.
|
||||
MCActResendEmailInfo n@Int recv@Text: #{pluralDEnN n "E‑Mail Kopie"} wurden an #{recv} versandt.
|
||||
|
||||
CCActDummy: Platzhalter
|
||||
@ -20,7 +20,7 @@ PrintJobAcknowledgements: Sent-dates for Letter to
|
||||
PrintRecipient: Recipient
|
||||
PrintAffected: Affetcted
|
||||
PrintSender: Sender
|
||||
PrintCourse: Course type
|
||||
PrintCourse: Course category
|
||||
PrintQualification: Qualification
|
||||
PrintPDF: PDF
|
||||
PrintManualRenewal: Manual sending of an apron driver's licence renewal letter
|
||||
@ -28,5 +28,8 @@ PrintLmsUser: E‑learning id
|
||||
PrintJobs: Print jobs
|
||||
PrintLetterType: Letter type shorthand
|
||||
|
||||
MCActDummy: Placeholder
|
||||
MCActResendEmail: Resend email copy
|
||||
MCActResendEmailTooltip: Resend an unchanged copy of the email. Only previous recipients will officially be listed, but they will not receive another copy.
|
||||
MCActResendEmailInfo n recv: #{n} #{noneOneMoreEN n "email copy" "email copy" "email copies"} were sent to #{recv} only.
|
||||
|
||||
CCActDummy: Placeholder
|
||||
@ -1,26 +1,30 @@
|
||||
# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25 Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
QualificationShort: Kürzel
|
||||
QualificationName: Qualifikation
|
||||
QualificationDescription: Beschreibung
|
||||
QualificationValidReason qsh@Text: #{qsh} Gültigkeit
|
||||
QualificationValidIndicator: Gültigkeit
|
||||
QualificationValidDuration: Gültigkeitsdauer
|
||||
QualificationAuditDuration: Aufbewahrung Audit Log
|
||||
QualificationAuditDurationTooltip n@Int: Optionaler Zeitraum zur Löschung von E‑Learning Daten. Hinweis: Der E‑Learning Server kann seine anonymisierten Daten schon früher löschen, aber spätestens #{n} Tage nach Abschluss.
|
||||
QualificationAuditDurationReuseError: Diese Qualifikation nutzt das E‑Learning einer anderen Qualifikation, für die derzeit keinen Löschzeitraum konfiguriert wurde.
|
||||
QualificationAuditDuration: Aufbewahrungszeitraum E‑Learning Log
|
||||
QualificationAuditDurationTooltip: Anzahl Tage zur Löschung von E‑Learning Daten. Hinweis: Der E‑Learning Server kann seine anonymisierten Daten schon früher löschen.
|
||||
QualificationAuditDurationReuseInfo: Aufbewahrungszeitraum E‑Learning Log wird ignoriert, da das E‑Learning einer anderen Qualifikation mitbenutzt wird.
|
||||
QualificationRefreshWithin: Erneurerungszeitraum
|
||||
QualificationRefreshWithinTooltip: Optionaler Zeitraum vor Ablauf für eine Benachrichtigung per Email. Bei aktiviertem automatischem E‑Learning wird dieses gestartet und die Benachrichtigung erfolgt per Brief oder Email.
|
||||
QualificationRefreshReminder: Zweite Erinnerung
|
||||
QualificationRefreshReminderTooltip: Optionaler Zeitraum vor Ablauf zur Versendung einer zweiten Erinnerung per Brief oder Email mit identischen E‑Learning Zugangsdaten, sofern die Qualifikation noch gültig und das E‑Learning noch offen ist.
|
||||
QualificationElearningStart: Wird das E‑Learning automatisch gestartet?
|
||||
QualificationElearningRenew: Verlängert ein erfolgreiches E‑Learning die Qualifikation automatisch um die reguläre Gültigkeitsdauer?
|
||||
QualificationElearningLimit: Ist die Anzahl der E‑Learning Versuche limitiert?
|
||||
QualificationElearningLimit: Limit Anzahl E‑Learning Versuche
|
||||
QualificationElearningLimitExplain: Ist die Anzahl der E‑Learning Versuche limitiert?
|
||||
QualificationElearningLimitMax n@Int: Maximal #{n} Versuche
|
||||
QualificationElearningNoLimit: Nicht limitiert
|
||||
QualificationExpiryNotification: Ungültigkeitsbenachrichtigung?
|
||||
QualificationExpiryNotificationTooltip: Nutzer werden benachrichtigt, wenn die Qualifikation ungültig wird, sofern der jeweilige Nutzer in seinen Benutzereinstellungen diese Art Benachrichtigung aktiviert hat.
|
||||
QualificationExpiryNotificationTooltip: Nutzer werden benachrichtigt, wenn die Qualifikation ungültig wird, sofern der jeweilige Nutzer in seinen Benutzereinstellungen diese Art Benachrichtigung nicht deaktiviert hat.
|
||||
QualificationAvsLicence: AVS Qualifikation
|
||||
QualificationSapId: SAP Qualifikations Id
|
||||
TableQualificationCountActive: Aktive
|
||||
TableQualificationCountActiveTooltip: Anzahl Personen mit momentan gültiger Qualifikation
|
||||
TableQualificationCountTotal: Gesamt
|
||||
@ -70,7 +74,7 @@ TableLmsNotified: Versand Benachrichtigung
|
||||
TableLmsNotifiedTooltip: Benachrichtigungen werden erst versendet wenn das LMS bestätigt die Eröffnung des E‑Learning für den Benutzer bestätigt hat, was ein paar Stunden dauern kann!
|
||||
TableLmsEnded: Beendet
|
||||
TableLmsStatus: Status E‑Learning
|
||||
TableLmsStatusTooltip mbMonth@(Maybe Int): Zeigt #{maybeToMessage "bis zu " (fmap (flip pluralDEeN "Monat") mbMonth) " nach Abschluss"} den letzten Zustand eines E‑Learnings an:
|
||||
TableLmsStatusTooltip n@Int: Zeigt bis zu #{pluralDEeN n "Tag"} nach Abschluss den letzten Zustand eines E‑Learnings an:
|
||||
TableLmsStatusDay: Datum letzte Statusänderung E‑Learning
|
||||
TableLmsSuccess: Bestanden
|
||||
TableLmsLock: Gesperrt
|
||||
@ -80,6 +84,7 @@ LmsStatusExpired: Durchgefallen nach Fristablauf
|
||||
LmsStatusSuccess: E#{nonBreakableDash}Learning bestanden
|
||||
LmsStatusPlanned: E#{nonBreakableDash}Learning wird gerade noch eröffnet (nur für Admin sichtbar)
|
||||
LmsStatusDelay: Hinweis: Statusänderung können in seltenen Fällen mehrere Stunden bis zur Anzeige benötigen.
|
||||
FilterLmsLongValid: Längerfristig gültig
|
||||
FilterLmsValid: Aktuell gültig
|
||||
FilterLmsRenewal: Erneuerung anstehend
|
||||
FilterLmsNotified: Benachrichtigt
|
||||
@ -98,8 +103,8 @@ LmsReportInsert: Neues LMS Ereignis
|
||||
LmsReportUpdate: LMS Ereignis Aktualisierung
|
||||
LmsReportCsvExceptionDuplicatedKey: CSV-Import LmsReport fand uneindeutigen Schlüssel
|
||||
LmsDirectUpload: Direkter Upload für automatisierte Systeme
|
||||
LmsErrorNoRefreshElearning: Fehler: E‑Learning wird nicht automatisch gestartet, da die Zeitspanne für den Erneurerungszeitraum nicht festgelegt wurde!
|
||||
LmsErrorNoRenewElearning: Fehler: Erfoglreiches E‑Learning verlängert die Qualifikation nicht automatisch, da die Gültigkeitsdauer nicht festgelegt wurde!
|
||||
LmsErrorNoRefreshElearning: Fehler: E‑Learning wird nicht automatisch gestartet, da die Zeitspanne für den Erneuerungszeitraum nicht festgelegt wurde!
|
||||
LmsErrorNoRenewElearning: Fehler: Erfolgreiches E‑Learning verlängert die Qualifikation nicht automatisch, da die Gültigkeitsdauer nicht festgelegt wurde!
|
||||
MailSubjectQualificationRenewal qname@Text: Qualifikation #{qname} muss demnächst erneuert werden
|
||||
MailSubjectQualificationExpiry qname@Text: Qualifikation #{qname} läuft demnächst ab
|
||||
MailSubjectQualificationExpired qname@Text: Qualifikation #{qname} ist ab sofort ungültig
|
||||
@ -116,7 +121,7 @@ QualificationActBlock: Entziehen
|
||||
QualificationActUnblock: Entzug aufheben
|
||||
QualificationActRenew: Qualifikation regulär verlängern
|
||||
QualificationActGrant: Qualifikation vergeben
|
||||
QualificationActGrantWarning: Diese Funktion ist nur für seltene Ausnahmefälle vorgesehen! Ein Entzug wird ggf. aufgehoben.
|
||||
QualificationActGrantWarning: Diese Funktion ist nur für seltene Ausnahmefälle vorgesehen! Ein Entzug wird ggf. aufgehoben; E‑Learning wird ggf. beendet.
|
||||
QualificationActStartELearning: E‑Learning für gültige Inhaber (neu) starten
|
||||
QualificationActStartELearningStatus l@QualificationShorthand n@Int m@Int: E‑Learning #{l} für #{n}/#{m} Teilnehmer (neu) gestartet. Hinweis: Es kann länger dauern, bis das LMS tatsächlich startet.
|
||||
QualificationStatusBlock l@QualificationShorthand n@Int m@Int: #{n}/#{m} #{l} entzogen
|
||||
@ -126,8 +131,7 @@ LmsRenewalInstructions: Weitere Anweisungen zur Verlängerung finden Sie im ange
|
||||
LmsNoRenewal: Leider kann diese Qualifikation nicht alleine durch E‑Learning verlängert werden. Bitte setzen Sie sich mit uns in Verbindung, wenn Sie die Qualifikation verlängern möchten und noch nicht wissen, wie Sie das tun können. Ignorieren Sie diese automatisch generierte Erinnerung, falls Sie sich bereits um die Verlängerung gekümmert haben
|
||||
LmsRenewalReminder: Erinnerung
|
||||
LmsActNotify: Benachrichtigung E‑Learning erneut per Post oder E-Mail versenden
|
||||
LmsActRenewPin: Neues zufällige E‑Learning Passwort zuweisen
|
||||
LmsActRenewNotify: Neue zufällige E‑Learning Passwort zuweisen und Benachrichtigung per Post oder E-Mail versenden
|
||||
LmsActRenewNotify: Neues zufälliges E‑Learning Passwort zuweisen und Benachrichtigung per Post oder E-Mail versenden
|
||||
LmsActReset: E‑Learning Fehlversuche zurücksetzen und entsperren
|
||||
LmsActResetInfo: E‑Learning Login, Passwort und Fortschritt bleiben unverändert, eine neue Benachrichtigung ist nicht notwendig. Nur möglich für bereits gesperrte Lerner. Es kann bis zu 2 Stunden dauern, bis das LMS die Anfrage umgesetzt hat.
|
||||
LmsActResetFeedback n@Int m@Int: Für #{n}/#{m} E‑Learning Nutzer wurden alle Fehlversuche zurückgesetzt.
|
||||
@ -136,6 +140,11 @@ LmsActRestartWarning: Das vorhandene E‑Learning wird komplett gelöscht! Für
|
||||
LmsActRestartFeedback n@Int m@Int: #{n}/#{m} E‑Learning Nutzer wurden komplett neu gestartet mit neuem Login und Passwort.
|
||||
LmsActRestartExtend: Gültig bis ggf. erhöhen für die nächsten # Tage
|
||||
LmsActRestartUnblock: Entzug ggf. aufheben
|
||||
LmsActTerminate: E‑Learning abbrechen
|
||||
LmsActTerminateInfo: Ein späterer automatischer Neustart des E‑Learning wird dadurch nicht verhindert, wenn eine gültige Qualifikation bald abläuft und E‑Learning für diese Qualifikation generell automatisch startet.
|
||||
LmsActTerminateFeedback n@Int m@Int: #{n}/#{m} E‑Learning Nutzer wurden zur Löschung freigegeben.
|
||||
LmsActTerminated n@Int: E‑Learning für #{n} Nutzer wurde beendet.
|
||||
LmsActTerminateWarning: ACHTUNG: Ein Ergebnis würde ohne Warnung verworfen, sollte ein Nutzer sein E‑Learning absolvieren, bevor die Löschung beim E‑learning Server effektiv wurde.
|
||||
LmsStateOpen: E‑Learning offen
|
||||
LmsStatusLocked: E‑Learning gesperrt, wird ggf. bald geöffnet
|
||||
LmsStatusUnlocked: E‑Learning offen, wird ggf. bald gesperrt
|
||||
@ -147,3 +156,18 @@ LmsActionFailed n@Int: Aktion nicht durchgeführt für #{n} #{pluralDE n "Person
|
||||
LmsStarted: E‑Learning eröffnet
|
||||
BtnLmsEnqueue: Nutzer mit ablaufenden Qualifikationen zum E‑Learning anmelden und benachrichtigen
|
||||
BtnLmsDequeue: Nutzer mit beendetem E‑Learning aufräumen und ggf. benachrichtigen
|
||||
|
||||
QualificationEditNote: Hinweis: Die Änderungen treten sofort in Kraft. Bitte vergewissern Sie sich vorher, dass alles korrekt eingestellt wurde!
|
||||
QualificationCreated qsh@Text: Qualifikation #{qsh} wurde angelegt.
|
||||
QualificationEdit qsh@Text: Qualifikation #{qsh} wurde geändert.
|
||||
QualFormErrorDuplShort qsh@Text: Es gibt bereits eine Qualifikation mit Kürzel #{qsh}!
|
||||
QualFormErrorDuplName qname@Text: Es gibt bereits eine Qualifikation mit Namen #{qname}!
|
||||
QualFormErrorSshMismatch: Qualifikationänderungsformular enthält unglültige Bereichsangabe. Bitte versuchen Sie erneut, nachdem Sie Seite neu geladen haben.
|
||||
|
||||
LmsOrphans: Verwaiste Logins
|
||||
LmsOrphanNr n@Int: #{n} verwaiste E‑Learning Logins für diese Qualifikation erkannt.
|
||||
LmsOrphanSeenFirst: Zuerst erkannt
|
||||
LmsOrphanSeenLast: Zuletzt erhalten
|
||||
LmsOrphanDeletedLast: Zuletzt Löschung beantragt
|
||||
LmsOrphanReason: Bemerkung
|
||||
LmsOrphanPreviewFltr: Löschungen bei nächstem Abruf anfordern?
|
||||
@ -1,26 +1,30 @@
|
||||
# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25 Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
QualificationShort: Shorthand
|
||||
QualificationName: Qualification
|
||||
QualificationDescription: Description
|
||||
QualificationValidReason qsh: #{qsh} Validity
|
||||
QualificationValidIndicator: Validity
|
||||
QualificationValidDuration: Validity period
|
||||
QualificationAuditDuration: Audit log retention period
|
||||
QualificationAuditDurationTooltip n@Int: Optional period for deletion of e‑learning data. Note that the e‑learning server may delete its anonymised data earlier, at most #{n} days after closing.
|
||||
QualificationAuditDurationReuseError: This qualification reuses the e‑learning from another qualification, which has no audit duration configured.
|
||||
QualificationAuditDurationTooltip: Days for deletion of e‑learning data. Note that the e‑learning server may delete its anonymised data earlier.
|
||||
QualificationAuditDurationReuseInfo: E‑learning audit log retention period ignore, since the e‑learning from another qualification is reused.
|
||||
QualificationRefreshWithin: Refresh within
|
||||
QualificationRefreshWithinTooltip: Optional period before expiry to send a notification by email. If e‑learning is set to start automatically, it will be started and e‑learning credentials are send with this notification by post or email.
|
||||
QualificationRefreshReminder: Second reminder
|
||||
QualificationRefreshReminderTooltip: Optional period before expiry to send a second notification by post or email once more, including the existing credentials, provided that the e‑learning is still undecided and the qualification has not yet expired.
|
||||
QualificationElearningStart: Is e‑learning automatically started?
|
||||
QualificationElearningRenew: Does successful e‑learning automatically extend a qualification by the default validity period?
|
||||
QualificationElearningLimit: Is the number of e‑learning attempts limited?
|
||||
QualificationElearningLimit: Limit of e‑learning attempts
|
||||
QualificationElearningLimitExplain: Is the number of e‑learning attempts limited?
|
||||
QualificationElearningLimitMax n: #{n} attempts maximum
|
||||
QualificationElearningNoLimit: No limit
|
||||
QualificationExpiryNotification: Invalidity notification?
|
||||
QualificationExpiryNotificationTooltip: Qualification holder are notfied upon invalidity, provided they have activated such notification in their user settings.
|
||||
QualificationExpiryNotification: Notification upon invalidation?
|
||||
QualificationExpiryNotificationTooltip: Qualification holder are notfied upon invalidation, provided they have not deactivated such notification in their user settings.
|
||||
QualificationAvsLicence: AVS Qualification
|
||||
QualificationSapId: SAP Qualification Id
|
||||
TableQualificationCountActive: Active
|
||||
TableQualificationCountActiveTooltip: Number of currently valid qualification holders
|
||||
TableQualificationCountTotal: Total
|
||||
@ -67,10 +71,10 @@ TableLmsStaff: Staff?
|
||||
TableLmsStarted: Started
|
||||
TableLmsReceived: Last update
|
||||
TableLmsNotified: Notification sent
|
||||
TableLmsNotifiedTooltip: Notfications are not sent before the LMS acknowledges the opening of the e‑learning course type for the user, which may take several hours!
|
||||
TableLmsNotifiedTooltip: Notfications are not sent before the LMS acknowledges the opening of the e‑learning course category for the user, which may take several hours!
|
||||
TableLmsEnded: Ended
|
||||
TableLmsStatus: Status e‑learning
|
||||
TableLmsStatusTooltip mbMonth: Shows #{maybeToMessage "for up to " (fmap (flip pluralENsN "month") mbMonth) " after closure"} the last e#{nonBreakableDash}learning status change:
|
||||
TableLmsStatusTooltip n: Shows for up to #{pluralENsN n "day"} after closure the last e#{nonBreakableDash}learning status change:
|
||||
TableLmsStatusDay: Date of last e‑learning status change
|
||||
TableLmsSuccess: Completed
|
||||
TableLmsLock: Locked
|
||||
@ -80,6 +84,7 @@ LmsStatusExpired: Failed due to expiry
|
||||
LmsStatusSuccess: Passed
|
||||
LmsStatusPlanned: E#{nonBreakableDash}learning is about to be opened soon (visible to Admins only)
|
||||
LmsStatusDelay: Note that status changes may occassionaly require more than a hour to be displayed here.
|
||||
FilterLmsLongValid: Long-term valid
|
||||
FilterLmsValid: Currently valid
|
||||
FilterLmsRenewal: Renewal due
|
||||
FilterLmsNotified: Notified
|
||||
@ -116,7 +121,7 @@ QualificationActBlock: Revoke
|
||||
QualificationActUnblock: Clear revocation
|
||||
QualificationActRenew: Renew qualification
|
||||
QualificationActGrant: Grant qualification
|
||||
QualificationActGrantWarning: Use with caution in rare exceptional cases only! Any revocation will be undone.
|
||||
QualificationActGrantWarning: Use with caution in rare exceptional cases only! Any revocation will be undone; any e‑learning terminated
|
||||
QualificationActStartELearning: Manually (re)start e‑learning for valid qualification holders
|
||||
QualificationActStartELearningStatus l n m: E‑learning #{l} (re)started for #{n}/#{m} users. Note: It may take a while, until the e‑learning is activated.
|
||||
QualificationStatusBlock l n m: #{n}/#{m} #{l} revoked
|
||||
@ -126,7 +131,6 @@ LmsRenewalInstructions: Instruction on how to accomplish the renewal are enclose
|
||||
LmsNoRenewal: Unfortunately, this particular qualification cannot be renewed through e‑learning only. Please contact us, if you do not yet know how to renew this qualification. Ignore this automatically generated reminder email, if you have made arrangements for the renewal of this qualification already.
|
||||
LmsRenewalReminder: Reminder
|
||||
LmsActNotify: Resend e‑learning notification by post or email
|
||||
LmsActRenewPin: Randomly replace e‑learning password
|
||||
LmsActRenewNotify: Randomly replace e‑learning password and re-send notification by post or email
|
||||
LmsActReset: Reset and unlock e‑learning
|
||||
LmsActResetInfo: E‑learning login, password and progress remain unchanged; a notification is thus not necessary. This is only possible for already failed learners. Note that the reset procedure may take up to 2 hours.
|
||||
@ -135,7 +139,12 @@ LmsActRestart: Restart e‑learning
|
||||
LmsActRestartWarning: The existing e‑learning will be erased immediately! For drivers with a valid licence, user and password will later be generated anew and a notification will be queued as usual, which may take several hours.
|
||||
LmsActRestartExtend: Ensure validity for the next # days
|
||||
LmsActRestartUnblock: Undo any revocations
|
||||
LmsActRestartFeedback n@Int m@Int: #{n}/#{m} e-learnings were completely restarted with new login credentials.
|
||||
LmsActRestartFeedback n m: #{n}/#{m} e-learnings were completely restarted with new login credentials.
|
||||
LmsActTerminate: Abort e‑learning
|
||||
LmsActTerminateInfo: E‑learning may restart later, if a valid qualification is about to expire and e-learning starting automatically for this qualification.
|
||||
LmsActTerminateFeedback n m: #{n}/#{m} e‑learnings marked for termination.
|
||||
LmsActTerminated n: #{n} e‑learnings were terminated.
|
||||
LmsActTerminateWarning: WARNING: Results will be discarded without warning if a user completes their e-learning in the meantime, before the deletion became effective on the e‑learning server.
|
||||
LmsStateOpen: E‑learning open
|
||||
LmsStatusLocked: E‑learning locked, may be opened soon
|
||||
LmsStatusUnlocked: E‑learning still open, may be locked soon
|
||||
@ -147,3 +156,18 @@ LmsActionFailed n: No action for #{n} #{pluralENs n "person"}, since there was n
|
||||
LmsStarted: E‑learning open since
|
||||
BtnLmsEnqueue: Enqueue users with expiring qualifications for e‑learning and notify them
|
||||
BtnLmsDequeue: Dequeue users with finished e‑learning and notify failed users
|
||||
|
||||
QualificationEditNote: Changes are effective immediately. Please double check that all settings are correct before submitting the changes!
|
||||
QualificationCreated qsh@Text: Qualification #{qsh} created.
|
||||
QualificationEdit qsh@Text: Qualification #{qsh} edited.
|
||||
QualFormErrorDuplShort qsh@Text: There already exists a qualification with shorthand #{qsh}!
|
||||
QualFormErrorDuplName qname@Text: There already exists a qualification with name #{qname}!
|
||||
QualFormErrorSshMismatch: Qualification edit form department mismatch. Please try again after reloading the page.
|
||||
|
||||
LmsOrphans: Orphaned logins
|
||||
LmsOrphanNr n@Int: #{n} orphaned e‑learning login detected for this qualification.
|
||||
LmsOrphanSeenFirst: First seen
|
||||
LmsOrphanSeenLast: Last seen
|
||||
LmsOrphanDeletedLast: Deletion requested
|
||||
LmsOrphanReason: Note
|
||||
LmsOrphanPreviewFltr: Deletion request next synch?
|
||||
|
||||
@ -40,4 +40,6 @@ SchoolAuthorshipStatementSheetDefinitionTip: Bitte in sowohl deutscher als auch
|
||||
SchoolAuthorshipStatementSheetExamDefinition: Eigenständigkeitserklärung für prüfungszugehörige Übungsblattabgaben
|
||||
SchoolAuthorshipStatementSheetExamDefinitionTip: Bitte in sowohl deutscher als auch englischer Sprache angeben.
|
||||
SchoolAuthorshipStatementSheetAllowOther: Abweichende Eigenständigkeitserklärungen für nicht-prüfungszugehörige Übungsblätter erlauben?
|
||||
SchoolAuthorshipStatementSheetExamAllowOther: Abweichende Eigenständigkeitserklärungen für prüfungszugehörige Übungsblätter erlauben?
|
||||
SchoolAuthorshipStatementSheetExamAllowOther: Abweichende Eigenständigkeitserklärungen für prüfungszugehörige Übungsblätter erlauben?
|
||||
|
||||
DailyActDummy: Platzhalter ohne Funktion
|
||||
@ -26,7 +26,7 @@ SchoolCreated ssh: Successfully created #{ssh}
|
||||
SchoolExists ssh: A department named „#{ssh}“ already exists
|
||||
SchoolAdmin: Admin
|
||||
SchoolLecturer: Lecturer
|
||||
SchoolEvaluation: Course type evaluation
|
||||
SchoolEvaluation: Course category evaluation
|
||||
SchoolExamOffice: Exam office
|
||||
|
||||
SchoolAuthorshipStatementSection: Statements of Authorship
|
||||
@ -40,4 +40,6 @@ SchoolAuthorshipStatementSheetDefinitionTip: Please enter both german and englis
|
||||
SchoolAuthorshipStatementSheetExamDefinition: Statement of Authorship for exam-related exercise sheets
|
||||
SchoolAuthorshipStatementSheetExamDefinitionTip: Please enter both german and english statements.
|
||||
SchoolAuthorshipStatementSheetAllowOther: Allow adaptations for exam-unrelated exercise sheets?
|
||||
SchoolAuthorshipStatementSheetExamAllowOther: Allow adaptations for exam-related exercise sheets?
|
||||
SchoolAuthorshipStatementSheetExamAllowOther: Allow adaptations for exam-related exercise sheets?
|
||||
|
||||
DailyActDummy: Placholder without function
|
||||
@ -9,17 +9,17 @@ MailCorrectionsTitle: Assigned corrections
|
||||
|
||||
#correctionsNotDistributed.hs + templates
|
||||
MailSubjectSubmissionsUnassigned csh sheetName: Corrections for #{sheetName} of #{csh} could not be distributed
|
||||
MailSubmissionsUnassignedIntro n courseName termDesc sheetName: #{n} corrections for #{sheetName} of the course type #{courseName} (#{termDesc}) could not be automatically distributed.
|
||||
MailSubmissionsUnassignedIntro n courseName termDesc sheetName: #{n} corrections for #{sheetName} of the course category #{courseName} (#{termDesc}) could not be automatically distributed.
|
||||
|
||||
#courseRegistered.hs + templates
|
||||
MailSubjectCourseRegistered csh: You were enrolled for #{csh}
|
||||
MailSubjectCourseRegisteredOther displayName csh: #{displayName} was enrolled for #{csh}
|
||||
MailCourseRegisteredIntro courseName termDesc: You were enrolled for the course type “#{courseName}” (#{termDesc})
|
||||
MailCourseRegisteredIntroOther displayName courseName termDesc: #{displayName} was enrolled for the course type “#{courseName}” (#{termDesc}).
|
||||
MailCourseRegisteredIntro courseName termDesc: You were enrolled for the course category “#{courseName}” (#{termDesc})
|
||||
MailCourseRegisteredIntroOther displayName courseName termDesc: #{displayName} was enrolled for the course category “#{courseName}” (#{termDesc}).
|
||||
|
||||
#examActive.hs + templates
|
||||
MailSubjectExamRegistrationActive csh examn: Registration is now allowed for #{examn} of #{csh}
|
||||
MailExamRegistrationActiveIntro courseName termDesc examn: You may now register for #{examn} of the course type #{courseName} (#{termDesc}).
|
||||
MailExamRegistrationActiveIntro courseName termDesc examn: You may now register for #{examn} of the course category #{courseName} (#{termDesc}).
|
||||
MailSubjectExamRegistrationSoonInactive csh examn: The registration period for #{examn} of #{csh} ends shortly
|
||||
MailExamRegistrationSoonInactiveIntro courseName termDesc examn: Soon you will no longer be allowed to register for #{examn} of #{courseName} (#{termDesc}).
|
||||
MailSubjectExamDeregistrationSoonInactive csh examn: Deregistration for #{examn} in #{csh} ends shortly
|
||||
@ -27,15 +27,15 @@ MailExamDeregistrationSoonInactiveIntro courseName termDesc examn: Soon you will
|
||||
|
||||
#examOffice.hs + templates
|
||||
MailSubjectExamOfficeExamResults coursen examn: Results for #{examn} of #{coursen} are now available
|
||||
MailExamOfficeExamResultsIntro courseName termDesc examn: A course administrator has made the results for #{examn} of the course type #{courseName} (#{termDesc}) available.
|
||||
MailExamOfficeExamResultsIntro courseName termDesc examn: A course administrator has made the results for #{examn} of the course category #{courseName} (#{termDesc}) available.
|
||||
MailSubjectExamOfficeExamResultsChanged coursen examn: Results for #{examn} of #{coursen} were changed
|
||||
MailExamOfficeExamResultsChangedIntro courseName termDesc examn: A course administrator has changed exam results for #{examn} of the course type #{courseName} (#{termDesc}).
|
||||
MailExamOfficeExamResultsChangedIntro courseName termDesc examn: A course administrator has changed exam results for #{examn} of the course category #{courseName} (#{termDesc}).
|
||||
MailSubjectExamOfficeExternalExamResults coursen@CourseName examn@ExamName: Results for #{examn} in #{coursen}
|
||||
MailExamOfficeExternalExamResultsIntro coursen@CourseName termDesc@Text examn@ExamName: A course administrator has changed or initially made available the results for #{examn} of the course type {coursen} (#{termDesc}).
|
||||
MailExamOfficeExternalExamResultsIntro coursen@CourseName termDesc@Text examn@ExamName: A course administrator has changed or initially made available the results for #{examn} of the course category {coursen} (#{termDesc}).
|
||||
|
||||
#examOffice.hs + templates
|
||||
MailSubjectExamResult csh examn: Results for #{examn} in #{csh} are now available
|
||||
MailExamResultIntro courseName termDesc examn: You may now view your result for #{examn} of the course type #{courseName} (#{termDesc}).
|
||||
MailExamResultIntro courseName termDesc examn: You may now view your result for #{examn} of the course category #{courseName} (#{termDesc}).
|
||||
|
||||
#sheetActive.hs + templates
|
||||
MailSubjectSheetActive csh sheetName: #{sheetName} in #{csh} was released
|
||||
@ -47,10 +47,10 @@ MailSheetSolutionIntro courseName termDesc sheetName: You may now download the s
|
||||
|
||||
#sheetInactive.hs + templates
|
||||
MailSubjectSheetSoonInactive csh sheetName: The submission period for #{sheetName} of #{csh} ends shortly
|
||||
MailSheetSoonInactiveIntro courseName termDesc sheetName: Soon you will no longer be allowed to submit for #{sheetName} of the course type #{courseName} (#{termDesc}).
|
||||
MailSheetSoonInactiveIntro courseName termDesc sheetName: Soon you will no longer be allowed to submit for #{sheetName} of the course category #{courseName} (#{termDesc}).
|
||||
MailSubjectSheetInactive csh sheetName: The submission period for #{sheetName} of #{csh} has ended
|
||||
MailSheetInactiveIntro courseName termDesc sheetName n num: The submission period for #{sheetName} of the course type #{courseName} (#{termDesc}) has ended. #{noneOneMoreEN num "" "One participant" (toMessage num <> " participants")}#{noneOneMoreEN n "" "" (" made " <> toMessage num)}#{noneOneMoreEN n "There were no submissions" " made one submission" " submissions"}.
|
||||
MailSheetInactiveIntroNoUserSubmission courseName termDesc sheetName n num: The submission period for #{sheetName} of the course type #{courseName} (#{termDesc}) has ended. #{noneOneMoreEN num "" "One participant already" (toMessage num <> " participants already")}#{noneOneMoreEN n "" "" (" made " <> toMessage num)}#{noneOneMoreEN n "" " made one submission" " submissions"}.
|
||||
MailSheetInactiveIntro courseName termDesc sheetName n num: The submission period for #{sheetName} of the course category #{courseName} (#{termDesc}) has ended. #{noneOneMoreEN num "" "One participant" (toMessage num <> " participants")}#{noneOneMoreEN n "" "" (" made " <> toMessage num)}#{noneOneMoreEN n "There were no submissions" " made one submission" " submissions"}.
|
||||
MailSheetInactiveIntroNoUserSubmission courseName termDesc sheetName n num: The submission period for #{sheetName} of the course category #{courseName} (#{termDesc}) has ended. #{noneOneMoreEN num "" "One participant already" (toMessage num <> " participants already")}#{noneOneMoreEN n "" "" (" made " <> toMessage num)}#{noneOneMoreEN n "" " made one submission" " submissions"}.
|
||||
MailSheetInactivePseudonymsCount n: The number of submissions above accounts only for the submissions already made directly in FRADrive. #{n} #{pluralEN n "pseudonym was" "pseudonyms were"} generated.
|
||||
MailSheetInactiveParticipantsCount n: There #{pluralEN n "is" "are"} currently #{n} #{pluralEN n "participant" "participants"} registered for the course.
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ AuthTagAdmin: User is administrator
|
||||
AuthTagExamOffice: User is part of an exam office
|
||||
AuthTagSystemExamOffice: User is charged with system wide exam administration
|
||||
AuthTagSystemPrinter: User is responsible for system wide letter printing
|
||||
AuthTagEvaluation: User is charged with course type evaluation
|
||||
AuthTagEvaluation: User is charged with course category evaluation
|
||||
AuthTagToken: User is presenting an authorisation-token
|
||||
AuthTagNoEscalation: User permissions are not being expanded to other departments
|
||||
AuthTagDeprecated: Page is not deprecated
|
||||
@ -26,7 +26,7 @@ AuthTagTutor: User is instructor
|
||||
AuthTagTutorControl: Instructors have control over their course
|
||||
AuthTagTime: Time restrictions are fulfilled
|
||||
AuthTagStaffTime: Time restrictions for teaching staff are fulfilled
|
||||
AuthTagCourseTime: Time restrictions for course type visibility are fulfilled
|
||||
AuthTagCourseTime: Time restrictions for course category visibility are fulfilled
|
||||
AuthTagCourseRegistered: User is enrolled in course
|
||||
AuthTagTutorialRegistered: User is course participant
|
||||
AuthTagExamRegistered: User is exam participant
|
||||
@ -37,11 +37,11 @@ AuthTagParticipant: User participates in course
|
||||
AuthTagRegisterGroup: User is not participant in any course of the same registration group
|
||||
AuthTagCapacity: Capacity is sufficient
|
||||
AuthTagEmpty: Resource is “empty”
|
||||
AuthTagMaterials: Course type material is publicly accessable
|
||||
AuthTagMaterials: Course category material is publicly accessable
|
||||
AuthTagOwner: User is owner
|
||||
AuthTagPersonalisedSheetFiles: User has been assigned personalised sheet files
|
||||
AuthTagRated: Submission is marked
|
||||
AuthTagUserSubmissions: Submissions are made by course type participants
|
||||
AuthTagUserSubmissions: Submissions are made by course category participants
|
||||
AuthTagCorrectorSubmissions: Submissions are registered by correctors
|
||||
AuthTagCorrectionAnonymous: Correction is anonymised
|
||||
AuthTagSelf: User is only accessing their only data
|
||||
|
||||
@ -31,7 +31,7 @@ DownloadFilesTip: When set, files are automatically treated as downloads. Otherw
|
||||
WarningDays: Deadline-preview
|
||||
WarningDaysTip: How many days ahead should deadlines regarding exams etc. be displayed on the homepage?
|
||||
ShowSex: Show sex of other users
|
||||
ShowSexTip: Should users' sex be displayed in (among others) lists of course type participants?
|
||||
ShowSexTip: Should users' sex be displayed in (among others) lists of course category participants?
|
||||
|
||||
PDFPassword: Password to lock PDF email attachments
|
||||
PDFPasswordTip: Please note that this password is displayed to FRADrive admins and is saved unencrypted
|
||||
@ -53,14 +53,14 @@ UserSchoolsTip: You will only receive department-wide notifications for the sele
|
||||
NotificationSettings: Desired notifications
|
||||
|
||||
NotificationTriggerKindAll: For all users
|
||||
NotificationTriggerKindCourseParticipant: For course type participants
|
||||
NotificationTriggerKindCourseParticipant: For course category participants
|
||||
NotificationTriggerKindExamParticipant: For exam participants
|
||||
NotificationTriggerKindCorrector: For correctors
|
||||
NotificationTriggerKindLecturer: For course administrators
|
||||
NotificationTriggerKindCourseLecturer: For course administrators
|
||||
NotificationTriggerKindAdmin: For administrators
|
||||
NotificationTriggerKindExamOffice: For the exam office
|
||||
NotificationTriggerKindEvaluation: For course type evaluations
|
||||
NotificationTriggerKindEvaluation: For course category evaluations
|
||||
NotificationTriggerKindSubmissionUser: For participants in an exercise sheet submission
|
||||
|
||||
NotificationTriggerSubmissionRatedGraded: My submission for an exercise sheet was marked (not purely informational)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -19,6 +19,7 @@ ProfileSubmissionGroups: Abgabegruppen
|
||||
ProfileSubmissions: Abgaben
|
||||
ProfileRemark: Hinweis
|
||||
ProfileQualifications: Eigene Qualifikationen
|
||||
ProfileEnrolledExams: Angemeldete Prüfungen
|
||||
PersonalInfoExamAchievementsWip: Die Anzeige von Prüfungsergebnissen wird momentan an dieser Stelle leider noch nicht unterstützt.
|
||||
PersonalInfoOwnTutorialsWip: Die Anzeige von Kurse, zu denen Sie als Ausbilder eingetragen sind wird momentan an dieser Stelle leider noch nicht unterstützt.
|
||||
PersonalInfoTutorialsWip: Die Anzeige von Kurse, zu denen Sie angemeldet sind wird momentan an dieser Stelle leider noch nicht unterstützt.
|
||||
@ -37,5 +38,6 @@ ProfileSuperviseeRemark n@Int m@Int: Dieser Nutzer ist Ansprechpartner für #{n}
|
||||
UserTelephone: Telefon
|
||||
UserMobile: Mobiltelefon
|
||||
Company: Firmenzugehörigkeit
|
||||
CompanyPersonalNumber: Personalnummer (nur Fraport AG)
|
||||
CompanyPersonalNumber: Personalnummer
|
||||
CompanyPersonalNumberFraport: Personalnummer (nur Fraport AG)
|
||||
CompanyDepartment: Abteilung
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25 Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -11,7 +11,7 @@ LastLogin: Last login
|
||||
NeverSet: Never
|
||||
ProfileCorrector: Corrector
|
||||
ProfileCourses: Own courses
|
||||
ProfileCourseParticipations: Course type registrations
|
||||
ProfileCourseParticipations: Course category registrations
|
||||
ProfileCourseExamResults: Exam achievements
|
||||
ProfileTutorials: Own courses
|
||||
ProfileTutorialParticipations: Courses
|
||||
@ -19,6 +19,7 @@ ProfileSubmissionGroups: Submission groups
|
||||
ProfileSubmissions: Submissions
|
||||
ProfileRemark: Remarks
|
||||
ProfileQualifications: Owned Qualifications
|
||||
ProfileEnrolledExams: Enrolled Exams
|
||||
PersonalInfoExamAchievementsWip: The feature to display your exam achievements has not yet been implemented.
|
||||
PersonalInfoOwnTutorialsWip: The feature to display courses you have been assigned to as instructor has not yet been implemented.
|
||||
PersonalInfoTutorialsWip: The feature to display courses you have registered for has not yet been implemented.
|
||||
@ -36,6 +37,7 @@ ProfileSuperviseeRemark n m: This person supervises #{pluralENsN n "person"}#{no
|
||||
|
||||
UserTelephone: Phone
|
||||
UserMobile: Mobile
|
||||
Company: Company affilitaion
|
||||
CompanyPersonalNumber: Personnel number (Fraport AG only)
|
||||
Company: Company affiliation
|
||||
CompanyPersonalNumber: Personnel number
|
||||
CompanyPersonalNumberFraport: Personnel number (Fraport AG only)
|
||||
CompanyDepartment: Department
|
||||
@ -43,6 +43,7 @@ SynchroniseAvsAllUsersQueued n@Int64: AVS-Synchronisation von allen #{n} #{plura
|
||||
SynchroniseUserdbUserQueued n@Int: Benutzerdatenbank-Synchronisation von #{n} #{pluralDE n "Benutzer:in" "Benutzer:innen"} angestoßen, die Ausführung wird mehrere Minuten benötigen!
|
||||
SynchroniseUserdbAllUsersQueued: Benutzerdatenbank-Synchronisation von allen Benutzer:innen angestoßen, die Ausführung kann eine Weile brauchen!
|
||||
UserListTitle: Komprehensive Benutzerliste
|
||||
UserRecipientsTitle name@Text: Benachrichtigungsempfänger für #{name}
|
||||
AccessRightsSaved: Berechtigungen erfolgreich verändert
|
||||
AccessRightsNotChanged: Berechtigungen wurden nicht verändert
|
||||
AuthLDAPLookupFailed: Nutzer:in konnte aufgrund eines LDAP-Fehlers nicht nachgeschlagen werden
|
||||
@ -96,7 +97,7 @@ UserHijack: Sitzung übernehmen
|
||||
UserAddSupervisor: Ansprechpartner hinzufügen
|
||||
UserSetSupervisor: Ansprechpartner ersetzen
|
||||
UserRemoveSupervisor: Alle Ansprechpartner entfernen
|
||||
UserRemoveSubordinates: Alle Ansprechpartnerbeziehungen zu Untergebenen beenden
|
||||
UserRemoveClients: Alle Ansprechpartnerbeziehungen zu Klienten beenden
|
||||
UserIsSupervisor: Ist Ansprechpartner
|
||||
UserAvsSwitchCompany: Als Primärfirma verwenden
|
||||
UserAvsSwitchCompanyField: Primärfirma auswählen
|
||||
@ -109,11 +110,12 @@ Name !ident-ok: Name
|
||||
UsersChangeSupervisorsSuccess usr@Int spr@Int: #{tshow spr} Ansprechpartner für #{tshow usr} Benutzer gesetzt.
|
||||
UsersChangeSupervisorsWarning usr@Int spr@Int bad@Int: Nur _{MsgUsersChangeSupervisorsSuccess usr spr} #{tshow bad} Ansprechpartner #{pluralDE bad "wurde" "wurden"} nicht gefunden!
|
||||
UsersRemoveSupervisors usr@Int: Alle Ansprechpartner für #{tshow usr} Benutzer gelöscht.
|
||||
UsersRemoveSubordinates usr@Int: Alle Ansprechpartnerbeziehungen für #{tshow usr} #{pluralDE usr "ehemaligen" "ehemalige"} Ansprechpartner gelöscht.
|
||||
UsersRemoveClients usr@Int: Alle Ansprechpartnerbeziehungen für #{tshow usr} #{pluralDE usr "ehemaligen" "ehemalige"} Ansprechpartner gelöscht.
|
||||
UserCompanyReason: Begründung der Firmenassoziation
|
||||
UserCompanyReasonTooltip: Optionale Notiz für besondere Fälle. Kann ggf. autmatische Entfernung bei AVS Firmenwechsel verhindern.
|
||||
UserSupervisorReason: Begründung Ansprechpartner
|
||||
UserSupervisorReasonTooltip: Optionale Notiz für besondere Fälle. Kann ggf. autmatische Entfernung bei AVS Firmenwechsel verhindern.
|
||||
UserSupervisorCompany: Ansprechpartner wegen Firma
|
||||
AdminUserAllNotifications: Alle Benachrichtigungen and diesen Benutzer
|
||||
AdminUserAuthentication: Authentification
|
||||
AdminUserAuthLastSync: Zuletzt synchronisiert
|
||||
|
||||
@ -43,6 +43,7 @@ SynchroniseAvsAllUsersQueued n: Triggered AVS synchronisation of all #{n} #{plur
|
||||
SynchroniseUserdbUserQueued n: Triggered user database synchronisation of #{n} #{pluralEN n "user" "users"}, which may take several minutes to complete.
|
||||
SynchroniseUserdbAllUsersQueued: Triggered user database synchronisation of all users, which may take quite a while to complete.
|
||||
UserListTitle: Comprehensive list of users
|
||||
UserRecipientsTitle name: Notificationrecipients for #{name}
|
||||
AccessRightsSaved: Successfully updated permissions
|
||||
AccessRightsNotChanged: Permissions left unchanged
|
||||
AuthLDAPLookupFailed: User could not be looked up due to a LDAP error
|
||||
@ -96,7 +97,7 @@ UserHijack: Hijack session
|
||||
UserAddSupervisor: Add supervisor
|
||||
UserSetSupervisor: Replace supervisors
|
||||
UserRemoveSupervisor: Set to unsupervised
|
||||
UserRemoveSubordinates: Remove all subordinates
|
||||
UserRemoveClients: Remove all clients
|
||||
UserIsSupervisor: Is supervisor
|
||||
UserAvsSwitchCompany: Use as primary company
|
||||
UserAvsSwitchCompanyField: Select primary company
|
||||
@ -109,11 +110,12 @@ Name: Name
|
||||
UsersChangeSupervisorsSuccess usr spr: #{pluralENsN spr "supervisor"} for #{pluralENsN usr "user"} set.
|
||||
UsersChangeSupervisorsWarning usr spr bad: Only _{MsgUsersChangeSupervisorsSuccess usr spr} #{pluralENsN bad "supervisors"} could not be identified!
|
||||
UsersRemoveSupervisors usr: Removed all supervisors for #{pluralENsN usr "user"}.
|
||||
UsersRemoveSubordinates usr: Removed all subordinates for #{pluralENsN usr "previous supervisor"}.
|
||||
UsersRemoveClients usr: Removed all clients for #{pluralENsN usr "previous supervisor"}.
|
||||
UserCompanyReason: Reason for company association
|
||||
UserCompanyReasonTooltip: Optional note for special cases. In some case this may prevent automatic removel upon AVS user company changes.
|
||||
UserSupervisorReason: Reason for supervision
|
||||
UserSupervisorReasonTooltip: Optional note for special cases. In some case this may prevent automatic removel upon AVS user company changes.
|
||||
UserSupervisorCompany: Supervisor for company
|
||||
AdminUserAllNotifications: All notification sent to this user
|
||||
|
||||
AdminUserAuthentication: Authentifizierung
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#messages or constructors that are used all over the code
|
||||
|
||||
Logo !ident-ok: FRADrive
|
||||
LdapIdentificationOrEmail: Fraport AG-Kennung / E-Mail-Adresse
|
||||
EmailInvitationWarning: Diese Adresse konnte keinem FRADrive-Benutzer/-Benutzerin zugeordnet werden. Es wird eine Einladung per E-Mail versandt.
|
||||
BoolIrrelevant !ident-ok: —
|
||||
FieldPrimary: Hauptfach
|
||||
@ -13,7 +14,8 @@ MultiEmailFieldTip: Es sind mehrere, Komma-separierte, E-Mail-Adressen möglich
|
||||
MultiSelectTip: Mehrfachauswahl und Abwählen mit Strg-Klick
|
||||
WeekDay: Wochentag
|
||||
Hours: Stunden
|
||||
LdapIdentificationOrEmail: Fraport AG-Kennung / E-Mail-Adresse
|
||||
SomeMonths: Monate
|
||||
SomeDays: Tage
|
||||
Months num@Int64: #{num} #{pluralDE num "Monat" "Monate"}
|
||||
Days num@Int64: #{num} #{pluralDE num "Tag" "Tage"}
|
||||
NoAutomaticUpdateTip: Dieser Wert wurde manuell editiert und wird daher nicht mehr automatisch durch as AVS aktualisiert.
|
||||
@ -31,4 +33,13 @@ PaginationPage: Angzeigte Seite
|
||||
PaginationError: Paginierung Parameter dürfen nicht negativ sein
|
||||
|
||||
NullDeletes: Zum Löschen NULL eingeben.
|
||||
SortPriority: Sortierungspriorität
|
||||
SortPriority: Sortierungspriorität
|
||||
NoProblem: Keine Probleme gefunden
|
||||
Unknown: ist unbekannt
|
||||
UnknownOrNotAllowed: ist unbekannt oder hier nicht erlaubt
|
||||
Ambiguous: ist uneindeutig
|
||||
Action: Aktion
|
||||
For: für
|
||||
Address: Adresse
|
||||
NoContactAddress: Keinerlei Kontaktdaten bekannt!
|
||||
StarKeepsEmptyDeletes: Stern zum Beibehalten, leer lassen zum Löschen
|
||||
@ -5,6 +5,7 @@
|
||||
#messages or constructors that are used all over the Code
|
||||
|
||||
Logo: FRADrive
|
||||
LdapIdentificationOrEmail: Fraport AG-Kennung / email address
|
||||
EmailInvitationWarning: This address could not be matched to any FRADrive user. An invitation will be sent via email.
|
||||
BoolIrrelevant: —
|
||||
FieldPrimary: Major
|
||||
@ -13,7 +14,8 @@ MultiEmailFieldTip: Multiple emails addresses may be specified (comma-separated)
|
||||
MultiSelectTip: Multiple selection and desection via Ctrl-Click
|
||||
WeekDay: Day of the week
|
||||
Hours: Hours
|
||||
LdapIdentificationOrEmail: Fraport AG-Kennung / email address
|
||||
SomeMonths: Months
|
||||
SomeDays: Days
|
||||
Months num: #{num} #{pluralEN num "Month" "Months"}
|
||||
Days num: #{num} #{pluralEN num "Day" "Days"}
|
||||
NoAutomaticUpdateTip: This particular value receives no automatic AVS updates, since it has been edited manually.
|
||||
@ -31,4 +33,13 @@ PaginationPage: Page to show
|
||||
PaginationError: Pagination parameter must not be negative
|
||||
|
||||
NullDeletes: Enter NULL to delete.
|
||||
SortPriority: Sort order priority
|
||||
SortPriority: Sort order priority
|
||||
NoProblem: No Probleme found
|
||||
Unknown: is unknown
|
||||
UnknownOrNotAllowed: is unknown or not allowed here
|
||||
Ambiguous: is ambiguous
|
||||
Action: Action
|
||||
For: for
|
||||
Address: Address
|
||||
NoContactAddress: No contact details known!
|
||||
StarKeepsEmptyDeletes: A star to keep unchanged, blank removes
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-24 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -55,6 +55,8 @@ BtnUserAssimilate: Assimilieren
|
||||
BtnCloseExam: Prüfung abschließen
|
||||
BtnFinishExam: Prüfungsergebnisse sichtbar schalten
|
||||
BtnConfirm: Bestätigen
|
||||
BtnPerform: Ausführen
|
||||
BtnCourseRegisterAdd: Personen suchen
|
||||
BtnCourseRegisterConfirm: Ausgewählte Personen anmelden
|
||||
BtnCourseRegisterAbort: Abbrechen
|
||||
BtnCourseRegisterAbort: Abbrechen
|
||||
BtnCloseReload: Schließen und aktualisieren
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-24 Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -55,6 +55,8 @@ BtnUserAssimilate: Assimilate
|
||||
BtnCloseExam: Close exam
|
||||
BtnFinishExam: Make results visible
|
||||
BtnConfirm: Confirm
|
||||
BtnPerform: Perform
|
||||
BtnCourseRegisterAdd: Search persons
|
||||
BtnCourseRegisterConfirm: Register selected persons
|
||||
BtnCourseRegisterAbort: Abort
|
||||
BtnCourseRegisterAbort: Abort
|
||||
BtnCloseReload: Close and reload
|
||||
@ -20,3 +20,7 @@ ExceptionNoOccurAt: Termin
|
||||
ExceptionKind: Termin ...
|
||||
ExceptionKindOccur: Findet statt
|
||||
ExceptionKindNoOccur: Findet nicht statt
|
||||
DayNext: Folgetag
|
||||
DayPrev: Vortag
|
||||
WeekNext: Nächste Woche
|
||||
WeekPrev: Vorherige Woche
|
||||
|
||||
@ -20,3 +20,7 @@ ExceptionNoOccurAt: Event
|
||||
ExceptionKind: Event ...
|
||||
ExceptionKindOccur: Does occur
|
||||
ExceptionKindNoOccur: Does not occur
|
||||
DayNext: Next day
|
||||
DayPrev: Previous day
|
||||
WeekNext: Next week
|
||||
WeekPrev: Previous week
|
||||
@ -71,6 +71,7 @@ BreadcrumbError: Fehler
|
||||
BreadcrumbUpload !ident-ok: Upload
|
||||
BreadcrumbUserAdd: Benutzer:in anlegen
|
||||
BreadcrumbUserNotifications: Benachrichtigungs-Einstellungen
|
||||
BreadcrumbUserRecipients: Benachrichtigungs-Empfänger
|
||||
BreadcrumbUserPassword: Passwort
|
||||
BreadcrumbAdminHeading !ident-ok: Administration
|
||||
BreadcrumbAdminFeaturesHeading: Studiengänge
|
||||
|
||||
@ -6,7 +6,7 @@ BreadcrumbCsvOptions: csv-options
|
||||
BreadcrumbSubmissionFile: File
|
||||
BreadcrumbSubmissionUserInvite: Invitation to participate in a submission
|
||||
BreadcrumbCryptoIDDispatch: CryptoID-redirect
|
||||
BreadcrumbCourseNotes: Course type notes
|
||||
BreadcrumbCourseNotes: Course category notes
|
||||
BreadcrumbHiWis: Correctors
|
||||
BreadcrumbMaterial: Material
|
||||
BreadcrumbSheet: Exercise sheet
|
||||
@ -14,7 +14,7 @@ BreadcrumbTutorial: Course
|
||||
BreadcrumbExam: Exam
|
||||
BreadcrumbCourseRegister: Register
|
||||
BreadcrumbCourseFavourite: Favourite
|
||||
BreadcrumbCourse: Course type
|
||||
BreadcrumbCourse: Course category
|
||||
BreadcrumbTerm: Year
|
||||
BreadcrumbSchool: Department
|
||||
BreadcrumbUser: User
|
||||
@ -28,11 +28,11 @@ BreadcrumbUserDelete: Delete user account
|
||||
BreadcrumbUserHijack: Hijack user session
|
||||
BreadcrumbSystemMessage: System message
|
||||
BreadcrumbSubmission: Submission
|
||||
BreadcrumbCourseNews: Course type news
|
||||
BreadcrumbCourseNewsDelete: Delete course type news
|
||||
BreadcrumbCourseEventDelete: Delete course type occurrence
|
||||
BreadcrumbCourseNews: Course category news
|
||||
BreadcrumbCourseNewsDelete: Delete course category news
|
||||
BreadcrumbCourseEventDelete: Delete course category occurrence
|
||||
BreadcrumbProfile: Settings
|
||||
BreadcrumbCourseParticipantInvitation: Invitation to be a course type participant
|
||||
BreadcrumbCourseParticipantInvitation: Invitation to be a course category participant
|
||||
BreadcrumbMaterialArchive: Archive
|
||||
BreadcrumbMaterialFile: File
|
||||
BreadcrumbMaterialVideo: Video
|
||||
@ -57,8 +57,8 @@ BreadcrumbExternalExamUsers: Participants
|
||||
BreadcrumbExternalExamGrades: Exam results
|
||||
BreadcrumbExternalExamStaffInvite: Invitation
|
||||
BreadcrumbExternalExamCorrect: Enter exam results
|
||||
BreadcrumbParticipantsList: Lists of course type participants
|
||||
BreadcrumbParticipants: Course type participants
|
||||
BreadcrumbParticipantsList: Lists of course category participants
|
||||
BreadcrumbParticipants: Course category participants
|
||||
BreadcrumbExamAutoOccurrence: Automatic occurrence/room distribution
|
||||
BreadcrumbStorageKey: Generate storage key
|
||||
BreadcrumbMessageHide: Hide
|
||||
@ -71,6 +71,7 @@ BreadcrumbError: Error
|
||||
BreadcrumbUpload: Upload
|
||||
BreadcrumbUserAdd: Add user
|
||||
BreadcrumbUserNotifications: Notification settings
|
||||
BreadcrumbUserRecipients: Notification recipients
|
||||
BreadcrumbUserPassword: Password
|
||||
BreadcrumbAdminHeading: Administration
|
||||
BreadcrumbAdminFeaturesHeading: Features of study
|
||||
@ -97,7 +98,7 @@ BreadcrumbTermShow: Years
|
||||
BreadcrumbTermCreate: Create new year
|
||||
BreadcrumbTermEdit: Edit year
|
||||
BreadcrumbTermCurrent: Current year
|
||||
BreadcrumbParticipantsIntersect: Common course type participants
|
||||
BreadcrumbParticipantsIntersect: Common course category participants
|
||||
BreadcrumbCourseList: Courses
|
||||
BreadcrumbCourseNew: Create new course
|
||||
BreadcrumbCourseEdit: Edit course
|
||||
@ -106,14 +107,14 @@ BreadcrumbCourseAddMembers: Add participants
|
||||
BreadcrumbCourseExamOffice: Exam offices
|
||||
BreadcrumbCorrectionsAssign: Assign corrections
|
||||
BreadcrumbSheetList: Exercise sheets
|
||||
BreadcrumbCourseCommunication: Course type message (email)
|
||||
BreadcrumbCourseCommunication: Course category message (email)
|
||||
BreadcrumbTutorialList: Courses
|
||||
BreadcrumbTutorialNew: Create new course
|
||||
BreadcrumbCourseDelete: Delete course
|
||||
BreadcrumbCourseNewsNew: Add course type news
|
||||
BreadcrumbCourseNewsEdit: Edit course type news
|
||||
BreadcrumbCourseEventNew: New course type occurrence
|
||||
BreadcrumbCourseEventEdit: Edit course type occurrence
|
||||
BreadcrumbCourseNewsNew: Add course category news
|
||||
BreadcrumbCourseNewsEdit: Edit course category news
|
||||
BreadcrumbCourseEventNew: New course category occurrence
|
||||
BreadcrumbCourseEventEdit: Edit course category occurrence
|
||||
BreadcrumbExamList: Exams
|
||||
BreadcrumbExamNew: Create new exam
|
||||
BreadcrumbExamEdit: Edit exam
|
||||
@ -123,7 +124,7 @@ BreadcrumbExamAddMembers: Add exam participants
|
||||
BreadcrumbExamCorrect: Grade exams
|
||||
BreadcrumbTutorialDelete: Delete course
|
||||
BreadcrumbTutorialEdit: Edit course
|
||||
BreadcrumbTutorialComm: Send course type message
|
||||
BreadcrumbTutorialComm: Send course category message
|
||||
BreadcrumbSheetEdit: Edit exercise sheet
|
||||
BreadcrumbSheetDelete: Delete exercise sheet
|
||||
BreadcrumbSubmissions: Submissions
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, David Mosbach <david.mosbach@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, David Mosbach <david.mosbach@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -34,6 +34,7 @@ MenuCourseIcon: Kurse
|
||||
MenuCourseMembers: Kursartteilnehmer:innen
|
||||
MenuCourseAddMembers: Kursartteilnehmer:innen hinzufügen
|
||||
MenuTutorialAddMembers: Kursteilnehmer:innen hinzufügen
|
||||
MenuTutorialExam exn@ExamName: Kursprüfung #{exn} bearbeiten
|
||||
MenuCourseCommunication: Kursartmitteilung (E‑Mail)
|
||||
MenuCourseExamOffice: Prüfungsbeauftragte
|
||||
MenuTermShow: Jahr
|
||||
@ -88,6 +89,7 @@ MenuTutorialComm: Mitteilung an Teilnehmer:innen
|
||||
MenuExamList: Prüfungen
|
||||
MenuExamNew: Neue Prüfung anlegen
|
||||
MenuExamEdit: Prüfung bearbeiten
|
||||
MenuExamEditComplete: Prüfung vollständig überarbeiten
|
||||
MenuExamUsers: Teilnehmer:innen
|
||||
MenuExamGrades: Prüfungsleistungen
|
||||
MenuExamAddMembers: Prüfungsteilnehmer hinzufügen
|
||||
@ -98,6 +100,8 @@ MenuExamOfficeUsers: Benutzer:innen
|
||||
MenuLecturerInvite: Funktionäre hinzufügen
|
||||
MenuSchoolList: Bereiche
|
||||
MenuSchoolNew: Neuen Bereich anlegen
|
||||
MenuSchoolDay ssh@SchoolId d@Text: #{d} #{unSchoolKey ssh} Tagesansicht
|
||||
MenuSchoolDayCheck: Konsistenzprüfung
|
||||
MenuExternalExamGrades: Prüfungsleistungen
|
||||
MenuExternalExamUsers: Teilnehmer:innen
|
||||
MenuExternalExamEdit: Bearbeiten
|
||||
@ -120,8 +124,9 @@ MenuCourseEventEdit: Kursarttermin bearbeiten
|
||||
MenuLanguage: Sprache
|
||||
|
||||
MenuQualifications: Qualifikationen
|
||||
MenuQualificationEdit: Bearbeiten
|
||||
MenuQualificationNew: Neue Qualifikation erstellen
|
||||
MenuLms !ident-ok: E‑Learning
|
||||
MenuLmsEdit: Bearbeiten E‑Learning
|
||||
MenuLmsUser: Benutzerqualifikationen
|
||||
MenuLmsUserSchool: Bereichs Benutzerqualifikationen
|
||||
MenuLmsUserAll: Alle Benutzerqualifikationen
|
||||
@ -137,6 +142,7 @@ MenuFirms: Firmen
|
||||
MenuFirmUsers: Angehörige
|
||||
MenuFirmSupervisors: Ansprechpartner
|
||||
MenuFirmsComm: Mitteilung
|
||||
MenuFirmsSupervision: Probleme Ansprechpartnerbeziehungen
|
||||
|
||||
MenuInterfaces: Schnittstellen
|
||||
MenuSap: SAP Schnittstelle
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, David Mosbach <david.mosbach@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-25-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, David Mosbach <david.mosbach@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -6,7 +6,7 @@ MenuAdminHeading: Administration
|
||||
MenuAdminFeaturesHeading: Features of study
|
||||
MenuInfoLecturerTitle: Information for course administrators
|
||||
MenuInfoLecturerCourses: Courses
|
||||
MenuInfoLecturerExercises: Course type Exercises
|
||||
MenuInfoLecturerExercises: Course category Exercises
|
||||
MenuInfoLecturerTutorials: Courses
|
||||
MenuInfoLecturerExams: Exams
|
||||
MenuCsvOptions: CSV-options
|
||||
@ -29,12 +29,13 @@ MenuAccount: Account
|
||||
MenuProfile: Settings
|
||||
MenuLogin: Login
|
||||
MenuLogout: Logout
|
||||
MenuCourseList: Course types
|
||||
MenuCourseList: Course categorys
|
||||
MenuCourseIcon: Courses
|
||||
MenuCourseMembers: Participants
|
||||
MenuCourseAddMembers: Add course type participants
|
||||
MenuCourseAddMembers: Add course category participants
|
||||
MenuTutorialAddMembers: Add course participants
|
||||
MenuCourseCommunication: Course type message (email)
|
||||
MenuTutorialExam exn@ExamName: Edit course exam #{exn}
|
||||
MenuCourseCommunication: Course category message (email)
|
||||
MenuCourseExamOffice: Exam offices
|
||||
MenuTermShow: Semesters
|
||||
MenuSubmissionDelete: Delete submission
|
||||
@ -49,7 +50,7 @@ MenuAdminErrMsg: Decrypt error message
|
||||
MenuAdminTokens: Issue tokens
|
||||
MenuProfileData: Personal information
|
||||
MenuTermCreate: Create new year
|
||||
MenuCourseNew: Create new course type
|
||||
MenuCourseNew: Create new course category
|
||||
MenuTermEdit: Edit year
|
||||
MenuTermCurrent: Current year
|
||||
MenuCorrection: Correction
|
||||
@ -84,10 +85,11 @@ MenuCorrectionsAssignSheet name: Assign corrections for #{name}
|
||||
MenuAuthPreds: Authorisation settings
|
||||
MenuTutorialDelete: Delete course
|
||||
MenuTutorialEdit: Edit course
|
||||
MenuTutorialComm: Send course type message
|
||||
MenuTutorialComm: Send course category message
|
||||
MenuExamList: Exams
|
||||
MenuExamNew: Create new exam
|
||||
MenuExamEdit: Edit exam
|
||||
MenuExamEditComplete: Revise entire exam
|
||||
MenuExamUsers: Participants
|
||||
MenuExamGrades: Exam results
|
||||
MenuExamAddMembers: Add exam participants
|
||||
@ -98,14 +100,16 @@ MenuExamOfficeUsers: Users
|
||||
MenuLecturerInvite: Add functionaries
|
||||
MenuSchoolList: Departments
|
||||
MenuSchoolNew: Create new department
|
||||
MenuSchoolDay ssh d: #{d} #{unSchoolKey ssh} Agenda
|
||||
MenuSchoolDayCheck: Consistence check
|
||||
MenuExternalExamGrades: Exam results
|
||||
MenuExternalExamUsers: Participants
|
||||
MenuExternalExamEdit: Edit
|
||||
MenuExternalExamNew: New external exam
|
||||
MenuExternalExamList: External exams
|
||||
MenuExternalExamCorrect: Enter exam results
|
||||
MenuParticipantsList: Lists of course type participants
|
||||
MenuParticipantsIntersect: Common course type participants
|
||||
MenuParticipantsList: Lists of course category participants
|
||||
MenuParticipantsIntersect: Common course category participants
|
||||
MenuFaq: FAQ
|
||||
MenuSheetPersonalisedFiles: Download personalised sheet files
|
||||
MenuCourseSheetPersonalisedFiles: Download template for personalised sheet files
|
||||
@ -113,17 +117,18 @@ MenuAdminCrontab: Crontab
|
||||
MenuAdminJobs: Job queue
|
||||
MenuGlossary: Glossary
|
||||
MenuVersion: Version history
|
||||
MenuCourseNewsNew: Add course type news
|
||||
MenuCourseNewsEdit: Edit course type news
|
||||
MenuCourseEventNew: New course type occurrence
|
||||
MenuCourseEventEdit: Edit course type occurrence
|
||||
MenuCourseNewsNew: Add course category news
|
||||
MenuCourseNewsEdit: Edit course category news
|
||||
MenuCourseEventNew: New course category occurrence
|
||||
MenuCourseEventEdit: Edit course category occurrence
|
||||
MenuLanguage: Language
|
||||
|
||||
MenuQualifications: Qualifications
|
||||
MenuQualificationEdit: Edit
|
||||
MenuQualificationNew: Create new qualification
|
||||
MenuLms: E‑learning
|
||||
MenuLmsEdit: Edit e‑learning
|
||||
MenuLmsUser: User Qualifications
|
||||
MenuLmsUserSchool: Institute User Qualifications
|
||||
MenuLmsUserSchool: Department User Qualifications
|
||||
MenuLmsUserAll: All User Qualifications
|
||||
MenuLmsUsers: Legacy download e‑learning users
|
||||
MenuLmsUpload: Upload
|
||||
@ -137,6 +142,7 @@ MenuFirms: Companies
|
||||
MenuFirmUsers: Associates
|
||||
MenuFirmSupervisors: Supervisors
|
||||
MenuFirmsComm: Messaging
|
||||
MenuFirmsSupervision: Problems supervisionship
|
||||
|
||||
MenuInterfaces: Interfaces
|
||||
MenuSap: SAP Interface
|
||||
|
||||
@ -12,8 +12,8 @@ NewsHeading: Aktuelles
|
||||
InfoHeading: Informationen
|
||||
LegalHeading: Rechtliche Informationen
|
||||
VersionHeading: Versionsgeschichte
|
||||
SystemMessageHeading: Uni2work Statusmeldung
|
||||
SystemMessageListHeading: Uni2work Statusmeldungen
|
||||
SystemMessageHeading: FRADrive Statusmeldung
|
||||
SystemMessageListHeading: FRADrive Statusmeldungen
|
||||
HeadingHelpRequest: Supportanfrage/Verbesserungsvorschlag
|
||||
ProfileHeading: Benutzereinstellungen
|
||||
ProfileDataHeading: Gespeicherte Benutzerdaten
|
||||
|
||||
@ -12,8 +12,8 @@ NewsHeading: News
|
||||
InfoHeading: Information
|
||||
LegalHeading: Legal
|
||||
VersionHeading: Version history
|
||||
SystemMessageHeading: Uni2work system message
|
||||
SystemMessageListHeading: Uni2work system message
|
||||
SystemMessageHeading: FRADrive system message
|
||||
SystemMessageListHeading: FRADrive system messages
|
||||
HeadingHelpRequest: Support request/Suggestion
|
||||
ProfileHeading: Settings
|
||||
ProfileDataHeading: Personal information
|
||||
@ -29,8 +29,8 @@ HeadingTermEditTid tid: Edit year #{tid}
|
||||
TermCourseListHeading tid: Courses #{tid}
|
||||
TermSchoolCourseListHeading tid school: Courses #{tid}, #{school}
|
||||
CourseListTitle: All courses
|
||||
CourseNewHeading: Create new course type
|
||||
CourseEditHeading tid ssh csh: Edit course type #{tid}-#{ssh}-#{csh}
|
||||
CourseNewHeading: Create new course category
|
||||
CourseEditHeading tid ssh csh: Edit course category #{tid}-#{ssh}-#{csh}
|
||||
SubmissionsCourse tid ssh csh: All submissions for Course #{tid}-#{ssh}-#{csh}
|
||||
SubmissionsSheet sheetName: Submissions for #{sheetName}
|
||||
SheetList tid ssh csh : #{tid}-#{ssh}-#{csh} Sheet Overview
|
||||
@ -38,7 +38,7 @@ SheetNewHeading tid ssh csh : #{tid}-#{ssh}-#{csh} New Exercise Sheet
|
||||
SheetTitle tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{tid}-#{ssh}-#{csh} #{sheetName}
|
||||
SheetTitleNew tid@TermId ssh@SchoolId csh@CourseShorthand : #{tid}-#{ssh}-#{csh}: New sheet
|
||||
SheetEditHead tid ssh csh sheetName: #{tid}-#{ssh}-#{csh} Edit #{sheetName}
|
||||
SheetDelHead tid ssh csh sheetName: Do you really want to delete sheet #{sheetName} from course type #{tid}-#{ssh}-#{csh}? Any associated submissions and corrections will be lost!
|
||||
SheetDelHead tid ssh csh sheetName: Do you really want to delete sheet #{sheetName} from course category #{tid}-#{ssh}-#{csh}? Any associated submissions and corrections will be lost!
|
||||
SubmissionEditHead tid ssh csh sheetName: #{tid}-#{ssh}-#{csh} #{sheetName}: Edit/Create submission
|
||||
CorrectionHead tid ssh csh sheetName cid: #{tid}-#{ssh}-#{csh} #{sheetName}: Marking
|
||||
CorrectionsTitle: Assigned corrections
|
||||
@ -48,8 +48,8 @@ CorrGrade: Mark submissions
|
||||
TableHeadingCsvImport: CSV import
|
||||
TableHeadingCsvExport: CSV export
|
||||
FavouritesEmptyTip: Your courses and recently visited courses are shown here.
|
||||
FavouritesToggleTip: The display mode for the current course type can be changed between automatic, permanent and never with a click on the star symbol.
|
||||
FavouritesUnavailableTip: Quick Actions for this course type are currently not available.
|
||||
FavouritesToggleTip: The display mode for the current course category can be changed between automatic, permanent and never with a click on the star symbol.
|
||||
FavouritesUnavailableTip: Quick Actions for this course category are currently not available.
|
||||
NavigationFavourites: Favourites
|
||||
ErrorResponseTitleInternalError internalError: An internal error occurred
|
||||
ErrorResponseTitleInvalidArgs invalidArgs: Request contained invalid arguments
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-24 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>, Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -47,12 +47,12 @@ TablePassed: Bestanden
|
||||
TableNotPassed: Nicht bestanden
|
||||
TableTutorialTutors: Ausbilder
|
||||
TableTutorialName: Bezeichnung
|
||||
TableTutorialType: Art
|
||||
TableTutorialRoom: Regulärer Raum
|
||||
TableTutorialType: Typ
|
||||
TableTutorialRoom: Raum
|
||||
TableTutorialRoomHidden: Raum nur für Teilnehmer
|
||||
TableTutorialRoomIsUnset !ident-ok: —
|
||||
TableTutorialRoomIsHidden: Raum wird nur Teilnehmern angezeigt
|
||||
TableTutorialTime: Zeit
|
||||
TableTutorialOccurrence: Termin
|
||||
TableTutorialDeregisterUntil: Abmeldungen bis
|
||||
TableTutorialFirstDay: Starttag
|
||||
TableActionsHead: Aktionen
|
||||
@ -80,6 +80,9 @@ TableCompanyFilter: Firma oder Nummer
|
||||
TableCompanyShort: Firmenkürzel
|
||||
TableCompanies: Firmen
|
||||
TablePrimeCompany: Primäre Firma
|
||||
TablePrimeCompanyShort: Kürzel primäre Firma
|
||||
TableBookingCompany: Buchende Firma
|
||||
TableBookingCompanyShort: Kürzel buchende Firma
|
||||
TableCompanyNo: Firmennummer
|
||||
TableCompanyNos: Firmennummern
|
||||
TableCompanyUser: Firmenangehöriger
|
||||
@ -97,8 +100,10 @@ TableCompanyNrRerouteDefault: Standard Umleitungen
|
||||
TableCompanyNrRerouteActive: Aktive Umleitungen
|
||||
TableRerouteActive: Umleitung
|
||||
TableCompanyPostalPreference: Benachrichtigungspräferenz neue Firmenangehörige
|
||||
TableCompanyPinPassword: Pin Passwort für PDF Anhänge
|
||||
TableSupervisor: Ansprechpartner
|
||||
TableSupervisee: Ansprechpartner für
|
||||
TableSupervisorActive: Aktiver Ansprechpartner
|
||||
TableSupervisee: Klient
|
||||
TableReason: Begründung
|
||||
TableCreationTime: Erstellungszeit
|
||||
TableJob !ident-ok: Job
|
||||
@ -109,10 +114,18 @@ TableJobCreationInstance: Ersteller
|
||||
ActJobDelete: Job entfernen
|
||||
ActJobDeleteForce n@Int: Auch vor #{pluralDEnN n "Minute"} gesperrte Jobs entfernen
|
||||
TableJobActDeleteFeedback n@Int m@Int: #{n}/#{m} Jobs entfernt
|
||||
ActJobSleep: Test Job einreihen
|
||||
JobSleepNr: Anzahl Jobs
|
||||
JobSleepSecs: Laufzeit in Sekunden pro Job
|
||||
JobSleepNow: Prioriäts-Jobs
|
||||
TableJobActSleepFeedback n@Int sec@Int prio@Bool: #{n} #{bool tempty "Prioritäts-" prio}#{pluralDEx 's' n "Job"} mit #{sec}s Laufzeit eingereiht.
|
||||
TableFilterComma: Es können mehrere alternative Suchkriterien mit Komma getrennt angegeben werden, wovon mindestens eines erfüllt werden muss.
|
||||
TableFilterCommaPlus: Mehrere alternative Suchkriterien mit Komma trennen. Mindestens ein Suchkriterium muss erfüllt werden, zusätzlich zu allen Suchkriterien mit vorangestelltem Plus-Symbol.
|
||||
TableFilterCommaPlusShort: Unterstützt mehrere Kriterien mit Komma-Plus, siehe oben.
|
||||
TableFilterCommaName: Mehrere Namen mit Komma trennen.
|
||||
TableFilterCommaNameNr: Mehrere Namen oder Nummern mit Komma trennen. Nummern werden nur exakt gesucht.
|
||||
TableFilterCommaNameNr: Mehrere Namen oder exakte Nummern mit Komma trennen.
|
||||
TableUserEdit: Benutzer bearbeiten
|
||||
TableRows: Zeilen
|
||||
TableRows: Zeilen
|
||||
TableUserParkingToken day@Text: Parkmarke #{day}
|
||||
TableFilterSentBefore: Gesendet bis
|
||||
TableFilterSentAfter: Gesendet ab
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022-24 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>, Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -20,7 +20,7 @@ TableMatrikelNr: AVS person no
|
||||
TableSex: Sex
|
||||
TableBirthday: Birthday
|
||||
TableSchool: Department
|
||||
TableCourse: Course
|
||||
TableCourse: Course category
|
||||
TableCourseMembers: Participants
|
||||
TableExamOccurrence: Occurrence/room
|
||||
TableExamName: Name
|
||||
@ -48,14 +48,14 @@ TableNotPassed: Failed
|
||||
TableTutorialTutors: Instructors
|
||||
TableTutorialName: Name
|
||||
TableTutorialType: Type
|
||||
TableTutorialRoom: Regular room
|
||||
TableTutorialRoom: Room
|
||||
TableTutorialRoomHidden: Room only for participants
|
||||
TableTutorialRoomIsUnset: —
|
||||
TableTutorialRoomIsHidden: Room is only displayed to participants
|
||||
TableTutorialDeregisterUntil: Deregister until
|
||||
TableTutorialFirstDay: Start date
|
||||
TableActionsHead: Actions
|
||||
TableTutorialTime: Time
|
||||
TableTutorialOccurrence: Session
|
||||
TableNoFilter: No restriction
|
||||
TableUserMatriculation: AVS number
|
||||
TableColumnStudyFeatures: Features of study
|
||||
@ -80,6 +80,9 @@ TableCompanyFilter: Company/Nr
|
||||
TableCompanyShort: Company shorthand
|
||||
TableCompanies: Companies
|
||||
TablePrimeCompany: Primary company
|
||||
TablePrimeCompanyShort: Primary company shorthand
|
||||
TableBookingCompany: Booking company
|
||||
TableBookingCompanyShort: Booking company shorthand
|
||||
TableCompanyNo: Company number
|
||||
TableCompanyNos: Company numbers
|
||||
TableCompanyUser: Associate
|
||||
@ -97,8 +100,10 @@ TableCompanyNrRerouteDefault: Default reroutes
|
||||
TableCompanyNrRerouteActive: Active reroutes
|
||||
TableRerouteActive: Reroute
|
||||
TableCompanyPostalPreference: Default notification preference
|
||||
TableCompanyPinPassword: Pin password for PDF attachments
|
||||
TableSupervisor: Supervisor
|
||||
TableSupervisee: Supervisor for
|
||||
TableSupervisorActive: Active supervisor
|
||||
TableSupervisee: Supervisee
|
||||
TableReason: Reason
|
||||
TableCreationTime: Creation
|
||||
TableJob !ident-ok: Job
|
||||
@ -109,10 +114,18 @@ TableJobCreationInstance: Creator
|
||||
ActJobDelete: Delete job
|
||||
ActJobDeleteForce n: Also delete jobs locked #{pluralENsN n "minute"} ago
|
||||
TableJobActDeleteFeedback n@Int m@Int: #{n}/#{m} queued jobs deleted
|
||||
ActJobSleep: Enqueue sleep job
|
||||
JobSleepNr: Number of jobs
|
||||
JobSleepSecs: Seconds per job
|
||||
JobSleepNow: Priority jobs
|
||||
TableJobActSleepFeedback n@Int sec@Int prio@Bool: #{n} #{bool tempty "priority " prio} sleep #{pluralENs n "job"} for #{sec}s enqueued.
|
||||
TableFilterComma: Separate multiple alternative filter criteria by comma, at least one of which must be fulfilled.
|
||||
TableFilterCommaPlus: Separate multiple alternative filter criteria by comma, at least one of which must be fulfilled in addition to all criteria preceded by a plus symbol.
|
||||
TableFilterCommaPlusShort: Support multiple criteria with comma/plus, see above.
|
||||
TableFilterCommaName: Separate names by comma.
|
||||
TableFilterCommaNameNr: Separate names and numbers by comma. Numbers have to match exact.
|
||||
TableFilterCommaNameNr: Separate names and exact numbers by comma.
|
||||
TableUserEdit: Edit user
|
||||
TableRows: Rows
|
||||
TableRows: Rows
|
||||
TableUserParkingToken day: Parking token #{day}
|
||||
TableFilterSentBefore: Sent before
|
||||
TableFilterSentAfter: Sent after
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2023-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Steffen Jost <jost@tcs.ifi.lmu.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>, Sarah Vaupel <sarah.vaupel@ifi.lmu.de>, Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2023-25-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Steffen Jost <jost@tcs.ifi.lmu.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>, Sarah Vaupel <sarah.vaupel@ifi.lmu.de>, Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -81,6 +81,7 @@ MultiUserFieldExplanationAnyUser: Dieses Eingabefeld sucht in den Adressen aller
|
||||
MultiUserFieldInvitationExplanation: An Adressen, die so keinem Uni2work-Benutzer/keiner Uni2work-Benutzerin zugeordnet werden können, wird eine Einladung per E-Mail versandt.
|
||||
MultiUserFieldInvitationExplanationAlways: Es wird an alle Adressen, die Sie hier angeben, eine Einladung per E-Mail versandt.
|
||||
AmbiguousEmail: E-Mail-Adresse nicht eindeutig
|
||||
UnknownEmail: E-Mail-Adresse konnte keinem bekannten Benutzer zugeordnet werden
|
||||
InvalidEmailAddress: E-Mail-Adresse ist ungültig
|
||||
InvalidEmailAddressWith e@Text: E-Mail-Adresse #{show e} ist ungültig
|
||||
MailFileAttachment: Dateianhang
|
||||
@ -91,6 +92,7 @@ UtilExamResultVoided: Entwertet
|
||||
CourseOption tid@TermId ssh@SchoolId csh@CourseShorthand coursen@CourseName !ident-ok: #{tid} - #{ssh} - #{csh}: #{coursen}
|
||||
RoomReferenceNone !ident-ok: —
|
||||
RoomReferenceSimple !ident-ok: Text
|
||||
RoomReferenceSimpleAt r@Text: in Raum #{r}
|
||||
RoomReferenceLink: Link & Anweisungen
|
||||
RoomReferenceSimpleText: Raum
|
||||
RoomReferenceSimpleTextPlaceholder: Raum
|
||||
@ -102,6 +104,7 @@ UtilNoneSet: Keine angegeben
|
||||
UtilEmptyChoice: Auswahl war leer
|
||||
UtilEmptyNoChangeTip: Eine leere Eingabe belässt den vorherigen Wert unverändert.
|
||||
MultiNoSelection: Keine Auswahl
|
||||
MustBePositive: muss positiv sein
|
||||
|
||||
#invitation.hs
|
||||
InvitationAction: Aktion
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
# SPDX-FileCopyrightText: 2023-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Sarah Vaupel <sarah.vaupel@ifi.lmu.de>, Winnie Ros <winnie.ros@campus.lmu.de>, Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2023-25-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Sarah Vaupel <sarah.vaupel@ifi.lmu.de>, Winnie Ros <winnie.ros@campus.lmu.de>, Steffen Jost <jost@tcs.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
#communication.hs
|
||||
RecipientCustom: Custom recipients
|
||||
RGCourseParticipants: Course type participants
|
||||
RGCourseParticipants: Course category participants
|
||||
RGCourseLecturers: Course administrators
|
||||
RGCourseCorrectors: Course type correctors
|
||||
RGCourseCorrectors: Course category correctors
|
||||
RGCourseTutors: Course instructors
|
||||
RGCourseParticipantsInTutorial: Course type participants who are registered for at least one course
|
||||
RGCourseParticipantsInTutorial: Course category participants who are registered for at least one course
|
||||
RGCourseUnacceptedApplicants: Applicants not accepted
|
||||
RecipientToggleAll: All/None
|
||||
CommCourseTestSubject customSubject: [TEST] #{customSubject}
|
||||
UtilCommCourseSubject: Course type message
|
||||
UtilCommCourseSubject: Course category message
|
||||
UtilCommFirmSubject: Company message
|
||||
CommRecipients: Recipients
|
||||
CommRecipientsTip: You always receive a copy of the message
|
||||
@ -27,7 +27,7 @@ RGSheetSubmittor shn: Submitted for exercise sheet “#{shn}”
|
||||
CommSubject: Subject
|
||||
CommContent: Content
|
||||
CommAttachments: Attachments
|
||||
CommAttachmentsTip: In general it is preferable to upload files as course type material instead of sending them as attachments. You can then link to the material from the message. The file is then permanently accessable to the recipients and to persons that, for example, register for the Course type at a later date.
|
||||
CommAttachmentsTip: In general it is preferable to upload files as course category material instead of sending them as attachments. You can then link to the material from the message. The file is then permanently accessable to the recipients and to persons that, for example, register for the Course category at a later date.
|
||||
CommSuccess n: Message was sent to #{n} #{pluralEN n "recipient" "recipients"}
|
||||
CommTestSuccess: Message was sent only to yourself for testing purposes
|
||||
|
||||
@ -81,6 +81,7 @@ MultiUserFieldExplanationAnyUser: This input searches through the addresses of a
|
||||
MultiUserFieldInvitationExplanation: For addresses, which are not found in this way, an invitation will be sent via email.
|
||||
MultiUserFieldInvitationExplanationAlways: An invitation will be sent via email to all addresses you enter here.
|
||||
AmbiguousEmail: Email address is ambiguous
|
||||
UnknownEmail: Email adresse is not associated with any registred user
|
||||
InvalidEmailAddress: Email address is invalid
|
||||
InvalidEmailAddressWith e: Email asdress #{show e} is invalid
|
||||
MailFileAttachment: Attached file
|
||||
@ -91,6 +92,7 @@ UtilExamResultVoided: Voided
|
||||
CourseOption tid ssh csh coursen: #{tid} - #{ssh} - #{csh}: #{coursen}
|
||||
RoomReferenceNone: —
|
||||
RoomReferenceSimple: Text
|
||||
RoomReferenceSimpleAt r: at room #{r}
|
||||
RoomReferenceLink: Link & Instructions
|
||||
RoomReferenceSimpleText: Room
|
||||
RoomReferenceSimpleTextPlaceholder: Room
|
||||
@ -102,6 +104,7 @@ UtilNoneSet: None set
|
||||
UtilEmptyChoice: Empty selection
|
||||
UtilEmptyNoChangeTip: Existing values remain unchanged if this field is left empty.
|
||||
MultiNoSelection: No selection
|
||||
MustBePositive: must be positive
|
||||
|
||||
#invitation.hs
|
||||
InvitationAction: Action
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022-24 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
-- SPDX-FileCopyrightText: 2022-25 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -11,8 +11,10 @@ Company
|
||||
prefersPostal Bool default=true -- new company users prefers letters by post instead of email
|
||||
postAddress StoredMarkup Maybe -- default company postal address, including company name
|
||||
email UserEmail Maybe -- Case-insensitive generic company eMail address
|
||||
pinPassword Bool default=true -- new company users only: should sensitive PDF email attachement be protected by a password?
|
||||
-- UniqueCompanyName name -- Should be Unique in AVS, but we do not yet need to enforce it
|
||||
-- UniqueCompanyShorthand shorthand -- unnecessary, since it is the primary key already
|
||||
UniqueCompanyAvsId avsId -- Should be the key, is not for historical reasons and for convenience in URLs and columns
|
||||
Primary shorthand -- newtype Key Company = CompanyKey { unCompanyKey :: CompanyShorthand }
|
||||
deriving Ord Eq Show Generic Binary
|
||||
|
||||
|
||||
@ -28,13 +28,12 @@ Course -- Information about a single course; contained info is always visible
|
||||
TermSchoolCourseName term school name -- name must be unique within school and semester
|
||||
deriving Generic
|
||||
CourseEvent
|
||||
type (CI Text)
|
||||
course CourseId OnDeleteCascade OnUpdateCascade
|
||||
room RoomReference Maybe
|
||||
roomHidden Bool default=false
|
||||
time Occurrences
|
||||
note StoredMarkup Maybe
|
||||
lastChanged UTCTime default=now()
|
||||
type (CI Text)
|
||||
course CourseId OnDeleteCascade OnUpdateCascade
|
||||
roomHidden Bool default=false
|
||||
time (JSONB Occurrences)
|
||||
note StoredMarkup Maybe
|
||||
lastChanged UTCTime default=now()
|
||||
deriving Generic
|
||||
|
||||
CourseAppInstructionFile
|
||||
|
||||
@ -37,16 +37,17 @@ ExamPart
|
||||
UniqueExamPartName exam name !force
|
||||
deriving Read Show Eq Ord Generic
|
||||
ExamOccurrence
|
||||
exam ExamId
|
||||
name ExamOccurrenceName
|
||||
room RoomReference Maybe
|
||||
roomHidden Bool default=false
|
||||
capacity Word64 Maybe
|
||||
start UTCTime
|
||||
end UTCTime Maybe
|
||||
description StoredMarkup Maybe
|
||||
exam ExamId
|
||||
name ExamOccurrenceName
|
||||
examiner UserId Maybe
|
||||
room RoomReference Maybe
|
||||
roomHidden Bool default=false
|
||||
capacity Word64 Maybe
|
||||
start UTCTime
|
||||
end UTCTime Maybe
|
||||
description StoredMarkup Maybe
|
||||
UniqueExamOccurrence exam name
|
||||
deriving Generic
|
||||
deriving Eq Ord Show Generic Binary
|
||||
ExamRegistration
|
||||
exam ExamId
|
||||
user UserId
|
||||
|
||||
@ -1,30 +1,30 @@
|
||||
-- SPDX-FileCopyrightText: 2022-23 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
-- SPDX-FileCopyrightText: 2022-25 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
Qualification
|
||||
-- INVARIANT: 2*refreshWithin < validDuration
|
||||
school SchoolId --TODO: Ansprechpartner der Schule in Briefe erwähnen
|
||||
shorthand (CI Text)
|
||||
name (CI Text)
|
||||
description StoredMarkup Maybe -- user-defined large Html, ought to contain full description
|
||||
validDuration Int Maybe -- > 0, qualification is valid indefinitely or for a specified number of months, use with addMonthsDay
|
||||
auditDuration Int Maybe -- > 0, number of months to keep audit log and LmsUserIdents; or indefinitely (dangerous, since LmsIdents may run out)
|
||||
refreshWithin CalendarDiffDays Maybe -- notify users about renewal within this number of month/days before expiry; to be used with addGregorianDurationClip
|
||||
refreshReminder CalendarDiffDays Maybe -- send a second notification about renewal within this number of month/days before expiry
|
||||
elearningStart Bool -- automatically schedule e-refresher
|
||||
elearningRenews Bool default=true -- successful e-learing automatically increases validity automatically by validDuration
|
||||
elearningLimit Int Maybe -- limit of e-learning attempts, currently only for informative purposes, as it is enforced by LMS only
|
||||
lmsReuses QualificationId Maybe -- if set, lms is also included within the given qualification's lms, but only for direct routes. AuditDuration is used from this Qualification instead.
|
||||
expiryNotification Bool default=true -- should expiryNotification be generated for this qualification?
|
||||
avsLicence AvsLicence Maybe -- if set, valid QualificationUsers are synchronized to AVS as a driving licence
|
||||
sapId Text Maybe -- if set, valid QualificationUsers with userCompanyPersonalNumber are transmitted via SAP interface under this id
|
||||
school SchoolId -- 1
|
||||
shorthand (CI Text) -- 2
|
||||
name (CI Text) -- 3
|
||||
description StoredMarkup Maybe -- 4 user-defined large Html, ought to contain full description
|
||||
validDuration Int Maybe -- 5 if > 0, qualification is valid indefinitely or for a specified number of months, use with addMonthsDay
|
||||
auditDuration Int default=366 -- 6 number of days to keep LMS audit log and LmsUserIdents -- TODO: audit period for QualificationUser/Block as well
|
||||
refreshWithin CalendarDiffDays Maybe -- 7 notify users about renewal within this number of month/days before expiry; to be used with addGregorianDurationClip
|
||||
refreshReminder CalendarDiffDays Maybe -- 8 send a second notification about renewal within this number of month/days before expiry
|
||||
elearningStart Bool -- 9 automatically schedule e-refresher
|
||||
elearningRenews Bool default=true -- 10 successful e-learing automatically increases validity automatically by validDuration
|
||||
elearningLimit Int Maybe -- 11 limit of e-learning attempts, currently only for informative purposes, as it is enforced by LMS only
|
||||
lmsReuses QualificationId Maybe -- 12 if set, lms is also included within the given qualification's lms, but only for direct routes. AuditDuration is used from this Qualification instead.
|
||||
expiryNotification Bool default=true -- 13 should expiryNotification be generated for this qualification?
|
||||
avsLicence AvsLicence Maybe -- 14 if set, valid QualificationUsers are synchronized to AVS as a driving licence
|
||||
sapId Text Maybe -- 15 if set, valid QualificationUsers with userCompanyPersonalNumber are transmitted via SAP interface under this id
|
||||
SchoolQualificationShort school shorthand -- must be unique per school and shorthand
|
||||
SchoolQualificationName school name -- must be unique per school and name
|
||||
-- across all schools, only one qualification may be a driving licence -- NO LONGER TRUE
|
||||
-- UniqueQualificationAvsLicence avsLicence !force -- either empty or unique
|
||||
-- NOTE: two NULL values are not equal for the purpose of Uniqueness constraints!
|
||||
deriving Show Eq Generic
|
||||
deriving Show Eq Generic Binary
|
||||
|
||||
-- TODOs:
|
||||
-- - Enstehen Kosten, wenn Teilnehmer für KnowHow eingereiht werden, aber nicht am Kurs teilnehmen?
|
||||
@ -164,4 +164,16 @@ LmsReportLog
|
||||
lock Bool -- (0|1)
|
||||
timestamp UTCTime default=now()
|
||||
missing Bool default=false
|
||||
deriving Generic Show
|
||||
|
||||
-- Table to manage unknown or orphaned lms identifiers
|
||||
LmsOrphan
|
||||
qualification QualificationId OnDeleteCascade OnUpdateCascade
|
||||
ident LmsIdent -- must be unique accross all LMS courses!
|
||||
seenFirst UTCTime default=now() -- first time reported by LMS
|
||||
seenLast UTCTime default=now() -- last acknowledgement by LMS, deletion uses QualificationAuditDuration
|
||||
deletedLast UTCTime Maybe -- last deletion request sent to LMS
|
||||
resultLast LmsState -- last received learning state
|
||||
reason Text Maybe -- to mark explicit e-learning deletions, etc
|
||||
UniqueLmsOrphan qualification ident -- unlike other tables, LMS Idents must only be unique within qualification, allowing orphans to be handled independently
|
||||
deriving Generic Show
|
||||
@ -6,10 +6,9 @@ Tutorial json
|
||||
name TutorialName
|
||||
course CourseId OnDeleteCascade OnUpdateCascade
|
||||
type (CI Text) -- "Tutorium", "Zentralübung", ...
|
||||
capacity Int Maybe -- limit for enrolment in this tutorial
|
||||
room RoomReference Maybe
|
||||
capacity Int Maybe -- limit for enrolment in this tutorial
|
||||
roomHidden Bool default=false
|
||||
time Occurrences
|
||||
time (JSONB Occurrences)
|
||||
regGroup (CI Text) Maybe -- each participant may register for one tutorial per regGroup
|
||||
registerFrom UTCTime Maybe
|
||||
registerTo UTCTime Maybe
|
||||
@ -25,8 +24,19 @@ Tutor
|
||||
UniqueTutor tutorial user
|
||||
deriving Generic
|
||||
TutorialParticipant
|
||||
tutorial TutorialId OnDeleteCascade OnUpdateCascade
|
||||
user UserId
|
||||
tutorial TutorialId OnDeleteCascade OnUpdateCascade
|
||||
user UserId
|
||||
company CompanyId Maybe
|
||||
drivingPermit UserDrivingPermit Maybe
|
||||
eyeExam UserEyeExam Maybe
|
||||
note Text Maybe
|
||||
UniqueTutorialParticipant tutorial user
|
||||
deriving Eq Ord Show
|
||||
deriving Generic
|
||||
deriving Eq Ord Show Generic
|
||||
TutorialParticipantDay
|
||||
tutorial TutorialId OnDeleteCascade OnUpdateCascade
|
||||
user UserId OnDeleteCascade OnUpdateCascade
|
||||
day Day
|
||||
attendance Bool default=true
|
||||
note Text Maybe
|
||||
UniqueTutorialParticipantDay tutorial user day
|
||||
deriving Show Generic
|
||||
@ -114,4 +114,9 @@ UserSupervisor
|
||||
reason Text Maybe -- miscellaneous reason, e.g. Winterservice supervisision
|
||||
UniqueUserSupervisor supervisor user -- each supervisor/user combination is unique (same supervisor can superviser the same user only once)
|
||||
deriving Generic Show
|
||||
|
||||
UserDay
|
||||
user UserId OnDeleteCascade OnUpdateCascade
|
||||
day Day
|
||||
parkingToken Bool default=false
|
||||
UniqueUserDay user day
|
||||
deriving Generic Show
|
||||
|
||||
30
package-lock.json
generated
30
package-lock.json
generated
@ -13577,11 +13577,7 @@
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/package-json-from-dist": {
|
||||
"version": "1.0.1",
|
||||
@ -17814,7 +17810,6 @@
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"dev": true,
|
||||
"license": "0BSD",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/tty-browserify": {
|
||||
@ -18963,6 +18958,29 @@
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"param-case": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
|
||||
"integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
|
||||
"extraneous": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
|
||||
"extraneous": true
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"extraneous": true,
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
22
routes
22
routes
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022-24 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Wolfgang Witt <Wolfgang.Witt@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>, Sarah Vaupel <sarah.vaupel@ifi.lmu.de>, Steffen Jost <jost@tcs.ifi.lmu.de>, Wolfgang Witt <Wolfgang.Witt@campus.lmu.de>, Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -61,6 +61,7 @@
|
||||
/users/#CryptoUUIDUser/hijack AdminHijackUserR GET POST !adminANDno-escalation
|
||||
/users/#CryptoUUIDUser/notifications UserNotificationR GET POST !self
|
||||
/users/#CryptoUUIDUser/password UserPasswordR GET POST !selfANDis-pw-hash
|
||||
/users/#CryptoUUIDUser/recipients UserRecipientsR GET !self
|
||||
!/users/functionary-invite/new AdminNewFunctionaryInviteR GET POST
|
||||
!/users/functionary-invite AdminFunctionaryInviteR GET POST
|
||||
!/users/add AdminUserAddR GET POST
|
||||
@ -129,6 +130,7 @@
|
||||
|
||||
/firms FirmAllR GET POST -- not yet !supervisor
|
||||
/firms/comm/+Companies FirmsCommR GET POST
|
||||
/firms/supervision FirmsSupervisionR GET POST
|
||||
/firm/#CompanyShorthand/comm FirmCommR GET POST
|
||||
/firm/#CompanyShorthand FirmUsersR GET POST -- not yet !supervisor
|
||||
/firm/#CompanyShorthand/supers FirmSupersR GET POST -- not yet !supervisor
|
||||
@ -161,8 +163,9 @@
|
||||
/school SchoolListR GET
|
||||
!/school/new SchoolNewR GET POST
|
||||
/school/#SchoolId SchoolR:
|
||||
/ SchoolEditR GET POST
|
||||
|
||||
/edit SchoolEditR GET POST
|
||||
/day/#Day SchoolDayR GET POST
|
||||
/day/#Day/check SchoolDayCheckR GET
|
||||
|
||||
/participants ParticipantsListR GET !evaluation
|
||||
/participants/#TermId/#SchoolId ParticipantsR GET !evaluation
|
||||
@ -232,6 +235,7 @@
|
||||
/delete TDeleteR GET POST
|
||||
/participants TUsersR GET POST !tutor
|
||||
/participants/add TAddUserR GET POST !tutor
|
||||
/participants/exam/#ExamName TExamR GET POST !tutor
|
||||
/register TRegisterR POST !timeANDcapacityANDcourse-registeredANDregister-group !timeANDtutorial-registered
|
||||
/communication TCommR GET POST !tutor
|
||||
/tutor-invite TInviteR GET POST !tutorANDtutor-control
|
||||
@ -281,20 +285,22 @@
|
||||
!/#UUID CryptoUUIDDispatchR GET !free -- just redirect
|
||||
-- !/*{CI FilePath} CryptoFileNameDispatchR GET !free -- Disabled until preliminary check for valid cID exists
|
||||
|
||||
/qualification QualificationAllR GET !free
|
||||
/qualification/#SchoolId QualificationSchoolR GET !free
|
||||
/qualification/#SchoolId/#QualificationShorthand QualificationR GET POST !free
|
||||
/qualification QualificationAllR GET !free
|
||||
/qualification/#SchoolId QualificationSchoolR GET !free
|
||||
!/qualification/#SchoolId/new QualificationNewR GET POST -- not free
|
||||
/qualification/#SchoolId/#QualificationShorthand QualificationR GET POST !free
|
||||
/qualification/#SchoolId/#QualificationShorthand/edit QualificationEditR GET POST -- not free
|
||||
-- /qualification/#SchoolId/#QualificationShorthand/#CryptoUUIDUser QualificationUserR GET -- see LmsUserR
|
||||
/qualifications/sap/direct QualificationSAPDirectR GET -- !token -- SAP EXPORT -- TODO reinstate token requirement
|
||||
/qualifications/sap/direct QualificationSAPDirectR GET -- !token -- SAP EXPORT -- TODO reinstate token requirement
|
||||
|
||||
|
||||
-- LMS
|
||||
/lms LmsAllR GET POST
|
||||
/lms/#SchoolId LmsSchoolR GET
|
||||
/lms/#SchoolId/#QualificationShorthand LmsR GET POST
|
||||
/lms/#SchoolId/#QualificationShorthand/edit LmsEditR GET POST
|
||||
-- new V2 LMS Interface
|
||||
/lms/#SchoolId/#QualificationShorthand/learners LmsLearnersR GET
|
||||
/lms/#SchoolId/#QualificationShorthand/learners/orphans LmsOrphansR GET
|
||||
/lms/#SchoolId/#QualificationShorthand/learners/direct LmsLearnersDirectR GET !token -- LMS
|
||||
/lms/#SchoolId/#QualificationShorthand/report LmsReportR GET POST
|
||||
/lms/#SchoolId/#QualificationShorthand/report/upload LmsReportUploadR GET POST
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>, Sarah Vaupel <sarah.vaupel@ifi.lmu.de>, Sarah Vaupel <vaupel.sarah@campus.lmu.de>, Steffen Jost <jost@tcs.ifi.lmu.de>, David Mosbach <david.mosbach@uniworx.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>,-2024 Gregor Kleen <gregor.kleen@ifi.lmu.de>, Sarah Vaupel <sarah.vaupel@ifi.lmu.de>, Sarah Vaupel <vaupel.sarah@campus.lmu.de>, Steffen Jost <jost@tcs.ifi.lmu.de>, David Mosbach <david.mosbach@uniworx.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -114,13 +114,8 @@ import GHC.RTS.Flags (getRTSFlags)
|
||||
|
||||
import qualified Prometheus
|
||||
|
||||
import qualified Data.IntervalMap.Strict as IntervalMap
|
||||
|
||||
import qualified Utils.Pool as Custom
|
||||
|
||||
import Utils.Postgresql
|
||||
import Handler.Utils.Memcached (manageMemcachedLocalInvalidations)
|
||||
|
||||
import qualified System.Clock as Clock
|
||||
|
||||
import Utils.Avs (mkAvsQuery)
|
||||
@ -136,6 +131,7 @@ import Handler.Users.Add
|
||||
import Handler.Admin
|
||||
import Handler.Term
|
||||
import Handler.School
|
||||
import Handler.School.DayTasks
|
||||
import Handler.Course
|
||||
import Handler.Sheet
|
||||
import Handler.Submission
|
||||
@ -217,18 +213,6 @@ makeFoundation appSettings''@AppSettings{..} = do
|
||||
appJobState <- liftIO newEmptyTMVarIO
|
||||
appHealthReport <- liftIO $ newTVarIO Set.empty
|
||||
|
||||
appFileSourceARC <- for appFileSourceARCConf $ \ARCConf{..} -> do
|
||||
ah <- initARCHandle arccMaximumGhost arccMaximumWeight
|
||||
void . Prometheus.register $ arcMetrics ARCFileSource ah
|
||||
return ah
|
||||
appFileSourcePrewarm <- for appFileSourcePrewarmConf $ \PrewarmCacheConf{..} -> do
|
||||
lh <- initLRUHandle precMaximumWeight
|
||||
void . Prometheus.register $ lruMetrics LRUFileSourcePrewarm lh
|
||||
return lh
|
||||
appFileInjectInhibit <- liftIO $ newTVarIO IntervalMap.empty
|
||||
for_ (guardOnM (isn't _JobsOffload appJobMode) appInjectFiles) $ \_ ->
|
||||
void . Prometheus.register $ injectInhibitMetrics appFileInjectInhibit
|
||||
|
||||
appStartTime <- liftIO getCurrentTime
|
||||
-- We need a log function to create a connection pool. We need a connection
|
||||
-- pool to create our foundation. And we need our foundation to get a
|
||||
@ -237,7 +221,7 @@ makeFoundation appSettings''@AppSettings{..} = do
|
||||
-- from there, and then create the real foundation.
|
||||
let
|
||||
mkFoundation :: _ -> (forall m. MonadIO m => Custom.Pool' m DBConnLabel DBConnUseState SqlBackend) -> _
|
||||
mkFoundation appSettings' appConnPool appSmtpPool appLdapPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appMemcachedLocal appUploadCache appVerpSecret appAuthKey appAuthPlugins appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery = UniWorX{..}
|
||||
mkFoundation appSettings' appConnPool appSmtpPool appLdapPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appUploadCache appVerpSecret appAuthKey appAuthPlugins appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery = UniWorX{..}
|
||||
tempFoundation = mkFoundation
|
||||
(error "appSettings' forced in tempFoundation")
|
||||
(error "connPool forced in tempFoundation")
|
||||
@ -250,7 +234,6 @@ makeFoundation appSettings''@AppSettings{..} = do
|
||||
(error "JSONWebKeySet forced in tempFoundation")
|
||||
(error "ClusterID forced in tempFoundation")
|
||||
(error "memcached forced in tempFoundation")
|
||||
(error "memcachedLocal forced in tempFoundation")
|
||||
(error "MinioConn forced in tempFoundation")
|
||||
(error "VerpSecret forced in tempFoundation")
|
||||
(error "AuthKey forced in tempFoundation")
|
||||
@ -384,12 +367,6 @@ makeFoundation appSettings''@AppSettings{..} = do
|
||||
$logWarnS "setup" "Clearing memcached"
|
||||
liftIO $ Memcached.flushAll memcachedConn
|
||||
return AppMemcached{..}
|
||||
appMemcachedLocal <- for appMemcachedLocalConf $ \ARCConf{..} -> do
|
||||
memcachedLocalARC <- initARCHandle arccMaximumGhost arccMaximumWeight
|
||||
void . Prometheus.register $ arcMetrics ARCMemcachedLocal memcachedLocalARC
|
||||
memcachedLocalInvalidationQueue <- newTVarIO mempty
|
||||
memcachedLocalHandleInvalidations <- allocateLinkedAsync . managePostgresqlChannel appDatabaseConf ChannelMemcachedLocalInvalidation $ manageMemcachedLocalInvalidations memcachedLocalARC memcachedLocalInvalidationQueue
|
||||
return AppMemcachedLocal{..}
|
||||
|
||||
appSessionStore <- mkSessionStore appSettings'' sqlPool `customRunSqlPool` sqlPool
|
||||
|
||||
@ -428,7 +405,7 @@ makeFoundation appSettings''@AppSettings{..} = do
|
||||
$logDebugS "Runtime configuration" $ tshowCrop appSettings'
|
||||
|
||||
-- TODO: reimplement user db failover
|
||||
let foundation = mkFoundation appSettings' sqlPool smtpPool ldapPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appMemcachedLocal appUploadCache appVerpSecret appAuthKey appAuthPlugins appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery
|
||||
let foundation = mkFoundation appSettings' sqlPool smtpPool ldapPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appUploadCache appVerpSecret appAuthKey appAuthPlugins appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery
|
||||
|
||||
-- Return the foundation
|
||||
$logInfoS "setup" "*** DONE ***"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2023-24 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
-- SPDX-FileCopyrightText: 2023-2024 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022-24 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -213,6 +213,12 @@ data Transaction
|
||||
, transactionNote :: Maybe Text
|
||||
, transactionReceived :: UTCTime -- when was the csv file received?
|
||||
}
|
||||
| TransactionLmsTerminated
|
||||
{ transactionQualification :: QualificationId
|
||||
, transactionLmsIdent :: LmsIdent
|
||||
, transactionLmsUser :: UserId
|
||||
, transactionNote :: Maybe Text
|
||||
}
|
||||
| TransactionQualificationUserEdit -- Note that a renewal always entails unblocking as well!
|
||||
{ transactionUser :: UserId -- qualification holder that is updated
|
||||
, transactionQualificationUser :: QualificationUserId -- not really necessary, maybe remove?
|
||||
@ -283,7 +289,8 @@ data AdminProblem
|
||||
, adminProblemUserOld :: Maybe UserId -- previous superior
|
||||
}
|
||||
| AdminProblemCompanySuperiorNotFound -- a company received a new superior user through AVS, but user could not be created from email
|
||||
{ adminProblemEmail :: Maybe Text -- new superior user's email, not found in LDAP
|
||||
{ adminProblemUser :: UserId -- user who had a supervisor but no longer has, due to supervisor change
|
||||
, adminProblemEmail :: Maybe Text -- new superior user's email, not found in LDAP
|
||||
, adminProblemCompany :: CompanyId -- affected company
|
||||
, adminProblemUserOld :: Maybe UserId -- previous superior
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
-- {-# LANGUAGE BangPatterns #-}
|
||||
{-# OPTIONS_GHC -Wwarn #-}
|
||||
{-# OPTIONS_GHC -Wwarn -fno-warn-orphans #-}
|
||||
|
||||
-- SPDX-FileCopyrightText: 2024-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>
|
||||
--
|
||||
@ -64,8 +63,9 @@ foreign import ccall unsafe "sodium_bin2hex"
|
||||
bin2hex :: ByteString -> String
|
||||
bin2hex bs = let tlen = S.length bs * 2 + 1 in
|
||||
S8.unpack . S8.init . snd . buildUnsafeByteString tlen $ \t ->
|
||||
constByteStrings [bs] $ \[(pbs, _)] ->
|
||||
c_sodium_bin2hex t (fromIntegral tlen) pbs (fromIntegral $ S.length bs)
|
||||
let aux [(pbs, _)] = c_sodium_bin2hex t (fromIntegral tlen) pbs (fromIntegral $ S.length bs)
|
||||
aux _ = error "Crypto.Saltine.Instances.bin2hex reached an impossible computation path"
|
||||
in constByteStrings [bs] aux
|
||||
|
||||
instance Show Key where
|
||||
show k = "SecretBox.Key {hashesTo = \"" <> (bin2hex . shorthash nullShKey $ encode k) <> "}\""
|
||||
|
||||
@ -117,4 +117,20 @@ instance {-# OVERLAPS #-} FromJSON (E.CryptoID "PrintJob" (CI FilePath)) where
|
||||
instance {-# OVERLAPS #-} FromJSONKey (E.CryptoID "PrintJob" (CI FilePath)) where
|
||||
fromJSONKey = FromJSONKeyTextParser $ maybe (fail "Could not parse CryptoPrintJob") return . fromPathPiece
|
||||
instance {-# OVERLAPS #-} ToMarkup (E.CryptoID "PrintJob" (CI FilePath)) where
|
||||
toMarkup = toMarkup . toPathPiece
|
||||
toMarkup = toMarkup . toPathPiece
|
||||
|
||||
|
||||
-- instance PathPiece a => PathPiece [a] where
|
||||
-- toPathPiece = textBracket '[' ']' . Text.intercalate "," . map toPathPiece
|
||||
-- fromPathPiece (textUnbracket '[' ']' . Text.strip -> Just t)
|
||||
-- | null t = Just []
|
||||
-- | otherwise = mapM fromPathPiece $ Text.split (==',') t
|
||||
-- fromPathPiece _ = Nothing
|
||||
|
||||
instance PathPiece [E.CryptoID "ExamOccurrence" UUID] where -- required for a form field sending multiple ids
|
||||
fromPathPiece (textUnbracket '[' ']' . Text.strip -> Just t)
|
||||
| null t = Just []
|
||||
| otherwise = fromPathMultiPiece $ Text.split (==',') t
|
||||
fromPathPiece _ = Nothing
|
||||
|
||||
toPathPiece = textBracket '[' ']' . Text.intercalate "," . toPathMultiPiece
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022-24 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2025 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -9,9 +9,12 @@ module Database.Esqueleto.Utils
|
||||
( true, false
|
||||
, vals, justVal, justValList, toValues
|
||||
, isJust, alt
|
||||
, isNumerical, hasLetter
|
||||
, isInfixOf, hasInfix
|
||||
, isPrefixOf_, hasPrefix_
|
||||
, strConcat, substring
|
||||
, strConcat
|
||||
, substring, substringRegex
|
||||
, decodeBase64, encodeEscape, mailContentContains
|
||||
, (=?.), (?=.)
|
||||
, (=~.), (~=.)
|
||||
, (>~.), (<~.)
|
||||
@ -49,10 +52,11 @@ module Database.Esqueleto.Utils
|
||||
, unKey
|
||||
, subSelectCountDistinct
|
||||
, selectCountRows, selectCountDistinct
|
||||
, selectMaybe
|
||||
, str2text, str2text'
|
||||
, str2citext
|
||||
, num2text --, text2num
|
||||
, day, day', dayMaybe, interval, diffDays, diffTimes
|
||||
, withinPeriod
|
||||
, exprLift
|
||||
, explicitUnsafeCoerceSqlExprValue
|
||||
, psqlVersion_
|
||||
@ -80,6 +84,7 @@ import Database.Esqueleto.Utils.TH
|
||||
import qualified Data.Text as Text
|
||||
import qualified Data.Text.Lazy as Lazy (Text)
|
||||
import qualified Data.ByteString.Lazy as Lazy (ByteString)
|
||||
import qualified Data.CaseInsensitive as CI
|
||||
|
||||
import Crypto.Hash (Digest, SHA256)
|
||||
|
||||
@ -95,7 +100,7 @@ import Data.Monoid (Last(..))
|
||||
|
||||
import Utils (commaSeparatedText)
|
||||
-- import Utils.Set (concatMapSet)
|
||||
|
||||
import Model.Types.Mail (MailContent)
|
||||
|
||||
{-# ANN any ("HLint: ignore Use any" :: String) #-}
|
||||
{-# ANN all ("HLint: ignore Use all" :: String) #-}
|
||||
@ -150,40 +155,51 @@ infixl 4 ?=.
|
||||
-- | like (=?.) but also succeeds if the right-hand side is NULL. Can often be avoided by moving from where- to join-condition!
|
||||
infixl 4 =~.
|
||||
(=~.) :: PersistField typ => E.SqlExpr (E.Value typ) -> E.SqlExpr (E.Value (Maybe typ)) -> E.SqlExpr (E.Value Bool)
|
||||
(=~.) a b = E.isNothing b E.||. (E.just a E.==. b)
|
||||
-- (=~.) a b = E.isNothing b E.||. (E.just a E.==. b) -- avoid expensive E.||.
|
||||
(=~.) a b = a E.==. E.coalesceDefault [b] a
|
||||
|
||||
infixl 4 ~=.
|
||||
(~=.) :: PersistField typ => E.SqlExpr (E.Value (Maybe typ)) -> E.SqlExpr (E.Value typ) -> E.SqlExpr (E.Value Bool)
|
||||
(~=.) a b = E.isNothing a E.||. (a E.==. E.just b)
|
||||
-- (~=.) a b = E.isNothing a E.||. (a E.==. E.just b) -- avoid expensive E.||.
|
||||
(~=.) a b = b E.==. E.coalesceDefault [a] b
|
||||
|
||||
-- | like (>.), but also succeeds if the right-hand side is NULL
|
||||
-- | like (>=.), but also succeeds if the right-hand side is NULL
|
||||
infixl 4 >~.
|
||||
(>~.) :: PersistField typ => E.SqlExpr (E.Value typ) -> E.SqlExpr (E.Value (Maybe typ)) -> E.SqlExpr (E.Value Bool)
|
||||
(>~.) a b = E.isNothing b E.||. (E.just a E.>. b)
|
||||
-- (>~.) a b = E.isNothing b E.||. (E.just a E.>. b)
|
||||
(>~.) a b = a E.>=. E.coalesceDefault [b] a
|
||||
|
||||
-- | like (<.), but also succeeds if the right-hand side is NULL
|
||||
-- | like (<=.), but also succeeds if the right-hand side is NULL
|
||||
infixl 4 <~.
|
||||
(<~.) :: PersistField typ => E.SqlExpr (E.Value typ) -> E.SqlExpr (E.Value (Maybe typ)) -> E.SqlExpr (E.Value Bool)
|
||||
(<~.) a b = E.isNothing b E.||. (E.just a E.<. b)
|
||||
-- (<~.) a b = E.isNothing b E.||. (E.just a E.<. b)
|
||||
(<~.) a b = a E.<=. E.coalesceDefault [b] a
|
||||
|
||||
infixr 2 ~., ~*., !~., !~*.
|
||||
|
||||
-- | PostgreSQL regular expression match, case sensitive. Works, but may throw SQL error for unblanced parenthesis, etc. Not suitable for dbTable filters
|
||||
(~.) :: E.SqlString s => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value Bool)
|
||||
(~.) :: (E.SqlString s, E.SqlString t) => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value t) -> E.SqlExpr (E.Value Bool)
|
||||
(~.) = E.unsafeSqlBinOp " ~ "
|
||||
|
||||
-- | PostgreSQL regular expression match, case insensitive. Works, but may throw SQL errors
|
||||
(~*.) :: E.SqlString s => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value Bool)
|
||||
(~*.) :: (E.SqlString s, E.SqlString t) => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value t) -> E.SqlExpr (E.Value Bool)
|
||||
(~*.) = E.unsafeSqlBinOp " ~* "
|
||||
|
||||
-- | PostgreSQL regular expression does not match, case sensitive. Works, but may throw SQL error for unblanced parenthesis, etc. Not suitable for dbTable filters
|
||||
(!~.) :: E.SqlString s => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value Bool)
|
||||
(!~.) :: (E.SqlString s, E.SqlString t) => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value t) -> E.SqlExpr (E.Value Bool)
|
||||
(!~.) = E.unsafeSqlBinOp " !~ "
|
||||
|
||||
-- | PostgreSQL regular expression does not match, case insensitive. Works, but may throw SQL errors
|
||||
(!~*.) :: E.SqlString s => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value Bool)
|
||||
(!~*.) :: (E.SqlString s, E.SqlString t) => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value t) -> E.SqlExpr (E.Value Bool)
|
||||
(!~*.) = E.unsafeSqlBinOp " !~* "
|
||||
|
||||
-- | PostgreSQL regex test if value contains only numbers
|
||||
isNumerical :: E.SqlString s => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value Bool)
|
||||
isNumerical = (~. E.val ("^[0-9]+$"::Text))
|
||||
|
||||
-- | PostgreSQL regex test if value contains at least one letter
|
||||
hasLetter :: E.SqlString s => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value Bool)
|
||||
hasLetter = (~*. E.val ("[a-z]"::Text))
|
||||
|
||||
-- | Negation of `isNothing` which is missing
|
||||
isJust :: PersistField typ => E.SqlExpr (E.Value (Maybe typ)) -> E.SqlExpr (E.Value Bool)
|
||||
@ -245,6 +261,37 @@ substring (E.ERaw _m1 f1) (E.ERaw _m2 f2) (E.ERaw _m3 f3)
|
||||
, strVals <> fromiVals <> foriVals
|
||||
)
|
||||
|
||||
substringRegex :: ( E.SqlString str, E.SqlString from)
|
||||
=> E.SqlExpr (E.Value str)
|
||||
-> E.SqlExpr (E.Value from)
|
||||
-> E.SqlExpr (E.Value str)
|
||||
substringRegex (E.ERaw _m1 f1) (E.ERaw _m2 f2)
|
||||
= E.ERaw E.noMeta $ \_nParens info ->
|
||||
let (strTLB, strVals) = f1 E.Parens info
|
||||
(fromiTLB, fromiVals) = f2 E.Parens info
|
||||
in ( "SUBSTRING" <> E.parens (E.parens strTLB <> " FROM " <> E.parens fromiTLB)
|
||||
, strVals <> fromiVals
|
||||
)
|
||||
|
||||
-- useful for searching within MailContent in db
|
||||
decodeBase64 :: E.SqlString str => E.SqlExpr (E.Value str) -> E.SqlExpr (E.Value str)
|
||||
decodeBase64 = E.unsafeSqlFunction "decode" . (, E.val "base64" :: E.SqlExpr (E.Value Text))
|
||||
|
||||
encodeEscape :: E.SqlString str => E.SqlExpr (E.Value str) -> E.SqlExpr (E.Value str)
|
||||
encodeEscape = E.unsafeSqlFunction "encode" . (, E.val "escape" :: E.SqlExpr (E.Value Text))
|
||||
|
||||
mailContentContains :: E.SqlString str => E.SqlExpr (E.Value MailContent) -> E.SqlExpr (E.Value str) -> E.SqlExpr (E.Value Bool)
|
||||
mailContentContains hay needle = hasNeedle plainText E.||. hasNeedle encodedBase64
|
||||
where
|
||||
hayText :: E.SqlExpr (E.Value Text) = E.unsafeSqlCastAs "text" hay
|
||||
hasNeedle = isInfixOf needle
|
||||
encodedBase64 = encodeEscape $ decodeBase64 $
|
||||
substringRegex hayText $ E.val reB64
|
||||
plainText = substringRegex hayText $ E.val rePlain
|
||||
reB64 :: Text = ".*\\{\"type\": \"text/plain; charset=utf-8\", \"content\": \\{\"content\": \"(.*?)\", \"encoding\": \"base64\"\\}.*"
|
||||
rePlain :: Text = ".*\\{\"type\": \"text/plain; charset=utf-8\", \"content\": \"(.*?)\", \"headers\": \\[\\], \"encoding\": \"quoted-printable-text\".*"
|
||||
|
||||
|
||||
explicitUnsafeCoerceSqlExprValue :: forall b a.
|
||||
Text
|
||||
-> E.SqlExpr (E.Value a)
|
||||
@ -281,7 +328,8 @@ subSelectOr q = parens . E.subSelectUnsafe $ flip (E.unsafeSqlAggregateFunction
|
||||
parens :: E.SqlExpr (E.Value a) -> E.SqlExpr (E.Value a)
|
||||
parens = E.unsafeSqlFunction ""
|
||||
|
||||
-- | Workaround for Esqueleto-Bug not placing parenthesis after NOT, see #155
|
||||
-- | Workaround for Esqueleto-Bug not placing parenthesis after NOT.
|
||||
-- This leads to erroneous filters. For examples, see DevOps #1970
|
||||
not__ :: E.SqlExpr (E.Value Bool) -> E.SqlExpr (E.Value Bool)
|
||||
not__ = E.not_ . parens
|
||||
|
||||
@ -510,10 +558,13 @@ allFilter fltrs needle criterias = F.foldr aux true fltrs
|
||||
where
|
||||
aux fltr acc = fltr needle criterias E.&&. acc
|
||||
|
||||
-- | Descending order of this field or SqlExpression, but with NULLS at the end.
|
||||
-- | Ascending order of this field or SqlExpression, but with NULLS at the end.
|
||||
-- For bool, just use ASC, since false < true < null
|
||||
ascNullsFirst :: PersistField a => E.SqlExpr (E.Value a) -> E.SqlExpr E.OrderBy
|
||||
ascNullsFirst = E.orderByExpr " ASC NULLS FIRST"
|
||||
|
||||
-- | Descending order of this field or SqlExpression, but with NULLS at the end.
|
||||
-- Use this if you want the order to be true, false, null
|
||||
descNullsLast :: PersistField a => E.SqlExpr (E.Value a) -> E.SqlExpr E.OrderBy
|
||||
descNullsLast = E.orderByExpr " DESC NULLS LAST"
|
||||
|
||||
@ -537,6 +588,7 @@ strip = E.unsafeSqlFunction "TRIM"
|
||||
|
||||
infix 4 `ciEq`
|
||||
|
||||
-- Note that this function is unnecessary if the DB type is citext
|
||||
ciEq :: E.SqlString s => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value Bool)
|
||||
ciEq a b = lower a E.==. lower b
|
||||
|
||||
@ -739,8 +791,9 @@ selectCountDistinct q = do
|
||||
_other
|
||||
-> error "E.countDistinct did not return exactly one result"
|
||||
|
||||
selectMaybe :: (E.SqlSelect a r, MonadIO m) => E.SqlQuery a -> E.SqlReadT m (Maybe r)
|
||||
selectMaybe = fmap listToMaybe . E.select . (<* E.limit 1)
|
||||
-- DEPRECATED: use Database.Esqueleto.selectOne instead
|
||||
-- selectMaybe :: (E.SqlSelect a r, MonadIO m) => E.SqlQuery a -> E.SqlReadT m (Maybe r) -- aka selectFirst
|
||||
-- selectMaybe = fmap listToMaybe . E.select . (<* E.limit 1)
|
||||
|
||||
-- | convert something that is like a text to text
|
||||
str2text :: E.SqlString a => E.SqlExpr (E.Value a) -> E.SqlExpr (E.Value Text)
|
||||
@ -749,6 +802,9 @@ str2text = E.unsafeSqlCastAs "text"
|
||||
str2text' :: E.SqlString a => E.SqlExpr (E.Value (Maybe a)) -> E.SqlExpr (E.Value (Maybe Text))
|
||||
str2text' = E.unsafeSqlCastAs "text"
|
||||
|
||||
str2citext :: E.SqlString a => E.SqlExpr (E.Value a) -> E.SqlExpr (E.Value (CI.CI Text))
|
||||
str2citext = E.unsafeSqlCastAs "citext"
|
||||
|
||||
-- | cast numeric type to text, which is safe and allows for an inefficient but safe comparison of numbers stored as text and numbers
|
||||
num2text :: Num n => E.SqlExpr (E.Value n) -> E.SqlExpr (E.Value Text)
|
||||
num2text = E.unsafeSqlCastAs "text"
|
||||
@ -767,6 +823,19 @@ day' = E.unsafeSqlCastAs "date"
|
||||
dayMaybe :: E.SqlExpr (E.Value (Maybe UTCTime)) -> E.SqlExpr (E.Value (Maybe Day))
|
||||
dayMaybe = E.unsafeSqlCastAs "date"
|
||||
|
||||
-- | Given an occurrence with start-time and maybe an end-time, does it overlap with a given day interval?
|
||||
-- If there is no end-time, then the start-time must be in between.
|
||||
withinPeriod :: (Day, Day) -> E.SqlExpr (E.Value UTCTime) -> E.SqlExpr (E.Value (Maybe UTCTime)) -> E.SqlExpr (E.Value Bool)
|
||||
withinPeriod (dbegin, dend) tfrom tto = day tfrom E.<=. E.val dend
|
||||
E.&&. E.coalesceDefault [dayMaybe tto]
|
||||
(day tfrom) E.>=. E.val dbegin
|
||||
-- Alternative variant which SJ expected to be more efficient, if there is an index on the first argument available,
|
||||
-- but FraportGPT thinks otherwise: "OR conditions may prevent the efficient use of an index. OR conditions can sometimes lead to a full table scan, whereas COALESCE is quite cheap"
|
||||
-- withinPeriod (dstart, dend) tfrom tto = day tfrom E.<=. E.val dend
|
||||
-- E.&&. ( day tfrom E.>=. E.val dstart
|
||||
-- E.||. (isJust tto E.&&. dayMaybe tto E.>=. justVal dstart ))
|
||||
|
||||
|
||||
interval :: CalendarDiffDays -> E.SqlExpr (E.Value Day) -- E.+=. requires both types to be the same, so we use Day
|
||||
-- interval _ = E.unsafeSqlCastAs "interval" $ E.unsafeSqlValue "'P2Y'" -- tested working example
|
||||
interval = E.unsafeSqlCastAs "interval". E.unsafeSqlValue . wrapSqlString . Text.Builder.fromString . iso8601Show
|
||||
@ -827,4 +896,4 @@ truncateTable :: (MonadIO m, BackendCompatible SqlBackend backend, PersistEntity
|
||||
=> proxy record -> ReaderT backend m ()
|
||||
truncateTable tbl =
|
||||
let tblName :: Text = P.unEntityNameDB $ P.entityDB $ P.entityDef tbl
|
||||
in E.rawExecute ("TRUNCATE TABLE " <> tblName <> " RESTART IDENTITY") []
|
||||
in E.rawExecute ("TRUNCATE TABLE " <> tblName <> " RESTART IDENTITY") []
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -9,7 +9,7 @@ module Database.Esqueleto.Utils.TH
|
||||
, sqlInTuple, sqlInTuples
|
||||
, _unValue
|
||||
, unValueN, unValueNIs
|
||||
, sqlIJproj, sqlLOJproj, sqlFOJproj
|
||||
, sqlIJproj, sqlLOJproj, sqlFOJproj, sqlMIXproj, sqlMIXproj'
|
||||
) where
|
||||
|
||||
import ClassyPrelude
|
||||
@ -26,6 +26,9 @@ import Data.List (foldr1, foldl)
|
||||
import Utils.TH
|
||||
import Control.Lens.Iso (Iso', iso)
|
||||
|
||||
{-# ANN module ("HLint: ignore Redundant bracket"::String) #-}
|
||||
|
||||
|
||||
class E.SqlSelect a r => SqlIn a r | a -> r, r -> a where
|
||||
sqlIn :: a -> [r] -> E.SqlExpr (E.Value Bool)
|
||||
|
||||
@ -99,7 +102,7 @@ unValueNIs arity uvIdx = do
|
||||
-- | Generic projections for InnerJoin-tuples
|
||||
-- gives I-th element of N-tuple of left-associative InnerJoin-pairs, i.e.
|
||||
--
|
||||
-- > $(projN n m) :: (t1 `E.InnerJoin` .. `E.InnerJoin` tn) -> tm@ (for m<=n)
|
||||
-- > $(sqlIJproj n m) :: (t1 `E.InnerJoin` .. `E.InnerJoin` tn) -> tm@ (for m<=n)
|
||||
sqlIJproj :: Int -> Int -> ExpQ
|
||||
sqlIJproj = leftAssociativePairProjection 'E.InnerJoin
|
||||
|
||||
@ -108,3 +111,23 @@ sqlLOJproj = leftAssociativePairProjection 'E.LeftOuterJoin
|
||||
|
||||
sqlFOJproj :: Int -> Int -> ExpQ
|
||||
sqlFOJproj = leftAssociativePairProjection 'E.FullOuterJoin
|
||||
|
||||
-- | Generic projections for Join-tuple
|
||||
-- gives i-th element of n-tuple of left-associative join pairs, i.e.
|
||||
--
|
||||
-- > $(sqlMIXproj "IR" 3) :: ((t1 `E.InnerJoin` t2) `E.RightOuterJoin` t3) -> t3
|
||||
sqlMIXproj :: String -> Int -> ExpQ
|
||||
sqlMIXproj = leftAssociativeProjection . map decodeJoin
|
||||
where
|
||||
decodeJoin 'I' = 'E.InnerJoin
|
||||
decodeJoin 'L' = 'E.LeftOuterJoin
|
||||
decodeJoin 'R' = 'E.RightOuterJoin
|
||||
decodeJoin 'F' = 'E.FullOuterJoin
|
||||
decodeJoin 'O' = 'E.FullOuterJoin
|
||||
decodeJoin 'X' = 'E.CrossJoin
|
||||
decodeJoin 'C' = 'E.CrossJoin
|
||||
decodeJoin c = error $ "Database.Esqueleto.Utils.TH.sqlMIXproj: received unknown SQL join kind \"" ++ c:"\"" -- always raised at compile time, so this is ok
|
||||
|
||||
-- Alternative using `reify`; works, but may require `$(return [])` between type definition and call to workaround ghc staging problems
|
||||
sqlMIXproj' :: Name -> Int -> ExpQ
|
||||
sqlMIXproj' t i = extractConstructorNames t >>= flip leftAssociativeProjection i
|
||||
|
||||
@ -27,7 +27,7 @@ instance Hashable LiteralType
|
||||
instance Binary LiteralType
|
||||
instance NFData LiteralType
|
||||
|
||||
|
||||
|
||||
deriving instance Generic PersistValue
|
||||
|
||||
instance Hashable PersistValue
|
||||
|
||||
@ -38,7 +38,7 @@ import Handler.Utils.I18n
|
||||
import Handler.Utils.Routes
|
||||
import Utils.Course (courseIsVisible)
|
||||
import Utils.Metrics (observeAuthTagEvaluation, AuthTagEvalOutcome(..))
|
||||
|
||||
|
||||
import qualified Data.Set as Set
|
||||
import qualified Data.Aeson as JSON
|
||||
import qualified Data.HashSet as HashSet
|
||||
@ -95,7 +95,7 @@ instance Exception InvalidAuthTag
|
||||
|
||||
|
||||
type AuthTagsEval m = AuthDNF -> Maybe (AuthId UniWorX) -> Route UniWorX -> Bool -> WriterT (Set AuthTag) m AuthResult
|
||||
|
||||
|
||||
data AccessPredicate
|
||||
= APPure (Maybe (AuthId UniWorX) -> Route UniWorX -> Bool -> Reader MsgRenderer AuthResult)
|
||||
| APHandler (Maybe (AuthId UniWorX) -> Route UniWorX -> Bool -> HandlerFor UniWorX AuthResult)
|
||||
@ -174,7 +174,7 @@ cacheAPDB mExp k mkV cont = APBindDB $ \mAuthId route isWrite -> do
|
||||
v <- mkV
|
||||
memcachedBySet mExp k v
|
||||
either (return . Left) (fmap Right . lift) $ cont mAuthId route isWrite v
|
||||
|
||||
|
||||
-- cacheAP' :: ( Binary k
|
||||
-- , Typeable v, Binary v
|
||||
-- )
|
||||
@ -185,7 +185,7 @@ cacheAPDB mExp k mkV cont = APBindDB $ \mAuthId route isWrite -> do
|
||||
-- cacheAP' mExp mkKV cont = APBind $ \mAuthId route isWrite -> case mkKV mAuthId route isWrite of
|
||||
-- Just (k, mkV) -> either (return . Left) (fmap Right) . cont mAuthId route isWrite . Just =<< memcachedBy mExp k mkV
|
||||
-- Nothing -> either (return . Left) (fmap Right) $ cont mAuthId route isWrite Nothing
|
||||
|
||||
|
||||
cacheAPDB' :: ( Binary k
|
||||
, Typeable v, Binary v, NFData v
|
||||
)
|
||||
@ -313,7 +313,8 @@ isDryRunDB = fmap unIsDryRun . cached . fmap MkIsDryRun $ orM
|
||||
|
||||
dnf <- throwLeft $ routeAuthTags currentRoute
|
||||
let eval :: forall m''. MonadAP m'' => AuthTagsEval m''
|
||||
eval dnf' mAuthId' route' isWrite' = evalAuthTags 'isDryRun (AuthTagActive $ const True) eval (noTokenAuth dnf') mAuthId' route' isWrite'
|
||||
-- eval dnf' mAuthId' route' isWrite' = evalAuthTags 'isDryRun (AuthTagActive $ const True) eval (noTokenAuth dnf') mAuthId' route' isWrite'
|
||||
eval dnf' = evalAuthTags 'isDryRun (AuthTagActive $ const True) eval (noTokenAuth dnf')
|
||||
in guardAuthResult <=< evalWriterT $ eval dnf mAuthId currentRoute isWrite
|
||||
|
||||
return False
|
||||
@ -368,7 +369,8 @@ validateBearer mAuthId' route' isWrite' token' = $runCachedMemoT $ for4 memo val
|
||||
noTokenAuth = over _dnfTerms . Set.filter . noneOf (re _nullable . folded) $ (== AuthToken) . plVar
|
||||
|
||||
eval :: forall m'. MonadAP m' => AuthTagsEval m'
|
||||
eval dnf' mAuthId'' route'' isWrite'' = evalAuthTags 'validateBearer (AuthTagActive $ const True) eval (noTokenAuth dnf') mAuthId'' route'' isWrite''
|
||||
-- eval dnf' mAuthId'' route'' isWrite'' = evalAuthTags 'validateBearer (AuthTagActive $ const True) eval (noTokenAuth dnf') mAuthId'' route'' isWrite''
|
||||
eval dnf' = evalAuthTags 'validateBearer (AuthTagActive $ const True) eval (noTokenAuth dnf')
|
||||
|
||||
bearerAuthority' <- hoist apRunDB $ do
|
||||
bearerAuthority' <- flip foldMapM bearerAuthority $ \case
|
||||
@ -538,14 +540,14 @@ tagAccessPredicate AuthAdmin = cacheAPSchoolFunction SchoolAdmin (Just $ Right d
|
||||
guardMExceptT (isJust adrights) (unauthorizedI MsgUnauthorizedSiteAdmin)
|
||||
return Authorized
|
||||
|
||||
tagAccessPredicate AuthSupervisor = APDB $ \_ _ mAuthId route _ -> case route of
|
||||
tagAccessPredicate AuthSupervisor = APDB $ \_ _ mAuthId route _ -> case route of
|
||||
ForProfileR cID -> checkSupervisor (mAuthId, cID)
|
||||
ForProfileDataR cID -> checkSupervisor (mAuthId, cID)
|
||||
FirmAllR -> checkAnySupervisor mAuthId
|
||||
FirmUsersR fsh -> checkCompanySupervisor (mAuthId, fsh)
|
||||
FirmSupersR fsh -> checkCompanySupervisor (mAuthId, fsh)
|
||||
r -> $unsupportedAuthPredicate AuthSupervisor r
|
||||
where
|
||||
r -> $unsupportedAuthPredicate AuthSupervisor r
|
||||
where
|
||||
checkSupervisor sup@(mAuthId, cID) = $cachedHereBinary sup . exceptT return return $ do
|
||||
authId <- maybeExceptT AuthenticationRequired $ return mAuthId
|
||||
uid <- decrypt cID
|
||||
@ -553,13 +555,13 @@ tagAccessPredicate AuthSupervisor = APDB $ \_ _ mAuthId route _ -> case route of
|
||||
guardMExceptT isSupervisor (unauthorizedI MsgUnauthorizedSupervisor)
|
||||
return Authorized
|
||||
checkCompanySupervisor sup@(mAuthId, fsh) = $cachedHereBinary sup . exceptT return return $ do
|
||||
authId <- maybeExceptT AuthenticationRequired $ return mAuthId
|
||||
authId <- maybeExceptT AuthenticationRequired $ return mAuthId
|
||||
-- isSupervisor <- lift . existsBy $ UniqueUserCompany authId $ CompanyKey fsh
|
||||
isSupervisor <- lift $ exists [UserCompanyUser ==. authId, UserCompanyCompany ==. CompanyKey fsh, UserCompanySupervisor ==. True]
|
||||
guardMExceptT isSupervisor (unauthorizedI $ MsgUnauthorizedCompanySupervisor fsh)
|
||||
return Authorized
|
||||
checkAnySupervisor mAuthId = $cachedHereBinary mAuthId . exceptT return return $ do
|
||||
authId <- maybeExceptT AuthenticationRequired $ return mAuthId
|
||||
authId <- maybeExceptT AuthenticationRequired $ return mAuthId
|
||||
isSupervisor <- lift $ exists [UserSupervisorSupervisor ==. authId]
|
||||
guardMExceptT isSupervisor (unauthorizedI MsgUnauthorizedAnySupervisor)
|
||||
return Authorized
|
||||
@ -692,7 +694,7 @@ tagAccessPredicate AuthLecturer = cacheAPDB' (Just $ Right diffMinute) mkLecture
|
||||
_ | is _Nothing mAuthId' -> return AuthenticationRequired
|
||||
CourseR{} -> unauthorizedI MsgUnauthorizedLecturer
|
||||
EExamR{} -> unauthorizedI MsgUnauthorizedExternalExamLecturer
|
||||
_other -> unauthorizedI MsgUnauthorizedSchoolLecturer
|
||||
_other -> unauthorizedI MsgUnauthorizedSchoolLecturer
|
||||
| otherwise -> Left $ APDB $ \_ _ mAuthId route _ -> case route of
|
||||
CourseR tid ssh csh _ -> $cachedHereBinary (mAuthId, tid, ssh, csh) . exceptT return return $ do
|
||||
authId <- maybeExceptT AuthenticationRequired $ return mAuthId
|
||||
@ -722,7 +724,7 @@ tagAccessPredicate AuthLecturer = cacheAPDB' (Just $ Right diffMinute) mkLecture
|
||||
return Authorized
|
||||
where
|
||||
mkLecturerList _ route _ = case route of
|
||||
CourseR{} -> cacheLecturerList
|
||||
CourseR{} -> cacheLecturerList
|
||||
EExamR{} -> Just
|
||||
( AuthCacheExternalExamStaffList
|
||||
, fmap (setOf $ folded . _Value) . E.select . E.from $ return . (E.^. ExternalExamStaffUser)
|
||||
@ -1199,7 +1201,7 @@ tagAccessPredicate AuthExamRegistered = APDB $ \_ _ mAuthId route _ -> case rout
|
||||
guardMExceptT hasRegistration $ unauthorizedI MsgUnauthorizedRegisteredExam
|
||||
return Authorized
|
||||
CSheetR tid ssh csh shn _ -> exceptT return return $ do
|
||||
requiredExam' <- $cachedHereBinary (tid, ssh, csh, shn) . lift . E.selectMaybe . E.from $ \(course `E.InnerJoin` sheet) -> do
|
||||
requiredExam' <- $cachedHereBinary (tid, ssh, csh, shn) . lift . E.selectOne . E.from $ \(course `E.InnerJoin` sheet) -> do
|
||||
E.on $ sheet E.^. SheetCourse E.==. course E.^. CourseId
|
||||
E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
@ -1704,7 +1706,7 @@ evalAccessWith :: (HasCallStack, MonadThrow m, MonadAP m) => [(AuthTag, Bool)] -
|
||||
evalAccessWith assumptions route isWrite = do
|
||||
mAuthId <- liftHandler maybeAuthId
|
||||
evalAccessWithFor assumptions mAuthId route isWrite
|
||||
|
||||
|
||||
evalAccessWithDB :: (HasCallStack, MonadThrow m, MonadAP m, BackendCompatible SqlReadBackend backend) => [(AuthTag, Bool)] -> Route UniWorX -> Bool -> ReaderT backend m AuthResult
|
||||
evalAccessWithDB = evalAccessWith
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022-23 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2025 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -40,10 +40,9 @@ module Foundation.I18n
|
||||
, ShortStudyFieldType(..)
|
||||
, StudyDegreeTermType(..)
|
||||
, ErrorResponseTitle(..)
|
||||
, UniWorXMessages(..)
|
||||
, uniworxMessages
|
||||
-- , UniWorXMessages(..), uniworxMessages
|
||||
, unRenderMessage, unRenderMessage', unRenderMessageLenient
|
||||
, SomeMessages(..)
|
||||
, SomeMessages(..), pattern SomeMsgs, pattern SpaceMsgs, pattern JoinMsgs
|
||||
, someMessages
|
||||
, module Foundation.I18n.TH
|
||||
) where
|
||||
@ -62,7 +61,7 @@ import qualified Data.Text as Text
|
||||
|
||||
import Utils.Form
|
||||
|
||||
import qualified GHC.Exts (IsList(..))
|
||||
-- import qualified GHC.Exts (IsList(..)) -- for UniWorXMessages
|
||||
|
||||
import Yesod.Form.I18n.German
|
||||
import Yesod.Form.I18n.English
|
||||
@ -280,16 +279,31 @@ mkMessageAddition ''UniWorX "Avs" "messages/uniworx/categories/avs" "de-de-forma
|
||||
|
||||
embedRenderMessage ''UniWorX ''LmsStatus (uncurry ((<>) . (<> "Status")) . Text.splitAt 3)
|
||||
|
||||
-- | Flexible variant of `UniWorXMessages` allowing custom separation
|
||||
data SomeMessages master = SomeMessages Text [SomeMessage master]
|
||||
|
||||
newtype SomeMessages master = SomeMessages [SomeMessage master]
|
||||
deriving newtype (Semigroup, Monoid)
|
||||
pattern SomeMsgs :: [SomeMessage master] -> SomeMessages master
|
||||
pattern SomeMsgs msgs = SomeMessages "\n " msgs
|
||||
|
||||
pattern SpaceMsgs :: [SomeMessage master] -> SomeMessages master
|
||||
pattern SpaceMsgs msgs = SomeMessages " " msgs
|
||||
|
||||
pattern JoinMsgs :: [SomeMessage master] -> SomeMessages master
|
||||
pattern JoinMsgs msgs = SomeMessages "" msgs
|
||||
|
||||
-- Not yet needed:
|
||||
-- instance Semigroup (SomeMessage master) where
|
||||
-- (SomeMessages s1 t1) <> (SomeMessages _s2 t2) = SomeMessages s1 $ t1 ++ t2
|
||||
|
||||
-- instance Monoid (SomeMessage master) where
|
||||
-- mempty = SomeMessages mempty mempty
|
||||
|
||||
instance master ~ master' => RenderMessage master (SomeMessages master') where
|
||||
renderMessage a b (SomeMessages msgs) = Text.intercalate "\n " $ renderMessage a b <$> msgs
|
||||
renderMessage a b (SomeMessages sep msgs) = Text.intercalate sep $ renderMessage a b <$> msgs
|
||||
|
||||
-- | convenienience function if all messages happen to belong to the exact same type
|
||||
someMessages :: RenderMessage master msg => [msg] -> SomeMessages master
|
||||
someMessages msgs = SomeMessages $ SomeMessage <$> msgs
|
||||
someMessages msgs = SomeMessages "\n " $ SomeMessage <$> msgs
|
||||
|
||||
|
||||
instance RenderMessage UniWorX (Maybe LmsStatus) where -- useful for Filter with optionsFinite
|
||||
@ -535,22 +549,24 @@ instance HasResolution a => ToMessage (Fixed a) where
|
||||
newtype ErrorResponseTitle = ErrorResponseTitle ErrorResponse
|
||||
embedRenderMessageVariant ''UniWorX ''ErrorResponseTitle ("ErrorResponseTitle" <>)
|
||||
|
||||
-- -- A list of messages is a message by itself. Uses blank for separation.
|
||||
-- -- Deprecated for now; replaced by the more flexibles SomeMessages. Easy to reinstate.
|
||||
-- --
|
||||
-- newtype UniWorXMessages = UniWorXMessages [SomeMessage UniWorX]
|
||||
-- deriving stock (Generic)
|
||||
-- deriving newtype (Semigroup, Monoid)
|
||||
|
||||
newtype UniWorXMessages = UniWorXMessages [SomeMessage UniWorX]
|
||||
deriving stock (Generic)
|
||||
deriving newtype (Semigroup, Monoid)
|
||||
-- instance IsList UniWorXMessages where
|
||||
-- type Item UniWorXMessages = SomeMessage UniWorX
|
||||
-- fromList = UniWorXMessages
|
||||
-- toList (UniWorXMessages msgs) = msgs
|
||||
|
||||
instance IsList UniWorXMessages where
|
||||
type Item UniWorXMessages = SomeMessage UniWorX
|
||||
fromList = UniWorXMessages
|
||||
toList (UniWorXMessages msgs) = msgs
|
||||
-- instance RenderMessage UniWorX UniWorXMessages where
|
||||
-- renderMessage foundation ls (UniWorXMessages msgs) =
|
||||
-- Text.unwords $ map (renderMessage foundation ls) msgs -- Text.unwords uses blank for separation
|
||||
|
||||
instance RenderMessage UniWorX UniWorXMessages where
|
||||
renderMessage foundation ls (UniWorXMessages msgs) =
|
||||
Text.unwords $ map (renderMessage foundation ls) msgs
|
||||
|
||||
uniworxMessages :: [UniWorXMessage] -> UniWorXMessages
|
||||
uniworxMessages = UniWorXMessages . map SomeMessage
|
||||
-- uniworxMessages :: [UniWorXMessage] -> UniWorXMessages
|
||||
-- uniworxMessages = UniWorXMessages . map SomeMessage
|
||||
|
||||
|
||||
-- This instance is required to use forms. You can modify renderMessage to
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2025 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -29,10 +29,12 @@ import Foundation.Routes
|
||||
import Foundation.I18n
|
||||
import Foundation.Authorization
|
||||
|
||||
import Utils.Company (areThereInsaneCompanySupervisions)
|
||||
import Utils.Sheet
|
||||
|
||||
import Handler.Utils.DateTime
|
||||
import Handler.Utils.Memcached
|
||||
import Handler.Utils.ExamOffice.Course
|
||||
import Utils.Sheet
|
||||
|
||||
import qualified Data.Set as Set
|
||||
import qualified Data.Map as Map
|
||||
@ -105,6 +107,7 @@ breadcrumb (UserPasswordR cID) = useRunDB $ do
|
||||
-> i18nCrumb MsgMenuUserPassword . Just $ AdminUserR cID
|
||||
| otherwise
|
||||
-> i18nCrumb MsgMenuUserPassword $ Just ProfileR
|
||||
breadcrumb (UserRecipientsR cID) = i18nCrumb MsgBreadcrumbUserRecipients . Just $ AdminUserR cID
|
||||
breadcrumb AdminNewFunctionaryInviteR = i18nCrumb MsgMenuLecturerInvite $ Just UsersR
|
||||
breadcrumb AdminFunctionaryInviteR = i18nCrumb MsgBreadcrumbFunctionaryInvite Nothing
|
||||
|
||||
@ -129,6 +132,7 @@ breadcrumb ConfigInterfacesR = i18nCrumb MsgConfigInterfacesHeading $ Just
|
||||
|
||||
breadcrumb FirmAllR = i18nCrumb MsgMenuFirms Nothing
|
||||
breadcrumb FirmsCommR{} = i18nCrumb MsgMenuFirmsComm $ Just FirmAllR
|
||||
breadcrumb FirmsSupervisionR= i18nCrumb MsgMenuFirmsSupervision $ Just FirmAllR
|
||||
breadcrumb FirmUsersR{} = i18nCrumb MsgMenuFirmUsers $ Just FirmAllR
|
||||
breadcrumb (FirmSupersR fsh)= i18nCrumb MsgMenuFirmSupervisors $ Just $ FirmUsersR fsh
|
||||
breadcrumb (FirmCommR fsh)= i18nCrumb MsgMenuFirmsComm $ Just $ FirmUsersR fsh
|
||||
@ -146,13 +150,19 @@ breadcrumb PrintAckR{} = i18nCrumb MsgMenuPrintSend $ Just PrintCenter
|
||||
breadcrumb PrintAckDirectR{}= i18nCrumb MsgMenuPrintAck $ Just PrintCenterR
|
||||
breadcrumb PrintLogR = i18nCrumb MsgMenuPrintLog $ Just PrintCenterR
|
||||
|
||||
breadcrumb SchoolListR = i18nCrumb MsgMenuSchoolList $ Just AdminR
|
||||
breadcrumb (SchoolR ssh sRoute) = case sRoute of
|
||||
SchoolEditR -> useRunDB . maybeT (i18nCrumb MsgBreadcrumbSchool $ Just SchoolListR) $ do
|
||||
breadcrumb SchoolListR = i18nCrumb MsgMenuSchoolList $ Just AdminR
|
||||
breadcrumb (SchoolR ssh SchoolEditR) =
|
||||
useRunDB . maybeT (i18nCrumb MsgBreadcrumbSchool $ Just SchoolListR) $ do
|
||||
School{..} <- MaybeT $ get ssh
|
||||
isAdmin <- lift $ hasReadAccessTo SchoolListR
|
||||
return (CI.original schoolName, bool Nothing (Just SchoolListR) isAdmin)
|
||||
breadcrumb SchoolNewR = i18nCrumb MsgMenuSchoolNew $ Just SchoolListR
|
||||
breadcrumb (SchoolR ssh (SchoolDayR d)) = do
|
||||
dt <- formatTime SelFormatDate d
|
||||
mr <- getMessageRender
|
||||
return (mr $ MsgMenuSchoolDay ssh dt, Just SchoolListR)
|
||||
breadcrumb (SchoolR ssh (SchoolDayCheckR d))
|
||||
= i18nCrumb MsgMenuSchoolDayCheck $ Just (SchoolR ssh (SchoolDayR d))
|
||||
breadcrumb SchoolNewR = i18nCrumb MsgMenuSchoolNew $ Just SchoolListR
|
||||
|
||||
breadcrumb (ExamOfficeR EOExamsR) = i18nCrumb MsgMenuExamOfficeExams Nothing
|
||||
breadcrumb (ExamOfficeR EOFieldsR) = i18nCrumb MsgMenuExamOfficeFields . Just $ ExamOfficeR EOExamsR
|
||||
@ -181,12 +191,14 @@ breadcrumb InstanceR = i18nCrumb MsgMenuInstance Nothing
|
||||
breadcrumb StatusR = i18nCrumb MsgMenuHealth Nothing -- never displayed
|
||||
|
||||
breadcrumb QualificationAllR = i18nCrumb MsgMenuQualifications Nothing
|
||||
breadcrumb (QualificationSchoolR ssh ) = useRunDB . maybeT (i18nCrumb MsgBreadcrumbSchool . Just $ SchoolListR) $ do -- redirect only, used in other breadcrumbs
|
||||
breadcrumb (QualificationSchoolR ssh ) = useRunDB . maybeT (i18nCrumb MsgBreadcrumbSchool . Just $ SchoolListR) $ do
|
||||
guardM . lift . existsBy . UniqueSchoolShorthand $ unSchoolKey ssh
|
||||
return (CI.original $ unSchoolKey ssh, Just QualificationAllR)
|
||||
breadcrumb (QualificationNewR ssh ) = i18nCrumb MsgMenuQualificationNew $ Just $ QualificationSchoolR ssh
|
||||
breadcrumb (QualificationR ssh qsh) =useRunDB . maybeT (i18nCrumb MsgBreadcrumbCourse . Just $ QualificationSchoolR ssh) $ do
|
||||
guardM . lift . existsBy $ SchoolQualificationShort ssh qsh
|
||||
return (CI.original qsh, Just $ QualificationSchoolR ssh)
|
||||
breadcrumb (QualificationEditR ssh qsh) = i18nCrumb MsgMenuQualificationEdit $ Just $ QualificationR ssh qsh
|
||||
breadcrumb QualificationSAPDirectR = i18nCrumb MsgMenuSap $ Just QualificationAllR -- never displayed
|
||||
|
||||
breadcrumb LmsAllR = i18nCrumb MsgMenuLms Nothing
|
||||
@ -196,10 +208,10 @@ breadcrumb (LmsSchoolR ssh ) = useRunDB . maybeT (i18nCrumb MsgBrea
|
||||
breadcrumb (LmsR ssh qsh) = useRunDB . maybeT (i18nCrumb MsgBreadcrumbCourse . Just $ LmsSchoolR ssh) $ do
|
||||
guardM . lift . existsBy $ SchoolQualificationShort ssh qsh
|
||||
return (CI.original qsh, Just $ LmsSchoolR ssh)
|
||||
breadcrumb (LmsEditR ssh qsh) = i18nCrumb MsgMenuLmsEdit $ Just $ LmsR ssh qsh
|
||||
-- v2
|
||||
breadcrumb (LmsLearnersR ssh qsh) = i18nCrumb MsgMenuLmsLearners $ Just $ LmsR ssh qsh
|
||||
breadcrumb (LmsLearnersDirectR ssh qsh) = i18nCrumb MsgMenuLmsLearners $ Just $ LmsLearnersR ssh qsh -- never displayed, TypedContent
|
||||
breadcrumb (LmsOrphansR ssh qsh) = i18nCrumb MsgLmsOrphans $ Just $ LmsLearnersR ssh qsh
|
||||
breadcrumb (LmsReportR ssh qsh) = i18nCrumb MsgMenuLmsReport $ Just $ LmsR ssh qsh
|
||||
breadcrumb (LmsReportUploadR ssh qsh) = i18nCrumb MsgMenuLmsUpload $ Just $ LmsReportR ssh qsh
|
||||
breadcrumb (LmsReportDirectR ssh qsh) = i18nCrumb MsgMenuLmsUpload $ Just $ LmsReportR ssh qsh -- never displayed
|
||||
@ -305,6 +317,7 @@ breadcrumb (CourseR tid ssh csh (TutorialR tutn sRoute)) = case sRoute of
|
||||
guardM . lift . hasReadAccessTo $ CTutorialR tid ssh csh tutn TUsersR
|
||||
return (CI.original tutn, Just $ CourseR tid ssh csh CTutorialListR)
|
||||
TAddUserR -> i18nCrumb MsgMenuTutorialAddMembers . Just $ CTutorialR tid ssh csh tutn TUsersR
|
||||
TExamR exn -> i18nCrumb (MsgMenuTutorialExam exn) . Just $ CTutorialR tid ssh csh tutn TUsersR
|
||||
TEditR -> i18nCrumb MsgMenuTutorialEdit . Just $ CTutorialR tid ssh csh tutn TUsersR
|
||||
TDeleteR -> i18nCrumb MsgMenuTutorialDelete . Just $ CTutorialR tid ssh csh tutn TUsersR
|
||||
TCommR -> i18nCrumb MsgMenuTutorialComm . Just $ CTutorialR tid ssh csh tutn TUsersR
|
||||
@ -935,19 +948,37 @@ pageActions :: ( MonadHandler m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> Route UniWorX -> m [Nav]
|
||||
pageActions NewsR = return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
{ navLabel = MsgMenuOpenCourses
|
||||
, navRoute = (CourseListR, [("courses-openregistration", toPathPiece True)])
|
||||
, navAccess' = NavAccessTrue
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
pageActions NewsR = do
|
||||
now <- liftIO getCurrentTime
|
||||
let nowaday = utctDay now
|
||||
nd <- formatTime SelFormatDate now
|
||||
schools <- useRunDB $ selectList [] [Asc SchoolShorthand]
|
||||
return $
|
||||
( NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
{ navLabel = MsgMenuOpenCourses
|
||||
, navRoute = (CourseListR, [("courses-openregistration", toPathPiece True)])
|
||||
, navAccess' = NavAccessTrue
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, navChildren = []
|
||||
}
|
||||
, navChildren = []
|
||||
}
|
||||
]
|
||||
) :
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
{ navLabel = MsgMenuSchoolDay ssh nd
|
||||
, navRoute = SchoolR ssh $ SchoolDayR nowaday
|
||||
, navAccess' = NavAccessTrue
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, navChildren = []
|
||||
}
|
||||
| sch <- schools, let ssh = sch ^. _entityKey
|
||||
]
|
||||
pageActions (CourseR tid ssh csh CShowR) = do
|
||||
materialListSecondary <- pageQuickActions NavQuickViewPageActionSecondary $ CourseR tid ssh csh MaterialListR
|
||||
tutorialListSecondary <- pageQuickActions NavQuickViewPageActionSecondary $ CourseR tid ssh csh CTutorialListR
|
||||
@ -1177,6 +1208,18 @@ pageActions SchoolListR = return
|
||||
, navChildren = []
|
||||
}
|
||||
]
|
||||
pageActions (SchoolR ssh (SchoolDayR nd)) = return $
|
||||
( NavPageActionPrimary
|
||||
{ navLink = defNavLinkModal MsgMenuSchoolDayCheck $ SchoolR ssh $ SchoolDayCheckR nd
|
||||
, navChildren = []
|
||||
}
|
||||
) :
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = defNavLink msg $ SchoolR ssh (SchoolDayR $ addDays n nd)
|
||||
, navChildren = []
|
||||
}
|
||||
| (msg, n) <- [(MsgWeekPrev, -7), (MsgDayPrev, -1), (MsgDayNext, 1), (MsgWeekNext, 7)]
|
||||
]
|
||||
pageActions UsersR = return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
@ -1763,6 +1806,12 @@ pageActions (CTutorialR tid ssh csh tutn TUsersR) = do
|
||||
}
|
||||
}
|
||||
]
|
||||
pageActions (CTutorialR tid ssh csh _tutn (TExamR ename)) = return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = defNavLink MsgMenuExamEditComplete $ CourseR tid ssh csh $ ExamR ename EEditR
|
||||
, navChildren = []
|
||||
}
|
||||
]
|
||||
pageActions (CourseR tid ssh csh CExamListR) = return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
@ -1957,7 +2006,7 @@ pageActions (CSheetR tid ssh csh shn SShowR) = do
|
||||
{ navLabel = MsgMenuSheetPersonalisedFiles
|
||||
, navRoute = CSheetR tid ssh csh shn SPersonalFilesR
|
||||
, navAccess' = NavAccessDB $
|
||||
let onlyPersonalised = fmap (maybe False $ not . E.unValue) . E.selectMaybe . E.from $ \(sheet `E.InnerJoin` course) -> do
|
||||
let onlyPersonalised = fmap (maybe False $ not . E.unValue) . E.selectOne . E.from $ \(sheet `E.InnerJoin` course) -> do
|
||||
E.on $ sheet E.^. SheetCourse E.==. course E.^. CourseId
|
||||
E.where_$ sheet E.^. SheetName E.==. E.val shn
|
||||
E.&&. course E.^. CourseTerm E.==. E.val tid
|
||||
@ -2378,6 +2427,20 @@ pageActions ParticipantsListR = return
|
||||
, navChildren = []
|
||||
}
|
||||
]
|
||||
pageActions QualificationAllR = do
|
||||
schools <- useRunDB $ selectList [] [Asc SchoolShorthand] -- selectKeysList here mysteriously leads to runtime error: InternalError "selectKeysImpl:" School: keyFromValues failed
|
||||
return [ NavPageActionSecondary { navLink = defNavLink (SomeMessage $ unSchoolKey sid) (QualificationSchoolR sid) } | Entity{entityKey=sid} <- schools ]
|
||||
pageActions (QualificationSchoolR sid) = return
|
||||
[ NavPageActionSecondary {
|
||||
navLink = defNavLink MsgMenuQualificationNew $ QualificationNewR sid
|
||||
}
|
||||
]
|
||||
pageActions (QualificationR sid qsh) = return
|
||||
[ NavPageActionSecondary {
|
||||
navLink = defNavLink MsgMenuQualificationEdit $ QualificationEditR sid qsh
|
||||
}
|
||||
]
|
||||
|
||||
pageActions (LmsR sid qsh) = return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = defNavLink MsgMenuLmsLearners $ LmsLearnersR sid qsh
|
||||
@ -2393,12 +2456,18 @@ pageActions (LmsR sid qsh) = return
|
||||
]
|
||||
}
|
||||
, NavPageActionSecondary {
|
||||
navLink = defNavLink MsgMenuLmsEdit $ LmsEditR sid qsh
|
||||
navLink = defNavLink MsgMenuQualificationEdit $ QualificationEditR sid qsh
|
||||
}
|
||||
-- , NavPageActionSecondary {
|
||||
-- navLink = defNavLink MsgMenuLmsFake $ LmsFakeR sid qsh
|
||||
-- }
|
||||
]
|
||||
pageActions (LmsLearnersR sid qsh) = return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = defNavLink MsgLmsOrphans $ LmsOrphansR sid qsh
|
||||
, navChildren = []
|
||||
}
|
||||
]
|
||||
pageActions ApiDocsR = return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
@ -2412,6 +2481,12 @@ pageActions ApiDocsR = return
|
||||
, navChildren = []
|
||||
}
|
||||
]
|
||||
pageActions FirmAllR = do
|
||||
let navLink = defNavLink MsgMenuFirmsSupervision FirmsSupervisionR
|
||||
navChildren = []
|
||||
(thereAre,_) <- liftHandler areThereInsaneCompanySupervisions
|
||||
return [ NavPageActionPrimary{..} | thereAre ]
|
||||
|
||||
pageActions (FirmUsersR fsh) = return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = defNavLink MsgTableCompanyNrSupers $ FirmSupersR fsh
|
||||
@ -2559,7 +2634,7 @@ submissionList tid csh shn uid = withReaderT (projectBackend @SqlReadBackend) .
|
||||
E.on $ sheet E.^. SheetCourse E.==. course E.^. CourseId
|
||||
|
||||
E.where_ $ submissionUser E.^. SubmissionUserUser E.==. E.val uid
|
||||
E.&&. sheet E.^. SheetName E.==. E.val shn
|
||||
E.&&. sheet E.^. SheetName E.==. E.val shn
|
||||
E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
E.&&. course E.^. CourseTerm E.==. E.val tid
|
||||
|
||||
|
||||
@ -258,7 +258,7 @@ siteLayout' overrideHeading widget = do
|
||||
forM_ authTagPivots $
|
||||
\authTag -> addMessageWidget Info $ msgModal [whamlet|_{MsgUnauthorizedDisabledTag authTag}|] (Left $ SomeRoute (AuthPredsR, catMaybes [(toPathPiece GetReferer, ) . toPathPiece <$> mcurrentRoute]))
|
||||
getMessages
|
||||
|
||||
|
||||
storedReasonAndToggleRoute <- case mcurrentRoute of
|
||||
(Just (CourseR tid ssh csh _)) -> (, Just . SomeRoute $ CourseR tid ssh csh CFavouriteR) <$> storedFavouriteReason tid ssh csh muid
|
||||
_otherwise -> pure (Nothing, Nothing)
|
||||
@ -270,8 +270,8 @@ siteLayout' overrideHeading widget = do
|
||||
, nav'
|
||||
, contentHeadline
|
||||
, mmsgs
|
||||
, maybe userDefaultMaxFavouriteTerms userMaxFavouriteTerms $ view _2 <$> muid
|
||||
, maybe userDefaultTheme userTheme $ view _2 <$> muid
|
||||
, maybe userDefaultMaxFavouriteTerms (userMaxFavouriteTerms . view _2) muid
|
||||
, maybe userDefaultTheme (userTheme . view _2) muid
|
||||
, storedReasonAndToggleRoute
|
||||
)
|
||||
|
||||
@ -303,7 +303,7 @@ siteLayout' overrideHeading widget = do
|
||||
| otherwise = Set.drop (Set.size ts - n) ts
|
||||
currentTerms = toTermKeySet $ filter (views (_2 . _Value) . maybe True $ is _FavouriteCurrent) favourites'
|
||||
toTermKeySet = setOf $ folded . _1 . _2 . to unTermKey
|
||||
|
||||
|
||||
favourites <- fmap catMaybes . forM favourites' $ \(c@(_, tid, ssh, csh), E.Value mFavourite, courseVisible, mayView, mayEdit)
|
||||
-> let courseRoute = CourseR tid ssh csh CShowR
|
||||
favouriteReason = fromMaybe FavouriteCurrent mFavourite
|
||||
@ -512,7 +512,7 @@ siteLayout' overrideHeading widget = do
|
||||
$(widgetFile "default-layout")
|
||||
withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet")
|
||||
|
||||
|
||||
|
||||
getSystemMessageState :: (MonadHandler m, HandlerSite m ~ UniWorX, BearerAuthSite UniWorX) => SystemMessageId -> m UserSystemMessageState
|
||||
getSystemMessageState smId = liftHandler $ do
|
||||
muid <- maybeAuthId
|
||||
@ -598,7 +598,7 @@ applySystemMessages = maybeT_ . catchMPlus (Proxy @CryptoIDError) $ do
|
||||
|
||||
|
||||
-- FIXME: Move headings into their respective handlers
|
||||
|
||||
|
||||
-- | Method for specifying page heading for handlers that call defaultLayout
|
||||
--
|
||||
-- All handlers whose code is under our control should use
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
-- SPDX-FileCopyrightText: 2022-26 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -11,11 +11,11 @@ module Foundation.Type
|
||||
, _SessionStorageMemcachedSql, _SessionStorageAcid
|
||||
, AppMemcached(..)
|
||||
, _memcachedKey, _memcachedConn
|
||||
, AppMemcachedLocal(..)
|
||||
, _memcachedLocalARC
|
||||
, SMTPPool
|
||||
, _appSettings', _appStatic, _appConnPool, _appSmtpPool, _appLdapPool, _appWidgetMemcached, _appHttpManager, _appLogger, _appLogSettings, _appCryptoIDKey, _appClusterID, _appInstanceID, _appJobState, _appSessionStore, _appSecretBoxKey, _appJSONWebKeySet, _appHealthReport, _appMemcached, _appUploadCache, _appVerpSecret, _appAuthKey, _appPersonalisedSheetFilesSeedKey, _appVolatileClusterSettingsCache, _appAvsQuery
|
||||
, DB, DBRead, Form, MsgRenderer, MailM, DBFile
|
||||
, DB
|
||||
, DBRead, DBRead', DBReadUq, DBReadUq'
|
||||
, Form, MsgRenderer, MailM, DBFile
|
||||
) where
|
||||
|
||||
import Import.NoFoundation
|
||||
@ -32,15 +32,10 @@ import qualified Jose.Jwk as Jose
|
||||
import qualified Database.Memcached.Binary.IO as Memcached
|
||||
import Network.Minio (MinioConn)
|
||||
|
||||
import Data.IntervalMap.Strict (IntervalMap)
|
||||
|
||||
import qualified Utils.Pool as Custom
|
||||
|
||||
import Utils.Metrics (DBConnUseState)
|
||||
|
||||
import qualified Data.ByteString.Lazy as Lazy
|
||||
import Data.Time.Clock.POSIX (POSIXTime)
|
||||
import GHC.Fingerprint (Fingerprint)
|
||||
import Handler.Sheet.PersonalisedFiles.Types (PersonalisedSheetFilesSeedKey)
|
||||
|
||||
import Utils.Avs (AvsQuery())
|
||||
@ -62,13 +57,6 @@ data AppMemcached = AppMemcached
|
||||
|
||||
makeLenses_ ''AppMemcached
|
||||
|
||||
data AppMemcachedLocal = AppMemcachedLocal
|
||||
{ memcachedLocalARC :: ARCHandle (Fingerprint, Lazy.ByteString) Int (NFDynamic, Maybe POSIXTime)
|
||||
, memcachedLocalHandleInvalidations :: Async ()
|
||||
, memcachedLocalInvalidationQueue :: TVar (Seq (Fingerprint, Lazy.ByteString))
|
||||
} deriving (Generic)
|
||||
|
||||
makeLenses_ ''AppMemcachedLocal
|
||||
|
||||
-- | The foundation datatype for your application. This can be a good place to
|
||||
-- keep settings and values requiring initialization before your application
|
||||
@ -93,14 +81,10 @@ data UniWorX = UniWorX
|
||||
, appJSONWebKeySet :: Jose.JwkSet
|
||||
, appHealthReport :: TVar (Set (UTCTime, HealthReport))
|
||||
, appMemcached :: Maybe AppMemcached
|
||||
, appMemcachedLocal :: Maybe AppMemcachedLocal
|
||||
, appUploadCache :: Maybe MinioConn
|
||||
, appVerpSecret :: VerpSecret
|
||||
, appAuthKey :: Auth.Key
|
||||
, appAuthPlugins :: [AuthPlugin UniWorX]
|
||||
, appFileSourceARC :: Maybe (ARCHandle (FileContentChunkReference, (Int, Int)) Int ByteString)
|
||||
, appFileSourcePrewarm :: Maybe (LRUHandle (FileContentChunkReference, (Int, Int)) UTCTime Int ByteString)
|
||||
, appFileInjectInhibit :: TVar (IntervalMap UTCTime (Set FileContentReference))
|
||||
, appPersonalisedSheetFilesSeedKey :: PersonalisedSheetFilesSeedKey
|
||||
, appVolatileClusterSettingsCache :: TVar VolatileClusterSettingsCache
|
||||
, appStartTime :: UTCTime -- for Status Page
|
||||
@ -124,9 +108,17 @@ instance HasCookieSettings RegisteredCookie UniWorX where
|
||||
instance (MonadHandler m, HandlerSite m ~ UniWorX) => ReadLogSettings m where
|
||||
readLogSettings = liftIO . readTVarIO =<< getsYesod (view _appLogSettings)
|
||||
|
||||
|
||||
type DB = YesodDB UniWorX
|
||||
type DBRead = ReaderT SqlReadBackend (HandlerFor UniWorX)
|
||||
-- ~ ReaderT SqlBackend (HandlerFor UniWorX)
|
||||
-- type DBRead = ReaderT SqlReadBackend (HandlerFor UniWorX) -- old, was too unflexible. Try DBRead first, then add suffixes ' or Uq until it types ;)
|
||||
type DBRead a = forall backend . (PersistQueryRead backend, BackendCompatible SqlBackend backend)
|
||||
=> ReaderT backend (HandlerFor UniWorX) a
|
||||
type DBRead' a = forall backend . (PersistQueryRead backend, BackendCompatible SqlBackend backend, BaseBackend backend ~ SqlBackend) -- ought to be redundant, but somehow isn´t. Using this everywhere give redundant constraint warnings, also undesirable
|
||||
=> ReaderT backend (HandlerFor UniWorX) a
|
||||
type DBReadUq a = forall backend . (PersistQueryRead backend, BackendCompatible SqlBackend backend, PersistUniqueRead backend) -- adding this to DBRead would yield some unnecessary constraint warnings
|
||||
=> ReaderT backend (HandlerFor UniWorX) a
|
||||
type DBReadUq' a = forall backend . (PersistQueryRead backend, BackendCompatible SqlBackend backend, BaseBackend backend ~ SqlBackend, PersistUniqueRead backend)
|
||||
=> ReaderT backend (HandlerFor UniWorX) a
|
||||
type Form x = Html -> MForm (HandlerFor UniWorX) (FormResult x, WidgetFor UniWorX ())
|
||||
type MsgRenderer = MsgRendererS UniWorX -- see Utils
|
||||
type MailM a = MailT (HandlerFor UniWorX) a
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>,Gregor Kleen <gregor.kleen@ifi.lmu.de>, Steffen Jost <jost@tcs.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
-- SPDX-FileCopyrightText: 2022-202025 Sarah Vaupel <sarah.vaupel@uniworx.de>,Gregor Kleen <gregor.kleen@ifi.lmu.de>, Steffen Jost <jost@tcs.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -25,6 +25,7 @@ import qualified Database.Esqueleto.Legacy as EL (on) -- needed for dbTable
|
||||
import qualified Database.Esqueleto.Utils as E
|
||||
|
||||
import Jobs
|
||||
import Utils.Company (areThereInsaneCompanySupervisions)
|
||||
import Handler.Utils
|
||||
import Handler.Utils.Avs
|
||||
import Handler.Utils.Users
|
||||
@ -83,13 +84,18 @@ handleAdminProblems mbProblemTable = do
|
||||
flagNonZero n | n <= 0 = flagError True
|
||||
| otherwise = messageTooltip =<< handlerToWidget (messageI Error (MsgProblemsDriverSynch n))
|
||||
|
||||
(usersAreReachable, driversHaveAvsIds, rDriversHaveFs, noStalePrintJobs, noBadAPCids, (interfaceOks, interfaceTable)) <- runDB $ (,,,,,)
|
||||
<$> areAllUsersReachable
|
||||
<*> allDriversHaveAvsId now
|
||||
showDiffTime t =
|
||||
let d = diffUTCTime now t
|
||||
in guardMonoid (d > secondsToNominalDiffTime 30) [whamlet|<small>_{MsgProblemLastCheckTime (formatDiffDays d)}|]
|
||||
|
||||
(usersAreReachable, aurTime) <- areAllUsersReachable -- cached
|
||||
(not -> thereAreInsaneFirmSupervisions, ifsTime) <- areThereInsaneCompanySupervisions -- cached
|
||||
(driversHaveAvsIds, rDriversHaveFs, not -> noStalePrintJobs, not -> noBadAPCids) <- runDBRead $ (,,,)
|
||||
<$> allDriversHaveAvsId now
|
||||
<*> allRDriversHaveFs now
|
||||
<*> (not <$> exists [PrintJobAcknowledged ==. Nothing, PrintJobCreated <. cutOffOldTime])
|
||||
<*> (not <$> exists [PrintAcknowledgeProcessed ==. False])
|
||||
<*> mkInterfaceLogTable mempty
|
||||
<*> exists [PrintJobAcknowledged ==. Nothing, PrintJobCreated <. cutOffOldTime]
|
||||
<*> exists [PrintAcknowledgeProcessed ==. False]
|
||||
(interfaceOks, interfaceTable) <- runDB $ mkInterfaceLogTable mempty
|
||||
let interfacesBadNr = length $ filter (not . snd) interfaceOks
|
||||
-- interfacesOk = all snd interfaceOks
|
||||
|
||||
@ -145,7 +151,7 @@ postAdminProblemsR = do
|
||||
getProblemUnreachableR, postProblemUnreachableR :: Handler Html
|
||||
getProblemUnreachableR = postProblemUnreachableR
|
||||
postProblemUnreachableR = do
|
||||
unreachables <- runDB retrieveUnreachableUsers
|
||||
unreachables <- runDBRead retrieveUnreachableUsers
|
||||
|
||||
-- the following form is a nearly identicaly copy from Handler.Users:
|
||||
((noreachUsersRes, noreachUsersWgt'), noreachUsersEnctype) <- runFormPost . identifyForm FIDUnreachableUsersAction $ buttonForm
|
||||
@ -219,9 +225,13 @@ mkUnreachableUsersTable = do
|
||||
dbtColonnade =
|
||||
-}
|
||||
|
||||
areAllUsersReachable :: DB Bool
|
||||
-- areAllUsersReachable = E.selectNotExists retrieveUnreachableUsers' -- works and would be more efficient, but we cannot check proper email validity within DB alone
|
||||
areAllUsersReachable = null <$> retrieveUnreachableUsers
|
||||
areAllUsersReachable :: Handler (Bool, UTCTime)
|
||||
areAllUsersReachable = $(memcachedByHere) (Just . Right $ 22 * diffHour) [st|isane-users-reachable|] $ do
|
||||
now <- liftIO getCurrentTime
|
||||
res <- runDBRead retrieveUnreachableUsers
|
||||
-- res <- E.selectNotExists retrieveUnreachableUsers' -- works and would be more efficient, but we cannot check proper email validity within DB alone
|
||||
$logInfoS "sanity" [st|Are there insane company supervisions: #{tshow res}|]
|
||||
return (null res,now)
|
||||
|
||||
-- retrieveUnreachableUsers' :: E.SqlQuery (E.SqlExpr (Entity User))
|
||||
-- retrieveUnreachableUsers' = do
|
||||
@ -232,7 +242,7 @@ areAllUsersReachable = null <$> retrieveUnreachableUsers
|
||||
-- E.&&. E.not_ ((user E.^. UserEmail) `E.like` E.val "%@%.%")
|
||||
-- return user
|
||||
|
||||
retrieveUnreachableUsers :: DB [Entity User]
|
||||
retrieveUnreachableUsers :: DBReadUq' [Entity User]
|
||||
retrieveUnreachableUsers = do
|
||||
emailOnlyUsers <- E.select $ do
|
||||
user <- E.from $ E.table @User
|
||||
@ -252,7 +262,7 @@ retrieveUnreachableUsers = do
|
||||
hasInvalidEmail = fmap isNothing . getUserEmail
|
||||
|
||||
|
||||
allDriversHaveAvsId :: UTCTime -> DB Bool
|
||||
allDriversHaveAvsId :: UTCTime -> DBReadUq Bool
|
||||
-- allDriversHaveAvsId = fmap isNothing . E.selectOne . retrieveDriversWithoutAvsId
|
||||
allDriversHaveAvsId = E.selectNotExists . retrieveDriversWithoutAvsId
|
||||
|
||||
@ -299,7 +309,7 @@ retrieveDriversWithoutAvsId now = do
|
||||
return usr
|
||||
|
||||
|
||||
allRDriversHaveFs :: UTCTime -> DB Bool
|
||||
allRDriversHaveFs :: UTCTime -> DBReadUq Bool
|
||||
-- allRDriversHaveFs = fmap isNothing . E.selectOne . retrieveDriversRWithoutF
|
||||
allRDriversHaveFs = E.selectNotExists . retrieveDriversRWithoutF
|
||||
|
||||
@ -368,22 +378,22 @@ mkProblemLogTable = do
|
||||
, sortable (Just "solved") (i18nCell MsgAdminProblemSolved) $ \( view $ resultProblem . _entityVal . _problemLogSolved -> t) -> cellMaybe dateTimeCell t
|
||||
, sortable (Just "solver") (i18nCell MsgAdminProblemSolver) $ \(preview resultSolver -> u) -> maybeCell u $ cellHasUserLink AdminUserR
|
||||
]
|
||||
dbtSorting = mconcat
|
||||
[ single ("time" , SortColumn $ queryProblem >>> (E.^. ProblemLogTime))
|
||||
, single ("info" , SortColumn $ queryProblem >>> (E.^. ProblemLogInfo))
|
||||
-- , single ("firm" , SortColumn ((E.->>. "company" ).(queryProblem >>> (E.^. ProblemLogInfo))))
|
||||
, single ("firm" , SortColumn $ \r -> queryProblem r E.^. ProblemLogInfo E.->>. "company")
|
||||
, single ("user" , sortUserNameBareM queryUser)
|
||||
, single ("solved", SortColumn $ queryProblem >>> (E.^. ProblemLogSolved))
|
||||
, single ("solver", sortUserNameBareM querySolver)
|
||||
dbtSorting = Map.fromList
|
||||
[ ("time" , SortColumn $ queryProblem >>> (E.^. ProblemLogTime))
|
||||
, ("info" , SortColumn $ queryProblem >>> (E.^. ProblemLogInfo))
|
||||
-- , ("firm" , SortColumn ((E.->>. "company" ).(queryProblem >>> (E.^. ProblemLogInfo))))
|
||||
, ("firm" , SortColumn $ \r -> queryProblem r E.^. ProblemLogInfo E.->>. "company")
|
||||
, ("user" , sortUserNameBareM queryUser)
|
||||
, ("solved", SortColumn $ queryProblem >>> (E.^. ProblemLogSolved))
|
||||
, ("solver", sortUserNameBareM querySolver)
|
||||
]
|
||||
dbtFilter = mconcat
|
||||
[ single ("user" , FilterColumn . E.mkContainsFilterWithCommaPlus Just $ views (to queryUser) (E.?. UserDisplayName))
|
||||
, single ("solver" , FilterColumn . E.mkContainsFilterWithCommaPlus Just $ views (to querySolver) (E.?. UserDisplayName))
|
||||
, single ("company" , FilterColumn . E.mkContainsFilter $ views (to queryProblem) ((E.->>. "company").(E.^. ProblemLogInfo)))
|
||||
, single ("solved" , FilterColumn . E.mkExactFilterLast $ views (to queryProblem) (E.isJust . (E.^. ProblemLogSolved)))
|
||||
-- , single ("problem" , FilterColumn . E.mkContainsFilter $ views (to queryProblem) ((E.->>. "problem").(E.^. ProblemLogInfo))) -- not stored in plaintext!
|
||||
, single ("problem" , mkFilterProjectedPost $ \(getLast -> criterion) dbr -> -- falls es nicht schnell genug ist: in dbtProj den Anzeigetext nur einmal berechnen
|
||||
dbtFilter = Map.fromList
|
||||
[ ("user" , FilterColumn . E.mkContainsFilterWithCommaPlus Just $ views (to queryUser) (E.?. UserDisplayName))
|
||||
, ("solver" , FilterColumn . E.mkContainsFilterWithCommaPlus Just $ views (to querySolver) (E.?. UserDisplayName))
|
||||
, ("company" , FilterColumn . E.mkContainsFilter $ views (to queryProblem) ((E.->>. "company").(E.^. ProblemLogInfo)))
|
||||
, ("solved" , FilterColumn . E.mkExactFilterLast $ views (to queryProblem) (E.isJust . (E.^. ProblemLogSolved)))
|
||||
-- , ("problem" , FilterColumn . E.mkContainsFilter $ views (to queryProblem) ((E.->>. "problem").(E.^. ProblemLogInfo))) -- not stored in plaintext!
|
||||
, ("problem" , mkFilterProjectedPost $ \(getLast -> criterion) dbr -> -- falls es nicht schnell genug ist: in dbtProj den Anzeigetext nur einmal berechnen
|
||||
ifNothingM criterion True $ \(crit::Text) -> do
|
||||
let problem = dbr ^. resultProblem . _entityVal . _problemLogAdminProblem
|
||||
protxt <- adminProblem2Text problem
|
||||
@ -398,9 +408,9 @@ mkProblemLogTable = do
|
||||
, prismAForm (singletonFilter "solved" . maybePrism _PathPiece) mPrev $ aopt (boolField . Just $ SomeMessage MsgBoolIrrelevant) (fslI MsgAdminProblemSolved)
|
||||
]
|
||||
acts :: Map ProblemTableAction (AForm Handler ProblemTableActionData)
|
||||
acts = mconcat
|
||||
[ singletonMap ProblemTableMarkSolved $ pure ProblemTableMarkSolvedData
|
||||
, singletonMap ProblemTableMarkUnsolved $ pure ProblemTableMarkUnsolvedData
|
||||
acts = Map.fromList
|
||||
[ (ProblemTableMarkSolved , pure ProblemTableMarkSolvedData)
|
||||
, (ProblemTableMarkUnsolved , pure ProblemTableMarkUnsolvedData)
|
||||
]
|
||||
dbtParams = DBParamsForm
|
||||
{ dbParamsFormMethod = POST
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -38,10 +38,6 @@ import qualified Database.Esqueleto.Utils as E
|
||||
-- import Database.Esqueleto.Utils.TH
|
||||
|
||||
|
||||
-- avoids repetition of local definitions
|
||||
single :: (k,a) -> Map k a
|
||||
single = uncurry Map.singleton
|
||||
|
||||
exceptionWgt :: SomeException -> Widget
|
||||
exceptionWgt (SomeException e) = [whamlet|<h2>Error:</h2> #{tshow e}|]
|
||||
|
||||
@ -627,7 +623,7 @@ instance HasUser LicenceTableData where
|
||||
mkLicenceTable :: AvsPersonIdMapPersonCard -> Set AvsPersonId -> Text -> AvsLicence -> Set AvsPersonId -> DB (FormResult (LicenceTableActionData, Set AvsPersonId), Widget)
|
||||
mkLicenceTable apidStatus rsChanged dbtIdent aLic apids = do
|
||||
(currentRoute, usrHasAvsRerr) <- liftHandler $ (,)
|
||||
<$> (fromMaybe (error "mkLicenceTable called from 404-handler") <$> liftHandler getCurrentRoute)
|
||||
<$> fmap (fromMaybe $ error "mkLicenceTable called from 404-handler") (liftHandler getCurrentRoute)
|
||||
<*> (messageTooltip <$> messageI Error MsgProblemAvsUsrHadR)
|
||||
avsQualifications <- selectList [QualificationAvsLicence !=. Nothing] [Asc QualificationName]
|
||||
now <- liftIO getCurrentTime
|
||||
@ -692,23 +688,23 @@ mkLicenceTable apidStatus rsChanged dbtIdent aLic apids = do
|
||||
) $ \(preview $ resultQualUser . _entityVal . _qualificationUserScheduleRenewal -> b) -> cellMaybe (flip ifIconCell IconNoNotification . not) b
|
||||
, sortable Nothing (i18nCell MsgTableAvsActiveCards) $ \(view $ resultUserAvs . _userAvsPersonId -> apid) -> foldMap avsPersonCardCell $ Map.lookup apid apidStatus
|
||||
]
|
||||
dbtSorting = mconcat
|
||||
[ single $ sortUserNameLink queryUser
|
||||
, single ("avspersonno" , SortColumn $ queryUserAvs >>> (E.^. UserAvsNoPerson))
|
||||
, single ("qualification" , SortColumn $ queryQualification >>> (E.?. QualificationShorthand))
|
||||
, single $ sortUserCompany queryUser
|
||||
, single ("valid-until" , SortColumn $ queryQualUser >>> (E.?. QualificationUserValidUntil))
|
||||
, single ("last-refresh" , SortColumn $ queryQualUser >>> (E.?. QualificationUserLastRefresh))
|
||||
, single ("first-held" , SortColumn $ queryQualUser >>> (E.?. QualificationUserFirstHeld))
|
||||
, single ("blocked" , SortColumnNeverNull $ queryQualBlock >>> (E.?. QualificationUserBlockFrom))
|
||||
, single ("schedule-renew", SortColumnNullsInv $ queryQualUser >>> (E.?. QualificationUserScheduleRenewal))
|
||||
-- , single ("validity" , SortColumn $ queryQualUser >>> (E.?. QualificationUserValidUntil))
|
||||
dbtSorting = Map.fromList
|
||||
[ sortUserNameLink queryUser
|
||||
, ("avspersonno" , SortColumn $ queryUserAvs >>> (E.^. UserAvsNoPerson))
|
||||
, ("qualification" , SortColumn $ queryQualification >>> (E.?. QualificationShorthand))
|
||||
, sortUserCompany queryUser
|
||||
, ("valid-until" , SortColumn $ queryQualUser >>> (E.?. QualificationUserValidUntil))
|
||||
, ("last-refresh" , SortColumn $ queryQualUser >>> (E.?. QualificationUserLastRefresh))
|
||||
, ("first-held" , SortColumn $ queryQualUser >>> (E.?. QualificationUserFirstHeld))
|
||||
, ("blocked" , SortColumnNeverNull $ queryQualBlock >>> (E.?. QualificationUserBlockFrom))
|
||||
, ("schedule-renew", SortColumnNullsInv $ queryQualUser >>> (E.?. QualificationUserScheduleRenewal))
|
||||
-- , ("validity" , SortColumn $ queryQualUser >>> (E.?. QualificationUserValidUntil))
|
||||
]
|
||||
|
||||
dbtFilter = mconcat
|
||||
[ single $ fltrUserNameEmail queryUser
|
||||
, single ("validity" , FilterColumn . E.mkExactFilterLast $ views (to queryQualUser) (validQualification' now))
|
||||
, single ( "user-company", FilterColumn . E.mkExistsFilter $ \row criterion ->
|
||||
dbtFilter = Map.fromList
|
||||
[ fltrUserNameEmail queryUser
|
||||
, ("validity" , FilterColumn . E.mkExactFilterLast $ views (to queryQualUser) (validQualification' now))
|
||||
, ( "user-company", FilterColumn . E.mkExistsFilter $ \row criterion ->
|
||||
E.from $ \(usrComp `E.InnerJoin` comp) -> do
|
||||
let testname = (E.val criterion :: E.SqlExpr (E.Value (CI Text))) `E.isInfixOf`
|
||||
(E.explicitUnsafeCoerceSqlExprValue "citext" (comp E.^. CompanyName) :: E.SqlExpr (E.Value (CI Text)))
|
||||
@ -738,11 +734,9 @@ mkLicenceTable apidStatus rsChanged dbtIdent aLic apids = do
|
||||
E.orderBy [E.desc countRows']
|
||||
E.limit 7
|
||||
pure (qblock E.^. QualificationUserBlockReason)
|
||||
mkOption :: E.Value Text -> Option Text
|
||||
mkOption (E.unValue -> t) = Option{ optionDisplay = t, optionInternalValue = t, optionExternalValue = toPathPiece t }
|
||||
suggestionsBlock :: HandlerFor UniWorX (OptionList Text)
|
||||
suggestionsBlock = mkOptionList . fmap mkOption <$> runDBRead (getBlockReasons E.not__)
|
||||
suggestionsUnblock = mkOptionList . fmap mkOption <$> runDBRead (getBlockReasons id)
|
||||
suggestionsBlock = mkOptionListText <$> runDBRead (getBlockReasons E.not__)
|
||||
suggestionsUnblock = mkOptionListText <$> runDBRead (getBlockReasons id)
|
||||
|
||||
acts :: Map LicenceTableAction (AForm Handler LicenceTableActionData)
|
||||
acts = mconcat
|
||||
@ -811,7 +805,8 @@ postAdminAvsUserR uuid = do
|
||||
mbContact <- try $ fmap fltrIdContact $ avsQuery $ AvsQueryContact $ Set.singleton $ AvsObjPersonId userAvsPersonId
|
||||
-- mbStatus <- try $ fmap fltrIdStatus $ avsQuery $ AvsQueryStatus $ Set.singleton userAvsPersonId
|
||||
mbStatus <- try $ queryAvsFullStatus userAvsPersonId -- TODO: delete Handler.Utils.Avs.lookupAvsUser if no longer needed -- NOTE: currently needed to provide card firms that are missing in AVS status query responses
|
||||
let compsUsed :: [CompanyName] = stripCI <$> mbStatus ^.. _Right . _Wrapped . folded . _avsStatusPersonCardStatus . folded . _avsDataFirm . _Just
|
||||
-- $logInfoS "AVS-1" [st|Status query for #{tshow userAvsPersonId} lieferte #{tshow mbStatus} |] -- DEBUG
|
||||
let compsUsed :: [CompanyName] = mbStatus ^.. _Right . _Wrapped . folded . _avsStatusPersonCardStatus . folded . _avsDataFirm . _Just . to stripCI
|
||||
compDict <- if 1 >= length compsUsed
|
||||
then return mempty -- switch company only sensible if there is more than one company to choose
|
||||
else do
|
||||
@ -1004,15 +999,15 @@ getProblemAvsErrorR = do
|
||||
E.on $ usravs E.^. UserAvsUser E.==. user E.^. UserId
|
||||
E.where_ $ E.isJust $ usravs E.^. UserAvsLastSynchError
|
||||
return (usravs, user) -- , E.substring (usravs E.^. UserAvsLastSynchError) (E.val ("'#\"%#\" %'") (E.val "#")) -- needs a different type on substring
|
||||
qerryUsrAvs :: (E.SqlExpr (Entity UserAvs) `E.InnerJoin` E.SqlExpr (Entity User)) -> E.SqlExpr (Entity UserAvs)
|
||||
qerryUsrAvs = $(E.sqlIJproj 2 1)
|
||||
qerryUser :: (E.SqlExpr (Entity UserAvs) `E.InnerJoin` E.SqlExpr (Entity User)) -> E.SqlExpr (Entity User)
|
||||
qerryUser = $(E.sqlIJproj 2 2)
|
||||
querryUsrAvs :: (E.SqlExpr (Entity UserAvs) `E.InnerJoin` E.SqlExpr (Entity User)) -> E.SqlExpr (Entity UserAvs)
|
||||
querryUsrAvs = $(E.sqlIJproj 2 1)
|
||||
querryUser :: (E.SqlExpr (Entity UserAvs) `E.InnerJoin` E.SqlExpr (Entity User)) -> E.SqlExpr (Entity User)
|
||||
querryUser = $(E.sqlIJproj 2 2)
|
||||
reserrUsrAvs :: Lens' (DBRow (Entity UserAvs, Entity User)) (Entity UserAvs)
|
||||
reserrUsrAvs = _dbrOutput . _1
|
||||
-- reserrUser :: Lens' (DBRow (Entity UserAvs, Entity User)) (Entity User)
|
||||
-- reserrUser = _dbrOutput . _2
|
||||
dbtRowKey = qerryUsrAvs >>> (E.^. UserAvsId)
|
||||
dbtRowKey = querryUsrAvs >>> (E.^. UserAvsId)
|
||||
dbtProj = dbtProjId
|
||||
dbtColonnade = dbColonnade $ mconcat
|
||||
[ colUserNameModalHdrAdmin MsgLmsUser AdminUserR
|
||||
@ -1025,15 +1020,15 @@ getProblemAvsErrorR = do
|
||||
, sortable (Just "avs-last-error") (i18nCell MsgLastAvsSynchError)
|
||||
$ cellMaybe textCell . view (reserrUsrAvs . _entityVal . _userAvsLastSynchError)
|
||||
]
|
||||
dbtSorting = mconcat
|
||||
[ single (sortUserNameLink qerryUser)
|
||||
, single ("avs-nr" , SortColumn $ qerryUsrAvs >>> (E.^. UserAvsNoPerson))
|
||||
, single ("avs-last-synch", SortColumnNullsInv $ qerryUsrAvs >>> (E.^. UserAvsLastSynch))
|
||||
, single ("avs-last-error", SortColumn $ qerryUsrAvs >>> (E.^. UserAvsLastSynchError))
|
||||
dbtSorting = Map.fromList
|
||||
[ sortUserNameLink querryUser
|
||||
, ("avs-nr" , SortColumn $ querryUsrAvs >>> (E.^. UserAvsNoPerson))
|
||||
, ("avs-last-synch", SortColumnNullsInv $ querryUsrAvs >>> (E.^. UserAvsLastSynch))
|
||||
, ("avs-last-error", SortColumn $ querryUsrAvs >>> (E.^. UserAvsLastSynchError))
|
||||
]
|
||||
dbtFilter = mconcat
|
||||
[ single $ fltrUserNameEmail qerryUser
|
||||
, single ("avs-last-error", FilterColumn $ E.mkContainsFilterWithCommaPlus Just $ views (to qerryUsrAvs) (E.^. UserAvsLastSynchError))
|
||||
dbtFilter = Map.fromList
|
||||
[ fltrUserNameEmail querryUser
|
||||
, ("avs-last-error", FilterColumn $ E.mkContainsFilterWithCommaPlus Just $ views (to querryUsrAvs) (E.^. UserAvsLastSynchError))
|
||||
]
|
||||
dbtFilterUI mPrev = mconcat
|
||||
[ fltrUserNameEmailHdrUI MsgLmsUser mPrev
|
||||
|
||||
@ -17,7 +17,7 @@ import Handler.Utils
|
||||
-- import Data.Aeson (fromJSON)
|
||||
-- import qualified Data.Aeson as Aeson
|
||||
-- import qualified Data.Aeson.Types as Aeson
|
||||
import qualified Data.Aeson.Encode.Pretty as Pretty
|
||||
import qualified Data.Aeson.Encode.Pretty as Pretty
|
||||
|
||||
-- import qualified Data.CaseInsensitive as CI
|
||||
import qualified Data.Text as Text
|
||||
@ -37,13 +37,13 @@ import qualified Database.Esqueleto.Utils as E
|
||||
|
||||
-- Number of minutes a job must have been locked already to allow forced deletion
|
||||
jobDeleteLockMinutes :: Int
|
||||
jobDeleteLockMinutes = 3
|
||||
jobDeleteLockMinutes = 3
|
||||
|
||||
deriveJSON defaultOptions
|
||||
{ constructorTagModifier = camelToPathPiece' 1
|
||||
} ''CronNextMatch
|
||||
|
||||
|
||||
|
||||
getAdminCrontabR :: Handler TypedContent
|
||||
getAdminCrontabR = do
|
||||
jState <- getsYesod appJobState
|
||||
@ -64,7 +64,7 @@ getAdminCrontabR = do
|
||||
|
||||
encodeBearer =<< bearerToken (HashSet.singleton . Left $ toJSON UserGroupCrontab) Nothing (HashMap.singleton BearerTokenRouteEval $ HashSet.singleton AdminCrontabR) Nothing (Just Nothing) Nothing
|
||||
|
||||
|
||||
|
||||
siteLayoutMsg MsgHeadingAdminCrontab $ do
|
||||
setTitleI MsgHeadingAdminCrontab
|
||||
[whamlet|
|
||||
@ -114,6 +114,7 @@ getAdminCrontabR = do
|
||||
|
||||
|
||||
data JobTableAction = ActJobDelete
|
||||
| ActJobSleep
|
||||
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic)
|
||||
|
||||
instance Universe JobTableAction
|
||||
@ -121,9 +122,10 @@ instance Finite JobTableAction
|
||||
nullaryPathPiece ''JobTableAction $ camelToPathPiece' 1
|
||||
embedRenderMessage ''UniWorX ''JobTableAction id
|
||||
|
||||
newtype JobTableActionData = ActJobDeleteData
|
||||
{ jobDeleteLocked :: Bool
|
||||
}
|
||||
data JobTableActionData
|
||||
= ActJobDeleteData { jobDeleteLocked :: Bool }
|
||||
| ActJobSleepData { jobSleepNr, jobSleepSecs :: Int
|
||||
, jobSleepNow :: Bool }
|
||||
deriving (Eq, Ord, Read, Show, Generic)
|
||||
|
||||
|
||||
@ -151,7 +153,7 @@ postAdminJobsR = do
|
||||
, sortable (Just "lock-instance") (i18nCell MsgTableJobLockInstance) $ \(view $ resultJob . _entityVal -> QueuedJob{..}) -> cellMaybe (stringCell . show) queuedJobLockInstance
|
||||
, sortable (Just "creation-instance") (i18nCell MsgTableJobCreationInstance) $ \(view $ resultJob . _entityVal -> QueuedJob{..}) -> stringCell $ show queuedJobCreationInstance
|
||||
]
|
||||
dbtSorting = Map.fromList
|
||||
dbtSorting = Map.fromList
|
||||
[ ("creation-time" , SortColumnNullsInv (E.^. QueuedJobCreationTime))
|
||||
, ("job" , SortColumn (\v -> v E.^. QueuedJobContent E.->>. "job"))
|
||||
, ("content" , SortColumn (E.^. QueuedJobContent))
|
||||
@ -168,11 +170,20 @@ postAdminJobsR = do
|
||||
prismAForm (singletonFilter "job" . maybePrism _PathPiece) mPrev $ aopt (hoistField lift textField) (fslI MsgTableJob)
|
||||
]
|
||||
dbtStyle = def { dbsFilterLayout = defaultDBSFilterLayout }
|
||||
|
||||
areq_posIntF msg = areq (posIntFieldI $ SomeMessages " " [SomeMessage msg, SomeMessage MsgMustBePositive]) (fslI msg)
|
||||
acts :: Map JobTableAction (AForm Handler JobTableActionData)
|
||||
acts = Map.singleton ActJobDelete $ ActJobDeleteData
|
||||
<$> areq checkBoxField (fslI $ MsgActJobDeleteForce jobDeleteLockMinutes) Nothing
|
||||
dbtParams = DBParamsForm
|
||||
{ dbParamsFormAdditional =
|
||||
acts = Map.fromList
|
||||
[ (ActJobDelete, ActJobDeleteData
|
||||
<$> areq checkBoxField (fslI $ MsgActJobDeleteForce jobDeleteLockMinutes) Nothing
|
||||
),(ActJobSleep, ActJobSleepData
|
||||
<$> areq_posIntF MsgJobSleepNr (Just 1)
|
||||
<*> areq_posIntF MsgJobSleepSecs (Just 60)
|
||||
<*> areq checkBoxField (fslI MsgJobSleepNow) (Just True)
|
||||
)]
|
||||
|
||||
dbtParams = DBParamsForm
|
||||
{ dbParamsFormAdditional =
|
||||
renderAForm FormStandard
|
||||
$ (, mempty) . First . Just
|
||||
<$> multiActionA acts (fslI MsgTableAction) Nothing
|
||||
@ -188,11 +199,11 @@ postAdminJobsR = do
|
||||
dbtCsvDecode = Nothing
|
||||
dbtExtraReps = []
|
||||
-- jobsDBTableValidator :: PSValidator (MForm Handler) (FormResult (First JobTableAction, DBFormResult QueuedJobId Bool (DBRow (Entity QueuedJob))))
|
||||
jobsDBTableValidator = def
|
||||
jobsDBTableValidator = def
|
||||
& defaultSorting [SortDescBy "creation-time"]
|
||||
postprocess :: FormResult (First JobTableActionData, DBFormResult QueuedJobId Bool (DBRow (Entity QueuedJob)))
|
||||
postprocess :: FormResult (First JobTableActionData, DBFormResult QueuedJobId Bool (DBRow (Entity QueuedJob)))
|
||||
-> FormResult (JobTableActionData, Set QueuedJobId)
|
||||
postprocess inp = do
|
||||
postprocess inp = do
|
||||
(First (Just act), jobMap) <- inp
|
||||
let jobSet = Map.keysSet . Map.filter id $ getDBFormResult (const False) jobMap
|
||||
return (act, jobSet)
|
||||
@ -205,24 +216,40 @@ postAdminJobsR = do
|
||||
cutoff = addUTCTime (nominalMinute * fromIntegral (negate jobDeleteLockMinutes)) now
|
||||
jobReq = length jobIds
|
||||
lockCriteria
|
||||
| jobDeleteLocked =
|
||||
| jobDeleteLocked =
|
||||
[ QueuedJobLockTime ==. Nothing ] ||.
|
||||
[ QueuedJobLockTime <=. Just cutoff ]
|
||||
| otherwise =
|
||||
| otherwise =
|
||||
[ QueuedJobLockTime ==. Nothing
|
||||
, QueuedJobLockInstance ==. Nothing
|
||||
]
|
||||
rmvd <- runDB $ fromIntegral <$> deleteWhereCount
|
||||
((QueuedJobId <-. Set.toList jobIds) : lockCriteria)
|
||||
|
||||
|
||||
addMessageI (bool Success Warning $ rmvd < jobReq) (MsgTableJobActDeleteFeedback rmvd jobReq)
|
||||
reloadKeepGetParams AdminJobsR
|
||||
|
||||
(ActJobSleepData{..}, _) -> do
|
||||
let jSleep = JobSleep jobSleepSecs
|
||||
enqSleep = bool (void . queueJob) queueJob' jobSleepNow jSleep
|
||||
replicateM_ jobSleepNr enqSleep
|
||||
addMessageI Success (MsgTableJobActSleepFeedback jobSleepNr jobSleepSecs jobSleepNow)
|
||||
reloadKeepGetParams AdminJobsR
|
||||
|
||||
-- gather some data on job worles
|
||||
(nrWorkers, jobStateVar) <- getsYesod (view _appJobWorkers &&& appJobState)
|
||||
jState <- atomically $ tryReadTMVar jobStateVar
|
||||
let running = Map.size . jobWorkers <$> jState
|
||||
|
||||
siteLayoutMsg MsgMenuAdminJobs $ do
|
||||
setTitleI MsgMenuAdminJobs
|
||||
[whamlet|
|
||||
^{jobsTable}
|
||||
<section>
|
||||
^{jobsTable}
|
||||
<section>
|
||||
<ul>
|
||||
<li> #{running} job workers currently running
|
||||
<li> #{nrWorkers} job workers configured to run
|
||||
|]
|
||||
where
|
||||
doEnc :: ToJSON a => a -> _
|
||||
@ -232,8 +259,8 @@ postAdminJobsR = do
|
||||
, Text.splitOn "-" t
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
getJobName :: Value -> Maybe Text
|
||||
getJobName (Object o)
|
||||
getJobName (Object o)
|
||||
| Just (String s) <- HashMap.lookup "job" o = Just s -- (kebabToCamel s)
|
||||
getJobName _ = Nothing
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>, Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>, Steffen Jost <jost@tcs.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -32,6 +32,8 @@ import qualified Database.Esqueleto.Experimental as E (selectOne, unValue)
|
||||
import qualified Database.Esqueleto.PostgreSQL as E (now_)
|
||||
import qualified Database.Esqueleto.Utils as E (psqlVersion_)
|
||||
|
||||
{-# ANN module ("HLint: ignore Functor law" :: String) #-}
|
||||
|
||||
-- BEGIN - Buttons needed only here
|
||||
data ButtonCreate = CreateMath | CreateInf | CrashApp -- Dummy for Example
|
||||
deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic)
|
||||
@ -91,6 +93,7 @@ makeDemoForm n = identifyForm ("adminTestForm" :: Text) $ \html -> do
|
||||
getAdminTestR, postAdminTestR :: Handler Html -- Demo Page. Referenzimplementierungen sollte hier gezeigt werden!
|
||||
getAdminTestR = postAdminTestR
|
||||
postAdminTestR = do
|
||||
uid <- requireAuthId -- this is an admin-only route anyway
|
||||
((btnResult, btnWdgt), btnEnctype) <- runFormPost $ identifyForm ("buttons" :: Text) (buttonForm :: Form ButtonCreate)
|
||||
let btnForm = wrapForm btnWdgt def
|
||||
{ formAction = Just $ SomeRoute AdminTestR
|
||||
@ -99,7 +102,9 @@ postAdminTestR = do
|
||||
}
|
||||
case btnResult of
|
||||
(FormSuccess CreateInf) -> addMessage Info "Informatik-Knopf gedrückt"
|
||||
(FormSuccess CreateMath) -> addMessage Warning "Knopf Mathematik erkannt"
|
||||
(FormSuccess CreateMath) -> do
|
||||
void $ queueJob $ JobUserNotification { jRecipient = uid, jNotification = NotificationUserAuthModeUpdate uid }
|
||||
addMessage Warning "Knopf Mathematik erkannt"
|
||||
(FormSuccess CrashApp) -> addMessage Error "Crash Button Ratio 0 betätigt" >> error ("Crash Button" <> show (1 % 0))
|
||||
FormMissing -> return ()
|
||||
_other -> addMessage Warning "KEIN Knopf erkannt"
|
||||
|
||||
@ -25,11 +25,6 @@ import qualified Database.Esqueleto.PostgreSQL as E
|
||||
import Database.Esqueleto.Utils.TH
|
||||
|
||||
|
||||
-- avoids repetition of local definitions
|
||||
single :: (k,a) -> Map k a
|
||||
single = uncurry Map.singleton
|
||||
|
||||
|
||||
data CCTableAction = CCActDummy -- just a dummy, since we don't now yet which actions we will be needing
|
||||
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic)
|
||||
|
||||
@ -119,17 +114,20 @@ mkCCTable = do
|
||||
, SomeExprValue $ E.coalesce [queryRecipientPrint row E.?. UserDisplayName, queryRecipientMail row E.?. UserDisplayName]
|
||||
]
|
||||
]
|
||||
dbtFilter = mconcat
|
||||
[ single ("sent" , FilterColumn . E.mkDayFilterTo
|
||||
$ \row -> E.coalesceDefault [queryPrint row E.?. PrintJobCreated, queryMail row E.?. SentMailSentAt] E.now_) -- either one is guaranteed to be non-null, default never used
|
||||
, single ("recipient" , FilterColumn . E.mkContainsFilterWithCommaPlus Just
|
||||
$ \row -> E.coalesce [queryRecipientPrint row E.?. UserDisplayName, queryRecipientMail row E.?. UserDisplayName])
|
||||
, single ("subject" , FilterColumn . E.mkContainsFilterWithCommaPlus Just
|
||||
dbtFilter = Map.fromList
|
||||
[ ("sentTo" , FilterColumn . E.mkDayFilterTo
|
||||
$ \row -> E.coalesceDefault [queryPrint row E.?. PrintJobCreated, queryMail row E.?. SentMailSentAt] E.now_) -- either one is guaranteed to be non-null, default never used
|
||||
, ("sentFrom" , FilterColumn . E.mkDayFilterFrom
|
||||
$ \row -> E.coalesceDefault [queryPrint row E.?. PrintJobCreated, queryMail row E.?. SentMailSentAt] E.now_) -- either one is guaranteed to be non-null, default never used
|
||||
, ("recipient" , FilterColumn . E.mkContainsFilterWithCommaPlus Just
|
||||
$ \row -> E.coalesce [queryRecipientPrint row E.?. UserDisplayName, queryRecipientMail row E.?. UserDisplayName])
|
||||
, ("subject" , FilterColumn . E.mkContainsFilterWithCommaPlus Just
|
||||
$ \row -> E.coalesce [E.str2text' $ queryPrint row E.?. PrintJobFilename
|
||||
,E.str2text' $ queryMail row E.?. SentMailHeaders ])
|
||||
]
|
||||
dbtFilterUI mPrev = mconcat
|
||||
[ prismAForm (singletonFilter "date" . maybePrism _PathPiece) mPrev $ aopt (hoistField lift dayField) (fslI MsgPrintJobCreated)
|
||||
[ prismAForm (singletonFilter "sentTo" . maybePrism _PathPiece) mPrev $ aopt (hoistField lift dayField) (fslI MsgTableFilterSentBefore)
|
||||
, prismAForm (singletonFilter "sentFrom" . maybePrism _PathPiece) mPrev $ aopt (hoistField lift dayField) (fslI MsgTableFilterSentAfter)
|
||||
, prismAForm (singletonFilter "recipient" . maybePrism _PathPiece) mPrev $ aopt (hoistField lift textField) (fslI MsgPrintRecipient & setTooltip MsgTableFilterCommaPlus)
|
||||
, prismAForm (singletonFilter "subject" . maybePrism _PathPiece) mPrev $ aopt (hoistField lift textField) (fslI MsgCommSubject & setTooltip MsgTableFilterCommaPlusShort)
|
||||
]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022-24 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <s.jost@fraport.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -70,7 +70,7 @@ courseToForm (Entity cid Course{..}) lecs lecInvites qualis = CourseForm
|
||||
, cfDeRegUntil = courseDeregisterUntil
|
||||
, cfLecturers = [Right (lecturerUser, lecturerType) | Lecturer{..} <- lecs]
|
||||
++ [Left (email, mType) | (email, InvDBDataLecturer mType) <- Map.toList lecInvites ]
|
||||
-- TODO: Filterung nach aktueller Schule, da ansonsten ein Sicherheitleck droht! Siehe #150
|
||||
-- TODO: Filterung nach aktueller Schule, da ansonsten ein Sicherheitleck droht! Siehe auch DevOps #1878
|
||||
, cfQualis = [ (courseQualificationQualification, courseQualificationSortOrder)
|
||||
| CourseQualification{..} <- qualis, courseQualificationCourse == cid ]
|
||||
}
|
||||
@ -452,6 +452,7 @@ courseEditHandler miButtonAction mbCourseForm = do
|
||||
sinkInvitationsF lecturerInvitationConfig $ map (\(lEmail, mLty) -> (lEmail, cid, (InvDBDataLecturer mLty, InvTokenDataLecturer))) invites
|
||||
void $ upsertCourseQualifications aid cid $ cfQualis res
|
||||
insert_ $ CourseEdit aid now cid
|
||||
memcachedInvalidateClass MemcachedKeyClassTutorialOccurrences
|
||||
memcachedByInvalidate AuthCacheLecturerList $ Proxy @(Set UserId)
|
||||
addMessageI Success $ MsgCourseEditOk tid ssh csh
|
||||
return True
|
||||
@ -470,7 +471,7 @@ upsertCourseQualifications uid cid qualis = do
|
||||
let newQualis = Map.fromList qualis
|
||||
oldQualis <- Map.fromList . fmap (\Entity{entityKey=k, entityVal=CourseQualification{..}} -> (courseQualificationQualification, (k, courseQualificationSortOrder)))
|
||||
<$> selectList [CourseQualificationCourse ==. cid] [Asc CourseQualificationQualification]
|
||||
-- NOTE: CourseQualification allow the immediate assignment of these qualifications to any enrolled user. Hence SchoolAdmins must not be allowed to assign school-foreign qualifications, see #150
|
||||
-- NOTE: CourseQualification allow the immediate assignment of these qualifications to any enrolled user. Hence SchoolAdmins must not be allowed to assign school-foreign qualifications here! Also see DevOps #1878
|
||||
okSchools <- Set.fromList . fmap (userFunctionSchool . entityVal)
|
||||
<$> selectList [UserFunctionUser ==. uid, UserFunctionFunction <-. [SchoolAdmin, SchoolLecturer]] [Asc UserFunctionSchool]
|
||||
{- Some debugging due to an error caused by using fromDistinctAscList with violated precondition:
|
||||
|
||||
@ -31,10 +31,8 @@ postCEvDeleteR tid ssh csh cID = do
|
||||
[whamlet|
|
||||
$newline never
|
||||
#{courseEventType}
|
||||
$maybe room <- courseEventRoom
|
||||
, #{roomReferenceText room}
|
||||
:
|
||||
^{occurrencesWidget courseEventTime}
|
||||
^{occurrencesWidget False courseEventTime}
|
||||
|]
|
||||
|
||||
drRecordConfirmString :: Entity CourseEvent -> DB Text
|
||||
|
||||
@ -26,9 +26,8 @@ postCEvEditR tid ssh csh cID = do
|
||||
replace eId CourseEvent
|
||||
{ courseEventCourse
|
||||
, courseEventType = cefType
|
||||
, courseEventRoom = cefRoom
|
||||
, courseEventRoomHidden = cefRoomHidden
|
||||
, courseEventTime = cefTime
|
||||
, courseEventTime = cefTime & JSONB
|
||||
, courseEventNote = cefNote
|
||||
, courseEventLastChanged = now
|
||||
}
|
||||
|
||||
@ -17,7 +17,6 @@ import qualified Database.Esqueleto.Legacy as E
|
||||
|
||||
data CourseEventForm = CourseEventForm
|
||||
{ cefType :: CI Text
|
||||
, cefRoom :: Maybe RoomReference
|
||||
, cefRoomHidden :: Bool
|
||||
, cefTime :: Occurrences
|
||||
, cefNote :: Maybe StoredMarkup
|
||||
@ -37,14 +36,12 @@ courseEventForm template = identifyForm FIDCourseEvent . renderWForm FormStandar
|
||||
let courseEventTypes = optionsPairs [ (courseEventType, courseEventType) | Entity _ CourseEvent{..} <- existingEvents ]
|
||||
|
||||
cefType' <- wreq (textField & cfStrip & cfCI & addDatalist courseEventTypes) (fslI MsgCourseEventType & addPlaceholder (mr MsgCourseEventTypePlaceholder)) (cefType <$> template)
|
||||
cefRoom' <- aFormToWForm $ roomReferenceFormOpt (fslI MsgCourseEventRoom) (cefRoom <$> template)
|
||||
cefRoomHidden' <- wpopt checkBoxField (fslI MsgCourseEventRoomHidden & setTooltip MsgCourseEventRoomHiddenTip) (cefRoomHidden <$> template)
|
||||
cefTime' <- aFormToWForm $ occurrencesAForm ("time" :: Text) (cefTime <$> template)
|
||||
cefNote' <- wopt htmlField (fslI MsgCourseEventNote) (cefNote <$> template)
|
||||
|
||||
return $ CourseEventForm
|
||||
<$> cefType'
|
||||
<*> cefRoom'
|
||||
<*> cefRoomHidden'
|
||||
<*> cefTime'
|
||||
<*> cefNote'
|
||||
@ -52,8 +49,7 @@ courseEventForm template = identifyForm FIDCourseEvent . renderWForm FormStandar
|
||||
courseEventToForm :: CourseEvent -> CourseEventForm
|
||||
courseEventToForm CourseEvent{..} = CourseEventForm
|
||||
{ cefType = courseEventType
|
||||
, cefRoom = courseEventRoom
|
||||
, cefRoomHidden = courseEventRoomHidden
|
||||
, cefTime = courseEventTime
|
||||
, cefTime = courseEventTime & unJSONB
|
||||
, cefNote = courseEventNote
|
||||
}
|
||||
|
||||
@ -24,9 +24,8 @@ postCEventsNewR tid ssh csh = do
|
||||
eId <- insert CourseEvent
|
||||
{ courseEventCourse = cid
|
||||
, courseEventType = cefType
|
||||
, courseEventRoom = cefRoom
|
||||
, courseEventRoomHidden = cefRoomHidden
|
||||
, courseEventTime = cefTime
|
||||
, courseEventTime = cefTime & JSONB
|
||||
, courseEventNote = cefNote
|
||||
, courseEventLastChanged = now
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022-23 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>, Steffen Jost <s.jost@fraport.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>, Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -13,6 +13,7 @@ import Import
|
||||
|
||||
import Handler.Utils
|
||||
import Handler.Utils.Avs
|
||||
import Handler.Utils.Company
|
||||
|
||||
import Jobs.Queue
|
||||
|
||||
@ -28,7 +29,7 @@ import Control.Monad.Except (MonadError(..))
|
||||
|
||||
import Generics.Deriving.Monoid (memptydefault, mappenddefault)
|
||||
|
||||
-- import Database.Esqueleto.Experimental ((:&)(..))
|
||||
import Database.Esqueleto.Experimental ((:&)(..))
|
||||
import qualified Database.Esqueleto.Experimental as E -- needs TypeApplications Lang-Pragma
|
||||
import qualified Database.Esqueleto.Utils as E
|
||||
|
||||
@ -44,20 +45,22 @@ defaultTutorialType = "Schulung"
|
||||
tutorialTypeSeparator :: TutorialType
|
||||
tutorialTypeSeparator = "_"
|
||||
|
||||
tutorialTemplateNames :: Maybe TutorialType -> [TutorialType]
|
||||
tutorialTemplateNames Nothing = ["Vorlage", "Template"]
|
||||
tutorialTemplateNames (Just name) = [prefixes <> suffixes | prefixes <- tutorialTemplateNames Nothing, suffixes <- [mempty, tutorialTypeSeparator <> name]]
|
||||
tutorialTypeSeparators :: [TutorialType]
|
||||
tutorialTypeSeparators = tutorialTypeSeparator : ["-"]
|
||||
|
||||
tutorialTemplateNames :: [TutorialType]
|
||||
tutorialTemplateNames = ["Vorlage", "Template"]
|
||||
|
||||
tutorialDefaultName :: Maybe TutorialType -> Day -> TutorialName
|
||||
tutorialDefaultName Nothing = formatDayForTutName
|
||||
tutorialDefaultName (Just ttyp) =
|
||||
tutorialDefaultName Nothing = formatDayForTutName
|
||||
tutorialDefaultName (Just ttyp) =
|
||||
let prefix = CI.mk $ snd $ Text.breakOnEnd (CI.original tutorialTypeSeparator) $ CI.original ttyp
|
||||
in (<> (tutorialTypeSeparator <> prefix)) . tutorialDefaultName Nothing
|
||||
|
||||
formatDayForTutName :: Day -> CI Text -- "%yy_%mm_%dd" -- Do not use user date display setting, since tutorial default names must be universal regardless of user
|
||||
-- formatDayForTutName = CI.mk . formatTime' "%y_%m_%d" -- we don't want to go monadic for this
|
||||
formatDayForTutName = CI.mk . Text.map d2u . Text.drop 2 . tshow
|
||||
where
|
||||
formatDayForTutName = CI.mk . Text.map d2u . Text.drop 2 . tshow
|
||||
where
|
||||
d2u '-' = '_'
|
||||
d2u c = c
|
||||
|
||||
@ -151,7 +154,7 @@ instance Monoid AddParticipantsResult where
|
||||
|
||||
getCAddUserR, postCAddUserR :: TermId -> SchoolId -> CourseShorthand -> Handler Html
|
||||
getCAddUserR = postCAddUserR
|
||||
postCAddUserR tid ssh csh = do
|
||||
postCAddUserR tid ssh csh = do
|
||||
today <- localDay . TZ.utcToLocalTimeTZ appTZ <$> liftIO getCurrentTime
|
||||
handleAddUserR tid ssh csh (Right today) Nothing
|
||||
-- postTAddUserR tid ssh csh (CI.mk $ tshow today) -- Don't use user date display setting, so that tutorial default names conform to all users
|
||||
@ -163,73 +166,71 @@ postTAddUserR tid ssh csh tutn = handleAddUserR tid ssh csh (Left tutn) Nothing
|
||||
|
||||
|
||||
handleAddUserR :: TermId -> SchoolId -> CourseShorthand -> Either TutorialName Day -> Maybe TutorialType -> Handler Html
|
||||
handleAddUserR tid ssh csh tdesc ttyp = do
|
||||
(cid, tutTypes, tutNameSuggestions) <- runDB $ do
|
||||
let plainTemplates = tutorialTemplateNames Nothing
|
||||
cid <- getKeyBy404 $ TermSchoolCourseShort tid ssh csh
|
||||
handleAddUserR tid ssh csh tdesc ttyp = do
|
||||
(cEnt@Entity{entityKey=cid}, tutTypes, tutNameSuggestions) <- runDB $ do
|
||||
cEnt@Entity{entityKey=cid} <- getBy404 $ TermSchoolCourseShort tid ssh csh
|
||||
tutTypes <- E.select $ E.distinct $ do
|
||||
tutorial <- E.from $ E.table @Tutorial
|
||||
let tuTyp = tutorial E.^. TutorialType
|
||||
E.where_ $ tutorial E.^. TutorialCourse E.==. E.val cid
|
||||
E.orderBy [E.asc tuTyp]
|
||||
return tuTyp
|
||||
let typeSet = Set.fromList [ maybe t CI.mk $ Text.stripPrefix temp_sep $ CI.original t
|
||||
| temp <- plainTemplates
|
||||
, let temp_sep = CI.original (temp <> tutorialTypeSeparator)
|
||||
, E.Value t <- tutTypes
|
||||
let typeSet = Set.fromList [ maybe t CI.mk $ firstJust (`Text.stripPrefix` s) [CI.original $ tpl <> sep | sep <- tutorialTypeSeparators, tpl <- tutorialTemplateNames]
|
||||
| E.Value t <- tutTypes, let s = CI.original t, t `notElem` tutorialTemplateNames
|
||||
]
|
||||
tutNames <- E.select $ do
|
||||
tutNames <- E.select $ do
|
||||
tutorial <- E.from $ E.table @Tutorial
|
||||
let tuName = tutorial E.^. TutorialName
|
||||
E.where_ $ tutorial E.^. TutorialCourse E.==. E.val cid
|
||||
E.&&. E.isJust (tutorial E.^. TutorialFirstDay)
|
||||
E.&&. E.not_ (E.any (E.hasPrefix_ (tutorial E.^. TutorialType) . E.val) plainTemplates)
|
||||
E.orderBy [E.desc $ tutorial E.^. TutorialFirstDay, E.asc tuName]
|
||||
E.&&. E.not_ (E.any (E.hasPrefix_ (tutorial E.^. TutorialType) . E.val) tutorialTemplateNames)
|
||||
E.orderBy $ [E.asc $ tutorial E.^. TutorialName `E.hasInfix` E.val tn | tn <- tutorialTemplateNames] -- avoid template names, if possible
|
||||
++ [E.desc $ tutorial E.^. TutorialFirstDay, E.asc tuName]
|
||||
E.limit 7
|
||||
return tuName
|
||||
let tutNameSuggestions = return $ mkOptionList [Option tno tn tno | etn <- tutNames, let tn = E.unValue etn, let tno = CI.original tn]
|
||||
return (cid, Set.toAscList typeSet, tutNameSuggestions) -- Set in order to remove duplicates and sort ascending at once
|
||||
return (cEnt, Set.toAscList typeSet, tutNameSuggestions) -- Set in order to remove duplicates and sort ascending at once
|
||||
|
||||
currentRoute <- fromMaybe (error "postCAddUserR called from 404-handler") <$> getCurrentRoute
|
||||
|
||||
(_ , registerConfirmResult) <- runButtonForm FIDCourseRegisterConfirm
|
||||
(_ , registerConfirmResult) <- runButtonForm FIDCourseRegisterConfirm
|
||||
-- $logDebugS "***AbortProblem***" $ tshow registerConfirmResult
|
||||
prefillUsers <- case registerConfirmResult of
|
||||
prefillUsers <- case registerConfirmResult of
|
||||
Nothing -> return mempty
|
||||
(Just BtnCourseRegisterAbort) -> do
|
||||
(Just BtnCourseRegisterAbort) -> do
|
||||
addMessageI Warning MsgAborted
|
||||
-- prefill confirmed users for convenience. Note that Browser-Back may also return to the filled form, but history.back() does not in Chrome
|
||||
confirmedActs :: [CourseRegisterActionData] <- exceptT (const $ return mempty) return . mapMM encodedSecretBoxOpen . lookupPostParams $ toPathPiece PostCourseUserAddConfirmAction -- ignore any exception, since it is only used to prefill a form field for convenience
|
||||
return $ Just $ Set.fromList $ fmap crActIdent confirmedActs
|
||||
(Just BtnCourseRegisterConfirm) -> do
|
||||
confirmedActs :: Set CourseRegisterActionData <- fmap Set.fromList . throwExceptT . mapMM encodedSecretBoxOpen . lookupPostParams $ toPathPiece PostCourseUserAddConfirmAction
|
||||
confirmedActs :: Set CourseRegisterActionData <- fmap Set.fromList . throwExceptT . mapMM encodedSecretBoxOpen . lookupPostParams $ toPathPiece PostCourseUserAddConfirmAction
|
||||
-- $logDebugS "CAddUserR confirmedActs" . tshow $ Set.map Aeson.encode confirmedActs
|
||||
unless (Set.null confirmedActs) $ do -- TODO: check that all acts are member of availableActs
|
||||
let
|
||||
users = Map.fromList . fmap (\act -> (crActIdent act, Just . view _1 $ crActUser act)) $ Set.toList confirmedActs
|
||||
tutActs = Set.filter (is _CourseRegisterActionAddTutorialMemberData) confirmedActs
|
||||
actTutorial = crActTutorial <$> Set.lookupMin tutActs -- tutorial ident must be the same for every added member!
|
||||
actTutorial = crActTutorial <$> Set.lookupMin tutActs -- tutorial ident must be the same for every added member!
|
||||
registeredUsers <- registerUsers cid users
|
||||
whenIsJust actTutorial $ \(tutName,tutType,tutDay) -> do
|
||||
whenIsJust (tutName <|> fmap (tutorialDefaultName tutType) tutDay) $ \tName -> do
|
||||
tutId <- upsertNewTutorial cid tName tutType tutDay
|
||||
tutId <- upsertNewTutorial cEnt tName tutType tutDay
|
||||
registerTutorialMembers tutId registeredUsers
|
||||
-- when (Set.size tutActs == Set.size confirmedActs) $ -- not sure how this condition might be false at this point
|
||||
redirect $ CTutorialR tid ssh csh tName TUsersR
|
||||
redirect $ CourseR tid ssh csh CUsersR
|
||||
return mempty
|
||||
|
||||
|
||||
((usersToAdd :: FormResult AddUserRequest, formWgt), formEncoding) <- runFormPost . identifyForm FIDCourseRegister . renderWForm FormStandard $ do
|
||||
let tutTypesMsg = [(SomeMessage tt,tt) | tt <- tutTypes]
|
||||
tutDefType = ttyp >>= (\ty -> if ty `elem` tutTypes then Just ty else Nothing)
|
||||
tutDefType = ttyp >>= (\ty -> if ty `elem` tutTypes then Just ty else Nothing)
|
||||
auReqUsers <- wreq (textField & cfAnySeparatedSet) (fslI MsgCourseParticipantsRegisterUsersField & setTooltip MsgCourseParticipantsRegisterUsersFieldTip) prefillUsers
|
||||
auReqTutorial <- optionalActionW
|
||||
( (,,)
|
||||
( (,,)
|
||||
<$> aopt (textField & cfStrip & cfCI & addDatalist tutNameSuggestions)
|
||||
(fslI MsgCourseParticipantsRegisterTutorialField & setTooltip MsgCourseParticipantsRegisterTutorialFieldTip)
|
||||
(Just $ maybeLeft tdesc)
|
||||
<*> aopt (selectFieldList tutTypesMsg)
|
||||
(fslI MsgTableTutorialType)
|
||||
(fslI MsgCourseParticipantsTutorialType & setTooltip MsgCourseParticipantsTutorialTypeTooltip)
|
||||
(Just tutDefType)
|
||||
<*> aopt dayField
|
||||
(fslI MsgTableTutorialFirstDay & setTooltip MsgCourseParticipantsRegisterTutorialFirstDayTip)
|
||||
@ -343,22 +344,41 @@ registerUser cid (_avsIdent, Just uid) = exceptT return return $ do
|
||||
|
||||
return $ mempty { aurRegisterSuccess = Set.singleton uid }
|
||||
|
||||
upsertNewTutorial :: CourseId -> TutorialName -> Maybe TutorialType -> Maybe Day -> Handler TutorialId
|
||||
upsertNewTutorial cid newTutorialName newTutorialType newFirstDay = runDB $ do
|
||||
upsertNewTutorial :: Entity Course -> TutorialName -> Maybe TutorialType -> Maybe Day -> Handler TutorialId
|
||||
upsertNewTutorial Entity{entityKey=cid, entityVal=crse} newTutorialName newTutorialType newFirstDay = runDB $ do
|
||||
now <- liftIO getCurrentTime
|
||||
existingTut <- getBy $ UniqueTutorial cid newTutorialName
|
||||
templateEnt <- selectFirst [TutorialType <-. tutorialTemplateNames newTutorialType] [Desc TutorialType, Asc TutorialName]
|
||||
-- templateEnt <- selectFirst [TutorialType <-. tutorialTemplateNames newTutorialType] [Desc TutorialType, Asc TutorialName] -- current prod as of 02/2025
|
||||
templateEnt <- E.selectOne $ do
|
||||
(tut :& crs :& trm) <- E.from $ E.table @Tutorial
|
||||
`E.innerJoin` E.table @Course
|
||||
`E.on` (\(tut :& crs) -> tut E.^. TutorialCourse E.==. crs E.^. CourseId)
|
||||
`E.innerJoin` E.table @Term
|
||||
`E.on` (\(_ :& crs :& trm) -> trm E.^. TermId E.==. crs E.^. CourseTerm)
|
||||
E.where_ $ crs E.^. CourseSchool E.==. E.val (crse & courseSchool) -- filter by School
|
||||
-- E.&&. tut E.^. TutorialName `E.in_` E.vals (tutorialTemplateNames newTutorialType) -- filter TutorialName being a template
|
||||
E.orderBy $ -- NOTE: E.desc to have true before false, only works for non-nullable columns!
|
||||
[ E.desc $ tut E.^. TutorialName `E.hasInfix` E.val pfx | pfx <- tutorialTemplateNames] -- prefer template names above all else
|
||||
++ mcons ((\ttyp -> E.desc $ tut E.^. TutorialName `E.hasInfix` E.val ttyp) <$> newTutorialType) -- prefer ttype, if given.
|
||||
[ E.desc $ tut E.^. TutorialCourse E.==. E.val cid -- prefer current course
|
||||
, E.desc $ crs E.^. CourseName E.==. E.val (crse & courseName) -- prefer courses with identical name
|
||||
, E.desc $ crs E.^. CourseShorthand E.==. E.val (crse & courseShorthand) -- prefer courses with identical shortcut
|
||||
, E.desc $ crs E.^. CourseTerm E.==. E.val (crse & courseTerm) -- prefer courses from current term
|
||||
, E.desc $ trm E.^. TermStart -- prefer most recently started term
|
||||
-- , E.desc $ tut E.^. tutorialRegisterFrom
|
||||
, E.asc $ tut E.^. TutorialName -- prefer tutorial name in alpahbetical order
|
||||
]
|
||||
return tut
|
||||
case (existingTut, newFirstDay, templateEnt) of
|
||||
(Just Entity{entityKey=tid},_,_) -> return tid -- no need to update, we ignore the anchor day
|
||||
(Just Entity{entityKey=tid},_,_) -> return tid -- no need to update, we ignore the anchor day
|
||||
(Nothing, Just moveDay, Just Entity{entityVal=Tutorial{..}}) -> do
|
||||
Course{..} <- get404 cid
|
||||
term <- get404 courseTerm
|
||||
let oldFirstDay = fromMaybe moveDay $ tutorialFirstDay <|> fst (occurrencesBounds term tutorialTime)
|
||||
newTime = normalizeOccurrences $ occurrencesAddBusinessDays term (oldFirstDay, moveDay) tutorialTime
|
||||
term <- get404 $ courseTerm crse
|
||||
let oldFirstDay = fromMaybe moveDay $ tutorialFirstDay <|> fst (occurrencesBounds term $ unJSONB tutorialTime)
|
||||
newTime = normalizeOccurrences $ occurrencesAddBusinessDays term (oldFirstDay, moveDay) $ unJSONB tutorialTime
|
||||
dayDiff = maybe 0 (diffDays moveDay) tutorialFirstDay
|
||||
mvTime = fmap $ addLocalDays dayDiff
|
||||
newType0 = CI.map (snd . Text.breakOnEnd (CI.original tutorialTypeSeparator)) tutorialType
|
||||
newType = if newType0 `elem` tutorialTemplateNames Nothing
|
||||
newType = if newType0 `elem` tutorialTemplateNames
|
||||
then fromMaybe defaultTutorialType newTutorialType
|
||||
else newType0
|
||||
Entity tutId _ <- upsert
|
||||
@ -367,13 +387,13 @@ upsertNewTutorial cid newTutorialName newTutorialType newFirstDay = runDB $ do
|
||||
, tutorialCourse = cid
|
||||
, tutorialType = newType
|
||||
, tutorialFirstDay = newFirstDay
|
||||
, tutorialTime = newTime
|
||||
, tutorialTime = newTime & JSONB
|
||||
, tutorialRegisterFrom = mvTime tutorialRegisterFrom
|
||||
, tutorialRegisterTo = mvTime tutorialRegisterTo
|
||||
, tutorialDeregisterUntil = mvTime tutorialDeregisterUntil
|
||||
, tutorialLastChanged = now
|
||||
, ..
|
||||
} [] -- update cannot happen due to previous case
|
||||
} [] -- update cannot happen due to previous case
|
||||
audit $ TransactionTutorialEdit tutId
|
||||
return tutId
|
||||
_ -> do
|
||||
@ -383,9 +403,8 @@ upsertNewTutorial cid newTutorialName newTutorialType newFirstDay = runDB $ do
|
||||
, tutorialCourse = cid
|
||||
, tutorialType = fromMaybe defaultTutorialType newTutorialType
|
||||
, tutorialCapacity = Nothing
|
||||
, tutorialRoom = Nothing
|
||||
, tutorialRoomHidden = False
|
||||
, tutorialTime = Occurrences mempty mempty
|
||||
, tutorialTime = mempty
|
||||
, tutorialRegGroup = Nothing
|
||||
, tutorialRegisterFrom = Nothing
|
||||
, tutorialRegisterTo = Nothing
|
||||
@ -393,7 +412,7 @@ upsertNewTutorial cid newTutorialName newTutorialType newFirstDay = runDB $ do
|
||||
, tutorialLastChanged = now
|
||||
, tutorialTutorControlled = False
|
||||
, tutorialFirstDay = Nothing
|
||||
} [] -- update cannot happen due to previous cases
|
||||
} [] -- update cannot happen due to previous cases
|
||||
audit $ TransactionTutorialEdit tutId
|
||||
return tutId
|
||||
|
||||
@ -401,6 +420,10 @@ registerTutorialMembers :: TutorialId -> Set UserId -> Handler ()
|
||||
registerTutorialMembers tutId (Set.toList -> users) = runDB $ do
|
||||
prevParticipants <- Set.fromList . fmap entityKey <$> selectList [TutorialParticipantUser <-. users, TutorialParticipantTutorial ==. tutId] []
|
||||
participants <- fmap Set.fromList . for users $ \tutorialParticipantUser -> do
|
||||
tutorialParticipantCompany <- selectCompanyUserPrime' tutorialParticipantUser
|
||||
let tutorialParticipantDrivingPermit = Nothing
|
||||
tutorialParticipantEyeExam = Nothing
|
||||
tutorialParticipantNote = Nothing
|
||||
Entity tutPartId _ <- upsert TutorialParticipant { tutorialParticipantTutorial = tutId, .. } []
|
||||
audit $ TransactionTutorialParticipantEdit tutId tutPartId tutorialParticipantUser
|
||||
return tutPartId
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -29,7 +29,7 @@ import Handler.Exam.List (mkExamTable)
|
||||
|
||||
getCShowR :: TermId -> SchoolId -> CourseShorthand -> Handler Html
|
||||
getCShowR tid ssh csh = do
|
||||
mbAid <- maybeAuthId
|
||||
mbAid <- maybeAuthId
|
||||
now <- liftIO getCurrentTime
|
||||
(cid,course,courseVisible,schoolName,participants,registration,lecturers,assistants,administrators,correctors,tutors,news,events,submissionGroup,_mayReRegister,(mayViewSheets, mayViewAnySheet), (mayViewMaterials, mayViewAnyMaterial),courseQualifications) <- runDB . maybeT notFound $ do
|
||||
[(E.Entity cid course, E.Value courseVisible, E.Value schoolName, E.Value participants, fmap entityVal -> registration)]
|
||||
@ -146,7 +146,7 @@ getCShowR tid ssh csh = do
|
||||
| otherwise
|
||||
-> return . modal $(widgetFile "course/login-to-register") . Left . SomeRoute $ AuthR LoginR
|
||||
registrationOpen <- hasWriteAccessTo $ CourseR tid ssh csh CRegisterR
|
||||
mayMassRegister <- hasWriteAccessTo $ CourseR tid ssh csh CAddUserR
|
||||
mayMassRegister <- hasWriteAccessTo $ CourseR tid ssh csh CAddUserR
|
||||
|
||||
MsgRenderer mr <- getMsgRenderer
|
||||
|
||||
@ -154,14 +154,14 @@ getCShowR tid ssh csh = do
|
||||
tutorialDBTable = DBTable{..}
|
||||
where
|
||||
resultTutorial :: Lens' (DBRow (Entity Tutorial, Bool)) (Entity Tutorial)
|
||||
resultTutorial = _dbrOutput . _1
|
||||
resultShowRoom = _dbrOutput . _2
|
||||
|
||||
resultTutorial = _dbrOutput . _1
|
||||
resultHideRoom = _dbrOutput . _2
|
||||
|
||||
dbtSQLQuery tutorial = do
|
||||
E.where_ $ tutorial E.^. TutorialCourse E.==. E.val cid
|
||||
let showRoom = maybe E.false (flip showTutorialRoom tutorial . E.val) mbAid
|
||||
E.||. E.not_ (tutorial E.^. TutorialRoomHidden)
|
||||
return (tutorial, showRoom)
|
||||
let hideRoom = maybe E.true (E.not__ . flip showTutorialRoom tutorial . E.val) mbAid
|
||||
E.&&. (tutorial E.^. TutorialRoomHidden)
|
||||
return (tutorial, hideRoom)
|
||||
dbtRowKey = (E.^. TutorialId)
|
||||
dbtProj = over (_dbrOutput . _2) E.unValue <$> dbtProjId
|
||||
dbtColonnade = dbColonnade $ mconcat
|
||||
@ -180,10 +180,10 @@ getCShowR tid ssh csh = do
|
||||
<li>
|
||||
^{nameEmailWidget' tutor}
|
||||
|]
|
||||
, sortable (Just "room") (i18nCell MsgTableTutorialRoom) $ \res -> if
|
||||
| res ^. resultShowRoom -> maybe (i18nCell MsgTableTutorialRoomIsUnset) roomReferenceCell $ views (resultTutorial . _entityVal) tutorialRoom res
|
||||
| otherwise -> i18nCell MsgTableTutorialRoomIsHidden & addCellClass ("explanation" :: Text)
|
||||
, sortable Nothing (i18nCell MsgTableTutorialTime) $ \(view $ resultTutorial . _entityVal -> Tutorial{..}) -> occurrencesCell tutorialTime
|
||||
, sortable Nothing (i18nCell MsgTableTutorialOccurrence) $ \res ->
|
||||
let roomHidden = res ^. resultHideRoom
|
||||
ttime = res ^. resultTutorial . _entityVal . _tutorialTime
|
||||
in occurrencesCell roomHidden ttime
|
||||
, sortable (Just "register-from") (i18nCell MsgTutorialRegisterFrom) $ \(view $ resultTutorial . _entityVal -> Tutorial{..}) -> maybeDateTimeCell tutorialRegisterFrom
|
||||
, sortable (Just "register-to") (i18nCell MsgTutorialRegisterTo) $ \(view $ resultTutorial . _entityVal -> Tutorial{..}) -> maybeDateTimeCell tutorialRegisterTo
|
||||
, sortable (Just "deregister-until") (i18nCell MsgTableTutorialDeregisterUntil) $ \(view $ resultTutorial . _entityVal -> Tutorial{..}) -> maybeDateTimeCell tutorialDeregisterUntil
|
||||
@ -220,7 +220,6 @@ getCShowR tid ssh csh = do
|
||||
[ ("type", SortColumn $ \tutorial -> tutorial E.^. TutorialType )
|
||||
, ("name", SortColumn $ \tutorial -> tutorial E.^. TutorialName )
|
||||
, ("first-day", SortColumnNullsInv $ \tutorial -> tutorial E.^. TutorialFirstDay )
|
||||
, ("room", SortColumn $ \tutorial -> tutorial E.^. TutorialRoom )
|
||||
, ("register-from", SortColumn $ \tutorial -> tutorial E.^. TutorialRegisterFrom )
|
||||
, ("register-to", SortColumn $ \tutorial -> tutorial E.^. TutorialRegisterTo )
|
||||
, ("deregister-until", SortColumn $ \tutorial -> tutorial E.^. TutorialDeregisterUntil )
|
||||
|
||||
@ -307,7 +307,7 @@ courseUserExamsSection (Entity cid Course{..}) (Entity uid _) = do
|
||||
[ dbSelect (_2 . applying _2) _1 $ return . view (_dbrOutput . _1 . _entityKey)
|
||||
, sortable (Just "name") (i18nCell MsgTableExamName) $ tellCell (Any True, mempty) . anchorCell' (\(view $ _dbrOutput . _1 . _entityVal -> Exam{..}) -> CExamR courseTerm courseSchool courseShorthand examName EShowR) (view $ _dbrOutput . _1 . _entityVal . _examName)
|
||||
, sortable (Just "occurrence") (i18nCell MsgTableExamOccurrence) $ maybe mempty (cell . toWidget) . preview (_dbrOutput . _2 . _Just . _entityVal . _examOccurrenceName)
|
||||
, sortable (Just "registration-time") (i18nCell MsgCourseExamRegistrationTime) $ maybe mempty (cell . formatTimeW SelFormatDateTime) . preview (_dbrOutput . _5 . _Just . _entityVal . _examRegistrationTime)
|
||||
, sortable (Just "registration-time") (i18nCell MsgCourseExamRegistrationTime) $ foldMap dateTimeCell . preview (_dbrOutput . _5 . _Just . _entityVal . _examRegistrationTime)
|
||||
, sortable (Just "bonus") (i18nCell MsgExamBonusAchieved) $ maybe mempty i18nCell . preview (_dbrOutput . _3 . _Just . _entityVal . _examBonusBonus)
|
||||
, sortable (Just "result") (i18nCell MsgTableExamResult) $ maybe mempty i18nCell . preview (_dbrOutput . _4 . _Just . _entityVal . _examResultResult)
|
||||
]
|
||||
@ -444,13 +444,11 @@ courseUserTutorialsSection (Entity cid Course{..}) (Entity uid _) = do
|
||||
<li>
|
||||
^{userEmailWidget usr}
|
||||
|]
|
||||
, sortable (Just "room") (i18nCell MsgTableTutorialRoom) $ maybe (i18nCell MsgTableTutorialRoomIsUnset) roomReferenceCell . view (_dbrOutput . _1 . _entityVal . _tutorialRoom)
|
||||
, sortable Nothing (i18nCell MsgTableTutorialTime) $ occurrencesCell . view (_dbrOutput . _1 . _entityVal . _tutorialTime)
|
||||
, sortable Nothing (i18nCell MsgTableTutorialOccurrence) $ occurrencesCell False . view (_dbrOutput . _1 . _entityVal . _tutorialTime)
|
||||
]
|
||||
dbtSorting = mconcat
|
||||
[ singletonMap "type" . SortColumn $ \(tutorial `E.InnerJoin` _) -> tutorial E.^. TutorialType
|
||||
, singletonMap "name" . SortColumn $ \(tutorial `E.InnerJoin` _) -> tutorial E.^. TutorialName
|
||||
, singletonMap "room" . SortColumn $ \(tutorial `E.InnerJoin` _) -> tutorial E.^. TutorialRoom
|
||||
, singletonMap "tutors" . SortColumn $ \(tutorial `E.InnerJoin` _) -> E.subSelectMaybe . E.from $ \(tutor `E.InnerJoin` user) -> do
|
||||
E.on $ tutor E.^. TutorUser E.==. user E.^. UserId
|
||||
E.where_ $ tutorial E.^. TutorialId E.==. tutor E.^. TutorTutorial
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user