add startPage option, other fixes and improvements

This commit is contained in:
_Bastler
2025-12-19 20:38:30 +01:00
parent 6875ed6bf2
commit db877f972a
46 changed files with 847 additions and 700 deletions
+9 -9
View File
@@ -1,12 +1,12 @@
{ {
"name": "we-bstly-angular", "name": "we-bstly-angular",
"version": "4.0.1", "version": "4.0.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "we-bstly-angular", "name": "we-bstly-angular",
"version": "4.0.1", "version": "4.0.2",
"dependencies": { "dependencies": {
"@angular/animations": "^20.3.15", "@angular/animations": "^20.3.15",
"@angular/cdk": "^20.2.14", "@angular/cdk": "^20.2.14",
@@ -35,7 +35,7 @@
"@angular/localize": "^20.3.15", "@angular/localize": "^20.3.15",
"@types/jasmine": "^5.1.13", "@types/jasmine": "^5.1.13",
"@types/jasminewd2": "^2.0.13", "@types/jasminewd2": "^2.0.13",
"@types/node": "^24.10.4", "@types/node": "^25.0.3",
"@types/openpgp": "^5.0.0", "@types/openpgp": "^5.0.0",
"jasmine-core": "~5.13.0", "jasmine-core": "~5.13.0",
"jasmine-spec-reporter": "~7.0.0", "jasmine-spec-reporter": "~7.0.0",
@@ -5577,9 +5577,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "24.10.4", "version": "25.0.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.4.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz",
"integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==", "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -6675,9 +6675,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001760", "version": "1.0.30001761",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz",
"integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", "integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "we-bstly-angular", "name": "we-bstly-angular",
"version": "4.0.1", "version": "4.0.2",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve", "start": "ng serve",
@@ -38,7 +38,7 @@
"@angular/localize": "^20.3.15", "@angular/localize": "^20.3.15",
"@types/jasmine": "^5.1.13", "@types/jasmine": "^5.1.13",
"@types/jasminewd2": "^2.0.13", "@types/jasminewd2": "^2.0.13",
"@types/node": "^24.10.4", "@types/node": "^25.0.3",
"@types/openpgp": "^5.0.0", "@types/openpgp": "^5.0.0",
"jasmine-core": "~5.13.0", "jasmine-core": "~5.13.0",
"jasmine-spec-reporter": "~7.0.0", "jasmine-spec-reporter": "~7.0.0",
+56 -54
View File
@@ -1,61 +1,62 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AuthGuard, AuthUpdateGuard, AuthenticatedGuard, AnonymousGuard, AdminGuard } from './auth/auth.guard'; import { AdminGuard, AnonymousGuard, AuthGuard, AuthUpdateGuard, AuthenticatedGuard } from './auth/auth.guard';
import { MainComponent } from './ui/main/main.component';
import { FormLoginComponent } from './pages/form-login/form-login.component';
import { FormLogin2FAComponent } from './pages/form-login-2fa/form-login-2fa.component';
import { PasswordComponent } from './pages/password/password.component';
import { PasswordResetComponent } from './pages/password-reset/password-reset.component';
import { AccountComponent } from './pages/account/account.component'; import { AccountComponent } from './pages/account/account.component';
import { RegisterComponent } from './pages/register/register.component';
import { TokensComponent } from './pages/tokens/tokens.component';
import { ServicesComponent } from './pages/services/services.component';
import { InfoComponent } from './pages/account/info/info.component';
import { ProfileComponent } from './pages/account/profile/profile.component';
import { VoucherComponent } from './pages/account/voucher/voucher.component';
import { SecurityComponent } from './pages/account/security/security.component';
import { UnavailableComponent } from './pages/unavailable/unavailable.component';
import { NotfoundComponent } from './pages/notfound/notfound.component';
import { UserComponent } from './pages/user/user.component'
import { JitsiComponent } from './pages/jitsi/jitsi.component'
import { ParteyComponent } from './pages/partey/partey.component'
import { ParteyTimeslotsComponent } from './pages/partey/timeslots/timeslots.compontent'
import { AliasesComponent } from './pages/account/aliases/aliases.component'; import { AliasesComponent } from './pages/account/aliases/aliases.component';
import { DomainsComponent } from './pages/account/domains/domains.component'; import { DomainsComponent } from './pages/account/domains/domains.component';
import { InvitesComponent } from './pages/invites/invites.component';
import { UrlShortenerComponent, UrlShortenerPasswordComponent } from './pages/urlshortener/urlshortener.component';
import { MinetestAccountsComponent } from './pages/minetest/accounts/accounts.component';
import { DividertestComponent } from './pages/dividertest/dividertest.component'
import { BorrowProvingComponent } from './pages/borrow/proving/proving.component';
import { BorrowItemEditComponent, BorrowItemsComponent } from './pages/borrow/items/items.component';
import { BorrowRequestsComponent } from './pages/borrow/requests/requests.component';
import { BorrowComponent } from './pages/borrow/borrow.component';
import { InviteCodeComponent } from './pages/invites/code/code.component';
import { JukeboxComponent } from './pages/jukebox/jukebox.compontent';
import { FormLoginOidcComponent } from './pages/form-login-oidc/form-login-oidc.component';
import { DyndnsComponent } from './pages/account/dyndns/dyndns.component'; import { DyndnsComponent } from './pages/account/dyndns/dyndns.component';
import { InfoComponent } from './pages/account/info/info.component';
import { ProfileComponent } from './pages/account/profile/profile.component';
import { SecurityComponent } from './pages/account/security/security.component';
import { VoucherComponent } from './pages/account/voucher/voucher.component';
import { AdminComponent } from './pages/admin/admin.component'; import { AdminComponent } from './pages/admin/admin.component';
import { AdminUsersComponent } from './pages/admin/users/users.component';
import { AdminServicesComponent } from './pages/admin/services/services.component';
import { AdminPermissionsComponent } from './pages/admin/permissions/permissions.component';
import { AdminQuotasComponent } from './pages/admin/quotas/quotas.component';
import { AdminJitsiRoomsComponent } from './pages/admin/jitsi-rooms/jitsi-rooms.component';
import { AdminMinetestAccountsComponent } from './pages/admin/minetest-accounts/minetest-accounts.component';
import { AdminShortenedUrlsComponent } from './pages/admin/shortened-urls/shortened-urls.component';
import { AdminJukeboxComponent } from './pages/admin/jukebox/jukebox.component';
import { AdminParteyMapsComponent } from './pages/admin/partey-maps/partey-maps.component';
import { AdminParteyTagsComponent } from './pages/admin/partey-tags/partey-tags.component';
import { AdminParteyReportsComponent } from './pages/admin/partey-reports/partey-reports.component';
import { AdminTimeslotsComponent } from './pages/admin/timeslots/timeslots.component';
import { AdminSystemPropertiesComponent } from './pages/admin/system-properties/system-properties.component';
import { AdminPermissionMappingsComponent } from './pages/admin/permission-mappings/permission-mappings.component';
import { AdminQuotaMappingsComponent } from './pages/admin/quota-mappings/quota-mappings.component';
import { AdminVoucherMappingsComponent } from './pages/admin/voucher-mappings/voucher-mappings.component';
import { AdminSystemProfileFieldsComponent } from './pages/admin/system-profile-fields/system-profile-fields.component';
import { AdminUserAliasesComponent } from './pages/admin/user-aliases/user-aliases.component';
import { AdminOidcClientsComponent } from './pages/admin/oidc-clients/oidc-clients.component';
import { AdminI18nComponent } from './pages/admin/i18n/i18n.component'; import { AdminI18nComponent } from './pages/admin/i18n/i18n.component';
import { AdminJitsiRoomsComponent } from './pages/admin/jitsi-rooms/jitsi-rooms.component';
import { AdminJukeboxComponent } from './pages/admin/jukebox/jukebox.component';
import { AdminMinetestAccountsComponent } from './pages/admin/minetest-accounts/minetest-accounts.component';
import { AdminOidcClientsComponent } from './pages/admin/oidc-clients/oidc-clients.component';
import { AdminParteyMapsComponent } from './pages/admin/partey-maps/partey-maps.component';
import { AdminParteyReportsComponent } from './pages/admin/partey-reports/partey-reports.component';
import { AdminParteyTagsComponent } from './pages/admin/partey-tags/partey-tags.component';
import { AdminPermissionMappingsComponent } from './pages/admin/permission-mappings/permission-mappings.component';
import { AdminPermissionsComponent } from './pages/admin/permissions/permissions.component';
import { AdminQuotaMappingsComponent } from './pages/admin/quota-mappings/quota-mappings.component';
import { AdminQuotasComponent } from './pages/admin/quotas/quotas.component';
import { AdminServicesComponent } from './pages/admin/services/services.component';
import { AdminShortenedUrlsComponent } from './pages/admin/shortened-urls/shortened-urls.component';
import { AdminSystemProfileFieldsComponent } from './pages/admin/system-profile-fields/system-profile-fields.component';
import { AdminSystemPropertiesComponent } from './pages/admin/system-properties/system-properties.component';
import { AdminTimeslotsComponent } from './pages/admin/timeslots/timeslots.component';
import { AdminUserAliasesComponent } from './pages/admin/user-aliases/user-aliases.component';
import { AdminUsersComponent } from './pages/admin/users/users.component';
import { AdminVoucherMappingsComponent } from './pages/admin/voucher-mappings/voucher-mappings.component';
import { BorrowComponent } from './pages/borrow/borrow.component';
import { BorrowItemsComponent } from './pages/borrow/items/items.component';
import { BorrowProvingComponent } from './pages/borrow/proving/proving.component';
import { BorrowRequestsComponent } from './pages/borrow/requests/requests.component';
import { DividertestComponent } from './pages/dividertest/dividertest.component';
import { FormLogin2FAComponent } from './pages/form-login-2fa/form-login-2fa.component';
import { FormLoginOidcComponent } from './pages/form-login-oidc/form-login-oidc.component';
import { FormLoginComponent } from './pages/form-login/form-login.component';
import { StartPageComponent } from './pages/home-redirect/home-redirect.component';
import { InviteCodeComponent } from './pages/invites/code/code.component';
import { InvitesComponent } from './pages/invites/invites.component';
import { JitsiComponent } from './pages/jitsi/jitsi.component';
import { JukeboxComponent } from './pages/jukebox/jukebox.compontent';
import { MinetestAccountsComponent } from './pages/minetest/accounts/accounts.component';
import { NotfoundComponent } from './pages/notfound/notfound.component';
import { ParteyComponent } from './pages/partey/partey.component';
import { ParteyTimeslotsComponent } from './pages/partey/timeslots/timeslots.compontent';
import { PasswordResetComponent } from './pages/password-reset/password-reset.component';
import { PasswordComponent } from './pages/password/password.component';
import { RegisterComponent } from './pages/register/register.component';
import { ServicesComponent } from './pages/services/services.component';
import { TokensComponent } from './pages/tokens/tokens.component';
import { UnavailableComponent } from './pages/unavailable/unavailable.component';
import { UrlShortenerComponent, UrlShortenerPasswordComponent } from './pages/urlshortener/urlshortener.component';
import { UserComponent } from './pages/user/user.component';
import { MainComponent } from './ui/main/main.component';
const routes: Routes = [ const routes: Routes = [
{ path: 'profile/:username', component: UserComponent, canActivate: [AuthUpdateGuard] }, { path: 'profile/:username', component: UserComponent, canActivate: [AuthUpdateGuard] },
@@ -64,10 +65,11 @@ const routes: Routes = [
{ path: 'partey/manage', component: ParteyComponent, canActivate: [AuthenticatedGuard] }, { path: 'partey/manage', component: ParteyComponent, canActivate: [AuthenticatedGuard] },
{ {
path: '', component: MainComponent, children: [ path: '', component: MainComponent, children: [
{ path: '', redirectTo: "/account/info", pathMatch: 'full' }, { path: '', redirectTo: "/home", pathMatch: 'full' },
{ path: 'login', component: FormLoginComponent, canActivate: [AnonymousGuard] }, { path: 'login', component: FormLoginComponent, canActivate: [AnonymousGuard] },
{ path: 'login/2fa', component: FormLogin2FAComponent, canActivate: [AnonymousGuard] }, { path: 'login/2fa', component: FormLogin2FAComponent, canActivate: [AnonymousGuard] },
{ path: 'login/oidc', component: FormLoginOidcComponent, canActivate: [AuthenticatedGuard] }, { path: 'login/oidc', component: FormLoginOidcComponent, canActivate: [AuthenticatedGuard] },
{ path: 'home', component: StartPageComponent, canActivate: [AuthenticatedGuard] },
{ path: 'service-login', component: FormLoginComponent, canActivate: [AnonymousGuard] }, { path: 'service-login', component: FormLoginComponent, canActivate: [AnonymousGuard] },
{ path: 'service-login/2fa', component: FormLogin2FAComponent, canActivate: [AnonymousGuard] }, { path: 'service-login/2fa', component: FormLogin2FAComponent, canActivate: [AnonymousGuard] },
{ path: 'password', component: PasswordComponent, canActivate: [AnonymousGuard] }, { path: 'password', component: PasswordComponent, canActivate: [AnonymousGuard] },
@@ -107,7 +109,8 @@ const routes: Routes = [
{ path: 'invite/:code', component: InviteCodeComponent, canActivate: [AuthGuard] }, { path: 'invite/:code', component: InviteCodeComponent, canActivate: [AuthGuard] },
{ {
path: 'admin', component: AdminComponent, canActivate: [AdminGuard], children: [ path: 'admin', component: AdminComponent, canActivate: [AdminGuard], children: [
{ path: '', redirectTo: "/admin/users", pathMatch: 'full' }, { path: '', redirectTo: "/admin/i18n", pathMatch: 'full' },
{ path: 'i18n', component: AdminI18nComponent, canActivate: [AdminGuard] },
{ path: 'users', component: AdminUsersComponent, canActivate: [AdminGuard] }, { path: 'users', component: AdminUsersComponent, canActivate: [AdminGuard] },
{ path: 'permissions', component: AdminPermissionsComponent, canActivate: [AdminGuard] }, { path: 'permissions', component: AdminPermissionsComponent, canActivate: [AdminGuard] },
{ path: 'permission-mappings', component: AdminPermissionMappingsComponent, canActivate: [AdminGuard] }, { path: 'permission-mappings', component: AdminPermissionMappingsComponent, canActivate: [AdminGuard] },
@@ -126,8 +129,7 @@ const routes: Routes = [
{ path: 'partey-maps', component: AdminParteyMapsComponent, canActivate: [AdminGuard] }, { path: 'partey-maps', component: AdminParteyMapsComponent, canActivate: [AdminGuard] },
{ path: 'partey-tags', component: AdminParteyTagsComponent, canActivate: [AdminGuard] }, { path: 'partey-tags', component: AdminParteyTagsComponent, canActivate: [AdminGuard] },
{ path: 'partey-reports', component: AdminParteyReportsComponent, canActivate: [AdminGuard] }, { path: 'partey-reports', component: AdminParteyReportsComponent, canActivate: [AdminGuard] },
{ path: 'timeslots', component: AdminTimeslotsComponent, canActivate: [AdminGuard] }, { path: 'timeslots', component: AdminTimeslotsComponent, canActivate: [AdminGuard] }
{ path: 'i18n', component: AdminI18nComponent, canActivate: [AdminGuard] }
] ]
}, },
{ path: 'unavailable', component: UnavailableComponent }, { path: 'unavailable', component: UnavailableComponent },
+84 -83
View File
@@ -1,108 +1,108 @@
import { NgModule, Injectable, APP_INITIALIZER } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule, HttpInterceptor, HttpHandler, HttpRequest, HTTP_INTERCEPTORS } from '@angular/common/http';
import { MaterialModule } from './material/material.module';
import { QrCodeModule } from 'ng-qrcode';
import { DatePipe } from '@angular/common';
import { ClipboardModule } from '@angular/cdk/clipboard'; import { ClipboardModule } from '@angular/cdk/clipboard';
import { DatePipe } from '@angular/common';
import { HTTP_INTERCEPTORS, HttpClientModule, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { APP_INITIALIZER, Injectable, NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { QrCodeModule } from 'ng-qrcode';
import { AppRoutingModule } from './app-routing.module';
import { MaterialModule } from './material/material.module';
import { AutofocusDirective } from './material/autofocus'; import { AutofocusDirective } from './material/autofocus';
import { I18nPipe, I18nEmptyPipe } from './utils/i18n.pipe';
import { MomentPipe } from './utils/moment.pipe';
import { MainComponent } from './ui/main/main.component';
import { AccountComponent } from './pages/account/account.component';
import { ServicesComponent } from './pages/services/services.component';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { FormLoginComponent } from './pages/form-login/form-login.component'; import { AccountComponent } from './pages/account/account.component';
import { FormLogin2FAComponent } from './pages/form-login-2fa/form-login-2fa.component';
import { TokensComponent } from './pages/tokens/tokens.component';
import { InvitesComponent } from './pages/invites/invites.component';
import { PermissionsComponent } from './ui/permissions/permissions.component';
import { ProfileFieldDialog, ProfileFieldsComponent, ProfileFieldBlob } from './ui/profilefields/profilefields.component';
import { ServicesGridComponent } from './ui/servicesgrid/servicesgrid.component';
import { ServicesTableComponent } from './ui/servicestable/servicestable.component';
import { ProfileFieldPgpBlob } from './ui/profilefields/binary/pgp/profilefield.pgp-blob';
import { QuotasComponent } from './ui/quotas/quotas.component';
import { SecurityComponent, SecurityKeyDialog, SecurityTotpDialog } from './pages/account/security/security.component';
import { VoucherComponent } from './pages/account/voucher/voucher.component';
import { VoucherDialog } from './pages/account/voucher/voucher.component';
import { InfoComponent } from './pages/account/info/info.component';
import { AliasesComponent } from './pages/account/aliases/aliases.component'; import { AliasesComponent } from './pages/account/aliases/aliases.component';
import { DomainsComponent } from './pages/account/domains/domains.component'; import { DomainsComponent } from './pages/account/domains/domains.component';
import { DyndnsComponent } from './pages/account/dyndns/dyndns.component'; import { DyndnsComponent } from './pages/account/dyndns/dyndns.component';
import { InfoComponent } from './pages/account/info/info.component';
import { ProfileComponent } from './pages/account/profile/profile.component'; import { ProfileComponent } from './pages/account/profile/profile.component';
import { PasswordComponent } from './pages/password/password.component'; import { SecurityComponent, SecurityKeyDialog, SecurityTotpDialog } from './pages/account/security/security.component';
import { VoucherComponent, VoucherDialog } from './pages/account/voucher/voucher.component';
import { BorrowItemEditComponent, BorrowItemsComponent } from './pages/borrow/items/items.component';
import { BorrowProvingComponent, BorrowProvingResultDialog } from './pages/borrow/proving/proving.component';
import { BorrowRequestEditComponent, BorrowRequestsComponent } from './pages/borrow/requests/requests.component';
import { DividertestComponent } from './pages/dividertest/dividertest.component';
import { FormLogin2FAComponent } from './pages/form-login-2fa/form-login-2fa.component';
import { FormLoginComponent } from './pages/form-login/form-login.component';
import { InvitesComponent } from './pages/invites/invites.component';
import { JitsiComponent, JitsiEditDialog, JitsiShareDialog } from './pages/jitsi/jitsi.component';
import { NotfoundComponent } from './pages/notfound/notfound.component';
import { ParteyComponent } from './pages/partey/partey.component';
import { ParteyTimeslotDialog, ParteyTimeslotsComponent } from './pages/partey/timeslots/timeslots.compontent';
import { PasswordResetComponent } from './pages/password-reset/password-reset.component'; import { PasswordResetComponent } from './pages/password-reset/password-reset.component';
import { PasswordComponent } from './pages/password/password.component';
import { RegisterComponent, RegisterDialog } from './pages/register/register.component'; import { RegisterComponent, RegisterDialog } from './pages/register/register.component';
import { UsernameDialog } from './pages/register/username-dialog/username.dialog'; import { UsernameDialog } from './pages/register/username-dialog/username.dialog';
import { ServicesComponent } from './pages/services/services.component';
import { TokensComponent } from './pages/tokens/tokens.component';
import { UnavailableComponent } from './pages/unavailable/unavailable.component'; import { UnavailableComponent } from './pages/unavailable/unavailable.component';
import { NotfoundComponent } from './pages/notfound/notfound.component'; import { UrlShortenerComponent, UrlShortenerEditDialog, UrlShortenerPasswordComponent, UrlShortenerShareDialog } from './pages/urlshortener/urlshortener.component';
import { HtmlComponent } from './utils/html/html.component';
import { ConfirmDialog } from './ui/confirm/confirm.component';
import { UserComponent } from './pages/user/user.component'; import { UserComponent } from './pages/user/user.component';
import { JitsiComponent, JitsiEditDialog, JitsiShareDialog } from './pages/jitsi/jitsi.component'; import { ConfirmDialog } from './ui/confirm/confirm.component';
import { ParteyComponent } from './pages/partey/partey.component';
import { ParteyTimeslotsComponent, ParteyTimeslotDialog } from './pages/partey/timeslots/timeslots.compontent';
import { UrlShortenerComponent, UrlShortenerPasswordComponent, UrlShortenerShareDialog, UrlShortenerEditDialog } from './pages/urlshortener/urlshortener.component';
import { BorrowItemEditComponent, BorrowItemsComponent } from './pages/borrow/items/items.component';
import { BorrowRequestEditComponent, BorrowRequestsComponent } from './pages/borrow/requests/requests.component';
import { BorrowProvingComponent, BorrowProvingResultDialog } from './pages/borrow/proving/proving.component';
import { DividerComponent } from './ui/divider/divider.component'; import { DividerComponent } from './ui/divider/divider.component';
import { DividertestComponent } from './pages/dividertest/dividertest.component'; import { MainComponent } from './ui/main/main.component';
import { PermissionsComponent } from './ui/permissions/permissions.component';
import { ProfileFieldPgpBlob } from './ui/profilefields/binary/pgp/profilefield.pgp-blob';
import { ProfileFieldBlob, ProfileFieldDialog, ProfileFieldsComponent } from './ui/profilefields/profilefields.component';
import { QuotasComponent } from './ui/quotas/quotas.component';
import { ServicesGridComponent } from './ui/servicesgrid/servicesgrid.component';
import { ServicesTableComponent } from './ui/servicestable/servicestable.component';
import { HtmlComponent } from './utils/html/html.component';
import { I18nEmptyPipe, I18nPipe } from './utils/i18n.pipe';
import { MomentPipe } from './utils/moment.pipe';
import { I18nService, I18nPaginatorIntl } from './services/i18n.service';
import { MinetestAccountsComponent } from './pages/minetest/accounts/accounts.component';
import { BorrowComponent } from './pages/borrow/borrow.component';
import { DurationpickerComponent } from './ui/durationpicker/durationpicker.component';
import { InviteCodeComponent } from './pages/invites/code/code.component';
import { InviteEditComponent } from './pages/invites/edit/invite.edit';
import { MatPaginatorIntl } from '@angular/material/paginator';
import { JukeboxComponent } from './pages/jukebox/jukebox.compontent';
import { FormLoginOidcComponent } from './pages/form-login-oidc/form-login-oidc.component';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MomentDateModule } from '@angular/material-moment-adapter'; import { MomentDateModule } from '@angular/material-moment-adapter';
import { MAT_DATE_FORMATS } from '@angular/material/core'; import { MAT_DATE_FORMATS } from '@angular/material/core';
import { DatetimepickerComponent } from './ui/datetimepicker/datetimepicker.component'; import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatPaginatorIntl } from '@angular/material/paginator';
import { AdminComponent } from './pages/admin/admin.component'; import { AdminComponent } from './pages/admin/admin.component';
import { AdminUsersComponent } from './pages/admin/users/users.component';
import { AdminUserEditDialog } from './pages/admin/users/user.edit';
import { AdminPermissionEditDialog } from './pages/admin/permissions/permission.edit';
import { AdminQuotaEditDialog } from './pages/admin/quotas/quota.edit';
import { AdminServiceEditDialog } from './pages/admin/services/service.edit';
import { AdminPermissionMappingEditDialog } from './pages/admin/permission-mappings/permission-mapping.edit';
import { AdminQuotaMappingEditDialog } from './pages/admin/quota-mappings/quota-mapping.edit';
import { AdminServicesComponent } from './pages/admin/services/services.component';
import { AdminPermissionsComponent } from './pages/admin/permissions/permissions.component';
import { AdminQuotasComponent } from './pages/admin/quotas/quotas.component';
import { AdminJitsiRoomsComponent } from './pages/admin/jitsi-rooms/jitsi-rooms.component';
import { AdminMinetestAccountsComponent } from './pages/admin/minetest-accounts/minetest-accounts.component';
import { AdminShortenedUrlsComponent } from './pages/admin/shortened-urls/shortened-urls.component';
import { AdminShortenedUrlEditDialog } from './pages/admin/shortened-urls/shortened-url.edit';
import { AdminJukeboxComponent } from './pages/admin/jukebox/jukebox.component';
import { AdminParteyMapsComponent } from './pages/admin/partey-maps/partey-maps.component';
import { AdminParteyTagsComponent } from './pages/admin/partey-tags/partey-tags.component';
import { AdminParteyReportsComponent } from './pages/admin/partey-reports/partey-reports.component';
import { AdminTimeslotsComponent } from './pages/admin/timeslots/timeslots.component';
import { AdminSystemPropertiesComponent } from './pages/admin/system-properties/system-properties.component';
import { AdminPermissionMappingsComponent } from './pages/admin/permission-mappings/permission-mappings.component';
import { AdminQuotaMappingsComponent } from './pages/admin/quota-mappings/quota-mappings.component';
import { AdminVoucherMappingsComponent } from './pages/admin/voucher-mappings/voucher-mappings.component';
import { AdminSystemProfileFieldsComponent } from './pages/admin/system-profile-fields/system-profile-fields.component';
import { AdminUserAliasesComponent } from './pages/admin/user-aliases/user-aliases.component';
import { AdminOidcClientsComponent } from './pages/admin/oidc-clients/oidc-clients.component';
import { AdminOidcClientEditDialog } from './pages/admin/oidc-clients/oidc-client.edit';
import { AdminI18nComponent } from './pages/admin/i18n/i18n.component'; import { AdminI18nComponent } from './pages/admin/i18n/i18n.component';
import { AdminI18nEditDialog } from './pages/admin/i18n/i18n.edit'; import { AdminI18nEditDialog } from './pages/admin/i18n/i18n.edit';
import { AdminVoucherMappingEditDialog } from './pages/admin/voucher-mappings/voucher-mapping.edit';
import { AdminSystemPropertyEditDialog } from './pages/admin/system-properties/system-property.edit';
import { AdminSystemProfileFieldEditDialog } from './pages/admin/system-profile-fields/system-profile-field.edit';
import { AdminUserAliasEditDialog } from './pages/admin/user-aliases/user-alias.edit';
import { AdminJitsiRoomEditDialog } from './pages/admin/jitsi-rooms/jitsi-room.edit'; import { AdminJitsiRoomEditDialog } from './pages/admin/jitsi-rooms/jitsi-room.edit';
import { AdminJitsiRoomsComponent } from './pages/admin/jitsi-rooms/jitsi-rooms.component';
import { AdminJukeboxComponent } from './pages/admin/jukebox/jukebox.component';
import { AdminMinetestAccountsComponent } from './pages/admin/minetest-accounts/minetest-accounts.component';
import { AdminOidcClientEditDialog } from './pages/admin/oidc-clients/oidc-client.edit';
import { AdminOidcClientsComponent } from './pages/admin/oidc-clients/oidc-clients.component';
import { AdminParteyMapsComponent } from './pages/admin/partey-maps/partey-maps.component';
import { AdminParteyReportsComponent } from './pages/admin/partey-reports/partey-reports.component';
import { AdminParteyTagsComponent } from './pages/admin/partey-tags/partey-tags.component';
import { AdminPermissionMappingEditDialog } from './pages/admin/permission-mappings/permission-mapping.edit';
import { AdminPermissionMappingsComponent } from './pages/admin/permission-mappings/permission-mappings.component';
import { AdminPermissionEditDialog } from './pages/admin/permissions/permission.edit';
import { AdminPermissionsComponent } from './pages/admin/permissions/permissions.component';
import { AdminQuotaMappingEditDialog } from './pages/admin/quota-mappings/quota-mapping.edit';
import { AdminQuotaMappingsComponent } from './pages/admin/quota-mappings/quota-mappings.component';
import { AdminQuotaEditDialog } from './pages/admin/quotas/quota.edit';
import { AdminQuotasComponent } from './pages/admin/quotas/quotas.component';
import { AdminServiceEditDialog } from './pages/admin/services/service.edit';
import { AdminServicesComponent } from './pages/admin/services/services.component';
import { AdminShortenedUrlEditDialog } from './pages/admin/shortened-urls/shortened-url.edit';
import { AdminShortenedUrlsComponent } from './pages/admin/shortened-urls/shortened-urls.component';
import { AdminSystemProfileFieldEditDialog } from './pages/admin/system-profile-fields/system-profile-field.edit';
import { AdminSystemProfileFieldsComponent } from './pages/admin/system-profile-fields/system-profile-fields.component';
import { AdminSystemPropertiesComponent } from './pages/admin/system-properties/system-properties.component';
import { AdminSystemPropertyEditDialog } from './pages/admin/system-properties/system-property.edit';
import { AdminTimeslotsComponent } from './pages/admin/timeslots/timeslots.component';
import { AdminUserAliasEditDialog } from './pages/admin/user-aliases/user-alias.edit';
import { AdminUserAliasesComponent } from './pages/admin/user-aliases/user-aliases.component';
import { AdminUserEditDialog } from './pages/admin/users/user.edit';
import { AdminUsersComponent } from './pages/admin/users/users.component';
import { AdminVoucherMappingEditDialog } from './pages/admin/voucher-mappings/voucher-mapping.edit';
import { AdminVoucherMappingsComponent } from './pages/admin/voucher-mappings/voucher-mappings.component';
import { BorrowComponent } from './pages/borrow/borrow.component';
import { FormLoginOidcComponent } from './pages/form-login-oidc/form-login-oidc.component';
import { StartPageComponent } from './pages/home-redirect/home-redirect.component';
import { InviteCodeComponent } from './pages/invites/code/code.component';
import { InviteEditComponent } from './pages/invites/edit/invite.edit';
import { JukeboxComponent } from './pages/jukebox/jukebox.compontent';
import { MinetestAccountsComponent } from './pages/minetest/accounts/accounts.component';
import { I18nPaginatorIntl, I18nService } from './services/i18n.service';
import { DatetimepickerComponent } from './ui/datetimepicker/datetimepicker.component';
import { DurationpickerComponent } from './ui/durationpicker/durationpicker.component';
export function init_app(i18n: I18nService) { export function init_app(i18n: I18nService) {
@@ -167,7 +167,8 @@ export class XhrInterceptor implements HttpInterceptor {
DatetimepickerComponent, DatetimepickerComponent,
DurationpickerComponent, DurationpickerComponent,
JukeboxComponent, JukeboxComponent,
AdminComponent, AdminUsersComponent, AdminUserEditDialog, AdminPermissionEditDialog, AdminQuotaEditDialog, StartPageComponent,
AdminComponent, AdminUsersComponent, AdminUserEditDialog, AdminPermissionEditDialog, AdminQuotaEditDialog,
AdminServiceEditDialog, AdminPermissionMappingEditDialog, AdminQuotaMappingEditDialog, AdminServiceEditDialog, AdminPermissionMappingEditDialog, AdminQuotaMappingEditDialog,
AdminOidcClientEditDialog, AdminVoucherMappingEditDialog, AdminSystemPropertyEditDialog, AdminOidcClientEditDialog, AdminVoucherMappingEditDialog, AdminSystemPropertyEditDialog,
AdminSystemProfileFieldEditDialog, AdminUserAliasEditDialog, AdminJitsiRoomEditDialog, AdminSystemProfileFieldEditDialog, AdminUserAliasEditDialog, AdminJitsiRoomEditDialog,
+9 -1
View File
@@ -47,11 +47,12 @@ export class AuthenticatedGuard implements CanActivate {
return that.router.navigateByUrl(that.router.parseUrl('/login?target=' + encodeURIComponent(state.url)), { skipLocationChange: true, replaceUrl: true }); return that.router.navigateByUrl(that.router.parseUrl('/login?target=' + encodeURIComponent(state.url)), { skipLocationChange: true, replaceUrl: true });
} }
this.profileService.get([ "locale", "darkTheme" ]).subscribe({ this.profileService.get([ "locale", "darkTheme", "startPage" ]).subscribe({
next: (profileFields: any) => { next: (profileFields: any) => {
let updateLocale = false; let updateLocale = false;
let darktheme = 'false'; let darktheme = 'false';
let updateTheme = false; let updateTheme = false;
let startPage = '/account/info';
for (let profileField of profileFields) { for (let profileField of profileFields) {
if (profileField.name == "darkTheme") { if (profileField.name == "darkTheme") {
darktheme = profileField.value; darktheme = profileField.value;
@@ -62,6 +63,8 @@ export class AuthenticatedGuard implements CanActivate {
updateLocale = true; updateLocale = true;
} }
} catch { } } catch { }
} else if (profileField.name == "startPage") {
startPage = profileField.value;
} }
} }
@@ -70,6 +73,11 @@ export class AuthenticatedGuard implements CanActivate {
localStorage.setItem("bstly.darkTheme", darktheme); localStorage.setItem("bstly.darkTheme", darktheme);
updateTheme = true; updateTheme = true;
} }
if (startPage != localStorage.getItem("bstly.startPage")) {
localStorage.setItem("bstly.startPage", startPage);
updateTheme = true;
}
} catch { } } catch { }
if (updateLocale || updateTheme) { if (updateLocale || updateTheme) {
@@ -7,10 +7,11 @@
</p> </p>
<mat-form-field> <mat-form-field>
<mat-label>{{'security.webauthn.nickname' | i18n}}</mat-label> <mat-label>{{'security.webauthn.nickname' | i18n}}</mat-label>
<input matInput [formControl]="nickname"> <input matInput cdkFocusInitial [formControl]="nickname" required="">
</mat-form-field> </mat-form-field>
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button mat-button (click)="dialogRef.close(null)">{{'cancel' | i18n}}</button> <a [disabled]="nickname.invalid" mat-raised-button [mat-dialog-close]="nickname.value" color="accent">{{'ok' |
<button mat-button (click)="dialogRef.close(nickname.value)" cdkFocusInitial>{{'ok' | i18n}}</button> i18n}}</a>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
</div> </div>
@@ -15,7 +15,7 @@
</mat-form-field> </mat-form-field>
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
<a [disabled]="code.invalid" mat-raised-button [mat-dialog-close]="code.value" <a [disabled]="code.invalid" mat-raised-button [mat-dialog-close]="code.value"
color="accent">{{'security.2fa.totp.enable' | i18n}}</a> color="accent">{{'security.2fa.totp.enable' | i18n}}</a>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
</div> </div>
@@ -146,6 +146,11 @@
</mat-list-item> </mat-list-item>
} }
</mat-list> </mat-list>
@if (webauthnWarning) {
<div class="mat-bg-error-container">
{{'security.webauthn.hint' | i18n}}
</div>
}
} }
</mat-card-content> </mat-card-content>
<mat-card-actions> <mat-card-actions>
@@ -1,3 +1,9 @@
@use '../../../../variables.scss' as vars;
mat-form-field { mat-form-field {
display: inline; display: inline;
} }
.mat-bg-error-container {
color: vars.$warn;
}
@@ -1,4 +1,4 @@
import { Component, Inject, OnInit, ViewChild } from '@angular/core'; import { Component, HostListener, Inject, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, NgForm, Validators } from '@angular/forms'; import { FormBuilder, FormControl, FormGroup, NgForm, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
@@ -16,13 +16,14 @@ import { MatchingValidator } from './../../../utils/matching.validator';
}) })
export class SecurityComponent implements OnInit { export class SecurityComponent implements OnInit {
public working: boolean; working: boolean;
public success: boolean; success: boolean;
public successStatus: boolean; successStatus: boolean;
public totp: boolean = false; totp: boolean = false;
public webauthn: boolean = false; webauthn: boolean = false;
public webAuthnSupported: boolean = false; webauthnWarning: boolean = false;
public webAuthnCredentials: any[] = []; webAuthnSupported: boolean = false;
webAuthnCredentials: any[] = [];
statuses = ["NORMAL", "SLEEP", "PURGE"]; statuses = ["NORMAL", "SLEEP", "PURGE"];
@@ -77,10 +78,12 @@ export class SecurityComponent implements OnInit {
next: (credentials) => { next: (credentials) => {
this.webAuthnCredentials = credentials; this.webAuthnCredentials = credentials;
this.webauthn = credentials.length > 0; this.webauthn = credentials.length > 0;
this.webauthnWarning = this.webauthn && credentials.some((c) => c.usage == 'LOGIN_2FA');
}, },
error: (error) => { error: (error) => {
this.webAuthnCredentials = []; this.webAuthnCredentials = [];
this.webauthn = false; this.webauthn = false;
this.webauthnWarning = false;
} }
}); });
} }
@@ -271,6 +274,18 @@ export class SecurityTotpDialog {
ngOnInit(): void { ngOnInit(): void {
this.code = new FormControl('', [Validators.required, Validators.pattern("[0-9]{6}")]); this.code = new FormControl('', [Validators.required, Validators.pattern("[0-9]{6}")]);
} }
@HostListener('window:keyup.Enter', ['$event'])
confirmDialog(): void {
if (this.code.valid && this.code.value) {
this.dialogRef.close(this.code.value);
}
}
@HostListener('window:keyup.Esc', ['$event'])
cancelDialog(): void {
this.dialogRef.close(false);
}
} }
@Component({ @Component({
@@ -288,5 +303,17 @@ export class SecurityKeyDialog implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.nickname = new FormControl('', []); this.nickname = new FormControl('', []);
} }
@HostListener('window:keyup.Enter', ['$event'])
confirmDialog(): void {
if (this.nickname.value) {
this.dialogRef.close(this.nickname.value);
}
}
@HostListener('window:keyup.Esc', ['$event'])
cancelDialog(): void {
this.dialogRef.close(false);
}
} }
+44 -46
View File
@@ -1,52 +1,50 @@
<h2>{{'admin.title' | i18n}} <mat-icon>admin_panel_settings</mat-icon></h2> <h2>{{'admin.title' | i18n}} <mat-icon>admin_panel_settings</mat-icon></h2>
<nav mat-tab-nav-bar [tabPanel]="tabPanel"> <nav mat-tab-nav-bar [tabPanel]="tabPanel">
<a mat-tab-link routerLink="users" routerLinkActive #rlausers="routerLinkActive" [active]="rlausers.isActive"> <a mat-tab-link routerLink="i18n" routerLinkActive #rli18n="routerLinkActive" [active]="rli18n.isActive">
{{'admin.users' | i18n}} {{'admin.i18n' | i18n}}
</a> </a>
<a mat-tab-link routerLink="permission-mappings" routerLinkActive #rlapermmap="routerLinkActive" <a mat-tab-link routerLink="users" routerLinkActive #rlausers="routerLinkActive" [active]="rlausers.isActive">
[active]="rlapermmap.isActive"> {{'admin.users' | i18n}}
{{'admin.permission_mappings' | i18n}} </a>
</a> <a mat-tab-link routerLink="permission-mappings" routerLinkActive #rlapermmap="routerLinkActive"
<a mat-tab-link routerLink="quota-mappings" routerLinkActive #rlaquotamap="routerLinkActive" [active]="rlapermmap.isActive">
[active]="rlaquotamap.isActive"> {{'admin.permission_mappings' | i18n}}
{{'admin.quota_mappings' | i18n}} </a>
</a> <a mat-tab-link routerLink="quota-mappings" routerLinkActive #rlaquotamap="routerLinkActive"
<a mat-tab-link routerLink="services" routerLinkActive #rlaservices="routerLinkActive" [active]="rlaquotamap.isActive">
[active]="rlaservices.isActive"> {{'admin.quota_mappings' | i18n}}
{{'admin.services' | i18n}} </a>
</a> <a mat-tab-link routerLink="services" routerLinkActive #rlaservices="routerLinkActive"
<a mat-tab-link routerLink="oidc-clients" routerLinkActive #rlaoidc="routerLinkActive" [active]="rlaoidc.isActive"> [active]="rlaservices.isActive">
{{'admin.oidc_clients' | i18n}} {{'admin.services' | i18n}}
</a> </a>
<a mat-tab-link routerLink="voucher-mappings" routerLinkActive #rlavouchers="routerLinkActive" <a mat-tab-link routerLink="oidc-clients" routerLinkActive #rlaoidc="routerLinkActive" [active]="rlaoidc.isActive">
[active]="rlavouchers.isActive"> {{'admin.oidc_clients' | i18n}}
{{'admin.voucher_mappings' | i18n}} </a>
</a> <a mat-tab-link routerLink="voucher-mappings" routerLinkActive #rlavouchers="routerLinkActive"
<a mat-tab-link routerLink="system-properties" routerLinkActive #rlasystem="routerLinkActive" [active]="rlavouchers.isActive">
[active]="rlasystem.isActive"> {{'admin.voucher_mappings' | i18n}}
{{'admin.system_properties' | i18n}} </a>
</a> <a mat-tab-link routerLink="system-properties" routerLinkActive #rlasystem="routerLinkActive"
<a mat-tab-link routerLink="system-profile-fields" routerLinkActive #rlaprofile="routerLinkActive" [active]="rlasystem.isActive">
[active]="rlaprofile.isActive"> {{'admin.system_properties' | i18n}}
{{'admin.system_profile_fields' | i18n}} </a>
</a> <a mat-tab-link routerLink="system-profile-fields" routerLinkActive #rlaprofile="routerLinkActive"
<a mat-tab-link routerLink="user-aliases" routerLinkActive #rlaaliases="routerLinkActive" [active]="rlaprofile.isActive">
[active]="rlaaliases.isActive"> {{'admin.system_profile_fields' | i18n}}
{{'admin.user_aliases' | i18n}} </a>
</a> <a mat-tab-link routerLink="user-aliases" routerLinkActive #rlaaliases="routerLinkActive"
<a mat-tab-link routerLink="jitsi-rooms" routerLinkActive #rlajitsi="routerLinkActive" [active]="rlajitsi.isActive"> [active]="rlaaliases.isActive">
{{'admin.jitsi_rooms' | i18n}} {{'admin.user_aliases' | i18n}}
</a> </a>
<a mat-tab-link routerLink="shortened-urls" routerLinkActive #rlaurls="routerLinkActive" <a mat-tab-link routerLink="jitsi-rooms" routerLinkActive #rlajitsi="routerLinkActive" [active]="rlajitsi.isActive">
[active]="rlaurls.isActive"> {{'admin.jitsi_rooms' | i18n}}
{{'admin.shortened_urls' | i18n}} </a>
</a> <a mat-tab-link routerLink="shortened-urls" routerLinkActive #rlaurls="routerLinkActive" [active]="rlaurls.isActive">
<a mat-tab-link routerLink="i18n" routerLinkActive #rli18n="routerLinkActive" {{'admin.shortened_urls' | i18n}}
[active]="rli18n.isActive"> </a>
{{'admin.i18n' | i18n}} <!--
</a>
<!--
<a mat-tab-link routerLink="minetest-accounts" routerLinkActive #rlaminetest="routerLinkActive" <a mat-tab-link routerLink="minetest-accounts" routerLinkActive #rlaminetest="routerLinkActive"
[active]="rlaminetest.isActive"> [active]="rlaminetest.isActive">
{{'admin.minetest_accounts' | i18n}} {{'admin.minetest_accounts' | i18n}}
+1 -1
View File
@@ -55,7 +55,7 @@
{{ 'admin.save' | i18n }} {{ 'admin.save' | i18n }}
</button> </button>
<button mat-button (click)="toggleRawJsonMode()"> <button mat-button (click)="toggleRawJsonMode()">
{{ 'admin.cancel' | i18n }} {{ 'cancel' | i18n }}
</button> </button>
</div> </div>
</div> </div>
+1 -1
View File
@@ -108,7 +108,7 @@ export class AdminI18nComponent implements OnInit, AfterViewInit {
if (obj.hasOwnProperty(key)) { if (obj.hasOwnProperty(key)) {
const value = obj[key]; const value = obj[key];
if (key === '.') { if (key === '') {
// Handle the special "." key - it represents the value at this level // Handle the special "." key - it represents the value at this level
result.push({ result.push({
key: parentPath, key: parentPath,
+11 -13
View File
@@ -5,30 +5,28 @@
<form> <form>
<mat-form-field appearance="outline" class="full-width"> <mat-form-field appearance="outline" class="full-width">
<mat-label>{{ 'admin.i18n.key' | i18n }}</mat-label> <mat-label>{{ 'admin.i18n.key' | i18n }}</mat-label>
<input matInput [(ngModel)]="key" name="key" required <input matInput [(ngModel)]="key" name="key" required [readonly]="data.entry !== null"
[readonly]="data.entry !== null" [placeholder]="'admin.i18n.key_placeholder' | i18n">
[placeholder]="'admin.i18n.key_placeholder' | i18n">
<mat-hint>{{ 'admin.i18n.key_hint' | i18n }}</mat-hint> <mat-hint>{{ 'admin.i18n.key_hint' | i18n }}</mat-hint>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline" class="full-width"> <mat-form-field appearance="outline" class="full-width">
<mat-label>{{ 'admin.i18n.value' | i18n }}</mat-label> <mat-label>{{ 'admin.i18n.value' | i18n }}</mat-label>
<textarea matInput [(ngModel)]="value" name="value" required <textarea matInput [(ngModel)]="value" name="value" required rows="4"
rows="4" [placeholder]="'admin.i18n.value_placeholder' | i18n"></textarea>
[placeholder]="'admin.i18n.value_placeholder' | i18n"></textarea>
</mat-form-field> </mat-form-field>
@if (errorMessage) { @if (errorMessage) {
<mat-error class="error-message">{{ errorMessage }}</mat-error> <mat-error class="error-message">{{ errorMessage }}</mat-error>
} }
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="onCancel()">{{ 'admin.cancel' | i18n }}</button> <a mat-raised-button color="primary" (click)="onSave()" [disabled]="saving || !isValid()">
<button mat-raised-button color="primary" (click)="onSave()" [disabled]="saving || !isValid()">
@if (saving) { @if (saving) {
<mat-spinner diameter="20"></mat-spinner> <mat-spinner diameter="20"></mat-spinner>
} }
{{ 'admin.save' | i18n }} {{ 'admin.save' | i18n }}
</button> </a>
</mat-dialog-actions> <a mat-button (click)="onCancel()">{{ 'cancel' | i18n }}</a>
</mat-dialog-actions>
@@ -12,38 +12,41 @@
<mat-label>{{ 'admin.jitsi_rooms.room' | i18n }}</mat-label> <mat-label>{{ 'admin.jitsi_rooms.room' | i18n }}</mat-label>
<input matInput formControlName="room" [placeholder]="'admin.jitsi_rooms.room' | i18n" required> <input matInput formControlName="room" [placeholder]="'admin.jitsi_rooms.room' | i18n" required>
@if (form.get('room')?.hasError('required')) { @if (form.get('room')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.jitsi_rooms.room_required' | i18n }} {{ 'admin.jitsi_rooms.room_required' | i18n }}
</mat-error> </mat-error>
} }
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>{{ 'admin.jitsi_rooms.starts' | i18n }}</mat-label> <mat-label>{{ 'admin.jitsi_rooms.starts' | i18n }}</mat-label>
<input matInput [matDatepicker]="startsPicker" formControlName="starts" [placeholder]="'admin.jitsi_rooms.starts' | i18n"> <input matInput [matDatepicker]="startsPicker" formControlName="starts"
[placeholder]="'admin.jitsi_rooms.starts' | i18n">
<mat-datepicker-toggle matSuffix [for]="startsPicker"></mat-datepicker-toggle> <mat-datepicker-toggle matSuffix [for]="startsPicker"></mat-datepicker-toggle>
<mat-datepicker #startsPicker></mat-datepicker> <mat-datepicker #startsPicker></mat-datepicker>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>{{ 'admin.jitsi_rooms.moderation_starts' | i18n }}</mat-label> <mat-label>{{ 'admin.jitsi_rooms.moderation_starts' | i18n }}</mat-label>
<input matInput [matDatepicker]="moderationStartsPicker" formControlName="moderationStarts" [placeholder]="'admin.jitsi_rooms.moderation_starts' | i18n"> <input matInput [matDatepicker]="moderationStartsPicker" formControlName="moderationStarts"
[placeholder]="'admin.jitsi_rooms.moderation_starts' | i18n">
<mat-datepicker-toggle matSuffix [for]="moderationStartsPicker"></mat-datepicker-toggle> <mat-datepicker-toggle matSuffix [for]="moderationStartsPicker"></mat-datepicker-toggle>
<mat-datepicker #moderationStartsPicker></mat-datepicker> <mat-datepicker #moderationStartsPicker></mat-datepicker>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>{{ 'admin.jitsi_rooms.expires' | i18n }}</mat-label> <mat-label>{{ 'admin.jitsi_rooms.expires' | i18n }}</mat-label>
<input matInput [matDatepicker]="expiresPicker" formControlName="expires" [placeholder]="'admin.jitsi_rooms.expires' | i18n"> <input matInput [matDatepicker]="expiresPicker" formControlName="expires"
[placeholder]="'admin.jitsi_rooms.expires' | i18n">
<mat-datepicker-toggle matSuffix [for]="expiresPicker"></mat-datepicker-toggle> <mat-datepicker-toggle matSuffix [for]="expiresPicker"></mat-datepicker-toggle>
<mat-datepicker #expiresPicker></mat-datepicker> <mat-datepicker #expiresPicker></mat-datepicker>
</mat-form-field> </mat-form-field>
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="onCancel()">{{ 'admin.cancel' | i18n }}</button> <a mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
<button mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
</mat-dialog-actions> <a mat-button (click)="onCancel()">{{ 'cancel' | i18n }}</a>
</mat-dialog-actions>
@@ -17,7 +17,9 @@
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>{{'admin.oidc_clients.client_id' | i18n}}</mat-label> <mat-label>{{'admin.oidc_clients.client_id' | i18n}}</mat-label>
<input matInput formControlName="clientId" readonly> <input matInput formControlName="clientId" readonly>
<button mat-icon-button matSuffix (click)="copyToClipboard(form.get('clientId')?.value, 'admin.oidc_clients.client_id_copied')" type="button" [title]="'admin.oidc_clients.copy_client_id' | i18n"> <button mat-icon-button matSuffix
(click)="copyToClipboard(form.get('clientId')?.value, 'admin.oidc_clients.client_id_copied')"
type="button" [title]="'admin.oidc_clients.copy_client_id' | i18n">
<mat-icon>content_copy</mat-icon> <mat-icon>content_copy</mat-icon>
</button> </button>
</mat-form-field> </mat-form-field>
@@ -25,10 +27,13 @@
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>{{'admin.oidc_clients.client_secret' | i18n}}</mat-label> <mat-label>{{'admin.oidc_clients.client_secret' | i18n}}</mat-label>
<input matInput [type]="hideSecret ? 'password' : 'text'" formControlName="clientSecret" readonly> <input matInput [type]="hideSecret ? 'password' : 'text'" formControlName="clientSecret" readonly>
<button mat-icon-button matSuffix (click)="hideSecret = !hideSecret" type="button" [title]="hideSecret ? ('admin.oidc_clients.show_secret' | i18n) : ('admin.oidc_clients.hide_secret' | i18n)"> <button mat-icon-button matSuffix (click)="hideSecret = !hideSecret" type="button"
[title]="hideSecret ? ('admin.oidc_clients.show_secret' | i18n) : ('admin.oidc_clients.hide_secret' | i18n)">
<mat-icon>{{hideSecret ? 'visibility' : 'visibility_off'}}</mat-icon> <mat-icon>{{hideSecret ? 'visibility' : 'visibility_off'}}</mat-icon>
</button> </button>
<button mat-icon-button matSuffix (click)="copyToClipboard(form.get('clientSecret')?.value, 'admin.oidc_clients.secret_copied')" type="button" [title]="'admin.oidc_clients.copy_secret' | i18n"> <button mat-icon-button matSuffix
(click)="copyToClipboard(form.get('clientSecret')?.value, 'admin.oidc_clients.secret_copied')"
type="button" [title]="'admin.oidc_clients.copy_secret' | i18n">
<mat-icon>content_copy</mat-icon> <mat-icon>content_copy</mat-icon>
</button> </button>
</mat-form-field> </mat-form-field>
@@ -145,9 +150,9 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="cancel()">{{'admin.cancel' | i18n}}</button> <a mat-raised-button color="primary" (click)="onSave()" [disabled]="!form.valid">
<button mat-raised-button color="primary" (click)="onSave()" [disabled]="!form.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
<a mat-button (click)="cancel()">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
@@ -72,9 +72,9 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="cancel()">{{'admin.cancel' | i18n}}</button> <a mat-raised-button color="primary" (click)="save()" [disabled]="!mappingForm.valid">
<button mat-raised-button color="primary" (click)="save()" [disabled]="!mappingForm.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
<a mat-button (click)="cancel()">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
@@ -31,9 +31,9 @@
</mat-checkbox> </mat-checkbox>
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<a mat-button [mat-dialog-close]="false">{{ 'cancel' | i18n }}</a>
<a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent"> <a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</a> </a>
<a mat-button [mat-dialog-close]="false">{{ 'cancel' | i18n }}</a>
</mat-dialog-actions> </mat-dialog-actions>
@@ -60,9 +60,9 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="cancel()">{{'admin.cancel' | i18n}}</button> <a mat-raised-button color="primary" (click)="save()" [disabled]="!mappingForm.valid">
<button mat-raised-button color="primary" (click)="save()" [disabled]="!mappingForm.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
<a mat-button (click)="cancel()">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
+4 -4
View File
@@ -38,9 +38,9 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="cancel()">{{'admin.cancel' | i18n}}</button> <a mat-raised-button color="primary" (click)="save()" [disabled]="!quotaForm.valid">
<button mat-raised-button color="primary" (click)="save()" [disabled]="!quotaForm.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
<a mat-button (click)="cancel()">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
@@ -42,9 +42,9 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="cancel()">{{'admin.cancel' | i18n}}</button> <a mat-raised-button color="primary" (click)="save()" [disabled]="!serviceForm.valid">
<button mat-raised-button color="primary" (click)="save()" [disabled]="!serviceForm.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
<a mat-button (click)="cancel()">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
@@ -6,22 +6,23 @@
<mat-label>{{ 'admin.shortened_urls.code' | i18n }}</mat-label> <mat-label>{{ 'admin.shortened_urls.code' | i18n }}</mat-label>
<input matInput formControlName="code" [placeholder]="'admin.shortened_urls.code' | i18n" required> <input matInput formControlName="code" [placeholder]="'admin.shortened_urls.code' | i18n" required>
@if (form.get('code')?.hasError('required')) { @if (form.get('code')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.shortened_urls.code' | i18n }} {{ 'admin.users.error.username' | i18n }} {{ 'admin.shortened_urls.code' | i18n }} {{ 'admin.users.error.username' | i18n }}
</mat-error> </mat-error>
} }
@if (isEditMode) { @if (isEditMode) {
<mat-hint>Code cannot be changed after creation</mat-hint> <mat-hint>Code cannot be changed after creation</mat-hint>
} }
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>{{ 'admin.shortened_urls.owner' | i18n }}</mat-label> <mat-label>{{ 'admin.shortened_urls.owner' | i18n }}</mat-label>
<input matInput formControlName="owner" type="number" [placeholder]="'admin.shortened_urls.owner' | i18n" required> <input matInput formControlName="owner" type="number" [placeholder]="'admin.shortened_urls.owner' | i18n"
required>
@if (form.get('owner')?.hasError('required')) { @if (form.get('owner')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.shortened_urls.owner' | i18n }} is required {{ 'admin.shortened_urls.owner' | i18n }} is required
</mat-error> </mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -29,9 +30,9 @@
<mat-label>{{ 'admin.shortened_urls.url' | i18n }}</mat-label> <mat-label>{{ 'admin.shortened_urls.url' | i18n }}</mat-label>
<input matInput formControlName="url" [placeholder]="'admin.shortened_urls.url' | i18n" required> <input matInput formControlName="url" [placeholder]="'admin.shortened_urls.url' | i18n" required>
@if (form.get('url')?.hasError('required')) { @if (form.get('url')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.shortened_urls.url' | i18n }} is required {{ 'admin.shortened_urls.url' | i18n }} is required
</mat-error> </mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -56,9 +57,9 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="onCancel()">{{ 'admin.cancel' | i18n }}</button> <a mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
<button mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
</mat-dialog-actions> <a mat-button (click)="onCancel()">{{ 'cancel' | i18n }}</a>
</mat-dialog-actions>
@@ -1,4 +1,5 @@
<h2 mat-dialog-title>{{ (isEditMode ? 'admin.system_profile_fields.edit' : 'admin.system_profile_fields.create') | i18n }}</h2> <h2 mat-dialog-title>{{ (isEditMode ? 'admin.system_profile_fields.edit' : 'admin.system_profile_fields.create') | i18n
}}</h2>
<mat-dialog-content> <mat-dialog-content>
<form [formGroup]="form"> <form [formGroup]="form">
@@ -6,12 +7,12 @@
<mat-label>{{ 'admin.system_profile_fields.name' | i18n }}</mat-label> <mat-label>{{ 'admin.system_profile_fields.name' | i18n }}</mat-label>
<input matInput formControlName="name" [placeholder]="'admin.system_profile_fields.name' | i18n" required> <input matInput formControlName="name" [placeholder]="'admin.system_profile_fields.name' | i18n" required>
@if (form.get('name')?.hasError('required')) { @if (form.get('name')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.system_profile_fields.name_required' | i18n }} {{ 'admin.system_profile_fields.name_required' | i18n }}
</mat-error> </mat-error>
} }
@if (isEditMode) { @if (isEditMode) {
<mat-hint>{{ 'admin.system_profile_fields.name_readonly' | i18n }}</mat-hint> <mat-hint>{{ 'admin.system_profile_fields.name_readonly' | i18n }}</mat-hint>
} }
</mat-form-field> </mat-form-field>
@@ -19,15 +20,15 @@
<mat-label>{{ 'admin.system_profile_fields.type' | i18n }}</mat-label> <mat-label>{{ 'admin.system_profile_fields.type' | i18n }}</mat-label>
<mat-select formControlName="type" required> <mat-select formControlName="type" required>
@for (type of profileFieldTypes; track type) { @for (type of profileFieldTypes; track type) {
<mat-option [value]="type"> <mat-option [value]="type">
{{ type }} {{ type }}
</mat-option> </mat-option>
} }
</mat-select> </mat-select>
@if (form.get('type')?.hasError('required')) { @if (form.get('type')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.system_profile_fields.type_required' | i18n }} {{ 'admin.system_profile_fields.type_required' | i18n }}
</mat-error> </mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -37,9 +38,9 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="onCancel()">{{ 'admin.cancel' | i18n }}</button> <a mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
<button mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
</mat-dialog-actions> <a mat-button (click)="onCancel()">{{ 'cancel' | i18n }}</a>
</mat-dialog-actions>
@@ -6,30 +6,31 @@
<mat-label>{{ 'admin.system_properties.key' | i18n }}</mat-label> <mat-label>{{ 'admin.system_properties.key' | i18n }}</mat-label>
<input matInput formControlName="key" [placeholder]="'admin.system_properties.key' | i18n" required> <input matInput formControlName="key" [placeholder]="'admin.system_properties.key' | i18n" required>
@if (form.get('key')?.hasError('required')) { @if (form.get('key')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.system_properties.key_required' | i18n }} {{ 'admin.system_properties.key_required' | i18n }}
</mat-error> </mat-error>
} }
@if (isEditMode) { @if (isEditMode) {
<mat-hint>{{ 'admin.system_properties.key_readonly' | i18n }}</mat-hint> <mat-hint>{{ 'admin.system_properties.key_readonly' | i18n }}</mat-hint>
} }
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>{{ 'admin.system_properties.value' | i18n }}</mat-label> <mat-label>{{ 'admin.system_properties.value' | i18n }}</mat-label>
<textarea matInput formControlName="value" [placeholder]="'admin.system_properties.value' | i18n" rows="5" required></textarea> <textarea matInput formControlName="value" [placeholder]="'admin.system_properties.value' | i18n" rows="5"
required></textarea>
@if (form.get('value')?.hasError('required')) { @if (form.get('value')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.system_properties.value_required' | i18n }} {{ 'admin.system_properties.value_required' | i18n }}
</mat-error> </mat-error>
} }
</mat-form-field> </mat-form-field>
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="onCancel()">{{ 'admin.cancel' | i18n }}</button> <a mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
<button mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
</mat-dialog-actions> <a mat-button (click)="onCancel()">{{ 'cancel' | i18n }}</a>
</mat-dialog-actions>
@@ -4,11 +4,12 @@
<form [formGroup]="form"> <form [formGroup]="form">
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>{{ 'admin.user_aliases.target' | i18n }}</mat-label> <mat-label>{{ 'admin.user_aliases.target' | i18n }}</mat-label>
<input matInput type="number" formControlName="target" [placeholder]="'admin.user_aliases.target' | i18n" required> <input matInput type="number" formControlName="target" [placeholder]="'admin.user_aliases.target' | i18n"
required>
@if (form.get('target')?.hasError('required')) { @if (form.get('target')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.user_aliases.target_required' | i18n }} {{ 'admin.user_aliases.target_required' | i18n }}
</mat-error> </mat-error>
} }
<mat-hint>{{ 'admin.user_aliases.target_hint' | i18n }}</mat-hint> <mat-hint>{{ 'admin.user_aliases.target_hint' | i18n }}</mat-hint>
</mat-form-field> </mat-form-field>
@@ -17,9 +18,9 @@
<mat-label>{{ 'admin.user_aliases.alias' | i18n }}</mat-label> <mat-label>{{ 'admin.user_aliases.alias' | i18n }}</mat-label>
<input matInput formControlName="alias" [placeholder]="'admin.user_aliases.alias' | i18n" required> <input matInput formControlName="alias" [placeholder]="'admin.user_aliases.alias' | i18n" required>
@if (form.get('alias')?.hasError('required')) { @if (form.get('alias')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.user_aliases.alias_required' | i18n }} {{ 'admin.user_aliases.alias_required' | i18n }}
</mat-error> </mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -27,23 +28,23 @@
<mat-label>{{ 'admin.user_aliases.visibility' | i18n }}</mat-label> <mat-label>{{ 'admin.user_aliases.visibility' | i18n }}</mat-label>
<mat-select formControlName="visibility" required> <mat-select formControlName="visibility" required>
@for (visibility of visibilityOptions; track visibility) { @for (visibility of visibilityOptions; track visibility) {
<mat-option [value]="visibility"> <mat-option [value]="visibility">
{{ visibility }} {{ visibility }}
</mat-option> </mat-option>
} }
</mat-select> </mat-select>
@if (form.get('visibility')?.hasError('required')) { @if (form.get('visibility')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.user_aliases.visibility_required' | i18n }} {{ 'admin.user_aliases.visibility_required' | i18n }}
</mat-error> </mat-error>
} }
</mat-form-field> </mat-form-field>
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="onCancel()">{{ 'admin.cancel' | i18n }}</button> <a mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
<button mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
</mat-dialog-actions> <a mat-button (click)="onCancel()">{{ 'cancel' | i18n }}</a>
</mat-dialog-actions>
+2 -2
View File
@@ -57,9 +57,9 @@
</mat-checkbox> </mat-checkbox>
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<a mat-button [mat-dialog-close]="false">{{ 'cancel' | i18n }}</a>
<a [disabled]="form.invalid || !passwordsMatch()" mat-raised-button (click)="save()" color="accent"> <a [disabled]="form.invalid || !passwordsMatch()" mat-raised-button (click)="save()" color="accent">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</a> </a>
<a mat-button [mat-dialog-close]="false">{{ 'cancel' | i18n }}</a>
</mat-dialog-actions> </mat-dialog-actions>
@@ -6,9 +6,9 @@
<mat-label>{{ 'admin.voucher_mappings.name' | i18n }}</mat-label> <mat-label>{{ 'admin.voucher_mappings.name' | i18n }}</mat-label>
<input matInput formControlName="name" [placeholder]="'admin.voucher_mappings.name' | i18n" required> <input matInput formControlName="name" [placeholder]="'admin.voucher_mappings.name' | i18n" required>
@if (form.get('name')?.hasError('required')) { @if (form.get('name')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.voucher_mappings.name_required' | i18n }} {{ 'admin.voucher_mappings.name_required' | i18n }}
</mat-error> </mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -19,16 +19,17 @@
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>{{ 'admin.voucher_mappings.voucher' | i18n }}</mat-label> <mat-label>{{ 'admin.voucher_mappings.voucher' | i18n }}</mat-label>
<input matInput type="number" formControlName="voucher" [placeholder]="'admin.voucher_mappings.voucher' | i18n" required> <input matInput type="number" formControlName="voucher" [placeholder]="'admin.voucher_mappings.voucher' | i18n"
required>
@if (form.get('voucher')?.hasError('required')) { @if (form.get('voucher')?.hasError('required')) {
<mat-error> <mat-error>
{{ 'admin.voucher_mappings.voucher_required' | i18n }} {{ 'admin.voucher_mappings.voucher_required' | i18n }}
</mat-error> </mat-error>
} }
@if (form.get('voucher')?.hasError('min')) { @if (form.get('voucher')?.hasError('min')) {
<mat-error> <mat-error>
{{ 'admin.voucher_mappings.voucher_min' | i18n }} {{ 'admin.voucher_mappings.voucher_min' | i18n }}
</mat-error> </mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -38,9 +39,9 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions align="end"> <mat-dialog-actions>
<button mat-button (click)="onCancel()">{{ 'admin.cancel' | i18n }}</button> <a mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
<button mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }} {{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button> </a>
</mat-dialog-actions> <a mat-button [mat-dialog-close]="false">{{ 'cancel' | i18n }}</a>
</mat-dialog-actions>
+1 -1
View File
@@ -188,10 +188,10 @@
<mat-dialog-actions> <mat-dialog-actions>
<div class="flex" fxLayoutAlign="space-between start"> <div class="flex" fxLayoutAlign="space-between start">
<div> <div>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
<a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent"> <a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">
<mat-icon>save</mat-icon>{{(create ? 'borrow.items.create' : 'borrow.items.save') | i18n}} <mat-icon>save</mat-icon>{{(create ? 'borrow.items.create' : 'borrow.items.save') | i18n}}
</a> </a>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
</div> </div>
@if (borrowItemId) { @if (borrowItemId) {
<a mat-button color="warn" (click)="confirmDelete()"> <a mat-button color="warn" (click)="confirmDelete()">
@@ -53,10 +53,10 @@
<mat-dialog-actions> <mat-dialog-actions>
<div class="flex" fxLayoutAlign="space-between start"> <div class="flex" fxLayoutAlign="space-between start">
<div> <div>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
<a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent"> <a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">
<mat-icon>save</mat-icon>{{(create ? 'borrow.request.create' : 'borrow.request.save') | i18n}} <mat-icon>save</mat-icon>{{(create ? 'borrow.request.create' : 'borrow.request.save') | i18n}}
</a> </a>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
</div> </div>
@if (borrowRequest.id) { @if (borrowRequest.id) {
<a mat-button color="warn" (click)="confirmDelete()"> <a mat-button color="warn" (click)="confirmDelete()">
@@ -1,4 +1,4 @@
<form action="{{apiUrl}}/auth/login/2fa" method="POST" #form2FA id="form2FA"> <form action="{{apiUrl}}/auth/login/2fa" method="POST" #form2FA id="form2FA" (keyup.enter)="form2FA.submit()">
<mat-card> <mat-card>
<mat-card-content> <mat-card-content>
<h2>{{'security.2fa.external' | i18n}}<mat-icon style="font-size: 1em;">open_in_new <h2>{{'security.2fa.external' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
@@ -57,6 +57,9 @@ export class FormLogin2FAComponent implements OnInit {
this.webAuthn = false; this.webAuthn = false;
if (!!this.selectedProvider && this.selectedProvider.id.startsWith('webauthn')) { if (!!this.selectedProvider && this.selectedProvider.id.startsWith('webauthn')) {
this.webAuthn = true; this.webAuthn = true;
if (this.providers.length == 1 && this.providers[0] == this.selectedProvider) {
this.webAuthnRequest();
}
} }
} }
@@ -0,0 +1,11 @@
<mat-card class="warn">
<mat-card-header>
<mat-card-title>{{'home-redirect' | i18n}}</mat-card-title>
<mat-card-subtitle>{{'home-redirect.hint' | i18n}}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<p>
{{'home-redirect.text' | i18n}}
</p>
</mat-card-content>
</mat-card>
@@ -0,0 +1,19 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
@Component({
standalone: false,
selector: 'app-home-redirect',
templateUrl: './home-redirect.component.html'
})
export class StartPageComponent implements OnInit {
constructor(
private router: Router) { }
ngOnInit(): void {
const startPage = localStorage.getItem("bstly.startPage") || '/account/info';
this.router.navigateByUrl(startPage);
}
}
+1 -1
View File
@@ -23,8 +23,8 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions> <mat-dialog-actions>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
<a mat-raised-button color="primary" [disabled]="form.invalid || working" (click)="save()"> <a mat-raised-button color="primary" [disabled]="form.invalid || working" (click)="save()">
{{'invites.edit.save' | i18n}} {{'invites.edit.save' | i18n}}
</a> </a>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
+1 -1
View File
@@ -39,7 +39,7 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions> <mat-dialog-actions>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
<a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">{{ 'jitsi.rooms.save' | <a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">{{ 'jitsi.rooms.save' |
i18n}}</a> i18n}}</a>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
@@ -51,8 +51,8 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions> <mat-dialog-actions>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
<a [disabled]="form.invalid" mat-raised-button (click)="timeslot.id ? save(timeslot) : create(timeslot)" <a [disabled]="form.invalid" mat-raised-button (click)="timeslot.id ? save(timeslot) : create(timeslot)"
color="accent">{{ (timeslot.id ? 'partey.timeslots.save' : 'partey.timeslots.create') | color="accent">{{ (timeslot.id ? 'partey.timeslots.save' : 'partey.timeslots.create') |
i18n}}</a> i18n}}</a>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
@@ -78,8 +78,8 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions> <mat-dialog-actions>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
<a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">{{ <a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">{{
'urlshortener.save' 'urlshortener.save'
| i18n}}</a> | i18n}}</a>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
+2 -2
View File
@@ -80,8 +80,8 @@ export class I18nService {
return empty ? this.empty(key, args, path) : (key || ""); return empty ? this.empty(key, args, path) : (key || "");
} else if (from[key]) { } else if (from[key]) {
if (typeof from[key] === 'object') { if (typeof from[key] === 'object') {
if (from[key]["."]) { if (from[key][""]) {
return this.insertArguments(from[key]["."], args); return this.insertArguments(from[key][""], args);
} }
return empty ? this.empty(key, args, path) : (key || ""); return empty ? this.empty(key, args, path) : (key || "");
} }
+11 -1
View File
@@ -1,4 +1,4 @@
import { Component, Inject } from '@angular/core'; import { Component, HostListener, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { I18nService } from '../../services/i18n.service'; import { I18nService } from '../../services/i18n.service';
@@ -18,5 +18,15 @@ export class ConfirmDialog {
this.text = data.empty ? i18nService.getEmpty(data.label, data.args) : i18nService.get(data.label, data.args); this.text = data.empty ? i18nService.getEmpty(data.label, data.args) : i18nService.get(data.label, data.args);
} }
@HostListener('window:keyup.Enter', ['$event'])
confirmDialog(): void {
this.dialogRef.close(true);
}
@HostListener('window:keyup.Esc', ['$event'])
cancelDialog(): void {
this.dialogRef.close(false);
}
} }
+61 -57
View File
@@ -2,10 +2,10 @@
<a href="javascript:" mat-icon-button (click)="sidenav.toggle()"> <a href="javascript:" mat-icon-button (click)="sidenav.toggle()">
<mat-icon>menu</mat-icon> <mat-icon>menu</mat-icon>
</a> </a>
<mat-icon svgIcon="logo"></mat-icon> <a class="home" routerLink="/">
<span> <mat-icon svgIcon="logo"></mat-icon>
we.bstly we.bstly
</span> </a>
<span class="spacer"></span> <span class="spacer"></span>
<ng-container> <ng-container>
@@ -15,17 +15,17 @@
</a> </a>
<mat-menu #menu="matMenu"> <mat-menu #menu="matMenu">
@if (!auth || auth && !auth.authenticated) { @if (!auth || auth && !auth.authenticated) {
<a routerLink="/login" routerLinkActive="active" mat-menu-item> <a routerLink="/login" routerLinkActive="active" mat-menu-item>
<mat-icon>login</mat-icon> {{'login' | i18n}} <mat-icon>login</mat-icon> {{'login' | i18n}}
</a> </a>
} }
@if (!auth || auth && !auth.authenticated) { @if (!auth || auth && !auth.authenticated) {
<mat-divider></mat-divider> <mat-divider></mat-divider>
} }
@for (locale of locales; track locale) { @for (locale of locales; track locale) {
<a mat-menu-item (click)="setLocale(locale)">{{'locale.' + locale + '.long' | <a mat-menu-item (click)="setLocale(locale)">{{'locale.' + locale + '.long' |
i18n}} @if (locale == currentLocale) { i18n}} @if (locale == currentLocale) {
<mat-icon>done</mat-icon> <mat-icon>done</mat-icon>
}</a> }</a>
} }
<a mat-menu-item> <a mat-menu-item>
@@ -34,12 +34,15 @@
</mat-slide-toggle> </mat-slide-toggle>
</a> </a>
@if (auth && auth.authenticated) { @if (auth && auth.authenticated) {
<mat-divider></mat-divider> <a (click)="setStartPage()" mat-menu-item matTooltip="{{'profileField.name.startPage.hint' | i18n}}">
<mat-icon>pin_drop</mat-icon> {{'profileField.name.startPage.set' | i18n}}
</a>
<mat-divider></mat-divider>
} }
@if (auth && auth.authenticated) { @if (auth && auth.authenticated) {
<a (click)="logout()" mat-menu-item> <a (click)="logout()" mat-menu-item>
<mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}} <mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}}
</a> </a>
} }
</mat-menu> </mat-menu>
</ng-container> </ng-container>
@@ -50,62 +53,63 @@
(click)="!isBiggerScreen() && opened=false"> (click)="!isBiggerScreen() && opened=false">
<mat-nav-list> <mat-nav-list>
@if (!auth || auth && !auth.authenticated) { @if (!auth || auth && !auth.authenticated) {
<a routerLink="/login" routerLinkActive="active" mat-list-item> <a routerLink="/login" routerLinkActive="active" mat-list-item>
<mat-icon>login</mat-icon> {{'login' | i18n}} <mat-icon>login</mat-icon> {{'login' | i18n}}
</a> </a>
} }
@if (auth && auth.authenticated) { @if (auth && auth.authenticated) {
<a routerLink="/account/info" routerLinkActive="active" mat-list-item> <a routerLink="/account/info" routerLinkActive="active" mat-list-item>
<mat-icon>account_circle</mat-icon> {{'account' | i18n}} <mat-icon>account_circle</mat-icon> {{'account' | i18n}}
</a> </a>
} }
@if (auth && auth.authenticated) { @if (auth && auth.authenticated) {
<a routerLink="/services" routerLinkActive="active" mat-list-item> <a routerLink="/services" routerLinkActive="active" mat-list-item>
<mat-icon>widgets</mat-icon> {{'services' | i18n}} <mat-icon>widgets</mat-icon> {{'services' | i18n}}
</a> </a>
} }
@if (auth && auth.authenticated && hasAdminRole()) { @if (auth && auth.authenticated && hasAdminRole()) {
<a routerLink="/admin" routerLinkActive="active" mat-list-item> <a routerLink="/admin" routerLinkActive="active" mat-list-item>
<mat-icon>admin_panel_settings</mat-icon> {{'admin.title' | i18n}} <mat-icon>admin_panel_settings</mat-icon> {{'admin.title' | i18n}}
</a> </a>
} }
<a routerLink="/tokens" mat-list-item> <a routerLink="/tokens" mat-list-item>
<mat-icon>card_giftcard</mat-icon> {{'tokens.redeem' | i18n}} <mat-icon>card_giftcard</mat-icon> {{'tokens.redeem' | i18n}}
</a> </a>
<a (click)="openExternal('https://wiki.bstly.de/services/webstly','_blank')" mat-list-item> <a (click)="openExternal('https://wiki.bstly.de/services/webstly','_blank')" mat-list-item>
<mat-icon>help</mat-icon> {{'help' | i18n}}<mat-icon style="font-size: 1em;">open_in_new <mat-icon>help</mat-icon> {{'help' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
</mat-icon> </mat-icon>
</a> </a>
<a (click)="openExternal('https://membership.bstly.de','_blank')" mat-list-item> <a (click)="openExternal('https://membership.bstly.de','_blank')" mat-list-item>
<mat-icon>shopping_cart</mat-icon> {{'tokens.get' | i18n}}<mat-icon style="font-size: 1em;">open_in_new <mat-icon>shopping_cart</mat-icon> {{'tokens.get' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
</mat-icon> </mat-icon>
</a> </a>
@if (auth && auth.authenticated) { @if (auth && auth.authenticated) {
<a (click)="logout()" mat-list-item> <a (click)="logout()" mat-list-item>
<mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}} <mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}}
</a> </a>
} }
</mat-nav-list> </mat-nav-list>
<span class="spacer"></span> <span class="spacer"></span>
<mat-nav-list> <mat-nav-list>
<a (click)="openExternal('https://www.bstly.de/imprint/')" mat-list-item style="font-size: 0.7em;"> <a (click)="openExternal('https://www.bstly.de/imprint/')" mat-list-item style="font-size: 0.7em;">
{{'imprint' | i18n}} {{'imprint' | i18n}}
</a> </a>
<a (click)="openExternal('https://www.bstly.de/privacy-policy/#we.bstly')" mat-list-item style="font-size: 0.7em;"> <a (click)="openExternal('https://www.bstly.de/privacy-policy/#we.bstly')" mat-list-item
{{'privacy-policy' | i18n}} style="font-size: 0.7em;">
</a> {{'privacy-policy' | i18n}}
<a (click)="openExternal('https://www.bstly.de')" mat-list-item style="font-size: 0.7em;"> </a>
Bastelei e. V. <a (click)="openExternal('https://www.bstly.de')" mat-list-item style="font-size: 0.7em;">
</a> Bastelei e. V.
</mat-nav-list> </a>
</mat-sidenav> </mat-nav-list>
</mat-sidenav>
<!-- Main content --> <!-- Main content -->
<mat-sidenav-content> <mat-sidenav-content>
<div class="container"> <div class="container">
<router-outlet></router-outlet> <router-outlet></router-outlet>
</div> </div>
</mat-sidenav-content> </mat-sidenav-content>
</mat-sidenav-container> </mat-sidenav-container>
+5
View File
@@ -0,0 +1,5 @@
a.home {
display: flex;
align-items: center;
color: var(--mat-toolbar-container-text-color, var(--mat-sys-on-surface));
}
+26
View File
@@ -139,6 +139,32 @@ export class MainComponent {
} }
setStartPage() {
if (this.auth && this.auth.authenticated) {
this.profileService.getField("startPage").subscribe({
next: (profileField: any) => {
if (profileField == null) {
profileField = {
"name": "startPage",
"type": "TEXT",
"visibility": "PRIVATE"
}
}
profileField.value = this.router.url;
this.profileService.createOrUpdate(profileField).subscribe({
next: (response: any) => {
try {
localStorage.setItem("bstly.startPage", response.value);
} catch { }
}
})
}
})
}
}
logout() { logout() {
this.authService.logout().subscribe({ this.authService.logout().subscribe({
next: (data) => { next: (data) => {
@@ -23,6 +23,6 @@
<mat-slide-toggle [(ngModel)]="data.confirmClose" [disabled]="!downloaded"> <mat-slide-toggle [(ngModel)]="data.confirmClose" [disabled]="!downloaded">
{{'pgp.privateKey.confirmStore' | i18n}} {{'pgp.privateKey.confirmStore' | i18n}}
</mat-slide-toggle> </mat-slide-toggle>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
<a mat-button color="accent" [disabled]="!data.confirmClose" [mat-dialog-close]="data.publicKey">{{'ok' | i18n}}</a> <a mat-button color="accent" [disabled]="!data.confirmClose" [mat-dialog-close]="data.publicKey">{{'ok' | i18n}}</a>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
@@ -134,7 +134,7 @@
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions> <mat-dialog-actions>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
<a [disabled]="form.invalid" mat-raised-button (click)="save(profileField)" color="accent">{{'save' | <a [disabled]="form.invalid" mat-raised-button (click)="save(profileField)" color="accent">{{'save' |
i18n}}</a> i18n}}</a>
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
</mat-dialog-actions> </mat-dialog-actions>
+152 -147
View File
@@ -1,14 +1,13 @@
{ {
"account": { "account": {
".": "Account", "": "Account",
"advanced": { "advanced": {
".": "Erweitert" "": "Erweitert"
} }
}, },
"admin": { "admin": {
".": "Administration", "": "Administration",
"actions": "Aktionen", "actions": "Aktionen",
"cancel": "Abbrechen",
"edit": "Bearbeiten", "edit": "Bearbeiten",
"delete": "Löschen", "delete": "Löschen",
"filter": "Filtern", "filter": "Filtern",
@@ -16,7 +15,7 @@
"no_results": "Keine Ergebnisse gefunden", "no_results": "Keine Ergebnisse gefunden",
"showing_entries": "{0} von {1} Einträgen angezeigt", "showing_entries": "{0} von {1} Einträgen angezeigt",
"jitsi_rooms": { "jitsi_rooms": {
".": "Jitsi-Räume", "": "Jitsi-Räume",
"confirm_delete": "Bist du sicher, dass du den Raum '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du den Raum '{0}' löschen möchtest?",
"create": "Jitsi-Raum erstellen", "create": "Jitsi-Raum erstellen",
"delete": "Jitsi-Raum löschen", "delete": "Jitsi-Raum löschen",
@@ -36,7 +35,7 @@
"title": "Jitsi-Räume" "title": "Jitsi-Räume"
}, },
"jukebox": { "jukebox": {
".": "Jukebox", "": "Jukebox",
"activate": "Jukebox aktivieren", "activate": "Jukebox aktivieren",
"autoplay": "Automatische Wiedergabe", "autoplay": "Automatische Wiedergabe",
"channel": "Kanal", "channel": "Kanal",
@@ -53,7 +52,7 @@
"status": "Status" "status": "Status"
}, },
"i18n": { "i18n": {
".": "Internationalisierung", "": "Internationalisierung",
"title": "Internationalisierungsverwaltung", "title": "Internationalisierungsverwaltung",
"locale": "Sprache", "locale": "Sprache",
"key": "Schlüssel", "key": "Schlüssel",
@@ -74,7 +73,7 @@
"raw_json_placeholder": "JSON-Daten hier eingeben..." "raw_json_placeholder": "JSON-Daten hier eingeben..."
}, },
"minetest_accounts": { "minetest_accounts": {
".": "Minetest-Accounts", "": "Minetest-Accounts",
"confirm_delete": "Bist du sicher, dass du den Minetest-Account '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du den Minetest-Account '{0}' löschen möchtest?",
"create": "Minetest-Account erstellen", "create": "Minetest-Account erstellen",
"created": "Erstellt", "created": "Erstellt",
@@ -85,7 +84,7 @@
"owner": "Besitzer" "owner": "Besitzer"
}, },
"oidc_clients": { "oidc_clients": {
".": "OIDC-Clients", "": "OIDC-Clients",
"advanced_settings": "Erweiterte Einstellungen", "advanced_settings": "Erweiterte Einstellungen",
"alias_allowed": "Alias erlaubt", "alias_allowed": "Alias erlaubt",
"alias_quota": "Alias-Kontingent", "alias_quota": "Alias-Kontingent",
@@ -130,7 +129,7 @@
"token_lifetime_hint": "Token-Lebensdauer in Sekunden" "token_lifetime_hint": "Token-Lebensdauer in Sekunden"
}, },
"partey_maps": { "partey_maps": {
".": "Partey-Karten", "": "Partey-Karten",
"confirm_delete": "Bist du sicher, dass du die Partey-Karte '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du die Partey-Karte '{0}' löschen möchtest?",
"create": "Partey-Karte erstellen", "create": "Partey-Karte erstellen",
"delete": "Partey-Karte löschen", "delete": "Partey-Karte löschen",
@@ -142,7 +141,7 @@
"tags": "Tags" "tags": "Tags"
}, },
"partey_reports": { "partey_reports": {
".": "Partey-Meldungen", "": "Partey-Meldungen",
"confirm_delete": "Bist du sicher, dass du diese Meldung löschen möchtest?", "confirm_delete": "Bist du sicher, dass du diese Meldung löschen möchtest?",
"confirm_delete_all": "Bist du sicher, dass du alle Meldungen löschen möchtest?", "confirm_delete_all": "Bist du sicher, dass du alle Meldungen löschen möchtest?",
"created": "Erstellt", "created": "Erstellt",
@@ -156,7 +155,7 @@
"world": "Welt" "world": "Welt"
}, },
"partey_tags": { "partey_tags": {
".": "Partey-Tags", "": "Partey-Tags",
"confirm_delete": "Bist du sicher, dass du den Partey-Tag '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du den Partey-Tag '{0}' löschen möchtest?",
"create": "Partey-Tag erstellen", "create": "Partey-Tag erstellen",
"delete": "Partey-Tag löschen", "delete": "Partey-Tag löschen",
@@ -169,7 +168,7 @@
"target": "Ziel" "target": "Ziel"
}, },
"permission_mappings": { "permission_mappings": {
".": "Berechtigungs-Zuordnungen", "": "Berechtigungs-Zuordnungen",
"addon": "Addon", "addon": "Addon",
"confirm_delete": "Bist du sicher, dass du die Berechtigungs-Zuordnung '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du die Berechtigungs-Zuordnung '{0}' löschen möchtest?",
"create": "Berechtigungs-Zuordnung erstellen", "create": "Berechtigungs-Zuordnung erstellen",
@@ -195,7 +194,7 @@
"title": "Berechtigungs-Zuordnungen" "title": "Berechtigungs-Zuordnungen"
}, },
"permissions": { "permissions": {
".": "Berechtigungen", "": "Berechtigungen",
"addon": "Addon", "addon": "Addon",
"confirm_delete": "Bist du sicher, dass du die Berechtigung '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du die Berechtigung '{0}' löschen möchtest?",
"create": "Berechtigung erstellen", "create": "Berechtigung erstellen",
@@ -217,7 +216,7 @@
"starts": "Beginnt" "starts": "Beginnt"
}, },
"quota_mappings": { "quota_mappings": {
".": "Kontingent-Zuordnungen", "": "Kontingent-Zuordnungen",
"append": "Anhängen", "append": "Anhängen",
"confirm_delete": "Bist du sicher, dass du die Kontingent-Zuordnung '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du die Kontingent-Zuordnung '{0}' löschen möchtest?",
"create": "Kontingent-Zuordnung erstellen", "create": "Kontingent-Zuordnung erstellen",
@@ -242,7 +241,7 @@
"value_required": "Wert ist erforderlich" "value_required": "Wert ist erforderlich"
}, },
"quotas": { "quotas": {
".": "Kontingente", "": "Kontingente",
"confirm_delete": "Bist du sicher, dass du das Kontingent '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du das Kontingent '{0}' löschen möchtest?",
"create": "Kontingent erstellen", "create": "Kontingent erstellen",
"create_quota": "Kontingent erstellen", "create_quota": "Kontingent erstellen",
@@ -266,7 +265,7 @@
"create": "Erstellen", "create": "Erstellen",
"save": "Speichern", "save": "Speichern",
"services": { "services": {
".": "Dienste", "": "Dienste",
"always_permitted": "Immer erlaubt", "always_permitted": "Immer erlaubt",
"category": "Kategorie", "category": "Kategorie",
"confirm_delete": "Bist du sicher, dass du den Dienst '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du den Dienst '{0}' löschen möchtest?",
@@ -284,7 +283,7 @@
"url_required": "URL ist erforderlich" "url_required": "URL ist erforderlich"
}, },
"shortened_urls": { "shortened_urls": {
".": "Kurz-URLs", "": "Kurz-URLs",
"code": "Code", "code": "Code",
"confirm_delete": "Bist du sicher, dass du die Kurz-URL '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du die Kurz-URL '{0}' löschen möchtest?",
"create": "Kurz-URL erstellen", "create": "Kurz-URL erstellen",
@@ -298,7 +297,7 @@
"url": "URL" "url": "URL"
}, },
"system_profile_fields": { "system_profile_fields": {
".": "System-Profilfelder", "": "System-Profilfelder",
"confirm_delete": "Bist du sicher, dass du das Profilfeld '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du das Profilfeld '{0}' löschen möchtest?",
"create": "Profilfeld erstellen", "create": "Profilfeld erstellen",
"delete": "Profilfeld löschen", "delete": "Profilfeld löschen",
@@ -316,7 +315,7 @@
"uniqueValue": "Eindeutiger Wert" "uniqueValue": "Eindeutiger Wert"
}, },
"system_properties": { "system_properties": {
".": "System-Eigenschaften", "": "System-Eigenschaften",
"confirm_delete": "Bist du sicher, dass du die Eigenschaft '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du die Eigenschaft '{0}' löschen möchtest?",
"create": "Eigenschaft erstellen", "create": "Eigenschaft erstellen",
"delete": "Eigenschaft löschen", "delete": "Eigenschaft löschen",
@@ -331,7 +330,7 @@
"value_required": "Wert ist erforderlich" "value_required": "Wert ist erforderlich"
}, },
"timeslots": { "timeslots": {
".": "Zeitfenster", "": "Zeitfenster",
"all": "Alle", "all": "Alle",
"apply_filter": "Filter anwenden", "apply_filter": "Filter anwenden",
"confirm_delete": "Bist du sicher, dass du das Zeitfenster '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du das Zeitfenster '{0}' löschen möchtest?",
@@ -353,7 +352,7 @@
}, },
"title": "Admin", "title": "Admin",
"user_aliases": { "user_aliases": {
".": "Benutzer-Aliase", "": "Benutzer-Aliase",
"alias": "Alias", "alias": "Alias",
"alias_required": "Alias ist erforderlich", "alias_required": "Alias ist erforderlich",
"confirm_delete": "Bist du sicher, dass du den Alias '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du den Alias '{0}' löschen möchtest?",
@@ -371,7 +370,7 @@
"visibility_required": "Sichtbarkeit ist erforderlich" "visibility_required": "Sichtbarkeit ist erforderlich"
}, },
"users": { "users": {
".": "Benutzer", "": "Benutzer",
"confirm_delete": "Bist du sicher, dass du den Benutzer '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du den Benutzer '{0}' löschen möchtest?",
"create": "Benutzer erstellen", "create": "Benutzer erstellen",
"created": "Erstellt", "created": "Erstellt",
@@ -391,7 +390,7 @@
"password": "Passwort", "password": "Passwort",
"password2": "Passwort bestätigen", "password2": "Passwort bestätigen",
"status": { "status": {
".": "Status", "": "Status",
"NORMAL": "Normal", "NORMAL": "Normal",
"PURGE": "Bereinigen", "PURGE": "Bereinigen",
"SLEEP": "Ruhezustand" "SLEEP": "Ruhezustand"
@@ -402,7 +401,7 @@
"view_quotas": "Kontingente anzeigen" "view_quotas": "Kontingente anzeigen"
}, },
"voucher_mappings": { "voucher_mappings": {
".": "Gutschein-Zuordnungen", "": "Gutschein-Zuordnungen",
"confirm_delete": "Bist du sicher, dass du die Gutschein-Zuordnung '{0}' löschen möchtest?", "confirm_delete": "Bist du sicher, dass du die Gutschein-Zuordnung '{0}' löschen möchtest?",
"create": "Gutschein-Zuordnung erstellen", "create": "Gutschein-Zuordnung erstellen",
"delete": "Gutschein-Zuordnung löschen", "delete": "Gutschein-Zuordnung löschen",
@@ -420,13 +419,13 @@
} }
}, },
"borrow": { "borrow": {
".": "Ausleihen", "": "Ausleihen",
"items": { "items": {
".": "Verleihbare Items", "": "Verleihbare Items",
"actions": "Aktionen", "actions": "Aktionen",
"autoAccept": "Automatisch akzeptieren", "autoAccept": "Automatisch akzeptieren",
"availability": { "availability": {
".": "Verfügbarkeit", "": "Verfügbarkeit",
"ALWAYS": "Immer", "ALWAYS": "Immer",
"MANUAL": "Manuel", "MANUAL": "Manuel",
"PERIOD": "Periodisch" "PERIOD": "Periodisch"
@@ -462,12 +461,12 @@
"save": "Item speichern", "save": "Item speichern",
"search": "Suche", "search": "Suche",
"slot": { "slot": {
".": "Slot", "": "Slot",
"add": "Slot hinzufügen", "add": "Slot hinzufügen",
"addManual": "Manuellen Slot hinzufügen", "addManual": "Manuellen Slot hinzufügen",
"addPeriod": "Periodischen Slot hinzufügen", "addPeriod": "Periodischen Slot hinzufügen",
"day": { "day": {
".": "Tag", "": "Tag",
"FRIDAY": "Freitag", "FRIDAY": "Freitag",
"MONDAY": "Montag", "MONDAY": "Montag",
"SATURDAY": "Samstag", "SATURDAY": "Samstag",
@@ -493,7 +492,7 @@
"name": "Item-Name" "name": "Item-Name"
}, },
"proving": { "proving": {
".": "Proving", "": "Proving",
"camera": "Camera", "camera": "Camera",
"flash": "Flash" "flash": "Flash"
}, },
@@ -513,7 +512,7 @@
"user": "Benutzer" "user": "Benutzer"
}, },
"requests": { "requests": {
".": "Anfragen", "": "Anfragen",
"actions": "Aktionen", "actions": "Aktionen",
"ends": "Endet", "ends": "Endet",
"mine": "Meine", "mine": "Meine",
@@ -531,10 +530,10 @@
"minutes": "Minuten" "minutes": "Minuten"
}, },
"email": { "email": {
".": "E-Mail Adresse", "": "E-Mail Adresse",
"invalid": "ungültige E-Mail Adresse", "invalid": "ungültige E-Mail Adresse",
"primary": { "primary": {
".": "primäre E-Mail Adresse", "": "primäre E-Mail Adresse",
"hint": "Eine primäre E-Mail Adresse dient dazu eine andere Kontaktmöglichkeit als deine we.bstly Adresse anzugeben." "hint": "Eine primäre E-Mail Adresse dient dazu eine andere Kontaktmöglichkeit als deine we.bstly Adresse anzugeben."
} }
}, },
@@ -548,10 +547,10 @@
"help-button": "Finde Hilfe im Wiki", "help-button": "Finde Hilfe im Wiki",
"imprint": "Impressum", "imprint": "Impressum",
"info": { "info": {
".": "Info" "": "Info"
}, },
"invite": { "invite": {
".": "Einleidung", "": "Einleidung",
"actions": "Aktionen", "actions": "Aktionen",
"create": "Einladung erstellen", "create": "Einladung erstellen",
"expires": "Gültig bis", "expires": "Gültig bis",
@@ -564,9 +563,9 @@
"starts": "Gültig ab" "starts": "Gültig ab"
}, },
"invites": { "invites": {
".": "Einladungen", "": "Einladungen",
"edit": { "edit": {
".": "Edit Invite", "": "Edit Invite",
"save": "Save Invite" "save": "Save Invite"
}, },
"error": { "error": {
@@ -578,21 +577,21 @@
"others": "Einladungen anderer Mitglieder", "others": "Einladungen anderer Mitglieder",
"quota": { "quota": {
"pubquiz": { "pubquiz": {
".": "Pubquiz", "": "Pubquiz",
"icon": "quiz", "icon": "quiz",
"text": "Einladung zum Pubquiz." "text": "Einladung zum Pubquiz."
} }
}, },
"redeemed": { "redeemed": {
"filter": { "filter": {
".": "Einglöst-Filter", "": "Einglöst-Filter",
"false": "Nicht eingelöst", "false": "Nicht eingelöst",
"none": "Kein Filter", "none": "Kein Filter",
"true": "Eingelöst" "true": "Eingelöst"
} }
}, },
"register": { "register": {
".": "Einladung einlösen", "": "Einladung einlösen",
"error": { "error": {
"ALREADY_REDEEMED": "Der Einladungscode wurde bereits eingelöst.", "ALREADY_REDEEMED": "Der Einladungscode wurde bereits eingelöst.",
"EXPIRED": "Der Einladungscode ist abgelaufen!", "EXPIRED": "Der Einladungscode ist abgelaufen!",
@@ -601,7 +600,7 @@
}, },
"login": "Login", "login": "Login",
"success": { "success": {
".": "Finished registration", "": "Finished registration",
"text": "Successfully registered your Account. You can login now!" "text": "Successfully registered your Account. You can login now!"
}, },
"time": "Invite valid from {0} till {1}", "time": "Invite valid from {0} till {1}",
@@ -611,7 +610,7 @@
}, },
"jitsi": { "jitsi": {
"rooms": { "rooms": {
".": "Jitsi Räume", "": "Jitsi Räume",
"clipboard": { "clipboard": {
"copied": "Jitsi Room Url in die Zwischenablage kopiert!" "copied": "Jitsi Room Url in die Zwischenablage kopiert!"
}, },
@@ -637,14 +636,14 @@
"starts": "Beginn" "starts": "Beginn"
}, },
"share": { "share": {
".": "Teilen", "": "Teilen",
"clipboard": { "clipboard": {
"copied": "In die Zwischenablage kopiert", "copied": "In die Zwischenablage kopiert",
"text": "Text in Zwischenablage kopieren", "text": "Text in Zwischenablage kopieren",
"url": "Url in Zwischenablage kopieren" "url": "Url in Zwischenablage kopieren"
}, },
"email": { "email": {
".": "Via E-Mail teilen", "": "Via E-Mail teilen",
"subject": "Einladung in Videokonferenz {0}" "subject": "Einladung in Videokonferenz {0}"
}, },
"text": { "text": {
@@ -657,27 +656,27 @@
} }
}, },
"jukebox": { "jukebox": {
".": "Jukebox", "": "Jukebox",
"addToQueue": { "addToQueue": {
".": "Zur Warteliste hinzufügen", "": "Zur Warteliste hinzufügen",
"confirm": "Möchtest du '{0} - {1}' zur Warteliste hinzufügen?", "confirm": "Möchtest du '{0} - {1}' zur Warteliste hinzufügen?",
"error": "Fehler", "error": "Fehler",
"success": "Erfolg" "success": "Erfolg"
}, },
"current": "Aktueller Titel", "current": "Aktueller Titel",
"forbidden": { "forbidden": {
".": "Keine Berechtigungen", "": "Keine Berechtigungen",
"hint": "Dir fehlen dir nötigen Berechtigungen die Jukebox zu verwenden." "hint": "Dir fehlen dir nötigen Berechtigungen die Jukebox zu verwenden."
}, },
"search": { "search": {
".": "Suche", "": "Suche",
"icon": "search", "icon": "search",
"more": "Mehr anzeigen", "more": "Mehr anzeigen",
"submit": "Abschicken" "submit": "Abschicken"
}, },
"timeout": "Bitte warte {0} Sekunden bis zu deiner nächsten Anfrage.", "timeout": "Bitte warte {0} Sekunden bis zu deiner nächsten Anfrage.",
"unavailable": { "unavailable": {
".": "Nicht verfügbar", "": "Nicht verfügbar",
"hint": "Aktuell ist die Jukebox ausgestellt." "hint": "Aktuell ist die Jukebox ausgestellt."
}, },
"wait": "Bitte warten." "wait": "Bitte warten."
@@ -693,7 +692,7 @@
} }
}, },
"login": { "login": {
".": "Login", "": "Login",
"external": "Login", "external": "Login",
"invalid": "Falscher Username oder Passwort.", "invalid": "Falscher Username oder Passwort.",
"keepSession": "Eingeloggt bleiben", "keepSession": "Eingeloggt bleiben",
@@ -702,7 +701,7 @@
"logout": "Logout", "logout": "Logout",
"minetest": { "minetest": {
"accounts": { "accounts": {
".": "Minetest Accounts", "": "Minetest Accounts",
"confirmDelete": "Möchtest du wirklich deinen Minetest Account '{0}' löschen? Nach der Löschung kann der Account nicht wiederhergestellt werden und andere können deinen Usernamen wieder registrieren!", "confirmDelete": "Möchtest du wirklich deinen Minetest Account '{0}' löschen? Nach der Löschung kann der Account nicht wiederhergestellt werden und andere können deinen Usernamen wieder registrieren!",
"create": "Minetest Account erstellen", "create": "Minetest Account erstellen",
"delete": "Löschen", "delete": "Löschen",
@@ -717,7 +716,7 @@
} }
}, },
"not-found": { "not-found": {
".": "Nicht gefunden", "": "Nicht gefunden",
"text": "Diese Seite wurde nicht gefunden." "text": "Diese Seite wurde nicht gefunden."
}, },
"ok": "Ok", "ok": "Ok",
@@ -731,41 +730,41 @@
"range": "Seite {0} von {1}" "range": "Seite {0} von {1}"
}, },
"partey": { "partey": {
".": "Partey", "": "Partey",
"tag": { "tag": {
".": "Partey Tag", "": "Partey Tag",
"access-storage": { "access-storage": {
".": "Zugang Lagerraum", "": "Zugang Lagerraum",
"hint": "Zugang zum Lagerraum im Erdgeschoss." "hint": "Zugang zum Lagerraum im Erdgeschoss."
}, },
"admin": { "admin": {
".": "Administrator", "": "Administrator",
"hint": "Sende Nachrichten an Räume." "hint": "Sende Nachrichten an Räume."
}, },
"cinema-mod": { "cinema-mod": {
".": "Moderator Kinosaal", "": "Moderator Kinosaal",
"hint": "Im Kinosaal: Zugang zur Bühne, Festlegen der Stream-Url, Moderationsrechte im Chatraum." "hint": "Im Kinosaal: Zugang zur Bühne, Festlegen der Stream-Url, Moderationsrechte im Chatraum."
}, },
"disco-mod": { "disco-mod": {
".": "Moderator Disco", "": "Moderator Disco",
"hint": "In der Disco: Zugang zur Bühne, Festlegen des Bühnenlayouts, Moderationsrechte im Chatraum." "hint": "In der Disco: Zugang zur Bühne, Festlegen des Bühnenlayouts, Moderationsrechte im Chatraum."
}, },
"game-mod": { "game-mod": {
".": "Spielezimmer Moderator", "": "Spielezimmer Moderator",
"hint": "Im Spielezimmer: Festlegen der Tischbezeichungen, Moderationsrechte im Chatraum." "hint": "Im Spielezimmer: Festlegen der Tischbezeichungen, Moderationsrechte im Chatraum."
} }
}, },
"tags": { "tags": {
".": "Partey Tags", "": "Partey Tags",
"expires": "Läuft ab", "expires": "Läuft ab",
"none": "Keine", "none": "Keine",
"upcoming": "Bevorstehend" "upcoming": "Bevorstehend"
}, },
"timeslots": { "timeslots": {
".": "Partey Sendeplätze", "": "Partey Sendeplätze",
"confirmDelete": "Möchtest du wirklich deinen Sendeplatz '{0}' um {1} löschen?", "confirmDelete": "Möchtest du wirklich deinen Sendeplatz '{0}' um {1} löschen?",
"create": { "create": {
".": "Neuen Sendplatz erstellen", "": "Neuen Sendplatz erstellen",
"AUDIO": "Neuer Audio Sendplatz", "AUDIO": "Neuer Audio Sendplatz",
"AUDIO_STREAM": "Neuer Audio Stream Sendplatz", "AUDIO_STREAM": "Neuer Audio Stream Sendplatz",
"VIDEO": "Neuer Video Sendplatz", "VIDEO": "Neuer Video Sendplatz",
@@ -780,17 +779,17 @@
"starts": "Ungültiger Beginn. Bitte prüfe kollidierende Sendeplätze oder Dauer." "starts": "Ungültiger Beginn. Bitte prüfe kollidierende Sendeplätze oder Dauer."
}, },
"filter": { "filter": {
".": "Filter", "": "Filter",
"after": "Nach dem", "after": "Nach dem",
"owner": { "owner": {
".": "User", "": "User",
"all": "Alle", "all": "Alle",
"mine": "Meine Senderplätze", "mine": "Meine Senderplätze",
"others": "Sendplätze von anderen" "others": "Sendplätze von anderen"
}, },
"search": "Suche", "search": "Suche",
"type": { "type": {
".": "Typ", "": "Typ",
"all": "Alle", "all": "Alle",
"AUDIO": "Audio", "AUDIO": "Audio",
"AUDIO_STREAM": "Audio Stream", "AUDIO_STREAM": "Audio Stream",
@@ -803,44 +802,44 @@
"noQuota": "Deine Quota für Sendeplätze ist leider aufgebraucht.", "noQuota": "Deine Quota für Sendeplätze ist leider aufgebraucht.",
"save": "Sendeplatz speichern", "save": "Sendeplatz speichern",
"secret": { "secret": {
".": "Audio Stream Secret", "": "Audio Stream Secret",
"copied": "In die Zwischenablage kopiert", "copied": "In die Zwischenablage kopiert",
"copy": "Audio Stream Secret kopieren" "copy": "Audio Stream Secret kopieren"
}, },
"share": { "share": {
".": "Freigabe", "": "Freigabe",
"placeholder": "Dateiname der Freigabe" "placeholder": "Dateiname der Freigabe"
}, },
"starts": "Beginn", "starts": "Beginn",
"stream": { "stream": {
".": "Stream", "": "Stream",
"AUDIO": "Icecast2 Stream Key", "AUDIO": "Icecast2 Stream Key",
"VIDEO": "PeerTube Video Id" "VIDEO": "PeerTube Video Id"
}, },
"title": "Titel", "title": "Titel",
"type": { "type": {
".": "Typ", "": "Typ",
"AUDIO": { "AUDIO": {
".": "Audio", "": "Audio",
"icon": "library_music" "icon": "library_music"
}, },
"AUDIO_STREAM": { "AUDIO_STREAM": {
".": "Audio Stream", "": "Audio Stream",
"icon": "music_note" "icon": "music_note"
}, },
"VIDEO": { "VIDEO": {
".": "Video", "": "Video",
"icon": "movie" "icon": "movie"
}, },
"VIDEO_STREAM": { "VIDEO_STREAM": {
".": "Video Stream", "": "Video Stream",
"icon": "live_tv" "icon": "live_tv"
} }
} }
} }
}, },
"password": { "password": {
".": "Passwort", "": "Passwort",
"change": "Passwort ändern", "change": "Passwort ändern",
"changed": "Passwort erfolgreich geändert", "changed": "Passwort erfolgreich geändert",
"confirm": "Passwort bestätigen", "confirm": "Passwort bestätigen",
@@ -861,7 +860,7 @@
"not-match": "Passwörter stimmen nicht überein.", "not-match": "Passwörter stimmen nicht überein.",
"request": "Neues Passwort anfordern", "request": "Neues Passwort anfordern",
"reset": { "reset": {
".": "Passwort setzen", "": "Passwort setzen",
"login": "Zum Login", "login": "Zum Login",
"success": { "success": {
"text": "Dein neues Passwort wurde übernommen. Du kannst dich nun mit deinem neuen Passwort einloggen.", "text": "Dein neues Passwort wurde übernommen. Du kannst dich nun mit deinem neuen Passwort einloggen.",
@@ -870,15 +869,15 @@
} }
}, },
"permissions": { "permissions": {
".": "Berechtigungen", "": "Berechtigungen",
"expires": "Gültig bis", "expires": "Gültig bis",
"name": "Name", "name": "Name",
"starts": "Gültig ab" "starts": "Gültig ab"
}, },
"pgp": { "pgp": {
".": "PGP", "": "PGP",
"privateKey": { "privateKey": {
".": "Privater PGP Schlüssel", "": "Privater PGP Schlüssel",
"confirmStore": "Ich habe meinen privaten Schlüssel sicher gespeichert!", "confirmStore": "Ich habe meinen privaten Schlüssel sicher gespeichert!",
"copied": "Privaten Schlüssel in die Zwischenablage kopiert", "copied": "Privaten Schlüssel in die Zwischenablage kopiert",
"copyKey": "In die Zwischenablage kopieren", "copyKey": "In die Zwischenablage kopieren",
@@ -890,7 +889,7 @@
"privacy-policy": "Datenschutzerklärung", "privacy-policy": "Datenschutzerklärung",
"profile": "Profil", "profile": "Profil",
"profileField": { "profileField": {
".": "Profilfeld", "": "Profilfeld",
"blob": { "blob": {
"pgp": "Neues PGP Schlüsselpar erstellen" "pgp": "Neues PGP Schlüsselpar erstellen"
}, },
@@ -900,98 +899,103 @@
"edit": "Bearbeiten", "edit": "Bearbeiten",
"error": { "error": {
"BLOB": { "BLOB": {
".": "Kein gültiger Binärblob" "": "Kein gültiger Binärblob"
}, },
"BOOL": { "BOOL": {
".": "Kein gültiger Boolean" "": "Kein gültiger Boolean"
}, },
"DATE": { "DATE": {
".": "Kein gültiges Datum" "": "Kein gültiges Datum"
}, },
"DATETIME": { "DATETIME": {
".": "Kein gültiges Datum oder Uhrzeit" "": "Kein gültiges Datum oder Uhrzeit"
}, },
"EMAIL": { "EMAIL": {
".": "Keine gültige E-Mail Adresse" "": "Keine gültige E-Mail Adresse"
}, },
"name": "Name zu kurz oder ungültig", "name": "Name zu kurz oder ungültig",
"NUMBER": { "NUMBER": {
".": "Keine gültige Nummer" "": "Keine gültige Nummer"
}, },
"TEXT": { "TEXT": {
".": "Textfeld zu lang" "": "Textfeld zu lang"
}, },
"TIME": { "TIME": {
".": "Keine gültige Uhrzeit" "": "Keine gültige Uhrzeit"
}, },
"type": "Ungültiger Typ für dieses Profilfeld", "type": "Ungültiger Typ für dieses Profilfeld",
"URL": { "URL": {
".": "Keine gültige URL" "": "Keine gültige URL"
}, },
"visibility": "Keine gültige Sichtbarkeit für Profilfeld" "visibility": "Keine gültige Sichtbarkeit für Profilfeld"
}, },
"index": "Index", "index": "Index",
"name": { "name": {
".": "Key", "": "Key",
"darkTheme": "Dunkles Thema", "darkTheme": "Dunkles Thema",
"email": "E-Mail Adresse", "email": "E-Mail Adresse",
"locale": "Sprache", "locale": "Sprache",
"primaryEmail": "E-Mail Adresse primär verwenden", "primaryEmail": "E-Mail Adresse primär verwenden",
"prtyMap": "Partey Karte", "prtyMap": "Partey Karte",
"publicKey": "Öffentlicher PGP Schlüssel" "publicKey": "Öffentlicher PGP Schlüssel",
"startPage": {
"": "Startseite",
"hint": "Aktuelle Seite als Startseite setzen",
"set": "Startseite setzen"
}
}, },
"openBlob": "Anzeigen", "openBlob": "Anzeigen",
"type": { "type": {
".": "Typ", "": "Typ",
"BLOB": { "BLOB": {
".": "Binärblob" "": "Binärblob"
}, },
"BOOL": { "BOOL": {
".": "Boolean" "": "Boolean"
}, },
"DATE": { "DATE": {
".": "Datum" "": "Datum"
}, },
"DATETIME": { "DATETIME": {
".": "Datum mit Uhrzeit" "": "Datum mit Uhrzeit"
}, },
"EMAIL": { "EMAIL": {
".": "E-Mail" "": "E-Mail"
}, },
"NUMBER": { "NUMBER": {
".": "Numerisch" "": "Numerisch"
}, },
"TEXT": { "TEXT": {
".": "Textfeld" "": "Textfeld"
}, },
"TIME": { "TIME": {
".": "Uhrzeit" "": "Uhrzeit"
}, },
"URL": { "URL": {
".": "URL" "": "URL"
} }
}, },
"value": "Wert" "value": "Wert"
}, },
"quotas": { "quotas": {
".": "Quotas", "": "Quotas",
"fixed_value": { "fixed_value": {
".": "Insgesamt", "": "Insgesamt",
"hint": "Den Verbrauch kannst du im jeweiligen Dienst nachschauen." "hint": "Den Verbrauch kannst du im jeweiligen Dienst nachschauen."
}, },
"name": "Name", "name": "Name",
"unit": { "unit": {
"#": "# (Anzahl)", "#": "# (Anzahl)",
".": "Einheit", "": "Einheit",
"G": "GB (Gigabyte)" "G": "GB (Gigabyte)"
}, },
"value": { "value": {
".": "Noch verfügbar", "": "Noch verfügbar",
"hint": "" "hint": ""
} }
}, },
"register": { "register": {
".": "Registrierung", "": "Registrierung",
"login": "Zum Login", "login": "Zum Login",
"success": { "success": {
"text": "Deine Registrierung war erfolgreich. Du kannst dich nun einloggen!", "text": "Deine Registrierung war erfolgreich. Du kannst dich nun einloggen!",
@@ -999,20 +1003,20 @@
}, },
"token": { "token": {
"locked": { "locked": {
".": "Benötigst einen Account um dieses Token einzulösen!", "": "Benötigst einen Account um dieses Token einzulösen!",
"action": "Bitte logge dich ein." "action": "Bitte logge dich ein."
}, },
"missing": { "missing": {
".": "Du benötigst leider ein gültiges Token!", "": "Du benötigst leider ein gültiges Token!",
"action": "Token einlösen" "action": "Token einlösen"
} }
} }
}, },
"save": "Speichern", "save": "Speichern",
"security": { "security": {
".": "Sicherheit", "": "Sicherheit",
"2fa": { "2fa": {
".": "Zwei-Faktor-Authentifizierung (2FA)", "": "Zwei-Faktor-Authentifizierung (2FA)",
"code": "Code", "code": "Code",
"external": "2FA erforderlich", "external": "2FA erforderlich",
"info": "Du kannst hier einen zweiten Faktor zusätzlich zu deinem Passwort hinzufügen. Beachte, dass dies nur den Login in deinen we.bstly-Account betrifft. 2FA gilt nicht für deinen E-Mail Account. Aktuell wird nur TOTP (bekannt als Google Authenticator) unterstützt.", "info": "Du kannst hier einen zweiten Faktor zusätzlich zu deinem Passwort hinzufügen. Beachte, dass dies nur den Login in deinen we.bstly-Account betrifft. 2FA gilt nicht für deinen E-Mail Account. Aktuell wird nur TOTP (bekannt als Google Authenticator) unterstützt.",
@@ -1022,7 +1026,7 @@
"missing": "Bitte 2FA Code angeben", "missing": "Bitte 2FA Code angeben",
"provider": "Provider", "provider": "Provider",
"totp": { "totp": {
".": "2FA (TOTP)", "": "2FA (TOTP)",
"activate": "Um TOTP als 2FA zu aktivieren, gebe bitte deinen aktuellen Code ein.", "activate": "Um TOTP als 2FA zu aktivieren, gebe bitte deinen aktuellen Code ein.",
"code": "TOTP Code", "code": "TOTP Code",
"confirmRemove": "Bist du sicher, dass du den TOTP als 2FA deaktivieren möchtest?", "confirmRemove": "Bist du sicher, dass du den TOTP als 2FA deaktivieren möchtest?",
@@ -1038,46 +1042,47 @@
"webauthn": "Security-Key/Passkey" "webauthn": "Security-Key/Passkey"
}, },
"oidc": { "oidc": {
".": "OpenID Connect Login", "": "OpenID Connect Login",
"alias": "Alias auswählen", "alias": "Alias auswählen",
"authorize": { "authorize": {
".": "Authorisieren", "": "Authorisieren",
"hint": "Authorisiere die Application auf Teile deines Profile zuzugreifen um dich zu authentifizieren." "hint": "Authorisiere die Application auf Teile deines Profile zuzugreifen um dich zu authentifizieren."
}, },
"login": "Login", "login": "Login",
"login.invalid": "Ungültige Anmeldedaten" "login.invalid": "Ungültige Anmeldedaten"
}, },
"status": { "status": {
".": "Status", "": "Status",
"change": "Status aktualisieren", "change": "Status aktualisieren",
"hint": "Dein User Status gibt an, wie mit deinen Account Daten umgegangen wird wenn deine Berechtigungen ausgelaufen sind.", "hint": "Dein User Status gibt an, wie mit deinen Account Daten umgegangen wird wenn deine Berechtigungen ausgelaufen sind.",
"NORMAL": { "NORMAL": {
".": "Normal", "": "Normal",
"hint": "Dein Account sowie alle gespeicherten Daten werden vier (4) Wochen nach Ablauf gelöscht. Du hast also vier Wochen Zeit deinen Account wieder zu reaktivieren." "hint": "Dein Account sowie alle gespeicherten Daten werden vier (4) Wochen nach Ablauf gelöscht. Du hast also vier Wochen Zeit deinen Account wieder zu reaktivieren."
}, },
"PURGE": { "PURGE": {
".": "Löschen", "": "Löschen",
"hint": "Dein Account sowie alle gespeicherten Daten werden umgehend(!) nach Ablauf gelöscht. Du kannst deinen Account nicht(!) mehr reaktivieren." "hint": "Dein Account sowie alle gespeicherten Daten werden umgehend(!) nach Ablauf gelöscht. Du kannst deinen Account nicht(!) mehr reaktivieren."
}, },
"SLEEP": { "SLEEP": {
".": "Schlafen", "": "Schlafen",
"hint": "Dein Account sowie alle gespeicherten Daten werden nicht(!) gelöscht. Du kannst deinen Account also jederzeit wieder reaktivieren." "hint": "Dein Account sowie alle gespeicherten Daten werden nicht(!) gelöscht. Du kannst deinen Account also jederzeit wieder reaktivieren."
}, },
"success": "Status erfolgreich geändert" "success": "Status erfolgreich geändert"
}, },
"webauthn": { "webauthn": {
".": "Security-Keys/Passkeys", "": "Security-Keys/Passkeys",
"confirmRemove": "Bist du sicher, dass du den Security-Key/Passkey '{0}' löschen möchtest?", "confirmRemove": "Bist du sicher, dass du den Security-Key/Passkey '{0}' löschen möchtest?",
"create": "Security-Key/Passkey hinzufügen", "create": "Security-Key/Passkey hinzufügen",
"dialog": { "dialog": {
"info": "Lege einen Namen für den Security-Key/Passkey fest." "info": "Lege einen Namen für den Security-Key/Passkey fest."
}, },
"info": "Verwalte deine Security-Keys/Passkeys definiere die Verwendung als Login oder 2FA. Achtung, die Verwendung als 'Login + 2FA' hebelt effektiv die Zwei-Faktor-Authentifizierung für den entsprechenden Security-Key/Passkey aus!", "hint": "Achtung, die Verwendung als 'Login + 2FA' hebelt effektiv die Zwei-Faktor-Authentifizierung für den entsprechenden Security-Key/Passkey aus!",
"info": "Verwalte deine Security-Keys/Passkeys definiere die Verwendung als Login oder 2FA.",
"nickname": "Name", "nickname": "Name",
"registered": "Deine Security-Keys/Passkeys", "registered": "Deine Security-Keys/Passkeys",
"remove": "Security-Key/Passkey löschen", "remove": "Security-Key/Passkey löschen",
"usage": { "usage": {
".": "Verwendung", "": "Verwendung",
"login": "Login", "login": "Login",
"login2fa": "Login + 2FA", "login2fa": "Login + 2FA",
"none": "Kein", "none": "Kein",
@@ -1090,13 +1095,13 @@
"text": "Beschreibung" "text": "Beschreibung"
}, },
"service-unavailable": { "service-unavailable": {
".": "Dienst nicht erreichbar", "": "Dienst nicht erreichbar",
"retry": "Seite neu laden", "retry": "Seite neu laden",
"support": "Support", "support": "Support",
"text": "Zurzeit scheint der Dienst nicht erreichbar zu sein. Wenn diese Meldung länger besteht, melde dich beim Support!" "text": "Zurzeit scheint der Dienst nicht erreichbar zu sein. Wenn diese Meldung länger besteht, melde dich beim Support!"
}, },
"services": { "services": {
".": "Dienste", "": "Dienste",
"alias_creation": { "alias_creation": {
"icon": "alternate_email", "icon": "alternate_email",
"subtitle": "Anlegen von alternativen Namen", "subtitle": "Anlegen von alternativen Namen",
@@ -1300,7 +1305,7 @@
"sourcecode": "Quellcode", "sourcecode": "Quellcode",
"token": "Token", "token": "Token",
"tokens": { "tokens": {
".": "Tokens", "": "Tokens",
"active": "Aktuelle Tokens", "active": "Aktuelle Tokens",
"enter": "Token einlösen", "enter": "Token einlösen",
"get": "Mitgliedschaft", "get": "Mitgliedschaft",
@@ -1312,12 +1317,12 @@
"redeemed": "Das Token wurde bereits eingelöst.", "redeemed": "Das Token wurde bereits eingelöst.",
"register": "Du bist neu hier? Dann registriere jetzt deinen Account um das Token einzulösen.", "register": "Du bist neu hier? Dann registriere jetzt deinen Account um das Token einzulösen.",
"validate": { "validate": {
".": "Token prüfen", "": "Token prüfen",
"other": "Neues Token prüfen" "other": "Neues Token prüfen"
} }
}, },
"urlshortener": { "urlshortener": {
".": "Urlshortener", "": "Urlshortener",
"advanced": "Erweitert", "advanced": "Erweitert",
"code": "Kürzel", "code": "Kürzel",
"confirmDelete": "Möchtest du wirklich deinen verkürzten Link für '{0}' löschen?", "confirmDelete": "Möchtest du wirklich deinen verkürzten Link für '{0}' löschen?",
@@ -1338,25 +1343,25 @@
"noQuota": "Deine Quota für verkürzte Links ist leider aufgebraucht.", "noQuota": "Deine Quota für verkürzte Links ist leider aufgebraucht.",
"note": "Notiz", "note": "Notiz",
"password": { "password": {
".": "Dieser Link ist mit einem Passwort geschützt. Gebe das Passwort ein um fortzufahren.", "": "Dieser Link ist mit einem Passwort geschützt. Gebe das Passwort ein um fortzufahren.",
"invalid": "Das angebene Passwort ist ungültig.", "invalid": "Das angebene Passwort ist ungültig.",
"submit": "Abschicken" "submit": "Abschicken"
}, },
"queryParameters": { "queryParameters": {
".": "Query Parameter weiterreichen", "": "Query Parameter weiterreichen",
"info": "Query Parameter werden an die Ziel Url weitergereicht" "info": "Query Parameter werden an die Ziel Url weitergereicht"
}, },
"save": "Speichern", "save": "Speichern",
"search": "Suchen", "search": "Suchen",
"share": { "share": {
".": "Teilen", "": "Teilen",
"clipboard": { "clipboard": {
"copied": "In die Zwischenablage kopiert", "copied": "In die Zwischenablage kopiert",
"text": "Text in Zwischenablage kopieren", "text": "Text in Zwischenablage kopieren",
"url": "Url in Zwischenablage kopieren" "url": "Url in Zwischenablage kopieren"
}, },
"email": { "email": {
".": "Via E-Mail teilen", "": "Via E-Mail teilen",
"subject": "Schau mal" "subject": "Schau mal"
}, },
"text": "Ich möchte den folgenden Link mit dir teilen: {0}" "text": "Ich möchte den folgenden Link mit dir teilen: {0}"
@@ -1364,9 +1369,9 @@
"url": "Url" "url": "Url"
}, },
"user": { "user": {
".": "User", "": "User",
"aliases": { "aliases": {
".": "Alternative Namen", "": "Alternative Namen",
"alias": "Alternativer Name", "alias": "Alternativer Name",
"confirmDelete": "Möchtest du wirklich den alternativen Namen '{0}' löschen?", "confirmDelete": "Möchtest du wirklich den alternativen Namen '{0}' löschen?",
"create": "Alternativen Namen anlegen", "create": "Alternativen Namen anlegen",
@@ -1377,7 +1382,7 @@
"noQuota": "Deine Quota für alternative Namen ist leider aufgebraucht." "noQuota": "Deine Quota für alternative Namen ist leider aufgebraucht."
}, },
"domains": { "domains": {
".": "Domains", "": "Domains",
"confirmDelete": "Möchtest du wirklich die Domain '{0}' löschen?", "confirmDelete": "Möchtest du wirklich die Domain '{0}' löschen?",
"create": "Domain hinzufügen", "create": "Domain hinzufügen",
"delete": "Löschen", "delete": "Löschen",
@@ -1385,18 +1390,18 @@
"error": "Diese Domain ist leider nicht zulässig.", "error": "Diese Domain ist leider nicht zulässig.",
"info": "Du kannst hier Domains hinzufügen.", "info": "Du kannst hier Domains hinzufügen.",
"secret": { "secret": {
".": "Secret", "": "Secret",
"copied": "In die Zwischenablage kopiert", "copied": "In die Zwischenablage kopiert",
"copy": "Secret in die Zwischenablage kopieren" "copy": "Secret in die Zwischenablage kopieren"
}, },
"validated": "Validiert" "validated": "Validiert"
}, },
"dyndns": { "dyndns": {
".": "DynDns", "": "DynDns",
"create": "Erstelle DynDns Token", "create": "Erstelle DynDns Token",
"new": "Erstelle neues DynDns Token", "new": "Erstelle neues DynDns Token",
"token": { "token": {
".": "DynDns Token", "": "DynDns Token",
"copied": "In die Zwischenablage kopiert", "copied": "In die Zwischenablage kopiert",
"copy": "Token in die Zwischenablage kopieren", "copy": "Token in die Zwischenablage kopieren",
"exists": "Du hast aktuell ein aktives DynDns Token. Wenn du ein neues Token generierst, wird das aktuelle Token gelöscht.", "exists": "Du hast aktuell ein aktives DynDns Token. Wenn du ein neues Token generierst, wird das aktuelle Token gelöscht.",
@@ -1404,53 +1409,53 @@
} }
}, },
"unavailable": { "unavailable": {
".": "Zugriff verweigert", "": "Zugriff verweigert",
"text": "Dieser Benutzer existiert nicht oder du hast keine Berechtigungen, um auf das Profil zuzugreifen." "text": "Dieser Benutzer existiert nicht oder du hast keine Berechtigungen, um auf das Profil zuzugreifen."
} }
}, },
"username": { "username": {
".": "Username", "": "Username",
"error": "Bitte wähle einen anderen Usernamen aus.", "error": "Bitte wähle einen anderen Usernamen aus.",
"generate": "Benutzername generieren", "generate": "Benutzername generieren",
"missing": "Bitte gebe einen Usernamen an." "missing": "Bitte gebe einen Usernamen an."
}, },
"visibility": { "visibility": {
".": "Sichtbarkeit", "": "Sichtbarkeit",
"PRIVATE": { "PRIVATE": {
".": "Privat", "": "Privat",
"icon": "lock" "icon": "lock"
}, },
"PROTECTED": { "PROTECTED": {
".": "Geschützt", "": "Geschützt",
"icon": "shield" "icon": "shield"
}, },
"PUBLIC": { "PUBLIC": {
".": "Öffentlich", "": "Öffentlich",
"icon": "public" "icon": "public"
} }
}, },
"voucher": { "voucher": {
".": "Gutscheincode", "": "Gutscheincode",
"code": "Code", "code": "Code",
"type": "Typ" "type": "Typ"
}, },
"vouchers": { "vouchers": {
".": "Gutscheincodes", "": "Gutscheincodes",
"addon": { "addon": {
".": "Add-On", "": "Add-On",
"text": "Dieser Gutscheincode ist für verschiedene Erweiterungen für deinen Account." "text": "Dieser Gutscheincode ist für verschiedene Erweiterungen für deinen Account."
}, },
"info": "Hier kannst du verschiedene Gutscheincodes generieren.", "info": "Hier kannst du verschiedene Gutscheincodes generieren.",
"registration": { "registration": {
".": "Registrierung", "": "Registrierung",
"text": "Dieser Gutscheincode ist für die Registrierung eines neuen Accounts." "text": "Dieser Gutscheincode ist für die Registrierung eines neuen Accounts."
}, },
"stored-safely": { "stored-safely": {
".": "Da wir keine Verbindungen von Gutscheincodes zu deinem Account speichern, speichere diesen Code bitte selber sicher ab. Falls du die Seite verlässt oder neu lädst ist der Code nicht mehr verfügbar!", "": "Da wir keine Verbindungen von Gutscheincodes zu deinem Account speichern, speichere diesen Code bitte selber sicher ab. Falls du die Seite verlässt oder neu lädst ist der Code nicht mehr verfügbar!",
"confirm": "Ich habe den Code sicher abgespeichert!" "confirm": "Ich habe den Code sicher abgespeichert!"
}, },
"temp": { "temp": {
".": "Temporäre Gutscheincodes", "": "Temporäre Gutscheincodes",
"info": "Hier werden deine aktuell angefragten Gutscheincodes angezeigt. Bitte speichere diese sicher ab, da wir diese Codes nicht für dich speichern!" "info": "Hier werden deine aktuell angefragten Gutscheincodes angezeigt. Bitte speichere diese sicher ab, da wir diese Codes nicht für dich speichern!"
} }
} }
+151 -146
View File
@@ -1,14 +1,13 @@
{ {
"account": { "account": {
".": "Account", "": "Account",
"advanced": { "advanced": {
".": "Advanced" "": "Advanced"
} }
}, },
"admin": { "admin": {
".": "Administration", "": "Administration",
"actions": "Actions", "actions": "Actions",
"cancel": "Cancel",
"edit": "Edit", "edit": "Edit",
"delete": "Delete", "delete": "Delete",
"filter": "Filter", "filter": "Filter",
@@ -16,7 +15,7 @@
"no_results": "No results found", "no_results": "No results found",
"showing_entries": "Showing {0} of {1} entries", "showing_entries": "Showing {0} of {1} entries",
"jitsi_rooms": { "jitsi_rooms": {
".": "Jitsi Rooms", "": "Jitsi Rooms",
"confirm_delete": "Are you sure you want to delete room '{0}'?", "confirm_delete": "Are you sure you want to delete room '{0}'?",
"create": "Create Jitsi Room", "create": "Create Jitsi Room",
"delete": "Delete Jitsi Room", "delete": "Delete Jitsi Room",
@@ -36,7 +35,7 @@
"title": "Jitsi Rooms" "title": "Jitsi Rooms"
}, },
"jukebox": { "jukebox": {
".": "Jukebox", "": "Jukebox",
"activate": "Activate Jukebox", "activate": "Activate Jukebox",
"autoplay": "Autoplay", "autoplay": "Autoplay",
"channel": "Channel", "channel": "Channel",
@@ -53,7 +52,7 @@
"status": "Status" "status": "Status"
}, },
"i18n": { "i18n": {
".": "Internationalization", "": "Internationalization",
"title": "Internationalization Management", "title": "Internationalization Management",
"locale": "Locale", "locale": "Locale",
"key": "Key", "key": "Key",
@@ -74,7 +73,7 @@
"raw_json_placeholder": "Enter JSON data here..." "raw_json_placeholder": "Enter JSON data here..."
}, },
"minetest_accounts": { "minetest_accounts": {
".": "Minetest Accounts", "": "Minetest Accounts",
"confirm_delete": "Are you sure you want to delete minetest account '{0}'?", "confirm_delete": "Are you sure you want to delete minetest account '{0}'?",
"create": "Create Minetest Account", "create": "Create Minetest Account",
"created": "Created", "created": "Created",
@@ -85,7 +84,7 @@
"owner": "Owner" "owner": "Owner"
}, },
"oidc_clients": { "oidc_clients": {
".": "OIDC Clients", "": "OIDC Clients",
"advanced_settings": "Advanced Settings", "advanced_settings": "Advanced Settings",
"alias_allowed": "Alias Allowed", "alias_allowed": "Alias Allowed",
"alias_quota": "Alias Quota", "alias_quota": "Alias Quota",
@@ -130,7 +129,7 @@
"token_lifetime_hint": "Token lifetime in seconds" "token_lifetime_hint": "Token lifetime in seconds"
}, },
"partey_maps": { "partey_maps": {
".": "Partey Maps", "": "Partey Maps",
"confirm_delete": "Are you sure you want to delete partey map '{0}'?", "confirm_delete": "Are you sure you want to delete partey map '{0}'?",
"create": "Create Partey Map", "create": "Create Partey Map",
"delete": "Delete Partey Map", "delete": "Delete Partey Map",
@@ -142,7 +141,7 @@
"tags": "Tags" "tags": "Tags"
}, },
"partey_reports": { "partey_reports": {
".": "Partey Reports", "": "Partey Reports",
"confirm_delete": "Are you sure you want to delete this report?", "confirm_delete": "Are you sure you want to delete this report?",
"confirm_delete_all": "Are you sure you want to delete all reports?", "confirm_delete_all": "Are you sure you want to delete all reports?",
"created": "Created", "created": "Created",
@@ -156,7 +155,7 @@
"world": "World" "world": "World"
}, },
"partey_tags": { "partey_tags": {
".": "Partey Tags", "": "Partey Tags",
"confirm_delete": "Are you sure you want to delete partey tag '{0}'?", "confirm_delete": "Are you sure you want to delete partey tag '{0}'?",
"create": "Create Partey Tag", "create": "Create Partey Tag",
"delete": "Delete Partey Tag", "delete": "Delete Partey Tag",
@@ -169,7 +168,7 @@
"target": "Target" "target": "Target"
}, },
"permission_mappings": { "permission_mappings": {
".": "Permission Mappings", "": "Permission Mappings",
"addon": "Addon", "addon": "Addon",
"confirm_delete": "Are you sure you want to delete permission mapping '{0}'?", "confirm_delete": "Are you sure you want to delete permission mapping '{0}'?",
"create": "Create Permission Mapping", "create": "Create Permission Mapping",
@@ -195,7 +194,7 @@
"title": "Permission Mappings" "title": "Permission Mappings"
}, },
"permissions": { "permissions": {
".": "Permissions", "": "Permissions",
"addon": "Addon", "addon": "Addon",
"confirm_delete": "Are you sure you want to delete permission '{0}'?", "confirm_delete": "Are you sure you want to delete permission '{0}'?",
"create": "Create Permission", "create": "Create Permission",
@@ -217,7 +216,7 @@
"starts": "Starts" "starts": "Starts"
}, },
"quota_mappings": { "quota_mappings": {
".": "Quota Mappings", "": "Quota Mappings",
"append": "Append", "append": "Append",
"confirm_delete": "Are you sure you want to delete quota mapping '{0}'?", "confirm_delete": "Are you sure you want to delete quota mapping '{0}'?",
"create": "Create Quota Mapping", "create": "Create Quota Mapping",
@@ -242,7 +241,7 @@
"value_required": "Value is required" "value_required": "Value is required"
}, },
"quotas": { "quotas": {
".": "Quotas", "": "Quotas",
"confirm_delete": "Are you sure you want to delete quota '{0}'?", "confirm_delete": "Are you sure you want to delete quota '{0}'?",
"create": "Create Quota", "create": "Create Quota",
"create_quota": "Create Quota", "create_quota": "Create Quota",
@@ -266,7 +265,7 @@
"create": "Create", "create": "Create",
"save": "Save", "save": "Save",
"services": { "services": {
".": "Services", "": "Services",
"always_permitted": "Always Permitted", "always_permitted": "Always Permitted",
"category": "Category", "category": "Category",
"confirm_delete": "Are you sure you want to delete service '{0}'?", "confirm_delete": "Are you sure you want to delete service '{0}'?",
@@ -284,7 +283,7 @@
"url_required": "URL is required" "url_required": "URL is required"
}, },
"shortened_urls": { "shortened_urls": {
".": "Shortened URLs", "": "Shortened URLs",
"code": "Code", "code": "Code",
"confirm_delete": "Are you sure you want to delete shortened URL '{0}'?", "confirm_delete": "Are you sure you want to delete shortened URL '{0}'?",
"create": "Create Shortened URL", "create": "Create Shortened URL",
@@ -298,7 +297,7 @@
"url": "URL" "url": "URL"
}, },
"system_profile_fields": { "system_profile_fields": {
".": "System Profile Fields", "": "System Profile Fields",
"confirm_delete": "Are you sure you want to delete profile field '{0}'?", "confirm_delete": "Are you sure you want to delete profile field '{0}'?",
"create": "Create Profile Field", "create": "Create Profile Field",
"delete": "Delete Profile Field", "delete": "Delete Profile Field",
@@ -316,7 +315,7 @@
"uniqueValue": "Unique Value" "uniqueValue": "Unique Value"
}, },
"system_properties": { "system_properties": {
".": "System Properties", "": "System Properties",
"confirm_delete": "Are you sure you want to delete property '{0}'?", "confirm_delete": "Are you sure you want to delete property '{0}'?",
"create": "Create Property", "create": "Create Property",
"delete": "Delete Property", "delete": "Delete Property",
@@ -331,7 +330,7 @@
"value_required": "Value is required" "value_required": "Value is required"
}, },
"timeslots": { "timeslots": {
".": "Timeslots", "": "Timeslots",
"all": "All", "all": "All",
"apply_filter": "Apply Filter", "apply_filter": "Apply Filter",
"confirm_delete": "Are you sure you want to delete timeslot '{0}'?", "confirm_delete": "Are you sure you want to delete timeslot '{0}'?",
@@ -353,7 +352,7 @@
}, },
"title": "Admin", "title": "Admin",
"user_aliases": { "user_aliases": {
".": "User Aliases", "": "User Aliases",
"alias": "Alias", "alias": "Alias",
"alias_required": "Alias is required", "alias_required": "Alias is required",
"confirm_delete": "Are you sure you want to delete alias '{0}'?", "confirm_delete": "Are you sure you want to delete alias '{0}'?",
@@ -371,7 +370,7 @@
"visibility_required": "Visibility is required" "visibility_required": "Visibility is required"
}, },
"users": { "users": {
".": "Users", "": "Users",
"confirm_delete": "Are you sure you want to delete user '{0}'?", "confirm_delete": "Are you sure you want to delete user '{0}'?",
"create": "Create User", "create": "Create User",
"created": "Created", "created": "Created",
@@ -391,7 +390,7 @@
"password": "Password", "password": "Password",
"password2": "Confirm Password", "password2": "Confirm Password",
"status": { "status": {
".": "Status", "": "Status",
"NORMAL": "Normal", "NORMAL": "Normal",
"PURGE": "Purge", "PURGE": "Purge",
"SLEEP": "Sleep" "SLEEP": "Sleep"
@@ -402,7 +401,7 @@
"view_quotas": "View Quotas" "view_quotas": "View Quotas"
}, },
"voucher_mappings": { "voucher_mappings": {
".": "Voucher Mappings", "": "Voucher Mappings",
"confirm_delete": "Are you sure you want to delete voucher mapping '{0}'?", "confirm_delete": "Are you sure you want to delete voucher mapping '{0}'?",
"create": "Create Voucher Mapping", "create": "Create Voucher Mapping",
"delete": "Delete Voucher Mapping", "delete": "Delete Voucher Mapping",
@@ -420,13 +419,13 @@
} }
}, },
"borrow": { "borrow": {
".": "Borrow", "": "Borrow",
"items": { "items": {
".": "Borrow Items", "": "Borrow Items",
"actions": "Actions", "actions": "Actions",
"autoAccept": "Accept automatically", "autoAccept": "Accept automatically",
"availability": { "availability": {
".": "Availability", "": "Availability",
"ALWAYS": "Always", "ALWAYS": "Always",
"MANUAL": "Manual", "MANUAL": "Manual",
"PERIOD": "Period" "PERIOD": "Period"
@@ -462,12 +461,12 @@
"save": "Save Item", "save": "Save Item",
"search": "Search", "search": "Search",
"slot": { "slot": {
".": "Slot", "": "Slot",
"add": "Add slot", "add": "Add slot",
"addManual": "Add manual slot", "addManual": "Add manual slot",
"addPeriod": "Add period slot", "addPeriod": "Add period slot",
"day": { "day": {
".": "Day", "": "Day",
"FRIDAY": "Friday", "FRIDAY": "Friday",
"MONDAY": "Monday", "MONDAY": "Monday",
"SATURDAY": "Saturday", "SATURDAY": "Saturday",
@@ -493,7 +492,7 @@
"name": "Item Name" "name": "Item Name"
}, },
"proving": { "proving": {
".": "Proving", "": "Proving",
"camera": "Camera", "camera": "Camera",
"flash": "Flash" "flash": "Flash"
}, },
@@ -513,7 +512,7 @@
"user": "User" "user": "User"
}, },
"requests": { "requests": {
".": "Requests", "": "Requests",
"actions": "Actions", "actions": "Actions",
"ends": "Ends", "ends": "Ends",
"mine": "Mine", "mine": "Mine",
@@ -531,10 +530,10 @@
"minutes": "Minutes" "minutes": "Minutes"
}, },
"email": { "email": {
".": "Email address", "": "Email address",
"invalid": "invalid email address", "invalid": "invalid email address",
"primary": { "primary": {
".": "primary email address", "": "primary email address",
"hint": "A primary email address is used for contact you instead of you we.bstly address." "hint": "A primary email address is used for contact you instead of you we.bstly address."
} }
}, },
@@ -548,10 +547,10 @@
"help-button": "Find help in Wiki", "help-button": "Find help in Wiki",
"imprint": "Imprint", "imprint": "Imprint",
"info": { "info": {
".": "Info" "": "Info"
}, },
"invite": { "invite": {
".": "Invite", "": "Invite",
"actions": "Actions", "actions": "Actions",
"create": "Create Invite", "create": "Create Invite",
"expires": "Expires", "expires": "Expires",
@@ -564,9 +563,9 @@
"starts": "Starts" "starts": "Starts"
}, },
"invites": { "invites": {
".": "Invites", "": "Invites",
"edit": { "edit": {
".": "Edit Invite", "": "Edit Invite",
"save": "Save Invite" "save": "Save Invite"
}, },
"error": { "error": {
@@ -578,21 +577,21 @@
"others": "Other's invites", "others": "Other's invites",
"quota": { "quota": {
"pubquiz": { "pubquiz": {
".": "Pubquiz", "": "Pubquiz",
"icon": "quiz", "icon": "quiz",
"text": "Invite to Pubquiz." "text": "Invite to Pubquiz."
} }
}, },
"redeemed": { "redeemed": {
"filter": { "filter": {
".": "Filter redeemed status", "": "Filter redeemed status",
"false": "Not redeemed", "false": "Not redeemed",
"none": "No filter", "none": "No filter",
"true": "Redeemed" "true": "Redeemed"
} }
}, },
"register": { "register": {
".": "Redeem Invite", "": "Redeem Invite",
"error": { "error": {
"ALREADY_REDEEMED": "The provided code is already redeemed!", "ALREADY_REDEEMED": "The provided code is already redeemed!",
"EXPIRED": "The provided code is expired!", "EXPIRED": "The provided code is expired!",
@@ -601,7 +600,7 @@
}, },
"login": "Login", "login": "Login",
"success": { "success": {
".": "Finished registration", "": "Finished registration",
"text": "Successfully registered your Account. You can login now!" "text": "Successfully registered your Account. You can login now!"
}, },
"time": "Invite valid from {0} till {1}", "time": "Invite valid from {0} till {1}",
@@ -611,7 +610,7 @@
}, },
"jitsi": { "jitsi": {
"rooms": { "rooms": {
".": "Jitsi Rooms", "": "Jitsi Rooms",
"clipboard": { "clipboard": {
"copied": "Jitsi Room url copied to clipboard!" "copied": "Jitsi Room url copied to clipboard!"
}, },
@@ -637,14 +636,14 @@
"starts": "Starts" "starts": "Starts"
}, },
"share": { "share": {
".": "Share", "": "Share",
"clipboard": { "clipboard": {
"copied": "Copied to clipboard", "copied": "Copied to clipboard",
"text": "Copy text to clipboard", "text": "Copy text to clipboard",
"url": "Copy url to clipboard" "url": "Copy url to clipboard"
}, },
"email": { "email": {
".": "Share via email", "": "Share via email",
"subject": "Invite to video conference {0}" "subject": "Invite to video conference {0}"
}, },
"text": { "text": {
@@ -657,27 +656,27 @@
} }
}, },
"jukebox": { "jukebox": {
".": "Jukebox", "": "Jukebox",
"addToQueue": { "addToQueue": {
".": "Add to queue", "": "Add to queue",
"confirm": "Add '{0} - {1}' to queue?", "confirm": "Add '{0} - {1}' to queue?",
"error": "Error", "error": "Error",
"success": "Sucess" "success": "Sucess"
}, },
"current": "Current track", "current": "Current track",
"forbidden": { "forbidden": {
".": "Forbidden", "": "Forbidden",
"hint": "You are not allowed to use the Jukebox." "hint": "You are not allowed to use the Jukebox."
}, },
"search": { "search": {
".": "Search", "": "Search",
"icon": "search", "icon": "search",
"more": "Show more", "more": "Show more",
"submit": "Submit" "submit": "Submit"
}, },
"timeout": "Please wait {0} seconds before next request.", "timeout": "Please wait {0} seconds before next request.",
"unavailable": { "unavailable": {
".": "unavailable", "": "unavailable",
"hint": "Currently the Jukebox is turned off." "hint": "Currently the Jukebox is turned off."
}, },
"wait": "Please wait." "wait": "Please wait."
@@ -693,7 +692,7 @@
} }
}, },
"login": { "login": {
".": "Login", "": "Login",
"external": "Login", "external": "Login",
"invalid": "Wrong username or password.", "invalid": "Wrong username or password.",
"keepSession": "Stay logged in", "keepSession": "Stay logged in",
@@ -702,7 +701,7 @@
"logout": "Logout", "logout": "Logout",
"minetest": { "minetest": {
"accounts": { "accounts": {
".": "Minetest Accounts", "": "Minetest Accounts",
"confirmDelete": "Are you sure you want to delete your Minetest Account '{0}'? Your account cannot be restored and others can claim your account name afterwards!", "confirmDelete": "Are you sure you want to delete your Minetest Account '{0}'? Your account cannot be restored and others can claim your account name afterwards!",
"create": "Create Minetest Account", "create": "Create Minetest Account",
"delete": "Delete", "delete": "Delete",
@@ -717,7 +716,7 @@
} }
}, },
"not-found": { "not-found": {
".": "Nothing found", "": "Nothing found",
"text": "This page was not found." "text": "This page was not found."
}, },
"ok": "Ok", "ok": "Ok",
@@ -731,41 +730,41 @@
"range": "page {0} of {1}" "range": "page {0} of {1}"
}, },
"partey": { "partey": {
".": "Partey", "": "Partey",
"tag": { "tag": {
".": "Partey Tag", "": "Partey Tag",
"access-storage": { "access-storage": {
".": "Access Storage", "": "Access Storage",
"hint": "Access to storage room in ground floor." "hint": "Access to storage room in ground floor."
}, },
"admin": { "admin": {
".": "Administrator", "": "Administrator",
"hint": "Send room messages." "hint": "Send room messages."
}, },
"cinema-mod": { "cinema-mod": {
".": "Cinema Moderator", "": "Cinema Moderator",
"hint": "In cinema: Enter stage, set stream url, moderate chat room." "hint": "In cinema: Enter stage, set stream url, moderate chat room."
}, },
"disco-mod": { "disco-mod": {
".": "Disco Moderator", "": "Disco Moderator",
"hint": "In cinema: Enter stage, change stage layer, moderate chat room." "hint": "In cinema: Enter stage, change stage layer, moderate chat room."
}, },
"game-mod": { "game-mod": {
".": "Game Moderator", "": "Game Moderator",
"hint": "In game room: Set table label, moderate chat room." "hint": "In game room: Set table label, moderate chat room."
} }
}, },
"tags": { "tags": {
".": "Partey Tags", "": "Partey Tags",
"expires": "Expires", "expires": "Expires",
"none": "None", "none": "None",
"upcoming": "Upcoming" "upcoming": "Upcoming"
}, },
"timeslots": { "timeslots": {
".": "Partey Timeslots", "": "Partey Timeslots",
"confirmDelete": "Are you sure you want to delete your Timeslot '{0}' from {1}?", "confirmDelete": "Are you sure you want to delete your Timeslot '{0}' from {1}?",
"create": { "create": {
".": "Create new Timeslot", "": "Create new Timeslot",
"AUDIO": "New Audio Timeslot", "AUDIO": "New Audio Timeslot",
"AUDIO_STREAM": "New Audio Stream Timeslot", "AUDIO_STREAM": "New Audio Stream Timeslot",
"VIDEO": "New Video Timeslot", "VIDEO": "New Video Timeslot",
@@ -780,17 +779,17 @@
"starts": "Invalid start. Please check for conflicting Timeslots or duration." "starts": "Invalid start. Please check for conflicting Timeslots or duration."
}, },
"filter": { "filter": {
".": "Filter", "": "Filter",
"after": "After", "after": "After",
"owner": { "owner": {
".": "Owner", "": "Owner",
"all": "All", "all": "All",
"mine": "My Timeslots", "mine": "My Timeslots",
"others": "Other Timeslots" "others": "Other Timeslots"
}, },
"search": "Search", "search": "Search",
"type": { "type": {
".": "Type", "": "Type",
"all": "All", "all": "All",
"AUDIO": "Audio", "AUDIO": "Audio",
"AUDIO_STREAM": "Audio Stream", "AUDIO_STREAM": "Audio Stream",
@@ -803,44 +802,44 @@
"noQuota": "Your quota for Timeslots is depleted.", "noQuota": "Your quota for Timeslots is depleted.",
"save": "Save Timeslot", "save": "Save Timeslot",
"secret": { "secret": {
".": "Audio Stream Secret", "": "Audio Stream Secret",
"copied": "Copied to clipboard", "copied": "Copied to clipboard",
"copy": "Copy Audio Stream Secret" "copy": "Copy Audio Stream Secret"
}, },
"share": { "share": {
".": "Share", "": "Share",
"placeholder": "Filename of share" "placeholder": "Filename of share"
}, },
"starts": "Starts", "starts": "Starts",
"stream": { "stream": {
".": "Stream", "": "Stream",
"AUDIO": "Icecast2 Stream Key", "AUDIO": "Icecast2 Stream Key",
"VIDEO": "PeerTube Video Id" "VIDEO": "PeerTube Video Id"
}, },
"title": "Title", "title": "Title",
"type": { "type": {
".": "Type", "": "Type",
"AUDIO": { "AUDIO": {
".": "Audio", "": "Audio",
"icon": "library_music" "icon": "library_music"
}, },
"AUDIO_STREAM": { "AUDIO_STREAM": {
".": "Audio Stream", "": "Audio Stream",
"icon": "music_note" "icon": "music_note"
}, },
"VIDEO": { "VIDEO": {
".": "Video", "": "Video",
"icon": "movie" "icon": "movie"
}, },
"VIDEO_STREAM": { "VIDEO_STREAM": {
".": "Video Stream", "": "Video Stream",
"icon": "live_tv" "icon": "live_tv"
} }
} }
} }
}, },
"password": { "password": {
".": "Password", "": "Password",
"change": "Change password", "change": "Change password",
"changed": "Successfully changed password", "changed": "Successfully changed password",
"confirm": "Confirm password", "confirm": "Confirm password",
@@ -855,13 +854,13 @@
}, },
"forgot": "Forgot password", "forgot": "Forgot password",
"invalid": { "invalid": {
".": "Password is invalid", "": "Password is invalid",
"hint": "Please provide password in a valid format." "hint": "Please provide password in a valid format."
}, },
"not-match": "Passwords did not match.", "not-match": "Passwords did not match.",
"request": "Request new password", "request": "Request new password",
"reset": { "reset": {
".": "Set password", "": "Set password",
"login": "Back to login", "login": "Back to login",
"success": { "success": {
"text": "Your new password has been applied. You can now login with your new password.", "text": "Your new password has been applied. You can now login with your new password.",
@@ -870,15 +869,15 @@
} }
}, },
"permissions": { "permissions": {
".": "Permissions", "": "Permissions",
"expires": "Valid until", "expires": "Valid until",
"name": "Name", "name": "Name",
"starts": "Valid from" "starts": "Valid from"
}, },
"pgp": { "pgp": {
".": "PGP", "": "PGP",
"privateKey": { "privateKey": {
".": "Private PGP key", "": "Private PGP key",
"confirmStore": "I have securely stored my private key!", "confirmStore": "I have securely stored my private key!",
"copied": "Private Key copied to clipbaord", "copied": "Private Key copied to clipbaord",
"copyKey": "Copy to clipboard", "copyKey": "Copy to clipboard",
@@ -890,7 +889,7 @@
"privacy-policy": "Privacy Policy", "privacy-policy": "Privacy Policy",
"profile": "Profile", "profile": "Profile",
"profileField": { "profileField": {
".": "Profile field", "": "Profile field",
"blob": { "blob": {
"pgp": "Create new PGP Keypair" "pgp": "Create new PGP Keypair"
}, },
@@ -900,92 +899,97 @@
"edit": "Edit", "edit": "Edit",
"error": { "error": {
"BLOB": { "BLOB": {
".": "Invalid binary blob" "": "Invalid binary blob"
}, },
"BOOL": { "BOOL": {
".": "Invalid boolean" "": "Invalid boolean"
}, },
"DATE": { "DATE": {
".": "Invalid date" "": "Invalid date"
}, },
"DATETIME": { "DATETIME": {
".": "Invalid date or time" "": "Invalid date or time"
}, },
"EMAIL": { "EMAIL": {
".": "Invalid email address" "": "Invalid email address"
}, },
"name": "name invalid or too short", "name": "name invalid or too short",
"NUMBER": { "NUMBER": {
".": "Invalid numeric" "": "Invalid numeric"
}, },
"TEXT": { "TEXT": {
".": "Text too long" "": "Text too long"
}, },
"type": "Invalid type for this profile field", "type": "Invalid type for this profile field",
"URL": { "URL": {
".": "Invalid URL" "": "Invalid URL"
}, },
"visibility": "Invalid visibility for profile field" "visibility": "Invalid visibility for profile field"
}, },
"index": "Index", "index": "Index",
"name": { "name": {
".": "Key", "": "Key",
"darkTheme": "Dark Theme", "darkTheme": "Dark Theme",
"email": "Email address", "email": "Email address",
"locale": "Locale", "locale": "Locale",
"primaryEmail": "Use email address primary", "primaryEmail": "Use email address primary",
"prtyMap": "Partey map", "prtyMap": "Partey map",
"publicKey": "Public PGP key" "publicKey": "Public PGP key",
"startPage": {
"": "Startpage",
"hint": "Set current page as Startpage",
"set": "Set Startpage"
}
}, },
"openBlob": "Display", "openBlob": "Display",
"type": { "type": {
".": "Type", "": "Type",
"BLOB": { "BLOB": {
".": "Binary blob" "": "Binary blob"
}, },
"BOOL": { "BOOL": {
".": "Boolean" "": "Boolean"
}, },
"DATE": { "DATE": {
".": "Date" "": "Date"
}, },
"DATETIME": { "DATETIME": {
".": "Date with time" "": "Date with time"
}, },
"EMAIL": { "EMAIL": {
".": "Email" "": "Email"
}, },
"NUMBER": { "NUMBER": {
".": "Numeric" "": "Numeric"
}, },
"TEXT": { "TEXT": {
".": "Text" "": "Text"
}, },
"URL": { "URL": {
".": "URL" "": "URL"
} }
}, },
"value": "Value" "value": "Value"
}, },
"quotas": { "quotas": {
".": "Quotas", "": "Quotas",
"fixed_value": { "fixed_value": {
".": "Total", "": "Total",
"hint": "You can look up your usage in the respective service." "hint": "You can look up your usage in the respective service."
}, },
"name": "Name", "name": "Name",
"unit": { "unit": {
"#": "# (Count)", "#": "# (Count)",
".": "Unit", "": "Unit",
"G": "GB (Gigabyte)" "G": "GB (Gigabyte)"
}, },
"value": { "value": {
".": "Available", "": "Available",
"hint": "" "hint": ""
} }
}, },
"register": { "register": {
".": "Registration", "": "Registration",
"login": "To Login", "login": "To Login",
"success": { "success": {
"text": "Successfully registered your Account. You can login now!", "text": "Successfully registered your Account. You can login now!",
@@ -993,20 +997,20 @@
}, },
"token": { "token": {
"locked": { "locked": {
".": "You need an account to redeem this token!", "": "You need an account to redeem this token!",
"action": "Please login." "action": "Please login."
}, },
"missing": { "missing": {
".": "You need a valid token!", "": "You need a valid token!",
"action": "Provide token" "action": "Provide token"
} }
} }
}, },
"save": "Save", "save": "Save",
"security": { "security": {
".": "Security", "": "Security",
"2fa": { "2fa": {
".": "Two-Factor-Authentication (2FA)", "": "Two-Factor-Authentication (2FA)",
"code": "Code", "code": "Code",
"external": "2FA required", "external": "2FA required",
"info": "You can additionally add a second factor to your password. Please keep in mind, that this only affects your we.bstly-Account and not your email login. Currently only TOTP (also known as Google Authenticator) and Security-Keys/Passkeys supported as 2FA method.", "info": "You can additionally add a second factor to your password. Please keep in mind, that this only affects your we.bstly-Account and not your email login. Currently only TOTP (also known as Google Authenticator) and Security-Keys/Passkeys supported as 2FA method.",
@@ -1016,7 +1020,7 @@
"missing": "Please enter 2FA code", "missing": "Please enter 2FA code",
"provider": "Provider", "provider": "Provider",
"totp": { "totp": {
".": "2FA (TOTP)", "": "2FA (TOTP)",
"activate": "Please enter your current code to enable TOTP as your 2FA.", "activate": "Please enter your current code to enable TOTP as your 2FA.",
"code": "TOTP code", "code": "TOTP code",
"confirmRemove": "Are you sure you want to disbale 2FA widh TOTP?", "confirmRemove": "Are you sure you want to disbale 2FA widh TOTP?",
@@ -1028,46 +1032,47 @@
"webauthn": "Security-Key/Passkey" "webauthn": "Security-Key/Passkey"
}, },
"oidc": { "oidc": {
".": "OpenID Connect Login", "": "OpenID Connect Login",
"alias": "Choose alias", "alias": "Choose alias",
"authorize": { "authorize": {
".": "Authorize", "": "Authorize",
"hint": "Authorize this application to access parts of your profile for authentication." "hint": "Authorize this application to access parts of your profile for authentication."
}, },
"login": "Login", "login": "Login",
"login.invalid": "Invalid login credentials" "login.invalid": "Invalid login credentials"
}, },
"status": { "status": {
".": "Status", "": "Status",
"change": "Change status", "change": "Change status",
"hint": "You Account Status controls the handling of your account data after all permissions expired.", "hint": "You Account Status controls the handling of your account data after all permissions expired.",
"NORMAL": { "NORMAL": {
".": "Normal", "": "Normal",
"hint": "Your account and all your data will be deleted after four (4) weeks. So you have 4 weeks left to reactivate your account." "hint": "Your account and all your data will be deleted after four (4) weeks. So you have 4 weeks left to reactivate your account."
}, },
"PURGE": { "PURGE": {
".": "Purge", "": "Purge",
"hint": "Your account and all your data will be deleted immediately after expiry. So you can not(!) reactivate your account." "hint": "Your account and all your data will be deleted immediately after expiry. So you can not(!) reactivate your account."
}, },
"SLEEP": { "SLEEP": {
".": "Sleep", "": "Sleep",
"hint": "Your account and all your data will not(!) be deleted. So you have reactivate your account anytime." "hint": "Your account and all your data will not(!) be deleted. So you have reactivate your account anytime."
}, },
"success": "Status successfully changed" "success": "Status successfully changed"
}, },
"webauthn": { "webauthn": {
".": "Security-Keys/Passkeys", "": "Security-Keys/Passkeys",
"confirmRemove": "Are you sure you want to delete your Security-Key/Passkey '{0}'?", "confirmRemove": "Are you sure you want to delete your Security-Key/Passkey '{0}'?",
"create": "Add Security-Key/Passkey", "create": "Add Security-Key/Passkey",
"dialog": { "dialog": {
"info": "Define a name for your Security-Key/Passkey" "info": "Define a name for your Security-Key/Passkey"
}, },
"info": "Manage your Security-Keys/Passkeys and define if the devices should be used for Login or 2FA. Attention! The usage as 'Login + 2FA' effectily disabled Two-Factor-Authentication for this Security-Key/Passkey", "hint": "Attention, the usage as 'Login + 2FA' effectily disabled Two-Factor-Authentication for this Security-Key/Passkey!",
"info": "Manage your Security-Keys/Passkeys and define if the devices should be used for Login or 2FA.",
"nickname": "Name", "nickname": "Name",
"registered": "Your Security-Keys/Passkeys", "registered": "Your Security-Keys/Passkeys",
"remove": "Remove Security-Key/Passkey", "remove": "Remove Security-Key/Passkey",
"usage": { "usage": {
".": "Usage", "": "Usage",
"login": "Login", "login": "Login",
"login2fa": "Login + 2FA", "login2fa": "Login + 2FA",
"none": "None", "none": "None",
@@ -1080,13 +1085,13 @@
"text": "Description" "text": "Description"
}, },
"service-unavailable": { "service-unavailable": {
".": "Service unavailable", "": "Service unavailable",
"retry": "Reload page", "retry": "Reload page",
"support": "Support", "support": "Support",
"text": "The service seems currently unavailable. If this message appears over a longer period, please contact our support!" "text": "The service seems currently unavailable. If this message appears over a longer period, please contact our support!"
}, },
"services": { "services": {
".": "Services", "": "Services",
"alias_creation": { "alias_creation": {
"icon": "alternate_email", "icon": "alternate_email",
"subtitle": "Creation of Aliases", "subtitle": "Creation of Aliases",
@@ -1290,7 +1295,7 @@
"sourcecode": "Source Code", "sourcecode": "Source Code",
"token": "Token", "token": "Token",
"tokens": { "tokens": {
".": "Token", "": "Token",
"active": "Current Tokens", "active": "Current Tokens",
"enter": "Enter token", "enter": "Enter token",
"get": "Membership", "get": "Membership",
@@ -1302,12 +1307,12 @@
"redeemed": "The provided token has already been redeemed.", "redeemed": "The provided token has already been redeemed.",
"register": "New here and need an account? Register a new account to redeem token.", "register": "New here and need an account? Register a new account to redeem token.",
"validate": { "validate": {
".": "Validate token", "": "Validate token",
"other": "Valiate new token" "other": "Valiate new token"
} }
}, },
"urlshortener": { "urlshortener": {
".": "Urlshortener", "": "Urlshortener",
"advanced": "Advanced", "advanced": "Advanced",
"code": "Code", "code": "Code",
"confirmDelete": "Are you sure you want to delete your shortened link for '{0}'?", "confirmDelete": "Are you sure you want to delete your shortened link for '{0}'?",
@@ -1328,25 +1333,25 @@
"noQuota": "Your quota for shortened links is depleted.", "noQuota": "Your quota for shortened links is depleted.",
"note": "Note", "note": "Note",
"password": { "password": {
".": "This link is password protected. Enter password to proceed.", "": "This link is password protected. Enter password to proceed.",
"invalid": "The given password is invalid.", "invalid": "The given password is invalid.",
"submit": "Submit" "submit": "Submit"
}, },
"queryParameters": { "queryParameters": {
".": "Pass query parameters", "": "Pass query parameters",
"info": "Pass query parameters to target url" "info": "Pass query parameters to target url"
}, },
"save": "Save", "save": "Save",
"search": "Search", "search": "Search",
"share": { "share": {
".": "Share", "": "Share",
"clipboard": { "clipboard": {
"copied": "Copied to clipboard", "copied": "Copied to clipboard",
"text": "Copy text to clipboard", "text": "Copy text to clipboard",
"url": "Copy url to clipboard" "url": "Copy url to clipboard"
}, },
"email": { "email": {
".": "Share via email", "": "Share via email",
"subject": "Take a look" "subject": "Take a look"
}, },
"text": "I want to share the following link with you: {0}" "text": "I want to share the following link with you: {0}"
@@ -1354,9 +1359,9 @@
"url": "Url" "url": "Url"
}, },
"user": { "user": {
".": "User", "": "User",
"aliases": { "aliases": {
".": "Aliases", "": "Aliases",
"alias": "Alias", "alias": "Alias",
"confirmDelete": "Are you sure you want to delete your alias '{0}'?", "confirmDelete": "Are you sure you want to delete your alias '{0}'?",
"create": "Add Alias", "create": "Add Alias",
@@ -1367,7 +1372,7 @@
"noQuota": "Your quota for Aliases is depleted." "noQuota": "Your quota for Aliases is depleted."
}, },
"domains": { "domains": {
".": "Domains", "": "Domains",
"confirmDelete": "Are you sure you want to delete your domain '{0}'?", "confirmDelete": "Are you sure you want to delete your domain '{0}'?",
"create": "Add Domain", "create": "Add Domain",
"delete": "Delete", "delete": "Delete",
@@ -1375,18 +1380,18 @@
"error": "This domain is invalid.", "error": "This domain is invalid.",
"info": "You can add Domains here.", "info": "You can add Domains here.",
"secret": { "secret": {
".": "Secret", "": "Secret",
"copied": "Copied to clipboard", "copied": "Copied to clipboard",
"copy": "Copy secret to clipboard" "copy": "Copy secret to clipboard"
}, },
"validated": "Validated" "validated": "Validated"
}, },
"dyndns": { "dyndns": {
".": "DynDns", "": "DynDns",
"create": "Create DynDns Token", "create": "Create DynDns Token",
"new": "Create new DynDns Token", "new": "Create new DynDns Token",
"token": { "token": {
".": "DynDns Token", "": "DynDns Token",
"copied": "Copied to clipboard", "copied": "Copied to clipboard",
"copy": "Copy Token to clipboard", "copy": "Copy Token to clipboard",
"exists": "You currently have an active Token. If you create a new token, the old one will be deleted.", "exists": "You currently have an active Token. If you create a new token, the old one will be deleted.",
@@ -1394,53 +1399,53 @@
} }
}, },
"unavailable": { "unavailable": {
".": "Access denied", "": "Access denied",
"text": "The provided user does not exists or you have insufficient privileges to access profile." "text": "The provided user does not exists or you have insufficient privileges to access profile."
} }
}, },
"username": { "username": {
".": "Username", "": "Username",
"error": "Please choose a different username.", "error": "Please choose a different username.",
"generate": "Generate username", "generate": "Generate username",
"missing": "Please enter a valid username." "missing": "Please enter a valid username."
}, },
"visibility": { "visibility": {
".": "Visibility", "": "Visibility",
"PRIVATE": { "PRIVATE": {
".": "Private", "": "Private",
"icon": "lock" "icon": "lock"
}, },
"PROTECTED": { "PROTECTED": {
".": "Protected", "": "Protected",
"icon": "shield" "icon": "shield"
}, },
"PUBLIC": { "PUBLIC": {
".": "Public", "": "Public",
"icon": "public" "icon": "public"
} }
}, },
"voucher": { "voucher": {
".": "Voucher", "": "Voucher",
"code": "Code", "code": "Code",
"type": "Typ" "type": "Typ"
}, },
"vouchers": { "vouchers": {
".": "Vouchers", "": "Vouchers",
"addon": { "addon": {
".": "Add-On", "": "Add-On",
"text": "This voucher is for different extension of your account." "text": "This voucher is for different extension of your account."
}, },
"info": "Generate different vouchers.", "info": "Generate different vouchers.",
"registration": { "registration": {
".": "Registration", "": "Registration",
"text": "This voucher is for a registration of a new account." "text": "This voucher is for a registration of a new account."
}, },
"stored-safely": { "stored-safely": {
".": "Please store the provided voucher code securely, since we do not store any relation of vouchers to your account. If you leave page or reload the code won't be shown up again!", "": "Please store the provided voucher code securely, since we do not store any relation of vouchers to your account. If you leave page or reload the code won't be shown up again!",
"confirm": "I securely stored the given voucher!" "confirm": "I securely stored the given voucher!"
}, },
"temp": { "temp": {
".": "Temporary vouchers", "": "Temporary vouchers",
"info": "You currently requested vouchers are displayed here. Please store them securely!" "info": "You currently requested vouchers are displayed here. Please store them securely!"
} }
} }