Skip to content

Commit 8c7cf4e

Browse files
committed
frontend/files/masked files: fix typo in reported in #8435
1 parent 7b579fe commit 8c7cf4e

24 files changed

+144
-37
lines changed

src/.claude/settings.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,17 @@
1717
"WebFetch(domain:cocalc.com)",
1818
"WebFetch(domain:doc.cocalc.com)",
1919
"WebFetch(domain:docs.anthropic.com)",
20-
"WebFetch(domain:github.com)"
20+
"WebFetch(domain:github.com)",
21+
"Bash(git checkout:*)",
22+
"Bash(git push:*)",
23+
"Bash(NODE_OPTIONS=--max-old-space-size=8192 ../node_modules/.bin/tsc --noEmit)",
24+
"Bash(docker run:*)",
25+
"Bash(../node_modules/.bin/tsc:*)",
26+
"Bash(npm view:*)",
27+
"WebFetch(domain:www.anthropic.com)",
28+
"WebFetch(domain:mistral.ai)",
29+
"Bash(pnpm i18n:*)",
30+
"WebFetch(domain:simplelocalize.io)"
2131
],
2232
"deny": []
2333
}

src/CLAUDE.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,40 @@ CoCalc is organized as a monorepo with key packages:
149149
- REFUSE to modify files when the git repository is on the `master` or `main` branch.
150150
- NEVER proactively create documentation files (`*.md`) or README files. Only create documentation files if explicitly requested by the User.
151151

152+
## React-intl / Internationalization (i18n)
153+
154+
CoCalc uses react-intl for internationalization with SimpleLocalize as the translation platform.
155+
156+
### Translation ID Naming Convention
157+
158+
Translation IDs follow a hierarchical pattern: `[directory].[subdir].[filename].[aspect].[label|title|tooltip|...]`
159+
160+
Examples:
161+
- `labels.masked_files` - for common UI labels
162+
- `account.sign-out.button.title` - for account sign-out dialog
163+
- `command.generic.force_build.label` - for command labels
164+
165+
### Translation Workflow
166+
167+
**For new translation keys:**
168+
1. Add the translation to source code (e.g., `packages/frontend/i18n/common.ts`)
169+
2. Run `pnpm i18n:extract` - updates `extracted.json` from source code
170+
3. Run `pnpm i18n:upload` - sends new strings to SimpleLocalize
171+
4. New keys are automatically translated to all languages
172+
5. Run `pnpm i18n:download` - fetches translations
173+
6. Run `pnpm i18n:compile` - compiles translation files
174+
175+
**For editing existing translation keys:**
176+
Same flow as above, but **before 3. i18n:upload**, delete the key. Only new keys are auto-translated. `pnpm i18n:delete [id]`.
177+
178+
### Translation File Structure
179+
180+
- `packages/frontend/i18n/README.md` - more information
181+
- `packages/frontend/i18n/common.ts` - shared translation definitions
182+
- `packages/frontend/i18n/extracted.json` - auto-generated, do not edit manually
183+
- `packages/frontend/i18n/[locale].json` - downloaded translations per language
184+
- `packages/frontend/i18n/[locale].compiled.json` - compiled for runtime use
185+
152186
# Ignore
153187

