diff --git a/Parlance/ClientApp/public/resources/translations/cs-CZ/translation.json b/Parlance/ClientApp/public/resources/translations/cs-CZ/translation.json index ae69e57b..48b22672 100644 --- a/Parlance/ClientApp/public/resources/translations/cs-CZ/translation.json +++ b/Parlance/ClientApp/public/resources/translations/cs-CZ/translation.json @@ -80,12 +80,17 @@ "CLOSE": "", "COMMENTS": "", "COMMENT_ADD": "", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS_few": "", "COMMENT_OPEN_THREADS_one": "", "COMMENT_OPEN_THREADS_other": "", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "", "COMMENT_POSTING_AS_PROMPT": "", "COMMENT_SEND_FAILURE_PROMPT": "", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "", "CONFIRM_PASSWORD_PROMPT": "", "CONNECTED_GLOSSARIES": "", @@ -177,6 +182,10 @@ "OK": "", "OTHER_LANGUAGES": "", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "", "PARLANCE_ADMINISTRATION_DESCRIPTION": "", "PARLANCE_ON_GIT": "", diff --git a/Parlance/ClientApp/public/resources/translations/da/translation.json b/Parlance/ClientApp/public/resources/translations/da/translation.json index 2924ca45..6958b662 100644 --- a/Parlance/ClientApp/public/resources/translations/da/translation.json +++ b/Parlance/ClientApp/public/resources/translations/da/translation.json @@ -81,10 +81,15 @@ "CLOSE": "Luk", "COMMENTS": "", "COMMENT_ADD": "", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS": "", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "", "COMMENT_POSTING_AS_PROMPT": "", "COMMENT_SEND_FAILURE_PROMPT": "", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "Bekræft adgangskode", "CONFIRM_PASSWORD_PROMPT": "Bekræft adgangskoden til din konto", "CONNECTED_GLOSSARIES": "", @@ -177,6 +182,10 @@ "OK": "", "OTHER_LANGUAGES": "", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "", "PARLANCE_ADMINISTRATION_DESCRIPTION": "", "PARLANCE_ON_GIT": "", diff --git a/Parlance/ClientApp/public/resources/translations/de/translation.json b/Parlance/ClientApp/public/resources/translations/de/translation.json index 034e62b3..2cb9367c 100644 --- a/Parlance/ClientApp/public/resources/translations/de/translation.json +++ b/Parlance/ClientApp/public/resources/translations/de/translation.json @@ -81,10 +81,15 @@ "CLOSE": "Schließen", "COMMENTS": "", "COMMENT_ADD": "", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS": "", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "", "COMMENT_POSTING_AS_PROMPT": "", "COMMENT_SEND_FAILURE_PROMPT": "", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "Passwort bestätigen", "CONFIRM_PASSWORD_PROMPT": "Bestätige das Passwort für deinen Account", "CONNECTED_GLOSSARIES": "", @@ -177,6 +182,10 @@ "OK": "Ok", "OTHER_LANGUAGES": "", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "Parlance Administration", "PARLANCE_ADMINISTRATION_DESCRIPTION": "Konfiguriere den Parlance server", "PARLANCE_ON_GIT": "", diff --git a/Parlance/ClientApp/public/resources/translations/en/translation.json b/Parlance/ClientApp/public/resources/translations/en/translation.json index 957e6f00..cc86b5f5 100644 --- a/Parlance/ClientApp/public/resources/translations/en/translation.json +++ b/Parlance/ClientApp/public/resources/translations/en/translation.json @@ -83,11 +83,16 @@ "CLOSE": "Close", "COMMENTS": "Comments", "COMMENT_ADD": "Add Comment", + "COMMENT_GO_TO_STRING": "Go to string", + "COMMENT_NOT_LOGGED_IN_PROMPT": "Log in to write a comment", "COMMENT_OPEN_THREADS_one": "{{count}} open thread", "COMMENT_OPEN_THREADS_other": "{{count}} open threads", + "COMMENT_ORIGINAL_TRANSLATION": "Original Translation", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "The translation entry no longer exists", "COMMENT_POST": "Post Comment", "COMMENT_POSTING_AS_PROMPT": "Posting as {{user}}", "COMMENT_SEND_FAILURE_PROMPT": "Unable to send the comment", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "{{ user }}'s profile picture", "CONFIRM_PASSWORD": "Confirm Password", "CONFIRM_PASSWORD_PROMPT": "Confirm the password for your account", "CONNECTED_GLOSSARIES": "Connected Glossaries", @@ -180,6 +185,10 @@ "OK": "OK", "OTHER_LANGUAGES": "Other Languages", "OVERVIEW": "Overview", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "No open threads", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "There are no open comment threads in this file right now", + "OVERVIEW_GO_TO_COMMENTS": "Go to comments", + "OVERVIEW_STATS": "Stats", "PARLANCE_ADMINISTRATION": "Parlance Administration", "PARLANCE_ADMINISTRATION_DESCRIPTION": "Configure the Parlance server", "PARLANCE_ON_GIT": "Parlance on Git", diff --git a/Parlance/ClientApp/public/resources/translations/es/translation.json b/Parlance/ClientApp/public/resources/translations/es/translation.json index e6feca45..a276b961 100644 --- a/Parlance/ClientApp/public/resources/translations/es/translation.json +++ b/Parlance/ClientApp/public/resources/translations/es/translation.json @@ -81,10 +81,15 @@ "CLOSE": "", "COMMENTS": "", "COMMENT_ADD": "", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS": "", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "", "COMMENT_POSTING_AS_PROMPT": "", "COMMENT_SEND_FAILURE_PROMPT": "", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "", "CONFIRM_PASSWORD_PROMPT": "", "CONNECTED_GLOSSARIES": "", @@ -177,6 +182,10 @@ "OK": "", "OTHER_LANGUAGES": "", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "", "PARLANCE_ADMINISTRATION_DESCRIPTION": "", "PARLANCE_ON_GIT": "", diff --git a/Parlance/ClientApp/public/resources/translations/fr-CA/translation.json b/Parlance/ClientApp/public/resources/translations/fr-CA/translation.json index 5f1ed5f3..f55f776e 100644 --- a/Parlance/ClientApp/public/resources/translations/fr-CA/translation.json +++ b/Parlance/ClientApp/public/resources/translations/fr-CA/translation.json @@ -81,11 +81,16 @@ "CLOSE": "Fermer", "COMMENTS": "", "COMMENT_ADD": "", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS_one": "", "COMMENT_OPEN_THREADS_other": "", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "", "COMMENT_POSTING_AS_PROMPT": "", "COMMENT_SEND_FAILURE_PROMPT": "", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "", "CONFIRM_PASSWORD_PROMPT": "", "CONNECTED_GLOSSARIES": "", @@ -178,6 +183,10 @@ "OK": "", "OTHER_LANGUAGES": "", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "", "PARLANCE_ADMINISTRATION_DESCRIPTION": "", "PARLANCE_ON_GIT": "", diff --git a/Parlance/ClientApp/public/resources/translations/he-IL/translation.json b/Parlance/ClientApp/public/resources/translations/he-IL/translation.json index 1e52bb5b..85639d14 100644 --- a/Parlance/ClientApp/public/resources/translations/he-IL/translation.json +++ b/Parlance/ClientApp/public/resources/translations/he-IL/translation.json @@ -31,16 +31,16 @@ "ACTIONS": "פעולות", "ADD_ENTRY_TO_GLOSSARY": "הוסף ערך למילון", "ADD_GLOSSARY": "הוסף מילון", - "ADD_GLOSSARY_CONNECT_PROJECT_PROMPT": "חבר מילון לפרויקט על ידי ביקור בפרויקט ובחירה ב-\u0022ניהול מילונים\u0022", + "ADD_GLOSSARY_CONNECT_PROJECT_PROMPT": "חבר מילון לפרויקט על ידי ביקור בפרויקט ובחירה ב-\"ניהול מילונים\"", "ADD_GLOSSARY_ERROR": "לא ניתן להוסיף מילון", "ADD_GLOSSARY_PROJECTS_CONNECTED_one": "פרויקט {{count}} מחובר", - "ADD_GLOSSARY_PROJECTS_CONNECTED_two": "{{count}} פרוייקטים מחוברים", "ADD_GLOSSARY_PROJECTS_CONNECTED_other": "{{count}} פרויקטים מחוברים", + "ADD_GLOSSARY_PROJECTS_CONNECTED_two": "{{count}} פרוייקטים מחוברים", "ADD_PROJECT": "הוסף פרויקט חדש", "ADD_PROJECT_ERROR": "לא ניתן להוסיף פרויקט חדש", "ADD_PROJECT_ERROR_PROMPT": "לא ניתן להוסיף את הפרויקט. נסה שוב במועד מאוחר יותר.", "ADD_PROJECT_PROMPT_1": "הזן את הנתונים הדרושים כדי להוסיף פרויקט", - "ADD_PROJECT_PROMPT_2": "ודא שהפרויקט מכיל קובץ \u003C1\u003E.parlance.json\u003C/1\u003E בשורש תיקיית הפרויקט.", + "ADD_PROJECT_PROMPT_2": "ודא שהפרויקט מכיל קובץ <1>.parlance.json בשורש תיקיית הפרויקט.", "ADD_TO_GLOSSARY": "הוסף למילון", "ADD_TO_GLOSSARY_CONFIRM": "הוסף ל-{{glossary}}", "ADD_TO_GLOSSARY_ERROR_NO_TERM": "הזן את המונח להוספה למילון", @@ -84,12 +84,17 @@ "CLOSE": "סגור", "COMMENTS": "תגובות", "COMMENT_ADD": "הוסף תגובה", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS_one": "פתוח שרשור תגובות {{count}}", - "COMMENT_OPEN_THREADS_two": "פתוחים {{count}} שרשורי תגובות", "COMMENT_OPEN_THREADS_other": "פתוחים {{count}} שרשורי תגובות", + "COMMENT_OPEN_THREADS_two": "פתוחים {{count}} שרשורי תגובות", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "פרסם תגובה", "COMMENT_POSTING_AS_PROMPT": "מפרסם כ-{{user}}", "COMMENT_SEND_FAILURE_PROMPT": "לא ניתן לפרסם תגובה", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "אשר סיסמה", "CONFIRM_PASSWORD_PROMPT": "אשר את הסיסמה לחשבון שלך", "CONNECTED_GLOSSARIES": "מילונים קשורים", @@ -129,7 +134,7 @@ "ERROR_TWO_FACTOR_IS_DISABLED": "אימות דו-גורמי מושבת.", "ERROR_UNKNOWN_USER": "המשתמש הזה אינו קיים.", "ERROR_USERNAME_ALREADY_EXISTS": "מצטערים, שם המשתמש הזה כבר תפוס.", - "ET_CETERA": "וכו\u0027", + "ET_CETERA": "וכו'", "FILTER_ALERT_STRINGS": "הצג מחרוזות עם התראות", "FILTER_ALL_STRINGS": "הצג כל המחרוזות", "FILTER_UNFINISHED_STRINGS": "הצג מחרוזות לא גמורות", @@ -182,6 +187,10 @@ "OK": "אישור", "OTHER_LANGUAGES": "שפות אחרות", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "ניהול Parlance", "PARLANCE_ADMINISTRATION_DESCRIPTION": "הגדר את שרת ה-Parlance", "PARLANCE_ON_GIT": "Parlance ב-Git", @@ -338,36 +347,36 @@ "USER_PERMISSIONS_TITLE": "הרשאות עבור {{user}}", "VCS_COMMIT": "בצע קומיט", "VCS_COMMIT_PROMPT_one": "בצע שינוי {{count}}?", - "VCS_COMMIT_PROMPT_two": "בצע {{count}} שינויים?", "VCS_COMMIT_PROMPT_other": "בצע {{count}} שינויים?", + "VCS_COMMIT_PROMPT_two": "בצע {{count}} שינויים?", "VCS_CREATED_COMMIT": "נוצר קומיט", "VCS_CREATED_COMMIT_PROMPT": "הקומיט נוצר", "VCS_CREATE_COMMIT": "צור קומיט", "VCS_DISCARD": "היפטר", "VCS_DISCARD_UNCOMMITTED_CHANGES": "היפטר משינויים להם לא בוצע קומיט", "VCS_DISCARD_UNCOMMITTED_CHANGES_PROMPT_one": "היפטר משינויים בהם לא בוצע קומיט בקובץ {{count}}?", - "VCS_DISCARD_UNCOMMITTED_CHANGES_PROMPT_two": "היפטר משינויים בהם לא בוצע קומיט ב-{{count}} קבצים?", "VCS_DISCARD_UNCOMMITTED_CHANGES_PROMPT_other": "היפטר משינויים בהם לא בוצע קומיט ב-{{count}} קבצים?", + "VCS_DISCARD_UNCOMMITTED_CHANGES_PROMPT_two": "היפטר משינויים בהם לא בוצע קומיט ב-{{count}} קבצים?", "VCS_FETCH": "השג", "VCS_GIT": "Git", "VCS_INCOMING_COMMITS": "קומיטים נכנסים", "VCS_INCOMING_COMMITS_PULL_one": "משוך קומיט {{count}}", - "VCS_INCOMING_COMMITS_PULL_two": "משוך {{count}} קומיטים", "VCS_INCOMING_COMMITS_PULL_other": "משוך {{count}} קומיטים", + "VCS_INCOMING_COMMITS_PULL_two": "משוך {{count}} קומיטים", "VCS_LAST_LOCAL_COMMIT": "קומיט מקומי אחרון", "VCS_LAST_REMOTE_COMMIT": "קומיט מכוון אחרון", "VCS_NOTHING_TO_COMMIT": "אין למה לבצע קומיט", "VCS_NOTHING_TO_COMMIT_PROMPT": "אין למה לבצע קומיט.", "VCS_OUTGOING_COMMITS": "קומיטים יוצאים", "VCS_OUTGOING_COMMITS_PUSH_one": "דחוף קומיט {{count}}", - "VCS_OUTGOING_COMMITS_PUSH_two": "דחוף {{count}} קומיטים", "VCS_OUTGOING_COMMITS_PUSH_other": "דחוף {{count}} קומיטים", + "VCS_OUTGOING_COMMITS_PUSH_two": "דחוף {{count}} קומיטים", "VCS_PULL": "משיכה", "VCS_PUSH": "דחיפה", "VCS_UNCOMMITTED_CHANGES": "שינויים שלא התבצעו", "VCS_UNCOMMITTED_CHANGES_COMMIT_one": "בצע קומיט לקובץ {{count}}", - "VCS_UNCOMMITTED_CHANGES_COMMIT_two": "בצע קומיטים ל-{{count}} קבצים", "VCS_UNCOMMITTED_CHANGES_COMMIT_other": "בצע קומיטים ל-{{count}} קבצים", + "VCS_UNCOMMITTED_CHANGES_COMMIT_two": "בצע קומיטים ל-{{count}} קבצים", "VERIFICATION_EMAIL_RESEND_PROMPT": "בדוק את דואר האלקטרוני שלך בשביל קוד אימות. ייתכן שתצטרך לבדוק את תיקיית הספאם שלך.", "VERIFY_EMAIL": "אמת דואר אלקטרוני", "VERIFY_EMAIL_FAILED_1": "אימות דואר האלקטרוני נכשל", diff --git a/Parlance/ClientApp/public/resources/translations/nl/translation.json b/Parlance/ClientApp/public/resources/translations/nl/translation.json index b6fee163..f6281892 100644 --- a/Parlance/ClientApp/public/resources/translations/nl/translation.json +++ b/Parlance/ClientApp/public/resources/translations/nl/translation.json @@ -81,11 +81,16 @@ "CLOSE": "Sluiten", "COMMENTS": "Reacties", "COMMENT_ADD": "Reactie Toevoegen", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS_one": "{{count}} open thread", "COMMENT_OPEN_THREADS_other": "", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "Reactie Plaatsen", "COMMENT_POSTING_AS_PROMPT": "Reageren als {{user}}", "COMMENT_SEND_FAILURE_PROMPT": "Kon de reactie niet verzenden", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "Wachtwoord Bevestigen", "CONFIRM_PASSWORD_PROMPT": "Bevestig het wachtwoord voor je account", "CONNECTED_GLOSSARIES": "", @@ -178,6 +183,10 @@ "OK": "Oké", "OTHER_LANGUAGES": "Andere Talen", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "Parlance-administratie", "PARLANCE_ADMINISTRATION_DESCRIPTION": "Parlance-server configureren", "PARLANCE_ON_GIT": "Parlance op Git", diff --git a/Parlance/ClientApp/public/resources/translations/pt-BR/translation.json b/Parlance/ClientApp/public/resources/translations/pt-BR/translation.json index 784b9384..b5c845a7 100644 --- a/Parlance/ClientApp/public/resources/translations/pt-BR/translation.json +++ b/Parlance/ClientApp/public/resources/translations/pt-BR/translation.json @@ -81,10 +81,15 @@ "CLOSE": "Fechar", "COMMENTS": "", "COMMENT_ADD": "", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS": "", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "", "COMMENT_POSTING_AS_PROMPT": "", "COMMENT_SEND_FAILURE_PROMPT": "", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "Confirmar senha", "CONFIRM_PASSWORD_PROMPT": "Confirme a senha para a sua conta", "CONNECTED_GLOSSARIES": "", @@ -177,6 +182,10 @@ "OK": "OK", "OTHER_LANGUAGES": "Outras linguagens", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "Administração de Parlance", "PARLANCE_ADMINISTRATION_DESCRIPTION": "Configurar servidor de Parlance", "PARLANCE_ON_GIT": "Parlance em Git", diff --git a/Parlance/ClientApp/public/resources/translations/ro-RO/translation.json b/Parlance/ClientApp/public/resources/translations/ro-RO/translation.json index fba46840..230e655b 100644 --- a/Parlance/ClientApp/public/resources/translations/ro-RO/translation.json +++ b/Parlance/ClientApp/public/resources/translations/ro-RO/translation.json @@ -37,7 +37,7 @@ "ADD_PROJECT_ERROR": "Nu am putut adăuga proiectul", "ADD_PROJECT_ERROR_PROMPT": "Nu am putut adăuga proiectul. Încearcă mai târziu.", "ADD_PROJECT_PROMPT_1": "Introdu datele necesare pentru a adăuga un proiect", - "ADD_PROJECT_PROMPT_2": "Asigură-te că proiectul conține un fișier \u003C1\u003E.parlance.json\u003C/1\u003E la rădăcină.", + "ADD_PROJECT_PROMPT_2": "Asigură-te că proiectul conține un fișier <1>.parlance.json la rădăcină.", "ADD_TO_GLOSSARY": "", "ADD_TO_GLOSSARY_CONFIRM": "", "ADD_TO_GLOSSARY_ERROR_NO_TERM": "", @@ -81,12 +81,17 @@ "CLOSE": "Închide", "COMMENTS": "Comentarii", "COMMENT_ADD": "Adaugă un comentariu", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS_few": "{{count}} conversații deschise", "COMMENT_OPEN_THREADS_one": "{{count}} conversație deschisă", "COMMENT_OPEN_THREADS_other": "{{count}} de conversații deschise", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "Postează comentariul", "COMMENT_POSTING_AS_PROMPT": "Postare ca {{user}}", "COMMENT_SEND_FAILURE_PROMPT": "Nu am putut trimite comentariul", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "Confirmă parola", "CONFIRM_PASSWORD_PROMPT": "Confirmă parola pentru contul tău", "CONNECTED_GLOSSARIES": "", @@ -179,6 +184,10 @@ "OK": "OK", "OTHER_LANGUAGES": "Alte limbi", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "Administrație Parlance", "PARLANCE_ADMINISTRATION_DESCRIPTION": "Configură serverul Parlance", "PARLANCE_ON_GIT": "Parlance pe Git", @@ -235,7 +244,7 @@ "SECURITY_KEY_ADD_NAME_PROMPT": "Numele cheii de securitate", "SECURITY_KEY_ADD_PROMPT": "Urmărește instrucțiunile din browser pentru a adăuga o cheie de securitate.", "SECURITY_KEY_ADVERTISEMENT": "Poți să te conectezi mai rapid cu o cheie de acces. Cheile de acces pot fi setate rapid, și sunt mai sigure ca parolele.", - "SECURITY_KEY_ADVERTISEMENT_2": "Dacă nu vrei să setezi o cheie de acces chiar acum, poți mereu să vizitezi \u0022Setări chei de acces\u0022 în setările contului tău pentru a seta una.", + "SECURITY_KEY_ADVERTISEMENT_2": "Dacă nu vrei să setezi o cheie de acces chiar acum, poți mereu să vizitezi \"Setări chei de acces\" în setările contului tău pentru a seta una.", "SECURITY_KEY_ADVERTISEMENT_FEATURE_1_CONTENT": "Setarea poate fi efectuată în 10 secunde.", "SECURITY_KEY_ADVERTISEMENT_FEATURE_1_HEADING": "Setare rapidă", "SECURITY_KEY_ADVERTISEMENT_FEATURE_2_CONTENT": "Nu poți să îți uiți cheia de acces pentru că nu există nimic de ținut minte!", @@ -249,8 +258,8 @@ "SECURITY_KEY_ADVERTISEMENT_NEVER": "Nu pe acest dispozitiv", "SECURITY_KEY_ADVERTISEMENT_OK": "Setează acum", "SECURITY_KEY_ADVERTISEMENT_SETUP_SUCCESS": "Cheia de acces a fost înregistrată cu succes pe acest cont", - "SECURITY_KEY_ADVERTISEMENT_SETUP_SUCCESS_2": "Data viitoare când te conectezi la Parlance, poți folosi această cheie de acces introducându-ți numele de utilizator și selectând \u0022Folosește o cheie de acces\u0022 când ți se cere parola.", - "SECURITY_KEY_ADVERTISEMENT_SETUP_SUCCESS_3": "Pentru a-ți gestiona cheile de acces, poți să vizitezi setările contului tău și să selectezi \u0022Gestionare chei de acces\u0022.", + "SECURITY_KEY_ADVERTISEMENT_SETUP_SUCCESS_2": "Data viitoare când te conectezi la Parlance, poți folosi această cheie de acces introducându-ți numele de utilizator și selectând \"Folosește o cheie de acces\" când ți se cere parola.", + "SECURITY_KEY_ADVERTISEMENT_SETUP_SUCCESS_3": "Pentru a-ți gestiona cheile de acces, poți să vizitezi setările contului tău și să selectezi \"Gestionare chei de acces\".", "SECURITY_KEY_ADVERTISEMENT_SETUP_SUCCESS_TITLE": "Cheie de acces setată cu succes", "SECURITY_KEY_ADVERTISEMENT_TITLE": "Setare cheie de acces", "SECURITY_KEY_DEREGISTER": "Anulează cheia de securitate", diff --git a/Parlance/ClientApp/public/resources/translations/uk/translation.json b/Parlance/ClientApp/public/resources/translations/uk/translation.json index 0bd48b94..5a584a1b 100644 --- a/Parlance/ClientApp/public/resources/translations/uk/translation.json +++ b/Parlance/ClientApp/public/resources/translations/uk/translation.json @@ -81,10 +81,15 @@ "CLOSE": "", "COMMENTS": "", "COMMENT_ADD": "", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS": "", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "", "COMMENT_POSTING_AS_PROMPT": "", "COMMENT_SEND_FAILURE_PROMPT": "", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "", "CONFIRM_PASSWORD_PROMPT": "", "CONNECTED_GLOSSARIES": "", @@ -177,6 +182,10 @@ "OK": "", "OTHER_LANGUAGES": "", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "", "PARLANCE_ADMINISTRATION_DESCRIPTION": "", "PARLANCE_ON_GIT": "", diff --git a/Parlance/ClientApp/public/resources/translations/vi/translation.json b/Parlance/ClientApp/public/resources/translations/vi/translation.json index 90e81ba2..4250413c 100644 --- a/Parlance/ClientApp/public/resources/translations/vi/translation.json +++ b/Parlance/ClientApp/public/resources/translations/vi/translation.json @@ -38,7 +38,7 @@ "ADD_PROJECT_ERROR": "Không thể thêm dự án", "ADD_PROJECT_ERROR_PROMPT": "", "ADD_PROJECT_PROMPT_1": "Điền vào dữ liệu để thêm dự án", - "ADD_PROJECT_PROMPT_2": "Đảm bảo rằng dự án này có tệp \u003C1\u003E.parlance.json\u003C/1\u003E trong thư mục góc", + "ADD_PROJECT_PROMPT_2": "Đảm bảo rằng dự án này có tệp <1>.parlance.json trong thư mục góc", "ADD_TO_GLOSSARY": "Thêm vào bảng chữ giải", "ADD_TO_GLOSSARY_CONFIRM": "Thêm vào {{glossary}}", "ADD_TO_GLOSSARY_ERROR_NO_TERM": "", @@ -82,10 +82,15 @@ "CLOSE": "Đóng", "COMMENTS": "", "COMMENT_ADD": "", + "COMMENT_GO_TO_STRING": "", + "COMMENT_NOT_LOGGED_IN_PROMPT": "", "COMMENT_OPEN_THREADS_other": "", + "COMMENT_ORIGINAL_TRANSLATION": "", + "COMMENT_ORIGINAL_TRANSLATION_NO_LONGER_EXISTS": "", "COMMENT_POST": "", "COMMENT_POSTING_AS_PROMPT": "", "COMMENT_SEND_FAILURE_PROMPT": "", + "COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT": "", "CONFIRM_PASSWORD": "Xác nhận mật khẩu", "CONFIRM_PASSWORD_PROMPT": "Xác nhận mật khẩu cho tài khoản của bạn", "CONNECTED_GLOSSARIES": "", @@ -178,6 +183,10 @@ "OK": "OK", "OTHER_LANGUAGES": "Ngôn ngữ khác", "OVERVIEW": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS": "", + "OVERVIEW_COMMENTS_NO_OPEN_THREADS_DESCRIPTION": "", + "OVERVIEW_GO_TO_COMMENTS": "", + "OVERVIEW_STATS": "", "PARLANCE_ADMINISTRATION": "Quản lý Parlance", "PARLANCE_ADMINISTRATION_DESCRIPTION": "Cấu hình máy chủ Parlance", "PARLANCE_ON_GIT": "Parlance trên Git", diff --git a/Parlance/ClientApp/src/components/Button.js b/Parlance/ClientApp/src/components/Button.js deleted file mode 100644 index ae24b8c8..00000000 --- a/Parlance/ClientApp/src/components/Button.js +++ /dev/null @@ -1,7 +0,0 @@ -import Styles from "./Button.module.css"; - -export default function (props) { - return
- {props.children} -
-} \ No newline at end of file diff --git a/Parlance/ClientApp/src/components/Button.tsx b/Parlance/ClientApp/src/components/Button.tsx new file mode 100644 index 00000000..b4f8b81d --- /dev/null +++ b/Parlance/ClientApp/src/components/Button.tsx @@ -0,0 +1,13 @@ +import Styles from "./Button.module.css"; +import {HTMLAttributes, ReactNode} from "react"; + +interface ButtonProps extends HTMLAttributes { + disabled?: boolean + children: ReactNode +} + +export default function (props: ButtonProps) { + return
+ {props.children} +
+} \ No newline at end of file diff --git a/Parlance/ClientApp/src/components/ListPage.js b/Parlance/ClientApp/src/components/ListPage.js deleted file mode 100644 index 808fbbd9..00000000 --- a/Parlance/ClientApp/src/components/ListPage.js +++ /dev/null @@ -1,45 +0,0 @@ -import Styles from "./ListPage.module.css"; -import {Route, Routes, useLocation, useNavigate} from "react-router-dom"; - -function toUrl(name) { - return name.toLowerCase().replace(" ", "-") -} - -function ListItem(props) { - const navigate = useNavigate(); - const location = useLocation(); - - const switchPage = () => { - navigate(toUrl(props.name)); - }; - - let styles = [Styles.listItem, Styles.listItemClickable] - if (location.pathname.includes(toUrl(props.name))) { - styles.push(Styles.selected); - } - - return
- {props.name} -
-} - -export default function ListPage({items}) { - return
-
- {items.map((item, i) => { - if (typeof (item) === "string") { - return {item.toUpperCase()} - } else { - return - } - })} -
-
- - {items.filter(item => typeof (item) === "object").map((item, index) => { - return - })} - -
-
-} \ No newline at end of file diff --git a/Parlance/ClientApp/src/components/ListPage.module.css b/Parlance/ClientApp/src/components/ListPage.module.css index 72a83129..4b4dcc34 100644 --- a/Parlance/ClientApp/src/components/ListPage.module.css +++ b/Parlance/ClientApp/src/components/ListPage.module.css @@ -7,7 +7,6 @@ .leftPane { flex-basis: 300px; - border-right: 1px solid var(--border-color); flex-grow: 1; display: flex; @@ -15,6 +14,14 @@ align-items: flex-end; } +:global(.ltr) .leftPane { + border-right: 1px solid var(--border-color); +} + +:global(.rtl) .leftPane { + border-left: 1px solid var(--border-color); +} + .rightPane { flex-basis: 600px; flex-grow: 1; @@ -35,4 +42,26 @@ .listItemClickable:active, .selected { background-color: var(--active-color); +} + +.mobileOnly { + display: none; +} + +@media (max-width: 600px) { + .mobileOnly { + display: block; + } + + .desktopOnly { + display: none; + } + + .leftPane { + align-items: stretch; + } + + .listItem { + width: initial; + } } \ No newline at end of file diff --git a/Parlance/ClientApp/src/components/ListPage.tsx b/Parlance/ClientApp/src/components/ListPage.tsx new file mode 100644 index 00000000..e1b86021 --- /dev/null +++ b/Parlance/ClientApp/src/components/ListPage.tsx @@ -0,0 +1,85 @@ +import Styles from "./ListPage.module.css"; +import {Outlet, Route, Routes, useLocation, useNavigate} from "react-router-dom"; +import {ReactNode} from "react"; +import BackButton from "./BackButton"; +import {useTranslation} from "react-i18next"; + +interface ListPageItemObject { + name: string, + slug: string, + render: ReactNode + default?: boolean +} + +type ListPageItem = ListPageItemObject | string; + +function ListItem(props: { + name: string + slug: string + default?: boolean +}) { + const navigate = useNavigate(); + const location = useLocation(); + + const switchPage = () => { + navigate(props.slug); + }; + + let styles = [Styles.listItem, Styles.listItemClickable] + if (location.pathname.includes(props.slug)) { + styles.push(Styles.selected); + } + + return
+ {props.name} +
+} + +function ListPageInner({items, isLeftPane}: { + items: ListPageItem[], + isLeftPane: boolean +}) { + const navigate = useNavigate(); + const {t} = useTranslation(); + + const goBack = () => { + navigate("..") + }; + + return
+
+ {items.map((item, i) => { + if (typeof (item) === "string") { + return {item.toUpperCase()} + } else { + return + } + })} +
+
+
+ +
+ +
+
+} + +export default function ListPage({items}: { + items: ListPageItem[] +}) { + return + } path={"/"}> + {(items.filter(item => typeof (item) === "object") as ListPageItemObject[]) + .filter(item => item.default) + .map(item => )} + + }> + {(items.filter(item => typeof (item) === "object") as ListPageItemObject[]).flatMap((item, index) => { + const routes = [] + if (item.default) routes.push() + return routes; + })} + + +} \ No newline at end of file diff --git a/Parlance/ClientApp/src/components/Modal.module.css b/Parlance/ClientApp/src/components/Modal.module.css index 4de7fa4c..4cb061b0 100644 --- a/Parlance/ClientApp/src/components/Modal.module.css +++ b/Parlance/ClientApp/src/components/Modal.module.css @@ -26,18 +26,26 @@ border: 1px solid var(--border-color); flex-basis: 600px; + max-height: 100vh; } .PopoverContainer { border-top: none; border-bottom: none; - border-right: none; display: grid; grid-template-rows: max-content 1fr; grid-template-areas: "heading" "body"; } +:global(.ltr) .PopoverContainer { + border-right: none; +} + +:global(.rtl) .PopoverContainer { + border-left: none; +} + .ModalHeading { margin: 0; font-size: 20pt; @@ -64,9 +72,16 @@ justify-content: center; padding: 10px; +} + +:global(.ltr) .BackButton { border-right: 1px solid var(--border-color); } +:global(.rtl) .BackButton { + border-left: 1px solid var(--border-color); +} + .BackButton:hover { background-color: var(--hover-color); } diff --git a/Parlance/ClientApp/src/components/Modal.tsx b/Parlance/ClientApp/src/components/Modal.tsx index 0458cc2d..1b3157b3 100644 --- a/Parlance/ClientApp/src/components/Modal.tsx +++ b/Parlance/ClientApp/src/components/Modal.tsx @@ -19,7 +19,7 @@ interface ModalExportProps { buttons?: ModalButton[] onButtonClick?: () => {} children?: ReactNode | TFunctionResult - onBackClicked?: () => {} + onBackClicked?: () => void heading?: string topComponent?: ReactNode } diff --git a/Parlance/ClientApp/src/components/PageHeading.module.css b/Parlance/ClientApp/src/components/PageHeading.module.css index deed3954..9a1fcfa3 100644 --- a/Parlance/ClientApp/src/components/PageHeading.module.css +++ b/Parlance/ClientApp/src/components/PageHeading.module.css @@ -13,4 +13,11 @@ font-weight: bold; text-transform: uppercase; margin: 0; +} + +.level4 { + font-size: 8pt; + font-weight: normal; + text-transform: uppercase; + margin: 0; } \ No newline at end of file diff --git a/Parlance/ClientApp/src/components/PageHeading.tsx b/Parlance/ClientApp/src/components/PageHeading.tsx index 7c700a7f..e71733bb 100644 --- a/Parlance/ClientApp/src/components/PageHeading.tsx +++ b/Parlance/ClientApp/src/components/PageHeading.tsx @@ -2,7 +2,7 @@ import Styles from "./PageHeading.module.css"; import {ReactElement, ReactNode} from "react"; interface PageHeadingProps { - level?: 1 | 2 | 3; + level?: 1 | 2 | 3 | 4; children: ReactNode; className?: string; } @@ -13,6 +13,8 @@ export default function PageHeading(props: PageHeadingProps): ReactElement { return

{props.children}

case 3: return

{props.children}

+ case 4: + return

{props.children}

default: return

{props.children}

} diff --git a/Parlance/ClientApp/src/components/comments/ThreadItem.module.css b/Parlance/ClientApp/src/components/comments/ThreadItem.module.css new file mode 100644 index 00000000..637b3e41 --- /dev/null +++ b/Parlance/ClientApp/src/components/comments/ThreadItem.module.css @@ -0,0 +1,61 @@ +.threadItem { + display: grid; + grid-template-columns: 1fr max-content; + grid-template-rows: max-content max-content max-content; + gap: 6px 0px; + grid-template-areas: + "threadTitle goButton" + "lastMessageDate goButton" + "lastMessage goButton"; + align-items: center; + + padding: 9px; + cursor: default; +} + +.threadItem:hover { + background-color: var(--hover-color); +} + +.threadItem:active { + background-color: var(--active-color); +} + +.threadTitle { + grid-area: threadTitle; +} + +.closed { + color: var(--foreground-disabled-color); +} + +.goButton { + grid-area: goButton; +} + +.lastMessage { + grid-area: lastMessage; +} + +.lastMessageDate { + grid-area: lastMessageDate; + font-size: 10pt; + opacity: 50%; +} + +.threadCreator { + font-size: 10pt; + + display: inline-flex; + align-items: center; + gap: 6px; +} + +.noPadding { + padding: 0; +} + +.threadCreatorImage { + height: 16px; + border-radius: 50%; +} \ No newline at end of file diff --git a/Parlance/ClientApp/src/components/comments/ThreadItem.tsx b/Parlance/ClientApp/src/components/comments/ThreadItem.tsx new file mode 100644 index 00000000..2122ff81 --- /dev/null +++ b/Parlance/ClientApp/src/components/comments/ThreadItem.tsx @@ -0,0 +1,29 @@ +import {Thread} from "../../interfaces/comments"; +import Styles from "./ThreadItem.module.css"; +import Icon from "../Icon"; +import {useTranslation} from "react-i18next"; +import moment from "moment"; + +export function ThreadItem({item, onCurrentThreadChanged, noPadding}: { + item: Thread, + onCurrentThreadChanged: (thread: Thread) => void, + noPadding?: boolean +}) { + const {t} = useTranslation(); + + return
onCurrentThreadChanged(item)}> + {item.title} + +
+ {moment(item.headComment.date).fromNow(false)} +
+
+ {item.headComment.text} +  —  + + {t("COMMENT_THREAD_PROFILE_PICTURE_ALT_TEXT", + {item.headComment.author.username} + +
+
+} \ No newline at end of file diff --git a/Parlance/ClientApp/src/interfaces/comments.ts b/Parlance/ClientApp/src/interfaces/comments.ts new file mode 100644 index 00000000..38ba3863 --- /dev/null +++ b/Parlance/ClientApp/src/interfaces/comments.ts @@ -0,0 +1,27 @@ +export interface Thread { + id: string + title: string + isClosed: boolean + isFlagged: boolean + headComment: HeadComment + project: string + subproject: string + language: string + key: string + sourceTranslation?: string +} + +interface HeadComment { + text: string + date: number + author: Author +} + +export interface Comment extends HeadComment { + event: string | null +} + +interface Author { + username: string + picture: string +} diff --git a/Parlance/ClientApp/src/interfaces/projects.ts b/Parlance/ClientApp/src/interfaces/projects.ts new file mode 100644 index 00000000..d77c05ce --- /dev/null +++ b/Parlance/ClientApp/src/interfaces/projects.ts @@ -0,0 +1,20 @@ +import {Thread} from "./comments"; + +export interface SubprojectLocaleMeta { + completionData: CompletionData + projectName: string, + subprojectName: string, + language: string, + canEdit: boolean, + openThreads: Thread[] +} + +export interface CompletionData { + count: number, + complete: number, + warnings: number, + errors: number, + cumulativeWarnings: number, + passedChecks: number, + needsAttention: number +} \ No newline at end of file diff --git a/Parlance/ClientApp/src/pages/Administration/index.js b/Parlance/ClientApp/src/pages/Administration/index.js index 59cca03a..b6548035 100644 --- a/Parlance/ClientApp/src/pages/Administration/index.js +++ b/Parlance/ClientApp/src/pages/Administration/index.js @@ -16,24 +16,29 @@ export default function(props) { t("PROJECTS"), { name: t("PROJECTS"), + slug: "projects", render: }, { name: t("GLOSSARIES"), + slug: "glossaries", render: }, t("SSH"), { name: t("SSH_KEYS"), + slug: "ssh-keys", render: }, t("USERS_AND_PERMISSIONS"), { name: t("SUPERUSERS"), + slug: "superusers", render: }, { name: t("LOCALES"), + slug: "locales", render: } ]; diff --git a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/CommentsDashboard.tsx b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/CommentsDashboard.tsx new file mode 100644 index 00000000..35c360f3 --- /dev/null +++ b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/CommentsDashboard.tsx @@ -0,0 +1,52 @@ +import ListPageBlock from "../../../../../components/ListPageBlock"; +import {VerticalLayout} from "../../../../../components/Layouts"; +import PageHeading from "../../../../../components/PageHeading"; +import {useTranslation} from "react-i18next"; +import SelectableList from "../../../../../components/SelectableList"; +import {useEffect, useState} from "react"; +import {Thread} from "../../../../../interfaces/comments"; +import {useParams} from "react-router-dom"; +import Fetch from "../../../../../helpers/Fetch"; +import {ThreadItem} from "../../../../../components/comments/ThreadItem"; +import PreloadingBlock from "../../../../../components/PreloadingBlock"; +import SilentInformation from "../../../../../components/SilentInformation"; +import Modal from "../../../../../components/Modal"; +import {CommentsThreadModal} from "./TranslationEditor/Comments/CommentsModal"; + +export function CommentsDashboard() { + const {project, subproject, language} = useParams(); + const {t} = useTranslation(); + const [comments, setComments] = useState(); + + const updateComments = async () => { + setComments(null); + setComments(await Fetch.get(`/api/comments/${project}/${subproject}/${language}`)); + } + + useEffect(() => { + void updateComments(); + }, []); + + const openThread = (thread: Thread) => { + Modal.mount() + } + + return
+ + + {t("COMMENTS")} + {comments?.length === 0 ? +
+ +
: <> + {comments ?
{t("COMMENT_OPEN_THREADS", {count: comments.length})}
: {t("COMMENT_OPEN_THREADS", {count: 0})}} + ({ + contents: {}} />, + onClick: () => openThread(thread) + })) : SelectableList.PreloadingText(3)}/> + + } +
+
+
+} diff --git a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Dashboard.js b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Dashboard.tsx similarity index 69% rename from Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Dashboard.js rename to Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Dashboard.tsx index a993ba4b..aab38476 100644 --- a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Dashboard.js +++ b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Dashboard.tsx @@ -9,10 +9,12 @@ import Hero from "../../../../../components/Hero"; import BackButton from "../../../../../components/BackButton"; import Spinner from "../../../../../components/Spinner"; import GlossariesDashboard from "./GlossariesDashboard"; +import {SubprojectLocaleMeta} from "../../../../../interfaces/projects"; +import {CommentsDashboard} from "./CommentsDashboard"; -export default function Dashboard(props) { +export default function Dashboard() { const {project, subproject, language} = useParams(); - const [data, setData] = useState(); + const [data, setData] = useState(); const navigate = useNavigate(); const {t} = useTranslation(); @@ -31,17 +33,25 @@ export default function Dashboard(props) { t("DASHBOARD"), { name: t("OVERVIEW"), - render: + slug: "overview", + render: , + default: true }, { name: t("GLOSSARIES"), - render: + slug: "glossaries", + render: + }, + { + name: t("COMMENTS"), + slug: "comments", + render: } ]; return
navigate("../..")}/> - navigate("translate") @@ -49,4 +59,4 @@ export default function Dashboard(props) { ]}/>
-} \ No newline at end of file +} diff --git a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Overview.js b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Overview.js deleted file mode 100644 index c654a096..00000000 --- a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Overview.js +++ /dev/null @@ -1,5 +0,0 @@ -export default function Overview({data}) { - return
- -
-} \ No newline at end of file diff --git a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Overview.module.css b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Overview.module.css new file mode 100644 index 00000000..e69de29b diff --git a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Overview.tsx b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Overview.tsx new file mode 100644 index 00000000..6bbc4778 --- /dev/null +++ b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/Overview.tsx @@ -0,0 +1,38 @@ +import {SubprojectLocaleMeta} from "../../../../../interfaces/projects"; +import {VerticalLayout} from "../../../../../components/Layouts"; +import ListPageBlock from "../../../../../components/ListPageBlock"; +import PageHeading from "../../../../../components/PageHeading"; +import {useTranslation} from "react-i18next"; +import SelectableList from "../../../../../components/SelectableList"; +import {useNavigate} from "react-router-dom"; + +export default function Overview({data}: { + data: SubprojectLocaleMeta +}) { + const {t} = useTranslation(); + const navigate = useNavigate(); + + const goToComments = () => { + navigate("../comments"); + } + + return
+ + + {t("OVERVIEW_STATS")} +
+ {data.completionData.complete}/{data.completionData.count} strings translated +
+
{data.completionData.warnings} warnings
+
{data.completionData.errors} errors
+
+
+ + + {t("COMMENTS")} +
{t("COMMENT_OPEN_THREADS", { count: data.openThreads.length })}
+ {t("OVERVIEW_GO_TO_COMMENTS")} +
+
+
+} \ No newline at end of file diff --git a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/CommentsModal.js b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/CommentsModal.js deleted file mode 100644 index 2cdab6ac..00000000 --- a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/CommentsModal.js +++ /dev/null @@ -1,53 +0,0 @@ -import {useTranslation} from "react-i18next"; -import Modal from "../../../../../../../components/Modal"; -import {useState} from "react"; -import {VerticalLayout} from "../../../../../../../components/Layouts"; -import PageHeading from "../../../../../../../components/PageHeading"; - -import Styles from "./CommentsModal.module.css"; -import Icon from "../../../../../../../components/Icon"; -import ThreadView from "./ThreadView"; -import ThreadReplyArea from "./ThreadReplyArea"; - -function ThreadItem({item, onCurrentThreadChanged}) { - return
onCurrentThreadChanged(item)}> - {item.title} - -
{item.headCommentBody}
-
{item.author.username}
-
-} - -export default function CommentsModal({project, subproject, language, tkey, threads, onUpdateThreads}) { - const [currentThread, setCurrentThread] = useState(); - const {t} = useTranslation(); - - const goBack = () => { - if (currentThread) { - setCurrentThread(null); - } else { - Modal.unmount(); - } - }; - - return - {currentThread ? : - <> - -
- {t("THREADS")} -
- {threads.map((x, i) => ) || t("THREADS_NO_THREADS")} -
- -
- {t("THREADS_NEW_THREAD")} -
- -
- } -
-} \ No newline at end of file diff --git a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/CommentsModal.module.css b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/CommentsModal.module.css index 0c7aa5ca..3c84799c 100644 --- a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/CommentsModal.module.css +++ b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/CommentsModal.module.css @@ -6,41 +6,6 @@ border-bottom: 1px solid var(--border-color); } -.threadItem { - display: grid; - grid-template-columns: 1fr max-content; - grid-template-rows: 1fr 1fr 1fr; - gap: 0px 0px; - grid-template-areas: - "threadTitle goButton" - "lastMessage goButton" - "threadCreator goButton"; - align-items: center; - - padding: 9px; - cursor: default; -} - -.threadItem:hover { - background-color: var(--hover-color); -} - -.threadItem:active { - background-color: var(--active-color); -} - -.threadTitle { - grid-area: threadTitle; -} - -.lastMessage { - grid-area: lastMessage; -} - -.threadCreator { - grid-area: threadCreator; -} - -.goButton { - grid-area: goButton; +.noThreads { + padding: 6px; } \ No newline at end of file diff --git a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/CommentsModal.tsx b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/CommentsModal.tsx new file mode 100644 index 00000000..8010e1ee --- /dev/null +++ b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/CommentsModal.tsx @@ -0,0 +1,69 @@ +import {useTranslation} from "react-i18next"; +import Modal from "../../../../../../../components/Modal"; +import {useState} from "react"; +import {VerticalLayout} from "../../../../../../../components/Layouts"; +import PageHeading from "../../../../../../../components/PageHeading"; + +import Styles from "./CommentsModal.module.css"; +import Icon from "../../../../../../../components/Icon"; +import ThreadView from "./ThreadView"; +import ThreadReplyArea from "./ThreadReplyArea"; +import {Thread} from "../../../../../../../interfaces/comments"; +import {ThreadItem} from "../../../../../../../components/comments/ThreadItem"; +import UserManager from "../../../../../../../helpers/UserManager"; + + +export function CommentsModal({project, subproject, language, tkey, threads, onUpdateThreads}: { + project: string, + subproject: string, + language: string, + tkey: string, + threads: Thread[], + onUpdateThreads: () => void, +}) { + const [currentThread, setCurrentThread] = useState(); + const {t} = useTranslation(); + + const goBack = () => { + if (currentThread) { + setCurrentThread(null); + } else { + Modal.unmount(); + } + }; + + return + {currentThread ? : + <> + +
+ {t("THREADS")} +
+ {threads.length ? threads.map((x, i) => ) :
+ {t("THREADS_NO_THREADS")} +
} +
+ {UserManager.currentUser && <> + +
+ {t("THREADS_NEW_THREAD")} +
+ +
+ } + } +
+} + +export function CommentsThreadModal({thread, onUpdateThreads, showHeader}: { + thread: Thread + onUpdateThreads: () => void, + showHeader?: boolean +}) { + return Modal.unmount()}> + {}} onReloadThreads={onUpdateThreads} showHeader={showHeader} /> + +} \ No newline at end of file diff --git a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/ThreadReplyArea.module.css b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/ThreadReplyArea.module.css index 65b15e92..eaa35d8d 100644 --- a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/ThreadReplyArea.module.css +++ b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/ThreadReplyArea.module.css @@ -41,13 +41,21 @@ input.titleBox { flex-direction: row; } -.buttonContainerInner div { +:global(.ltr) .buttonContainerInner div { border-left: 1px solid var(--border-color); } +:global(.rtl) .buttonContainerInner div { + border-right: 1px solid var(--border-color); +} + .postingPrompt { display: flex; align-items: center; padding: 9px; gap: 6px; +} + +.loggedOutMessage { + padding: 9px; } \ No newline at end of file diff --git a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/ThreadReplyArea.js b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/ThreadReplyArea.tsx similarity index 54% rename from Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/ThreadReplyArea.js rename to Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/ThreadReplyArea.tsx index 783f381a..aa1b9efd 100644 --- a/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/ThreadReplyArea.js +++ b/Parlance/ClientApp/src/pages/Projects/Subprojects/Languages/Translation/TranslationEditor/Comments/ThreadReplyArea.tsx @@ -5,6 +5,12 @@ import Button from "../../../../../../../components/Button"; import UserManager from "../../../../../../../helpers/UserManager"; import Fetch from "../../../../../../../helpers/Fetch"; import {useState} from "react"; +import {Comment, Thread} from "../../../../../../../interfaces/comments"; + +interface CloseResponse { + comments: Comment[], + thread: Thread +} export default function ThreadReplyArea({ project, @@ -14,7 +20,16 @@ export default function ThreadReplyArea({ thread, onReloadThreads, onCurrentThreadChanged, onThreadDataChanged - }) { + }: { + project?: string, + subproject?: string, + language?: string, + tkey?: string, + thread?: Thread, + onReloadThreads: () => void, + onCurrentThreadChanged: (thread: Thread | null) => void, + onThreadDataChanged?: (threadData: Comment[]) => void +}) { const [title, setTitle] = useState(""); const [body, setBody] = useState(""); const [error, setError] = useState(""); @@ -26,7 +41,7 @@ export default function ThreadReplyArea({ setError(""); if (threadId) { try { - onThreadDataChanged(await Fetch.post(`/api/comments/${thread.id}`, { + onThreadDataChanged!(await Fetch.post(`/api/comments/${thread.id}`, { body: body })); } catch { @@ -34,7 +49,7 @@ export default function ThreadReplyArea({ return; } } else { - let thread; + let thread: Thread | null; try { thread = await Fetch.post(`/api/comments/${project}/${subproject}/${language}/${tkey}`, { title: title, @@ -53,46 +68,53 @@ export default function ThreadReplyArea({ }; const toggleClosed = async () => { + if (!thread) return; + let comments, newThread; if (thread.isClosed) { try { - ({comments, thread: newThread} = await Fetch.delete(`/api/comments/${thread.id}/close`)); + ({comments, thread: newThread} = await Fetch.delete(`/api/comments/${thread.id}/close`)); } catch { setError(t("THREAD_REOPEN_FAILURE_PROMPT")) return; } } else { try { - ({comments, thread: newThread} = await Fetch.post(`/api/comments/${thread.id}/close`)); + ({comments, thread: newThread} = await Fetch.post(`/api/comments/${thread.id}/close`, null)); } catch { setError(t("THREAD_CLOSE_FAILURE_PROMPT")) return; } } - onThreadDataChanged(comments); + onThreadDataChanged!(comments); onReloadThreads(); onCurrentThreadChanged(newThread); } return
- {!threadId && setTitle(e.target.value)}/>} -