feat(#22): Use translation keys in files
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<UDashboardPanel id="administration">
|
||||
<template #header>
|
||||
<UDashboardNavbar title="Administration - JSON Template Editor" :ui="{ right: 'gap-3' }">
|
||||
<UDashboardNavbar :title="$t('templates.editorTitle')" :ui="{ right: 'gap-3' }">
|
||||
<template #leading>
|
||||
<UDashboardSidebarCollapse />
|
||||
</template>
|
||||
@@ -10,21 +10,21 @@
|
||||
<UButton
|
||||
v-if="hasUnsavedChanges"
|
||||
icon="i-lucide-rotate-ccw"
|
||||
label="Zurücksetzen"
|
||||
:label="$t('templates.reset')"
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
@click="resetEditor"
|
||||
/>
|
||||
<UButton
|
||||
icon="i-lucide-file-plus"
|
||||
label="Neue Vorlage"
|
||||
:label="$t('templates.newTemplate')"
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
@click="createNewTemplate"
|
||||
/>
|
||||
<UButton
|
||||
icon="i-lucide-save"
|
||||
label="Speichern"
|
||||
:label="$t('common.save')"
|
||||
:disabled="!hasUnsavedChanges || !isValidJson"
|
||||
:loading="isSaving"
|
||||
@click="saveTemplate"
|
||||
@@ -40,17 +40,17 @@
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg">{{ currentTemplate.name }}</h3>
|
||||
<p class="text-sm text-muted mt-1">
|
||||
Zuletzt bearbeitet am {{ formatDate(new Date(currentTemplate.modifiedAt)) }}
|
||||
{{ $t('templates.lastModified') }} {{ formatDate(new Date(currentTemplate.modifiedAt)) }}
|
||||
</p>
|
||||
</div>
|
||||
<UBadge v-if="hasUnsavedChanges" label="Ungespeicherte Änderungen" color="warning" variant="subtle" />
|
||||
<UBadge v-if="hasUnsavedChanges" :label="$t('templates.unsavedChanges')" color="warning" variant="subtle" />
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
<UCard v-else class="mb-4">
|
||||
<div class="text-center py-4">
|
||||
<UIcon name="i-lucide-info" class="size-8 text-muted mx-auto mb-2" />
|
||||
<p class="text-muted">Keine Vorlage gefunden. Erstellen Sie eine neue Vorlage.</p>
|
||||
<p class="text-muted">{{ $t('templates.noTemplateFound') }}</p>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
@@ -70,8 +70,8 @@
|
||||
v-if="!isValidJson"
|
||||
color="error"
|
||||
icon="i-lucide-alert-circle"
|
||||
title="Ungültiges JSON"
|
||||
description="Das JSON-Format ist ungültig. Bitte korrigieren Sie die Syntax."
|
||||
:title="$t('templates.invalidJson')"
|
||||
:description="$t('templates.invalidJsonDescription')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -92,6 +92,7 @@ const colorMode = useColorMode()
|
||||
const { hasRole } = usePermissions()
|
||||
const { getAllApplicationFormTemplates, updateApplicationFormTemplate, createApplicationFormTemplate } =
|
||||
await useApplicationFormTemplate()
|
||||
const { t: $t } = useI18n()
|
||||
|
||||
if (!hasRole('CHIEF_EXECUTIVE_OFFICER') && !hasRole('IT_DEPARTMENT')) {
|
||||
await navigateTo('/')
|
||||
@@ -194,8 +195,8 @@ function createNewTemplate() {
|
||||
async function saveTemplate() {
|
||||
if (!isValidJson.value) {
|
||||
toast.add({
|
||||
title: 'Fehler',
|
||||
description: 'Das JSON-Format ist ungültig.',
|
||||
title: $t('common.error'),
|
||||
description: $t('templates.invalidJsonDescription'),
|
||||
color: 'error'
|
||||
})
|
||||
return
|
||||
@@ -210,15 +211,15 @@ async function saveTemplate() {
|
||||
if (currentTemplate.value?.id) {
|
||||
currentTemplate.value = await updateApplicationFormTemplate(currentTemplate.value.id, dataWithDates)
|
||||
toast.add({
|
||||
title: 'Erfolg',
|
||||
description: 'Vorlage erfolgreich aktualisiert.',
|
||||
title: $t('common.success'),
|
||||
description: $t('templates.updated'),
|
||||
color: 'success'
|
||||
})
|
||||
} else {
|
||||
currentTemplate.value = await createApplicationFormTemplate(dataWithDates)
|
||||
toast.add({
|
||||
title: 'Erfolg',
|
||||
description: 'Vorlage erfolgreich erstellt.',
|
||||
title: $t('common.success'),
|
||||
description: $t('templates.created'),
|
||||
color: 'success'
|
||||
})
|
||||
}
|
||||
@@ -230,8 +231,8 @@ async function saveTemplate() {
|
||||
await refreshNuxtData('applicationFormTemplates')
|
||||
} catch (error) {
|
||||
toast.add({
|
||||
title: 'Fehler',
|
||||
description: 'Fehler beim Speichern der Vorlage.',
|
||||
title: $t('common.error'),
|
||||
description: $t('templates.saveError'),
|
||||
color: 'error'
|
||||
})
|
||||
console.error('Error saving template:', error)
|
||||
@@ -242,7 +243,7 @@ async function saveTemplate() {
|
||||
|
||||
onBeforeRouteLeave((to, from, next) => {
|
||||
if (hasUnsavedChanges.value) {
|
||||
const answer = window.confirm('Sie haben ungespeicherte Änderungen. Möchten Sie die Seite wirklich verlassen?')
|
||||
const answer = window.confirm($t('templates.unsavedWarning'))
|
||||
if (answer) {
|
||||
next()
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<UDashboardPanel id="home">
|
||||
<template #header>
|
||||
<UDashboardNavbar title="Home" :ui="{ right: 'gap-3' }">
|
||||
<UDashboardNavbar :title="$t('common.home')" :ui="{ right: 'gap-3' }">
|
||||
<template #leading>
|
||||
<UDashboardSidebarCollapse />
|
||||
</template>
|
||||
@@ -9,7 +9,7 @@
|
||||
<template #right>
|
||||
<UButton
|
||||
icon="i-lucide-circle-plus"
|
||||
label="Neuer Mitbestimmungsantrag"
|
||||
:label="$t('applicationForms.createNew')"
|
||||
to="/create"
|
||||
:disabled="!canWriteApplicationForms"
|
||||
size="xl"
|
||||
@@ -59,6 +59,7 @@ import { useUserStore } from '~~/stores/useUserStore'
|
||||
|
||||
const route = useRoute()
|
||||
const toast = useToast()
|
||||
const { t: $t } = useI18n()
|
||||
|
||||
definePageMeta({
|
||||
// Prevent whole page from re-rendering when navigating between sections to keep state
|
||||
@@ -113,7 +114,7 @@ async function onSave() {
|
||||
const updated = await updateForm(applicationForm.value.id, applicationForm.value)
|
||||
if (updated) {
|
||||
updateApplicationForm(updated)
|
||||
toast.add({ title: 'Success', description: 'Application form saved', color: 'success' })
|
||||
toast.add({ title: $t('common.success'), description: $t('applicationForms.saved'), color: 'success' })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,7 +123,7 @@ async function onSubmit() {
|
||||
if (applicationForm.value) {
|
||||
await submitApplicationForm(applicationForm.value.id)
|
||||
await navigateTo('/')
|
||||
toast.add({ title: 'Success', description: 'Application form submitted', color: 'success' })
|
||||
toast.add({ title: $t('common.success'), description: $t('applicationForms.submitted'), color: 'success' })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<template>
|
||||
<UDashboardPanel id="versions">
|
||||
<template #header>
|
||||
<UDashboardNavbar :title="`Versionen: ${applicationForm?.name}`">
|
||||
<UDashboardNavbar :title="$t('versions.pageTitle', { name: applicationForm?.name })">
|
||||
<template #leading>
|
||||
<UDashboardSidebarCollapse />
|
||||
</template>
|
||||
@@ -15,7 +15,12 @@
|
||||
|
||||
<template #body>
|
||||
<div class="p-6">
|
||||
<VersionHistory v-if="applicationForm" :application-form-id="applicationForm.id" :current-form="applicationForm" @restored="handleRestored" />
|
||||
<VersionHistory
|
||||
v-if="applicationForm"
|
||||
:application-form-id="applicationForm.id"
|
||||
:current-form="applicationForm"
|
||||
@restored="handleRestored"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</UDashboardPanel>
|
||||
@@ -25,6 +30,7 @@
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const { t: $t } = useI18n()
|
||||
|
||||
definePageMeta({
|
||||
key: (route) => `${route.params.id}-versions`
|
||||
@@ -36,8 +42,8 @@ const { applicationForm, navigationLinks: links, refresh } = await useApplicatio
|
||||
async function handleRestored() {
|
||||
await refresh()
|
||||
toast.add({
|
||||
title: 'Version wiederhergestellt',
|
||||
description: 'Das Formular wurde auf die ausgewählte Version zurückgesetzt.',
|
||||
title: $t('versions.restored'),
|
||||
description: $t('versions.restoredDescription'),
|
||||
color: 'success'
|
||||
})
|
||||
router.push(`/application-forms/${applicationForm.value.id}/0`)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<UDashboardPanel id="home">
|
||||
<template #header>
|
||||
<UDashboardNavbar title="Home" :ui="{ right: 'gap-3' }">
|
||||
<UDashboardNavbar :title="$t('common.home')" :ui="{ right: 'gap-3' }">
|
||||
<template #leading>
|
||||
<UDashboardSidebarCollapse />
|
||||
</template>
|
||||
@@ -18,9 +18,9 @@
|
||||
<div class="flex flex-col gap-4 sm:gap-6 lg:gap-12 w-full lg:max-w-4xl mx-auto">
|
||||
<div v-if="!canWriteApplicationForms" class="text-center py-12">
|
||||
<UIcon name="i-lucide-shield-x" class="w-16 h-16 mx-auto text-red-400 mb-4" />
|
||||
<h2 class="text-2xl font-semibold text-gray-700 mb-2">Keine Berechtigung</h2>
|
||||
<p class="text-gray-500 mb-4">Sie haben keine Berechtigung zum Erstellen von Anträgen.</p>
|
||||
<UButton to="/" class="mt-4"> Zurück zur Übersicht </UButton>
|
||||
<h2 class="text-2xl font-semibold text-gray-700 mb-2">{{ $t('applicationForms.noPermission') }}</h2>
|
||||
<p class="text-gray-500 mb-4">{{ $t('applicationForms.noPermissionDescription') }}</p>
|
||||
<UButton to="/" class="mt-4"> {{ $t('applicationForms.backToOverview') }} </UButton>
|
||||
</div>
|
||||
<div v-else-if="applicationFormTemplate">
|
||||
<FormStepperWithNavigation
|
||||
@@ -29,7 +29,7 @@
|
||||
@submit="onSubmit"
|
||||
@add-input-form="handleAddInputForm"
|
||||
>
|
||||
<UFormField label="Name" class="mb-4">
|
||||
<UFormField :label="$t('common.name')" class="mb-4">
|
||||
<UInput v-model="applicationFormTemplate.name" class="w-full" />
|
||||
</UFormField>
|
||||
</FormStepperWithNavigation>
|
||||
@@ -57,6 +57,7 @@ const { canWriteApplicationForms } = usePermissions()
|
||||
const userStore = useUserStore()
|
||||
const { selectedOrganization } = storeToRefs(userStore)
|
||||
const toast = useToast()
|
||||
const { t: $t } = useI18n()
|
||||
|
||||
const { data, error } = await useAsyncData<PagedApplicationFormDto>(
|
||||
'create-application-form',
|
||||
@@ -98,7 +99,7 @@ watch(
|
||||
async function onSave() {
|
||||
const applicationForm = await prepareAndCreateApplicationForm()
|
||||
if (applicationForm) {
|
||||
toast.add({ title: 'Success', description: 'Application form saved', color: 'success' })
|
||||
toast.add({ title: $t('common.success'), description: $t('applicationForms.saved'), color: 'success' })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +108,7 @@ async function onSubmit() {
|
||||
if (applicationForm) {
|
||||
await submitApplicationForm(applicationForm.id)
|
||||
await navigateTo('/')
|
||||
toast.add({ title: 'Success', description: 'Application form submitted', color: 'success' })
|
||||
toast.add({ title: $t('common.success'), description: $t('applicationForms.submitted'), color: 'success' })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<UDashboardPanel id="home">
|
||||
<template #header>
|
||||
<UDashboardNavbar title="Home" :ui="{ right: 'gap-3' }">
|
||||
<UDashboardNavbar :title="$t('common.home')" :ui="{ right: 'gap-3' }">
|
||||
<template #leading>
|
||||
<UDashboardSidebarCollapse />
|
||||
</template>
|
||||
|
||||
<template #right>
|
||||
Aktuelle Organisation
|
||||
{{ $t('organization.current') }}
|
||||
<USelect
|
||||
v-model="selectedOrganizationId"
|
||||
:items="organizations"
|
||||
@@ -20,7 +20,7 @@
|
||||
class="w-48"
|
||||
/>
|
||||
|
||||
<UTooltip text="Notifications" :shortcuts="['N']">
|
||||
<UTooltip :text="$t('notifications.tooltip')" :shortcuts="['N']">
|
||||
<UButton color="neutral" variant="ghost" square @click="isNotificationsSlideoverOpen = true">
|
||||
<UChip :show="unreadCount > 0" color="error" inset>
|
||||
<UIcon name="i-lucide-bell" class="size-5 shrink-0" />
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<UButton
|
||||
icon="i-lucide-circle-plus"
|
||||
label="Neuer Mitbestimmungsantrag"
|
||||
:label="$t('applicationForms.createNew')"
|
||||
to="/create"
|
||||
:disabled="!canWriteApplicationForms"
|
||||
size="xl"
|
||||
@@ -86,18 +86,18 @@
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<UIcon name="i-lucide-pencil" class="size-4 text-muted shrink-0" />
|
||||
<span class="text-muted">
|
||||
Zuletzt bearbeitet von
|
||||
{{ $t('applicationForms.lastEditedBy') }}
|
||||
<span class="font-medium text-highlighted">{{ applicationFormElem.lastModifiedBy.name }}</span>
|
||||
am {{ formatDate(applicationFormElem.modifiedAt) }}
|
||||
{{ $t('common.on') }} {{ formatDate(applicationFormElem.modifiedAt) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<UIcon name="i-lucide-user-plus" class="size-4 text-muted shrink-0" />
|
||||
<span class="text-muted">
|
||||
Erstellt von
|
||||
{{ $t('applicationForms.createdBy') }}
|
||||
<span class="font-medium text-highlighted">{{ applicationFormElem.createdBy.name }}</span>
|
||||
am {{ formatDate(applicationFormElem.createdAt) }}
|
||||
{{ $t('common.on') }} {{ formatDate(applicationFormElem.createdAt) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -122,6 +122,7 @@ const { getAllApplicationForms, deleteApplicationFormById } = useApplicationForm
|
||||
const route = useRoute()
|
||||
const userStore = useUserStore()
|
||||
const { organizations, selectedOrganization } = storeToRefs(userStore)
|
||||
const { t: $t } = useI18n()
|
||||
|
||||
// Inject notification state from layout
|
||||
const { isNotificationsSlideoverOpen, unreadCount } = inject('notificationState', {
|
||||
@@ -178,7 +179,7 @@ const applicationForms = computed({
|
||||
function getLinksForApplicationForm(applicationForm: ApplicationFormDto) {
|
||||
return [
|
||||
{
|
||||
label: 'Löschen',
|
||||
label: $t('common.delete'),
|
||||
icon: 'i-lucide-trash',
|
||||
to: `?delete&id=${applicationForm.id}`,
|
||||
disabled: !canWriteApplicationForms.value
|
||||
|
||||
@@ -1,40 +1,37 @@
|
||||
<template>
|
||||
<UCard variant="subtle">
|
||||
<template #header>
|
||||
<div class="text-center">
|
||||
<UIcon name="i-lucide-lock" class="mx-auto h-16 w-16 text-primary-500 mb-6" />
|
||||
<h1 class="text-3xl font-bold text-gray-900 mb-2">
|
||||
Welcome
|
||||
</h1>
|
||||
<p class="text-gray-600">
|
||||
You will be redirected to Keycloak to authenticate
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<UCard variant="subtle">
|
||||
<template #header>
|
||||
<div class="text-center">
|
||||
<UButton
|
||||
color="primary"
|
||||
size="xl"
|
||||
icon="i-lucide-log-in"
|
||||
@click="handleSignIn"
|
||||
>
|
||||
Sign in with Keycloak
|
||||
</UButton>
|
||||
<UIcon name="i-lucide-lock" class="mx-auto h-16 w-16 text-primary-500 mb-6" />
|
||||
<h1 class="text-3xl font-bold text-gray-900 mb-2">
|
||||
{{ $t('auth.welcome') }}
|
||||
</h1>
|
||||
<p class="text-gray-600">
|
||||
{{ $t('auth.redirectMessage') }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<div class="text-center text-xs text-gray-500">
|
||||
By signing in, you agree to our terms of service
|
||||
</div>
|
||||
</template>
|
||||
</UCard>
|
||||
<div class="text-center">
|
||||
<UButton color="primary" size="xl" icon="i-lucide-log-in" @click="handleSignIn">
|
||||
{{ $t('auth.signIn') }}
|
||||
</UButton>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="text-center text-xs text-gray-500">
|
||||
{{ $t('auth.termsAgreement') }}
|
||||
</div>
|
||||
</template>
|
||||
</UCard>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({ auth: false, layout: 'auth' })
|
||||
|
||||
useSeoMeta({ title: 'Login' })
|
||||
const { t: $t } = useI18n()
|
||||
|
||||
useSeoMeta({ title: $t('auth.login') })
|
||||
|
||||
function handleSignIn() {
|
||||
navigateTo('/auth/keycloak', { external: true })
|
||||
|
||||
Reference in New Issue
Block a user