154188
- Ignore files covered by `.gitignore`
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
# Delete specific translation keys from SimpleLocalize
3+
# Usage: ./delete.sh key1 [key2 key3 ...]
4+
5+
if [ $# -eq 0 ]; then
6+
echo "Usage: $0 key1 [key2 key3 ...]"
7+
echo "Delete one or more translation keys from SimpleLocalize"
8+
echo ""
9+
echo "Example:"
10+
echo " $0 labels.masked_files"
11+
echo " $0 labels.masked_files account.sign-out.button.title"
12+
exit 1
13+
fi
14+
15+
# Check if SIMPLELOCALIZE_KEY is set
16+
if [ -z "${SIMPLELOCALIZE_KEY}" ]; then
17+
echo "Error: SIMPLELOCALIZE_KEY is not set or is empty. Please provide a valid API key." >&2
18+
exit 1
19+
fi
20+
21+
echo "Deleting translation keys from SimpleLocalize..."
22+
23+
# Loop through all provided keys
24+
for key in "$@"; do
25+
echo
26+
echo "Deleting '$key':"
27+
curl \
28+
--location \
29+
--request DELETE "https://api.simplelocalize.io/api/v1/translation-keys?key=$key" \
30+
--header "X-SimpleLocalize-Token: $SIMPLELOCALIZE_KEY"
31+
done
32+
33+
echo
34+
echo
35+
echo "Done! Now you should run:"
36+
echo " pnpm i18n:upload (to re-upload the key with new content)"
37+
echo " pnpm i18n:download (to fetch updated translations)"
38+
echo " pnpm i18n:compile (to compile translation files)"

src/packages/frontend/i18n/bin/upload.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,27 @@ curl -s -X 'POST' 'https://api.simplelocalize.io/api/v2/jobs/auto-translate' \
1919
-H "X-SimpleLocalize-Token: $SIMPLELOCALIZE_KEY" \
2020
-H 'Content-Type: application/json' \
2121
-d '{"options": []}' | jq '.data|length'
22+
23+
echo "Waiting for auto-translation jobs to complete..."
24+
25+
# Wait for all auto-translation jobs to complete
26+
while true; do
27+
sleep 3
28+
29+
# Get all active jobs
30+
jobs_response=$(curl -s -X 'GET' 'https://api.simplelocalize.io/api/v1/jobs' \
31+
-H 'accept: application/json' \
32+
-H "X-SimpleLocalize-Token: $SIMPLELOCALIZE_KEY")
33+
34+
# Count jobs that are not yet completed (state != "SUCCESS")
35+
total_jobs=$(echo "$jobs_response" | jq '.data | length')
36+
success_jobs=$(echo "$jobs_response" | jq '[.data[] | select(.state == "SUCCESS")] | length')
37+
active_jobs=$((total_jobs - success_jobs))
38+
39+
if [ "$active_jobs" -eq 0 ]; then
40+
echo "✓ All auto-translation jobs completed!"
41+
break
42+
else
43+
echo " $active_jobs job(s) still running..."
44+
fi
45+
done

src/packages/frontend/i18n/common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ export const labels = defineMessages({
489489
masked_files: {
490490
id: "labels.masked_files",
491491
defaultMessage:
492-
"{masked, select, true {Hide masked files} other {Show masked files}}. Masked files are autogenerated or temporary files, which are not meant to be edited. They are be grayed out.",
492+
"{masked, select, true {Hide masked files} other {Show masked files}}. Masked files are autogenerated or temporary files, which are not meant to be edited. They are grayed out.",
493493
description: "show/hide masked files in a file-explorer in a UI.",
494494
},
495495
folder: {

src/packages/frontend/i18n/trans/ar_EG.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@
946946
"labels.linux_terminal": "لينكس تيرمنال",
947947
"labels.loading": "جار التحميل...",
948948
"labels.log": "تسجيل",
949-
"labels.masked_files": "{masked, select, true {إخفاء الملفات المخفية} other {إظهار الملفات المخفية}}. الملفات المخفية هي ملفات تم إنشاؤها تلقائيًا أو ملفات مؤقتة، ولا يُقصد تحريرها. ستكون باللون الرمادي.",
949+
"labels.masked_files": "{masked, select, true {إخفاء الملفات المقنعة} other {إظهار الملفات المقنعة}}. الملفات المقنعة هي ملفات تم إنشاؤها تلقائيًا أو ملفات مؤقتة، والتي لا يُقصد تعديلها. يتم تظليلها باللون الرمادي.",
950950
"labels.message.plural": "{num, plural, one {رسالة} other {رسائل}}",
951951
"labels.messages": "رسائل",
952952
"labels.messages.all_messages": "جميع الرسائل",
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "إضافة الترخيص",
12231223
"project.no-internet-modal.info": "<strong>تم تعطيل الوصول إلى الإنترنت لهذا المشروع.</strong> هذا التقييد يمنع تثبيت حزم بايثون (pip، conda) أو حزم R، واستخدام Git لاستنساخ المستودعات، وتنزيل مجموعات البيانات أو الوصول إلى واجهات برمجة التطبيقات. قد تتعطل الأوامر التي تحاول الوصول إلى الإنترنت أو تفشل في الاكتمال، حيث يتم حظر الاتصالات الشبكية لمنع سوء الاستخدام. <A>تعرف على المزيد</A>.",
12241224
"project.no-internet-modal.message": "لحل هذه المشكلة، <A1>تحتاج إلى تطبيق</A1> <A2>ترخيص صالح</A2> يوفر ترقيات أو <A3>شراء ترخيص</A3>.",
1225-
"project.no-internet-modal.title": "لا يوجد اتصال بالإنترنت",
1225+
"project.no-internet-modal.title": "المشروع \"{name}\" ليس لديه وصول إلى الإنترنت",
12261226
"project.open_file.what": "افتح الملف \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "تخطيط شريط النشاط",
12281228
"project.page.activity-bar.explanation": "هذه الميزة تعدل وظيفة شريط الأزرار في الجانب الأيسر من المشروع. بشكل افتراضي، تعرض الأزرار صفحات كاملة وعلامات صغيرة للوحات المنبثقة. عند اختيار خيار \"الصفحات الكاملة\"، يتم عرض الأزرار فقط، وتفتح الصفحات الكاملة عند النقر. وعلى العكس، عند اختيار وضع \"اللوحات المنبثقة\"، تتوسع اللوحات المنبثقة فقط عند النقر. في كلتا الحالتين الأخيرتين، يمكن عرض نوع اللوحة البديل بالنقر مع الضغط على مفتاح Shift على الزر المقابل.",

src/packages/frontend/i18n/trans/de_DE.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@
946946
"labels.linux_terminal": "Linux-Terminal",
947947
"labels.loading": "Laden...",
948948
"labels.log": "Protokoll",
949-
"labels.masked_files": "{masked, select, true {Maskierte Dateien verbergen} other {Maskierte Dateien anzeigen}}. Maskierte Dateien sind automatisch generierte oder temporäre Dateien, die nicht bearbeitet werden sollen. Sie werden ausgegraut.",
949+
"labels.masked_files": "{masked, select, true {Maskierte Dateien ausblenden} other {Maskierte Dateien anzeigen}}. Maskierte Dateien sind automatisch generierte oder temporäre Dateien, die nicht bearbeitet werden sollen. Sie sind ausgegraut.",
950950
"labels.message.plural": "{num, plural, one {Nachricht} other {Nachrichten}}",
951951
"labels.messages": "Nachrichten",
952952
"labels.messages.all_messages": "Alle Nachrichten",
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "Lizenz hinzufügen",
12231223
"project.no-internet-modal.info": "<strong>Der Internetzugang ist für dieses Projekt deaktiviert.</strong> Diese Einschränkung verhindert die Installation von Python-Paketen (pip, conda) oder R-Paketen, die Verwendung von Git zum Klonen von Repositories, das Herunterladen von Datensätzen oder den Zugriff auf APIs. Befehle, die versuchen, auf das Internet zuzugreifen, können hängen bleiben oder nicht abgeschlossen werden, da Netzwerkverbindungen blockiert sind, um Missbrauch zu verhindern. <A>Mehr erfahren</A>.",
12241224
"project.no-internet-modal.message": "Um dies zu beheben, müssen Sie eine <A2>gültige Lizenz</A2> anwenden, die Upgrades bereitstellt oder eine <A3>Lizenz kaufen</A3>.",
1225-
"project.no-internet-modal.title": "Kein Internetzugang",
1225+
"project.no-internet-modal.title": "Projekt \"{name}\" hat keinen Internetzugang",
12261226
"project.open_file.what": "öffne die Datei \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "Layout der Aktivitätsleiste",
12281228
"project.page.activity-bar.explanation": "Diese Funktion ändert die Funktionalität der linken Seitenleiste des Projekts. Standardmäßig werden Schaltflächen für ganze Seiten und kleine Caret-Zeichen für Flyout-Panels angezeigt. Bei Auswahl der Option \"ganze Seiten\" werden nur Schaltflächen angezeigt, die beim Klicken ganze Seiten öffnen. Umgekehrt, wenn die Option \"Flyout-Panels\" gewählt wird, erweitern sich nur Flyout-Panels beim Klicken. In beiden letzteren Fällen kann der alternative Paneltyp durch Shift-Klicken auf die entsprechende Schaltfläche angezeigt werden.",

src/packages/frontend/i18n/trans/es_ES.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@
946946
"labels.linux_terminal": "Terminal de Linux",
947947
"labels.loading": "Cargando...",
948948
"labels.log": "Registro",
949-
"labels.masked_files": "{masked, select, true {Ocultar archivos enmascarados} other {Mostrar archivos enmascarados}}. Los archivos enmascarados son archivos autogenerados o temporales, que no están destinados a ser editados. Estarán atenuados.",
949+
"labels.masked_files": "{masked, select, true {Ocultar archivos enmascarados} other {Mostrar archivos enmascarados}}. Los archivos enmascarados son archivos autogenerados o temporales, que no están destinados a ser editados. Están atenuados.",
950950
"labels.message.plural": "{num, plural, one {mensaje} other {mensajes}}",
951951
"labels.messages": "Mensajes",
952952
"labels.messages.all_messages": "Todos los mensajes",
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "Agregar licencia",
12231223
"project.no-internet-modal.info": "<strong>El acceso a Internet está desactivado para este proyecto.</strong> Esta restricción impide instalar paquetes de Python (pip, conda) o paquetes de R, usar Git para clonar repositorios, descargar conjuntos de datos o acceder a APIs. Los comandos que intenten acceder a Internet pueden quedar en espera o no completarse, ya que las conexiones de red están bloqueadas para prevenir abusos. <A>Más información</A>.",
12241224
"project.no-internet-modal.message": "Para solucionar esto, <A1>necesitas aplicar</A1> una <A2>licencia válida</A2> que proporcione actualizaciones o <A3>comprar una licencia</A3>.",
1225-
"project.no-internet-modal.title": "Sin acceso a Internet",
1225+
"project.no-internet-modal.title": "El proyecto \"{name}\" no tiene acceso a Internet",
12261226
"project.open_file.what": "abre el archivo \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "Diseño de la barra de actividad",
12281228
"project.page.activity-bar.explanation": "Esta función modifica la funcionalidad de la barra de botones en el lado izquierdo del proyecto. Por defecto, muestra botones para páginas completas y pequeños signos de acento para paneles desplegables. Al seleccionar la opción de \"páginas completas\", solo se muestran botones, y estos abren páginas completas al hacer clic. Por el contrario, al optar por el modo de \"paneles desplegables\", solo los paneles desplegables se expanden al hacer clic. En ambos casos, el tipo de panel alternativo se puede mostrar haciendo clic con la tecla shift presionada en el botón correspondiente.",

src/packages/frontend/i18n/trans/es_PV.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@
946946
"labels.linux_terminal": "Linux Terminala",
947947
"labels.loading": "Kargatzen...",
948948
"labels.log": "Egunkari",
949-
"labels.masked_files": "{masked, select, true {Maskatutako fitxategiak ezkutatu} other {Maskatutako fitxategiak erakutsi}}. Maskatutako fitxategiak automatikoki sortutako edo behin-behineko fitxategiak dira, ez dira editatzeko pentsatuta. Kolore grisarekin agertuko dira.",
949+
"labels.masked_files": "{masked, select, true {Ezkutatu maskaratutako fitxategiak} other {Erakutsi maskaratutako fitxategiak}}. Maskaratutako fitxategiak automatikoki sortutako edo behin-behineko fitxategiak dira, eta ez dira editatzeko pentsatuta. Grisez agertzen dira.",
950950
"labels.message.plural": "{num, plural, one {Mezua} other {Mezuak}}",
951951
"labels.messages": "Mezuak",
952952
"labels.messages.all_messages": "Mezu guztiak",
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "Gehitu Lizentzia",
12231223
"project.no-internet-modal.info": "<strong>Interneteko sarbidea desgaituta dago proiektu honetarako.</strong> Murrizketa honek Python paketeak (pip, conda) edo R paketeak instalatzea eragozten du, Git erabiliz biltegiak klonatzea, datu-multzoak deskargatzea edo APIetara sartzea. Internetera sartzen saiatzen diren komandoek zintzilik geratu edo amaitzea huts egin dezakete, sareko konexioak blokeatuta daudelako gehiegikeria saihesteko. <A>Gehiago ikasi</A>.",
12241224
"project.no-internet-modal.message": "Hau konpontzeko, <A1>behar duzu aplikatu</A1> <A2>baliozko lizentzia</A2> eguneratzeak ematen dituzten edo <A3>lizentzia erosi</A3>.",
1225-
"project.no-internet-modal.title": "Ez dago Interneteko sarbiderik",
1225+
"project.no-internet-modal.title": "Proiektuak \"{name}\" ez dauka interneteko sarbiderik",
12261226
"project.open_file.what": "ireki fitxategia \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "Aktibitate barra diseinua",
12281228
"project.page.activity-bar.explanation": "Ezaugarri honek proiektuaren ezkerreko jarduera-barraren funtzionalitatea aldatzen du. Lehenespenez, orrialde osoetarako botoiak eta flyout panelentzako kurtsore txikiak erakusten ditu. \"Orrialde osoak\" aukera hautatzean, botoiak soilik erakusten dira, eta horiek klik egitean orrialde osoak irekitzen dituzte. Aldiz, \"flyout panelak\" modua aukeratzean, flyout panelak soilik zabaltzen dira klik egitean. Azken bi kasuetan, panel mota alternatiboa dagokion botoia shift-klik eginez erakuts daiteke.",

src/packages/frontend/i18n/trans/fr_FR.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "Ajouter une licence",
12231223
"project.no-internet-modal.info": "<strong>L'accès à Internet est désactivé pour ce projet.</strong> Cette restriction empêche l'installation de packages Python (pip, conda) ou de packages R, l'utilisation de Git pour cloner des dépôts, le téléchargement de jeux de données ou l'accès aux APIs. Les commandes qui tentent d'accéder à Internet peuvent se bloquer ou échouer à se terminer, car les connexions réseau sont bloquées pour prévenir les abus. <A>En savoir plus</A>.",
12241224
"project.no-internet-modal.message": "Pour résoudre ce problème, vous <A1>devez appliquer</A1> une <A2>licence valide</A2> offrant des mises à jour ou <A3>acheter une licence</A3>.",
1225-
"project.no-internet-modal.title": "Pas d'accès Internet",
1225+
"project.no-internet-modal.title": "Le projet \"{name}\" n'a pas d'accès à Internet",
12261226
"project.open_file.what": "ouvrir le fichier \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "Disposition de la barre d'activités",
12281228
"project.page.activity-bar.explanation": "Cette fonctionnalité modifie la fonctionnalité de la barre de boutons à gauche du projet. Par défaut, elle affiche des boutons pour les pages complètes et de petits signes de chevron pour les panneaux déroulants. En sélectionnant l'option \"pages complètes\", seuls les boutons sont affichés et ils ouvrent des pages complètes en cliquant dessus. À l'inverse, en choisissant le mode \"panneaux déroulants\", seuls les panneaux déroulants se déploient en cliquant dessus. Dans les deux derniers cas, le type de panneau alternatif peut être affiché en cliquant tout en maintenant la touche majuscule sur le bouton correspondant.",

0 commit comments

Comments
 (0)