From 50fa07d0b7bda4f21b6cc76fb995051191c94ea7 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Thu, 2 Apr 2026 09:14:07 +0200 Subject: [PATCH] feat(i18n): enhance localization files with new configuration prompts - Added new localization strings across multiple languages for missing configuration prompts, including messages for league selection and MyTischtennis URL requirements. - Updated TeamManagementView to display missing configuration alerts, improving user guidance during team setup. --- frontend/src/i18n/locales/de-CH.json | 5 +- frontend/src/i18n/locales/de-extended.json | 5 +- frontend/src/i18n/locales/de.json | 3 + frontend/src/i18n/locales/en-AU.json | 5 +- frontend/src/i18n/locales/en-GB.json | 3 + frontend/src/i18n/locales/en-US.json | 5 +- frontend/src/i18n/locales/es.json | 5 +- frontend/src/i18n/locales/fil.json | 5 +- frontend/src/i18n/locales/fr.json | 5 +- frontend/src/i18n/locales/it.json | 5 +- frontend/src/i18n/locales/ja.json | 5 +- frontend/src/i18n/locales/pl.json | 5 +- frontend/src/i18n/locales/th.json | 5 +- frontend/src/i18n/locales/tl.json | 5 +- frontend/src/i18n/locales/zh.json | 5 +- frontend/src/views/TeamManagementView.vue | 193 ++++++++++++++++++--- 16 files changed, 230 insertions(+), 34 deletions(-) diff --git a/frontend/src/i18n/locales/de-CH.json b/frontend/src/i18n/locales/de-CH.json index c72afa17..43a1a302 100644 --- a/frontend/src/i18n/locales/de-CH.json +++ b/frontend/src/i18n/locales/de-CH.json @@ -915,7 +915,10 @@ "firstHalf": "Vorrunde", "firstHalfFull": "Vorrunde (Juli - Dezember)", "secondHalf": "Rückrunde", - "secondHalfFull": "Rückrunde (ab 1. Januar)" + "secondHalfFull": "Rückrunde (ab 1. Januar)", + "missingConfigSummary": "Fehlende Angaben:", + "leagueFieldRequired": "Bitte eine Spielklasse auswählen und speichern.", + "myTischtennisUrlRequired": "MyTischtennis-URL einfügen und parsen, um Team-ID und Ligendaten zu übernehmen." }, "pdfGenerator": { "teamLineupTitle": "Mannschaftsaufstellung", diff --git a/frontend/src/i18n/locales/de-extended.json b/frontend/src/i18n/locales/de-extended.json index fb7463e7..48dc7fbb 100644 --- a/frontend/src/i18n/locales/de-extended.json +++ b/frontend/src/i18n/locales/de-extended.json @@ -599,7 +599,10 @@ "firstHalf": "Vorrunde", "firstHalfFull": "Vorrunde (Juli - Dezember)", "secondHalf": "Rückrunde", - "secondHalfFull": "Rückrunde (ab 1. Januar)" + "secondHalfFull": "Rückrunde (ab 1. Januar)", + "missingConfigSummary": "Fehlende Angaben:", + "leagueFieldRequired": "Bitte eine Spielklasse auswählen und speichern.", + "myTischtennisUrlRequired": "MyTischtennis-URL einfügen und parsen, um Team-ID und Ligendaten zu übernehmen." }, "pdfGenerator": { "teamLineupTitle": "Mannschaftsaufstellung", diff --git a/frontend/src/i18n/locales/de.json b/frontend/src/i18n/locales/de.json index bec1fffd..b23099c5 100644 --- a/frontend/src/i18n/locales/de.json +++ b/frontend/src/i18n/locales/de.json @@ -1462,6 +1462,9 @@ "notCreated": "Nicht erstellt", "autoFetchEnabled": "Automatischer Datenabruf ist aktiviert", "missingItems": "Fehlend: {items}", + "missingConfigSummary": "Fehlende Angaben:", + "leagueFieldRequired": "Bitte eine Spielklasse auswählen und speichern.", + "myTischtennisUrlRequired": "MyTischtennis-URL einfügen und parsen, um Team-ID und Ligendaten zu übernehmen.", "enterUrlForAutoConfig": "MyTischtennis-URL eingeben für automatische Konfiguration", "errorLoadingStats": "Statistiken konnten nicht geladen werden.", "asyncJobStartFailed": "Async-Job konnte nicht gestartet werden.", diff --git a/frontend/src/i18n/locales/en-AU.json b/frontend/src/i18n/locales/en-AU.json index 07249a18..7dcd1c83 100644 --- a/frontend/src/i18n/locales/en-AU.json +++ b/frontend/src/i18n/locales/en-AU.json @@ -915,7 +915,10 @@ "firstHalf": "First half", "firstHalfFull": "First half (July - December)", "secondHalf": "Second half", - "secondHalfFull": "Second half (from 1 January)" + "secondHalfFull": "Second half (from 1 January)", + "missingConfigSummary": "Missing:", + "leagueFieldRequired": "Please select a league class and save.", + "myTischtennisUrlRequired": "Paste and parse the MyTischtennis URL to link the team ID and league data." }, "pdfGenerator": { "teamLineupTitle": "Team line-up", diff --git a/frontend/src/i18n/locales/en-GB.json b/frontend/src/i18n/locales/en-GB.json index c64647a8..d9d0c211 100644 --- a/frontend/src/i18n/locales/en-GB.json +++ b/frontend/src/i18n/locales/en-GB.json @@ -1153,6 +1153,9 @@ "notCreated": "Not created", "autoFetchEnabled": "Automatic data retrieval is enabled", "missingItems": "Missing: {items}", + "missingConfigSummary": "Missing:", + "leagueFieldRequired": "Please select a league class and save.", + "myTischtennisUrlRequired": "Paste and parse the MyTischtennis URL to link the team ID and league data.", "enterUrlForAutoConfig": "Enter a myTischtennis URL for automatic configuration", "errorLoadingStats": "Statistics could not be loaded.", "asyncJobStartFailed": "The async job could not be started.", diff --git a/frontend/src/i18n/locales/en-US.json b/frontend/src/i18n/locales/en-US.json index df59556a..bc536cac 100644 --- a/frontend/src/i18n/locales/en-US.json +++ b/frontend/src/i18n/locales/en-US.json @@ -915,7 +915,10 @@ "firstHalf": "First half", "firstHalfFull": "First half (July - December)", "secondHalf": "Second half", - "secondHalfFull": "Second half (from 1 January)" + "secondHalfFull": "Second half (from 1 January)", + "missingConfigSummary": "Missing:", + "leagueFieldRequired": "Please select a league class and save.", + "myTischtennisUrlRequired": "Paste and parse the MyTischtennis URL to link the team ID and league data." }, "pdfGenerator": { "teamLineupTitle": "Team line-up", diff --git a/frontend/src/i18n/locales/es.json b/frontend/src/i18n/locales/es.json index 42448bcc..b7ebed47 100644 --- a/frontend/src/i18n/locales/es.json +++ b/frontend/src/i18n/locales/es.json @@ -882,7 +882,10 @@ "firstHalf": "Primera vuelta", "firstHalfFull": "Primera vuelta (julio - diciembre)", "secondHalf": "Segunda vuelta", - "secondHalfFull": "Segunda vuelta (desde el 1 de enero)" + "secondHalfFull": "Segunda vuelta (desde el 1 de enero)", + "missingConfigSummary": "Información faltante:", + "leagueFieldRequired": "Seleccione una liga y guarde.", + "myTischtennisUrlRequired": "Pegue y analice la URL de MyTischtennis para vincular el ID del equipo y los datos de la liga." }, "pdfGenerator": { "teamLineupTitle": "Alineación del equipo", diff --git a/frontend/src/i18n/locales/fil.json b/frontend/src/i18n/locales/fil.json index 39a8401a..161fa4c8 100644 --- a/frontend/src/i18n/locales/fil.json +++ b/frontend/src/i18n/locales/fil.json @@ -882,7 +882,10 @@ "firstHalf": "Unang yugto", "firstHalfFull": "Unang yugto (Hulyo - Disyembre)", "secondHalf": "Ikalawang yugto", - "secondHalfFull": "Ikalawang yugto (mula Enero 1)" + "secondHalfFull": "Ikalawang yugto (mula Enero 1)", + "missingConfigSummary": "Nawawalang impormasyon:", + "leagueFieldRequired": "Mangyaring pumili ng liga at i-save.", + "myTischtennisUrlRequired": "I-paste at i-parse ang URL ng MyTischtennis para i-link ang team ID at datos ng liga." }, "pdfGenerator": { "teamLineupTitle": "Line-up ng koponan", diff --git a/frontend/src/i18n/locales/fr.json b/frontend/src/i18n/locales/fr.json index 3dd9d1d4..8a81172c 100644 --- a/frontend/src/i18n/locales/fr.json +++ b/frontend/src/i18n/locales/fr.json @@ -882,7 +882,10 @@ "firstHalf": "Phase aller", "firstHalfFull": "Phase aller (juillet - décembre)", "secondHalf": "Phase retour", - "secondHalfFull": "Phase retour (à partir du 1er janvier)" + "secondHalfFull": "Phase retour (à partir du 1er janvier)", + "missingConfigSummary": "Informations manquantes :", + "leagueFieldRequired": "Veuillez sélectionner une classe de ligue et enregistrer.", + "myTischtennisUrlRequired": "Collez et analysez l’URL MyTischtennis pour lier l’ID d’équipe et les données de ligue." }, "pdfGenerator": { "teamLineupTitle": "Composition de l’équipe", diff --git a/frontend/src/i18n/locales/it.json b/frontend/src/i18n/locales/it.json index 33a4b36e..dedba998 100644 --- a/frontend/src/i18n/locales/it.json +++ b/frontend/src/i18n/locales/it.json @@ -882,7 +882,10 @@ "firstHalf": "Girone d’andata", "firstHalfFull": "Girone d’andata (luglio - dicembre)", "secondHalf": "Girone di ritorno", - "secondHalfFull": "Girone di ritorno (dal 1° gennaio)" + "secondHalfFull": "Girone di ritorno (dal 1° gennaio)", + "missingConfigSummary": "Dati mancanti:", + "leagueFieldRequired": "Seleziona una classe di campionato e salva.", + "myTischtennisUrlRequired": "Incolla e analizza l’URL MyTischtennis per collegare l’ID squadra e i dati della lega." }, "pdfGenerator": { "teamLineupTitle": "Formazione della squadra", diff --git a/frontend/src/i18n/locales/ja.json b/frontend/src/i18n/locales/ja.json index b7d5c70c..7052a04c 100644 --- a/frontend/src/i18n/locales/ja.json +++ b/frontend/src/i18n/locales/ja.json @@ -882,7 +882,10 @@ "firstHalf": "前期", "firstHalfFull": "前期(7月 - 12月)", "secondHalf": "後期", - "secondHalfFull": "後期(1月1日以降)" + "secondHalfFull": "後期(1月1日以降)", + "missingConfigSummary": "不足している情報:", + "leagueFieldRequired": "リーグを選択して保存してください。", + "myTischtennisUrlRequired": "MyTischtennis の URL を貼り付けて解析し、チーム ID とリーグデータを関連付けます。" }, "pdfGenerator": { "teamLineupTitle": "チーム登録メンバー", diff --git a/frontend/src/i18n/locales/pl.json b/frontend/src/i18n/locales/pl.json index abedaa98..2b35aee9 100644 --- a/frontend/src/i18n/locales/pl.json +++ b/frontend/src/i18n/locales/pl.json @@ -882,7 +882,10 @@ "firstHalf": "Pierwsza runda", "firstHalfFull": "Pierwsza runda (lipiec - grudzień)", "secondHalf": "Druga runda", - "secondHalfFull": "Druga runda (od 1 stycznia)" + "secondHalfFull": "Druga runda (od 1 stycznia)", + "missingConfigSummary": "Brakujące informacje:", + "leagueFieldRequired": "Wybierz klasę rozgrywkową i zapisz.", + "myTischtennisUrlRequired": "Wklej i przeanalizuj adres URL MyTischtennis, aby powiązać ID drużyny i dane ligi." }, "pdfGenerator": { "teamLineupTitle": "Skład drużyny", diff --git a/frontend/src/i18n/locales/th.json b/frontend/src/i18n/locales/th.json index 8020add3..666b5e3e 100644 --- a/frontend/src/i18n/locales/th.json +++ b/frontend/src/i18n/locales/th.json @@ -882,7 +882,10 @@ "firstHalf": "ครึ่งแรก", "firstHalfFull": "ครึ่งแรก (กรกฎาคม - ธันวาคม)", "secondHalf": "ครึ่งหลัง", - "secondHalfFull": "ครึ่งหลัง (ตั้งแต่ 1 มกราคม)" + "secondHalfFull": "ครึ่งหลัง (ตั้งแต่ 1 มกราคม)", + "missingConfigSummary": "รายการที่ขาด:", + "leagueFieldRequired": "โปรดเลือกระดับลีกและบันทึก", + "myTischtennisUrlRequired": "วางและแยกวิเคราะห์ URL ของ MyTischtennis เพื่อเชื่อมโยง ID ทีมและข้อมูลลีก" }, "pdfGenerator": { "teamLineupTitle": "รายชื่อทีม", diff --git a/frontend/src/i18n/locales/tl.json b/frontend/src/i18n/locales/tl.json index ea20ba32..58b09843 100644 --- a/frontend/src/i18n/locales/tl.json +++ b/frontend/src/i18n/locales/tl.json @@ -882,7 +882,10 @@ "firstHalf": "Unang yugto", "firstHalfFull": "Unang yugto (Hulyo - Disyembre)", "secondHalf": "Ikalawang yugto", - "secondHalfFull": "Ikalawang yugto (mula Enero 1)" + "secondHalfFull": "Ikalawang yugto (mula Enero 1)", + "missingConfigSummary": "Nawawalang impormasyon:", + "leagueFieldRequired": "Mangyaring pumili ng liga at mag-save.", + "myTischtennisUrlRequired": "I-paste at i-parse ang URL ng MyTischtennis para i-link ang team ID at datos ng liga." }, "pdfGenerator": { "teamLineupTitle": "Line-up ng koponan", diff --git a/frontend/src/i18n/locales/zh.json b/frontend/src/i18n/locales/zh.json index 5010c398..ebc07e2f 100644 --- a/frontend/src/i18n/locales/zh.json +++ b/frontend/src/i18n/locales/zh.json @@ -882,7 +882,10 @@ "firstHalf": "上半程", "firstHalfFull": "上半程(7月 - 12月)", "secondHalf": "下半程", - "secondHalfFull": "下半程(1月1日起)" + "secondHalfFull": "下半程(1月1日起)", + "missingConfigSummary": "缺少的信息:", + "leagueFieldRequired": "请选择联赛级别并保存。", + "myTischtennisUrlRequired": "粘贴并解析 MyTischtennis 链接以获取球队 ID 和联赛数据。" }, "pdfGenerator": { "teamLineupTitle": "球队阵容", diff --git a/frontend/src/views/TeamManagementView.vue b/frontend/src/views/TeamManagementView.vue index 54d418da..268af016 100644 --- a/frontend/src/views/TeamManagementView.vue +++ b/frontend/src/views/TeamManagementView.vue @@ -59,8 +59,24 @@ +
+ {{ t('teamManagement.missingConfigSummary') }} + +
+
- -
@@ -92,7 +114,10 @@ {{ t('teamManagement.teamName') }} {{ teamToEdit.name }} -
+
{{ t('teamManagement.league') }} {{ teamToEdit.league ? teamToEdit.league.name : t('teamManagement.noLeague') }}
@@ -119,14 +144,18 @@ -
-

- {{ getMyTischtennisStatus(teamToEdit).missing }} -

-

+

+

{{ t('teamManagement.noIssues') }}

-
+
+

{{ t('teamManagement.myTischtennisUrlRequired') }}

⚠️ {{ myTischtennisError }}
✅ {{ myTischtennisSuccess }}
@@ -1651,43 +1688,76 @@ export default { }; const getMyTischtennisStatus = (team) => { + const empty = { + complete: false, + partial: false, + missing: '', + missingItemLabels: [], + tooltip: '', + needsLeague: false, + needsTeamId: false, + needsLeagueGroupId: false, + needsLeagueAssociation: false, + needsLeagueGroupName: false + }; if (!team) { - return { complete: false, partial: false, missing: '', tooltip: '' }; + return { ...empty }; } - + const hasTeamId = !!team.myTischtennisTeamId; const hasLeague = !!team.league; - const hasLeagueConfig = hasLeague && - !!team.league.myTischtennisGroupId && - !!team.league.association && + const hasLeagueConfig = hasLeague && + !!team.league.myTischtennisGroupId && + !!team.league.association && !!team.league.groupname; - + const missingItems = []; if (!hasTeamId) missingItems.push(t('teamManagement.teamId')); if (!hasLeague) missingItems.push(t('teamManagement.league')); if (hasLeague && !team.league.myTischtennisGroupId) missingItems.push(t('teamManagement.groupId')); if (hasLeague && !team.league.association) missingItems.push(t('teamManagement.association')); if (hasLeague && !team.league.groupname) missingItems.push(t('teamManagement.groupName')); - + const complete = hasTeamId && hasLeagueConfig; const partial = (hasTeamId || hasLeagueConfig) && !complete; - + let tooltip = ''; if (complete) { tooltip = t('teamManagement.autoFetchEnabled'); } else if (partial) { tooltip = t('teamManagement.missingItems', { items: missingItems.join(', ') }); } else { - tooltip = t('teamManagement.enterUrlForAutoConfig'); + tooltip = missingItems.length > 0 + ? t('teamManagement.missingItems', { items: missingItems.join(', ') }) + : t('teamManagement.enterUrlForAutoConfig'); } - + return { complete, partial, missing: missingItems.length > 0 ? t('teamManagement.missingItems', { items: missingItems.join(', ') }) : '', - tooltip + missingItemLabels: [...missingItems], + tooltip, + needsLeague: !hasLeague, + needsTeamId: !hasTeamId, + needsLeagueGroupId: !!(hasLeague && !team.league.myTischtennisGroupId), + needsLeagueAssociation: !!(hasLeague && !team.league.association), + needsLeagueGroupName: !!(hasLeague && !team.league.groupname) }; }; + + const editorTabNeedsAttention = (section) => { + const team = teamToEdit.value; + if (!team) return false; + const s = getMyTischtennisStatus(team); + if (s.complete) return false; + if (section === 'basic') return s.needsLeague; + if (section === 'myTischtennis') { + if (s.needsLeague) return false; + return !s.complete; + } + return false; + }; const loadClubMembers = async () => { if (!teamToEdit.value) { @@ -2291,6 +2361,7 @@ export default { configureLeagueFromUrl, clearParsedData, getMyTischtennisStatus, + editorTabNeedsAttention, fetchTeamDataManually, refreshPlayerStats, loadClubMembers, @@ -2519,6 +2590,86 @@ export default { color: var(--primary-dark); } +.workspace-section-button.needs-attention:not(.active) { + border-color: #c45c4a; + background: #fff5f2; + color: #8a2e22; + box-shadow: 0 0 0 1px rgba(196, 92, 74, 0.35); +} + +.workspace-section-button.needs-attention.active { + box-shadow: 0 0 0 2px rgba(196, 92, 74, 0.45); +} + +.workspace-missing-banner { + margin: 0 0 1rem; + padding: 0.65rem 0.85rem; + border-radius: var(--border-radius); + border: 1px solid #e8c9c4; + background: #fff8f6; + color: #5c2e28; + font-size: 0.9rem; +} + +.workspace-missing-banner-label { + display: block; + font-weight: 700; + margin-bottom: 0.35rem; + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.04em; + color: #8a3d34; +} + +.workspace-missing-list { + margin: 0; + padding-left: 1.15rem; +} + +.workspace-missing-list li { + margin: 0.15rem 0; +} + +.settings-summary-card--warning { + border-color: #e8a598; + background: #fff8f6; +} + +label.field-needs-attention span:first-of-type, +.settings-field-league.field-needs-attention > span:first-of-type { + color: #8a2e22; + font-weight: 600; +} + +.field-needs-attention select, +.field-needs-attention-wrap .compact-url-input { + border-color: #d97b6a !important; + box-shadow: 0 0 0 1px rgba(217, 123, 106, 0.35); +} + +.field-attention-hint { + display: block; + font-size: 0.8rem; + color: #9d3b32; + margin-top: 0.35rem; +} + +.field-attention-hint-block { + margin-top: 0.25rem; + margin-bottom: 0.35rem; +} + +.mytt-missing-checklist { + margin: 0.4rem 0 0; + padding-left: 1.2rem; + color: var(--text-color); + font-size: 0.9rem; +} + +.mytt-missing-checklist li { + margin: 0.2rem 0; +} + .workspace-section-panel { background: white; border: 1px solid var(--border-color);