Add locize cli script
This commit is contained in:
parent
828ea32a46
commit
6e7935a005
34
README.md
34
README.md
|
|
@ -101,19 +101,35 @@ Preferences -> Tools -> Actions on Save
|
|||
|
||||
## Translations
|
||||
|
||||
We use (vue-i18n)[https://kazupon.github.io/vue-i18n/] for translations
|
||||
and (vue-i18n-extract)[https://github.com/Spittal/vue-i18n-extract] for helper
|
||||
scripts.
|
||||
We use (Locize)[https://locize.com] together with (i18next)[https://www.i18next.com/]
|
||||
for translations on the Frontend.
|
||||
|
||||
```
|
||||
# will create a report on command line with missing translations
|
||||
npm run vue-i18n-extract
|
||||
The master for translated files is on Locize. Missing keys get automatically added to
|
||||
Locize, no manual step is needed.
|
||||
The translations are done on Locize.
|
||||
|
||||
# add missing translations to files, see docs for more options
|
||||
cd client
|
||||
npx vue-i18n-extract --add
|
||||
Please make sure that the required environment variables are set
|
||||
(see ./env_secrets/local_daniel.env for the values):
|
||||
|
||||
* LOCIZE_PROJECT_ID
|
||||
* LOCIZE_API_KEY
|
||||
|
||||
The files in ./client/locales are only used as reference and are not the master!
|
||||
|
||||
But you can still sync the local locale files with Locize with the following command.
|
||||
Please be careful and do not lose translations. The savest way is to only add the
|
||||
keys to the German file and let Locize translate them.
|
||||
|
||||
```bash
|
||||
npm run locize:sync
|
||||
```
|
||||
|
||||
### "_many" plural form in French and Italian
|
||||
|
||||
See https://github.com/i18next/i18next/issues/1691#issuecomment-968063348
|
||||
for an explanation why this plural form is needed in French and Italian.
|
||||
But not in German and English.
|
||||
|
||||
## Deployment to CapRover
|
||||
|
||||
### CapRover Dev (vbv-lernwelt.control.iterativ.ch)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Preview, setup } from "@storybook/vue3";
|
||||
import { createI18n } from "vue-i18n";
|
||||
import de from "../src/locales/de.json";
|
||||
import de from "../src/locales/de/translation.json";
|
||||
import "../tailwind.css";
|
||||
import { withVueRouter } from "./mockRouter";
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -16,7 +16,8 @@
|
|||
"storybook": "storybook dev -p 6006",
|
||||
"tailwind": "tailwindcss -i tailwind.css -o ../server/vbv_lernwelt/static/css/tailwind.css --watch",
|
||||
"test": "vitest run",
|
||||
"typecheck": "npm run codegen && vue-tsc --noEmit -p tsconfig.app.json --composite false"
|
||||
"typecheck": "npm run codegen && vue-tsc --noEmit -p tsconfig.app.json --composite false",
|
||||
"locize:sync": "locize sync --path ./src/locales"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/tailwindcss": "^0.1.3",
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
"graphql": "^16.6.0",
|
||||
"i18next-locize-backend": "^6.2.2",
|
||||
"i18next-vue": "^2.2.0",
|
||||
"locize": "^2.4.6",
|
||||
"lodash": "^4.17.21",
|
||||
"loglevel": "^1.8.0",
|
||||
"mitt": "^3.0.0",
|
||||
|
|
@ -79,6 +81,7 @@
|
|||
"eslint-plugin-storybook": "^0.6.12",
|
||||
"eslint-plugin-vue": "^9.15.0",
|
||||
"jsdom": "^22.1.0",
|
||||
"locize-cli": "^7.14.6",
|
||||
"postcss": "^8.4.14",
|
||||
"postcss-import": "^15.1.0",
|
||||
"prettier": "^2.8.8",
|
||||
|
|
|
|||
|
|
@ -1,9 +1,17 @@
|
|||
import type { AvailableLanguages } from "@/stores/user";
|
||||
import i18next from "i18next";
|
||||
import { locizePlugin } from "locize";
|
||||
|
||||
import Backend from "i18next-locize-backend";
|
||||
|
||||
import { nextTick } from "vue";
|
||||
|
||||
declare module "i18next" {
|
||||
interface CustomTypeOptions {
|
||||
returnNull: false;
|
||||
}
|
||||
}
|
||||
|
||||
export const SUPPORT_LOCALES: AvailableLanguages[] = ["de", "fr", "it"];
|
||||
|
||||
export function i18nextInit() {
|
||||
|
|
@ -15,13 +23,16 @@ export function i18nextInit() {
|
|||
// init i18next
|
||||
// for all options read: https://www.i18next.com/overview/configuration-options
|
||||
.use(Backend)
|
||||
.use(locizePlugin)
|
||||
.init({
|
||||
debug: true,
|
||||
fallbackLng: "de",
|
||||
defaultNS: "translation",
|
||||
returnNull: false,
|
||||
saveMissing: true,
|
||||
backend: {
|
||||
projectId: "7518c269-cbf7-4d25-bc5c-6ceba2a8b74b",
|
||||
apiKey: "0001d5bd-04c9-4ade-bedd-308a01d86860",
|
||||
projectId: import.meta.env.VITE_LOCIZE_PROJECTID,
|
||||
apiKey: import.meta.env.VITE_LOCIZE_API_KEY,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
{
|
||||
"Benutzername": "Benutzername",
|
||||
"Hier findest du die Trainerunterlagen (Lösungsblätter, Präsentationen etc.) für deinen Circle.": "Hier findest du die Trainerunterlagen (Lösungsblätter, Präsentationen etc.) für deinen Circle.",
|
||||
"Klicke auf den Button, um dich über SSO anzumelden oder zu registrieren.": "Klicke auf den Button, um dich über SSO anzumelden oder zu registrieren.",
|
||||
"MS Teams öffnen": "MS Teams öffnen",
|
||||
"Nächste Termine:": "Nächste Termine:",
|
||||
"Passwort": "Passwort",
|
||||
"SSO Login/Registration": "SSO Login/Registration",
|
||||
"Trainerunterlagen": "Trainerunterlagen",
|
||||
"Zur Zeit sind keine Termine vorhanden": "Zur Zeit sind keine Termine vorhanden",
|
||||
"welcome": "Hallo Welt",
|
||||
"assignment": {
|
||||
"acceptConditionsDisclaimer": "Bedingungen akzeptieren und Ergebnisse abgeben",
|
||||
"assessmentDocumentDisclaimer": "Diese geleitete Fallarbeit wird auf Grund des folgenden Beurteilungsinstrument bewertet:",
|
||||
|
|
@ -69,7 +64,8 @@
|
|||
"profileLink": "Profil anzeigen",
|
||||
"progress": "Teilnehmende / Status",
|
||||
"tasksDone": "Erledigte Transferaufträge von Teilnehmer.",
|
||||
"title": "Cockpit"
|
||||
"title": "Cockpit",
|
||||
"trainerFilesText": "Hier findest du die Trainerunterlagen (Lösungsblätter, Präsentationen etc.) für deinen Circle."
|
||||
},
|
||||
"competences": {
|
||||
"assessAgain": "Sich nochmals einschätzen",
|
||||
|
|
@ -92,6 +88,9 @@
|
|||
"nocourses": "Du wurdest noch keinem Lehrgang zugewiesen.",
|
||||
"welcome": "Willkommen, {{name}}"
|
||||
},
|
||||
"dueDates": {
|
||||
"nextDueDates": "Nächste Termine"
|
||||
},
|
||||
"feedback": {
|
||||
"answers": "Antworten",
|
||||
"areYouSatisfied": "Wie zufrieden bist du?",
|
||||
|
|
@ -143,10 +142,10 @@
|
|||
"certificate_other": "Zertifikate",
|
||||
"circles": "Circles",
|
||||
"close": "Schliessen",
|
||||
"exam_one": "Prüfung",
|
||||
"exam_other": "Prüfungen",
|
||||
"examResult_one": "Prüfungsresultat",
|
||||
"examResult_other": "Prüfungsresultate",
|
||||
"exam_one": "Prüfung",
|
||||
"exam_other": "Prüfungen",
|
||||
"feedback_one": "Feedback",
|
||||
"feedback_other": "Feedbacks",
|
||||
"introduction": "Einleitung",
|
||||
|
|
@ -190,6 +189,12 @@
|
|||
"topics": "Themen:",
|
||||
"welcomeBack": "Willkommen zurück in deinem Lehrgang:"
|
||||
},
|
||||
"login": {
|
||||
"demoLogin": "Demo Login",
|
||||
"login": "Login",
|
||||
"ssoLogin": "SSO Login/Registration",
|
||||
"ssoText": "Klicke auf den Button, um dich über SSO anzumelden oder zu registrieren."
|
||||
},
|
||||
"mainNavigation": {
|
||||
"logout": "Abmelden",
|
||||
"profile": "Profil"
|
||||
|
|
@ -231,5 +236,6 @@
|
|||
},
|
||||
"settings": {
|
||||
"emailNotifications": "Email Benachrichtigungen"
|
||||
}
|
||||
},
|
||||
"welcome": "Hallo Welt"
|
||||
}
|
||||
|
|
@ -1,11 +1,7 @@
|
|||
{
|
||||
"Benutzername": "Nom d’utilisateur",
|
||||
"Hier findest du die Trainerunterlagen (Lösungsblätter, Präsentationen etc.) für deinen Circle.": "Tu trouves ici les documents de formation (feuilles de solution, présentations, etc.) pour ton cercle.",
|
||||
"Klicke auf den Button, um dich über SSO anzumelden oder zu registrieren.": "Clique sur le bouton pour te connecter via le SSO ou t’inscrire.",
|
||||
"MS Teams öffnen": "Ouvrir MS Teams ",
|
||||
"Nächste Termine:": "Prochaines réunions :",
|
||||
"Passwort": "Mot de passe",
|
||||
"SSO Login/Registration": "Connexion SSO / Inscription",
|
||||
"Trainerunterlagen": "Documents du formateur / de la formatrice",
|
||||
"Zur Zeit sind keine Termine vorhanden": "Aucune réunion n’est prévue pour le moment",
|
||||
"assignment": {
|
||||
|
|
@ -68,7 +64,8 @@
|
|||
"profileLink": "Afficher le profil",
|
||||
"progress": "Personne participante / Statut",
|
||||
"tasksDone": "Exercices d’application terminés par les participants.",
|
||||
"title": "Cockpit"
|
||||
"title": "Cockpit",
|
||||
"trainerFilesText": "Tu trouves ici les documents de formation (feuilles de solution, présentations, etc.) pour ton cercle."
|
||||
},
|
||||
"competences": {
|
||||
"assessAgain": "S’évaluer à nouveau",
|
||||
|
|
@ -91,6 +88,9 @@
|
|||
"nocourses": "Tu n’as été affecté(e) à aucune formation encore.",
|
||||
"welcome": "Bienvenue, {{name}}"
|
||||
},
|
||||
"dueDates": {
|
||||
"nextDueDates": "Prochaines réunions"
|
||||
},
|
||||
"feedback": {
|
||||
"answers": "Réponses",
|
||||
"areYouSatisfied": "Quel est ton degré de satisfaction ?",
|
||||
|
|
@ -138,14 +138,18 @@
|
|||
"backCapitalized": "@.capitalize:general.back",
|
||||
"backToCircle": "Revenir au cercle",
|
||||
"backToLearningPath": "Revenir au programme de formation",
|
||||
"certificate_many": "Certificats",
|
||||
"certificate_one": "Certificat",
|
||||
"certificate_other": "Certificats",
|
||||
"circles": "Cercles",
|
||||
"close": "Fermer",
|
||||
"exam_one": "Examen",
|
||||
"exam_other": "Examens",
|
||||
"examResult_many": "Résultats de l’examen",
|
||||
"examResult_one": "Résultat de l’examen",
|
||||
"examResult_other": "Résultats de l’examen",
|
||||
"exam_many": "Examens",
|
||||
"exam_one": "Examen",
|
||||
"exam_other": "Examens",
|
||||
"feedback_many": "Feed-backs",
|
||||
"feedback_one": "Feed-back",
|
||||
"feedback_other": "Feed-backs",
|
||||
"introduction": "Introduction",
|
||||
|
|
@ -155,6 +159,7 @@
|
|||
"next": "Continuer",
|
||||
"nextStep": "Cela continue",
|
||||
"no": "Non",
|
||||
"notification_many": "Notifications",
|
||||
"notification_one": "Notification",
|
||||
"notification_other": "Notifications",
|
||||
"profileLink": "Détails",
|
||||
|
|
@ -167,6 +172,7 @@
|
|||
"start": "C’est parti !",
|
||||
"submission": "Remise",
|
||||
"title": "myAFA",
|
||||
"transferTask_many": "Exercices d’application",
|
||||
"transferTask_one": "Exercice d’application",
|
||||
"transferTask_other": "Exercices d’application",
|
||||
"yes": "Oui"
|
||||
|
|
@ -189,6 +195,12 @@
|
|||
"topics": "Thèmes :",
|
||||
"welcomeBack": "Cela fait plaisir de te revoir dans ta formation :"
|
||||
},
|
||||
"login": {
|
||||
"demoLogin": "Connexion Demo",
|
||||
"login": "Login",
|
||||
"ssoLogin": "Connexion SSO / Inscription",
|
||||
"ssoText": "Clique sur le bouton pour te connecter via le SSO ou t’inscrire."
|
||||
},
|
||||
"mainNavigation": {
|
||||
"logout": "Se déconnecter",
|
||||
"profile": "Profil"
|
||||
|
|
@ -196,6 +208,7 @@
|
|||
"mediaLibrary": {
|
||||
"handlungsfelder": {
|
||||
"description": "Trouve toutes les ressources des champs d’action, comme les outils didactiques, les liens et autres informations utiles.",
|
||||
"title_many": "Champs d’action",
|
||||
"title_one": "Champ d’action",
|
||||
"title_other": "Champs d’action"
|
||||
},
|
||||
|
|
@ -1,11 +1,7 @@
|
|||
{
|
||||
"Benutzername": "Nome utente",
|
||||
"Hier findest du die Trainerunterlagen (Lösungsblätter, Präsentationen etc.) für deinen Circle.": "Qui trovi i documenti del/della trainer (soluzioni, presentazioni ecc.) per il tuo Circle.",
|
||||
"Klicke auf den Button, um dich über SSO anzumelden oder zu registrieren.": "Clicca sul pulsante per effettuare il login o registrarti tramite SSO.",
|
||||
"MS Teams öffnen": "Aprire MS Teams",
|
||||
"Nächste Termine:": "Prossime scadenze:",
|
||||
"Passwort": "Password",
|
||||
"SSO Login/Registration": "Login/Registrazione SSO",
|
||||
"Trainerunterlagen": "Documenti del/della trainer",
|
||||
"Zur Zeit sind keine Termine vorhanden": "Al momento non ci sono scadenze",
|
||||
"assignment": {
|
||||
|
|
@ -68,7 +64,8 @@
|
|||
"profileLink": "Mostrare il profilo",
|
||||
"progress": "Partecipanti / Stato",
|
||||
"tasksDone": "Incarichi di trasferimento completati dal/dalla partecipante.",
|
||||
"title": "Cockpit"
|
||||
"title": "Cockpit",
|
||||
"trainerFilesText": "Qui trovi i documenti del/della trainer (soluzioni, presentazioni ecc.) per il tuo Circle."
|
||||
},
|
||||
"competences": {
|
||||
"assessAgain": "Nuova auto-valutazione",
|
||||
|
|
@ -91,6 +88,9 @@
|
|||
"nocourses": "Non sei ancora stato/a assegnato/a a nessun corso.",
|
||||
"welcome": "Ti diamo il benvenuto, {{name}}"
|
||||
},
|
||||
"dueDates": {
|
||||
"nextDueDates": "Prossime scadenze"
|
||||
},
|
||||
"feedback": {
|
||||
"answers": "Risposte",
|
||||
"areYouSatisfied": "Quanto sei soddisfatto/a?",
|
||||
|
|
@ -138,14 +138,18 @@
|
|||
"backCapitalized": "@.capitalize:general.back",
|
||||
"backToCircle": "Torna al Circle",
|
||||
"backToLearningPath": "Torna al percorso formativo",
|
||||
"certificate_many": "Certificati",
|
||||
"certificate_one": "Certificato",
|
||||
"certificate_other": "Certificati",
|
||||
"circles": "Circle",
|
||||
"close": "Chiudere",
|
||||
"exam_one": "Esame",
|
||||
"exam_other": "Esami",
|
||||
"examResult_many": "Risultati degli esami",
|
||||
"examResult_one": "Risultato dell’esame",
|
||||
"examResult_other": "Risultati degli esami",
|
||||
"exam_many": "Esami",
|
||||
"exam_one": "Esame",
|
||||
"exam_other": "Esami",
|
||||
"feedback_many": "Feedback",
|
||||
"feedback_one": "Feedback",
|
||||
"feedback_other": "Feedback",
|
||||
"introduction": "Introduzione",
|
||||
|
|
@ -155,6 +159,7 @@
|
|||
"next": "Avanti",
|
||||
"nextStep": "Continua",
|
||||
"no": "No",
|
||||
"notification_many": "Notifiche",
|
||||
"notification_one": "Notifica",
|
||||
"notification_other": "Notifiche",
|
||||
"profileLink": "Mostrare i dettagli",
|
||||
|
|
@ -167,6 +172,7 @@
|
|||
"start": "Si comincia",
|
||||
"submission": "Consegna",
|
||||
"title": "myAFA",
|
||||
"transferTask_many": "Incarichi di trasferimento",
|
||||
"transferTask_one": "Incarico di trasferimento",
|
||||
"transferTask_other": "Incarichi di trasferimento",
|
||||
"yes": "Sì"
|
||||
|
|
@ -189,6 +195,12 @@
|
|||
"topics": "Temi:",
|
||||
"welcomeBack": "Bentornato/a al tuo corso:"
|
||||
},
|
||||
"login": {
|
||||
"demoLogin": "Login Demo",
|
||||
"login": "Login",
|
||||
"ssoLogin": "Login/Registrazione SSO",
|
||||
"ssoText": "Clicca sul pulsante per effettuare il login o registrarti tramite SSO."
|
||||
},
|
||||
"mainNavigation": {
|
||||
"logout": "Logout",
|
||||
"profile": "Profilo"
|
||||
|
|
@ -196,6 +208,7 @@
|
|||
"mediaLibrary": {
|
||||
"handlungsfelder": {
|
||||
"description": "Trova tutte le risorse dei campi d’azione, come materiali didattici, link e altre informazioni utili.",
|
||||
"title_many": "Campi d’azione",
|
||||
"title_one": "Campo d’azione",
|
||||
"title_other": "Campi d’azione"
|
||||
},
|
||||
|
|
@ -25,8 +25,7 @@ const userStore = useUserStore();
|
|||
<template>
|
||||
<main class="bg-gray-200 lg:px-12 lg:py-12">
|
||||
<div class="container-medium">
|
||||
<h1 class="mb-8">Login</h1>
|
||||
<h2>{{ $t("welcome") }}</h2>
|
||||
<h1 class="mb-8">{{ $t("login.login") }}</h1>
|
||||
|
||||
<form
|
||||
v-if="loginMethod === 'local'"
|
||||
|
|
@ -74,20 +73,16 @@ const userStore = useUserStore();
|
|||
|
||||
<div v-if="loginMethod === 'sso'" class="bg-white p-4 lg:p-8">
|
||||
<p>
|
||||
{{
|
||||
$t(
|
||||
"Klicke auf den Button, um dich über SSO anzumelden oder zu registrieren."
|
||||
)
|
||||
}}
|
||||
{{ $t("login.ssoText") }}
|
||||
</p>
|
||||
<p class="btn-primary mt-8">
|
||||
<a :href="`/sso/login/?lang=${userStore.language}`">
|
||||
{{ $t("SSO Login/Registration") }}
|
||||
{{ $t("login.ssoLogin") }}
|
||||
</a>
|
||||
</p>
|
||||
<p class="mt-8">
|
||||
<a href="/login-local">
|
||||
{{ $t("Demo Login") }}
|
||||
{{ $t("login.demoLogin") }}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -99,11 +99,7 @@ function setActiveClasses(translationKey: string) {
|
|||
{{ $t("Trainerunterlagen") }}
|
||||
</h3>
|
||||
<div class="mb-4">
|
||||
{{
|
||||
$t(
|
||||
"Hier findest du die Trainerunterlagen (Lösungsblätter, Präsentationen etc.) für deinen Circle."
|
||||
)
|
||||
}}
|
||||
{{ $t("cockpit.trainerFilesText") }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<p class="mb-4 font-bold">{{ $t("Nächste Termine:") }}</p>
|
||||
<p class="mb-4 font-bold">{{ $t("dueDates.nextDueDates") }}:</p>
|
||||
<!-- ul>
|
||||
<li class="border-b border-t py-3">
|
||||
<p class="pr-12">24. November 2022, 11 Uhr - Austausch mit Trainer</p>
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -506,11 +506,12 @@ CSP_DEFAULT_SRC = [
|
|||
"ws://127.0.0.1:5173",
|
||||
"localhost:8000",
|
||||
"localhost:8001",
|
||||
"*.locize.app",
|
||||
"blob:",
|
||||
"data:",
|
||||
"http://*",
|
||||
]
|
||||
CSP_FRAME_ANCESTORS = ("'self'",)
|
||||
CSP_FRAME_ANCESTORS = ("'self'", "https://www.locize.app")
|
||||
|
||||
SPECTACULAR_SETTINGS = {
|
||||
"TITLE": "VBV Lernwelt API",
|
||||
|
|
|
|||
Loading…
Reference in New Issue