fix(i18n): add missing marketplace.accessDenied and translate calendar form
- Add marketplace.accessDenied to de.json and en.json - Add 12 calendar form field/action keys to widgets.calendar in both locales - Replace all hardcoded English strings in calendar-source-form.tsx with t() calls - Remove locale-detection hack on Cancel button (was comparing t() result to English string) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -83,16 +83,16 @@ export function CalendarSourceForm({
|
|||||||
try {
|
try {
|
||||||
const parsed = new URL(value);
|
const parsed = new URL(value);
|
||||||
if (parsed.protocol !== 'https:') {
|
if (parsed.protocol !== 'https:') {
|
||||||
setUrlError('URL must use HTTPS protocol');
|
setUrlError(t('calendar.formUrlErrorHttps'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
setUrlError('');
|
setUrlError('');
|
||||||
return true;
|
return true;
|
||||||
} catch {
|
} catch {
|
||||||
setUrlError('Invalid URL format');
|
setUrlError(t('calendar.formUrlErrorInvalid'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}, []);
|
}, [t]);
|
||||||
|
|
||||||
// Form is valid when name, type, and url are filled and url is https
|
// Form is valid when name, type, and url are filled and url is https
|
||||||
const isFormValid =
|
const isFormValid =
|
||||||
@@ -136,7 +136,7 @@ export function CalendarSourceForm({
|
|||||||
{/* Name */}
|
{/* Name */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="source-name" className="mb-1 block text-sm text-foreground">
|
<label htmlFor="source-name" className="mb-1 block text-sm text-foreground">
|
||||||
Name *
|
{t('calendar.formFieldName')} *
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="source-name"
|
id="source-name"
|
||||||
@@ -151,7 +151,7 @@ export function CalendarSourceForm({
|
|||||||
{/* Type */}
|
{/* Type */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="source-type" className="mb-1 block text-sm text-foreground">
|
<label htmlFor="source-type" className="mb-1 block text-sm text-foreground">
|
||||||
Type *
|
{t('calendar.formFieldType')} *
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="source-type"
|
id="source-type"
|
||||||
@@ -176,7 +176,7 @@ export function CalendarSourceForm({
|
|||||||
htmlFor="exchange-mode"
|
htmlFor="exchange-mode"
|
||||||
className="mb-1 block text-sm text-foreground"
|
className="mb-1 block text-sm text-foreground"
|
||||||
>
|
>
|
||||||
Exchange Mode
|
{t('calendar.formFieldExchangeMode')}
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="exchange-mode"
|
id="exchange-mode"
|
||||||
@@ -196,7 +196,7 @@ export function CalendarSourceForm({
|
|||||||
{/* URL */}
|
{/* URL */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="source-url" className="mb-1 block text-sm text-foreground">
|
<label htmlFor="source-url" className="mb-1 block text-sm text-foreground">
|
||||||
URL *
|
{t('calendar.formFieldUrl')} *
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="source-url"
|
id="source-url"
|
||||||
@@ -228,7 +228,7 @@ export function CalendarSourceForm({
|
|||||||
htmlFor="source-username"
|
htmlFor="source-username"
|
||||||
className="mb-1 block text-sm text-foreground"
|
className="mb-1 block text-sm text-foreground"
|
||||||
>
|
>
|
||||||
Username
|
{t('calendar.formFieldUsername')}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="source-username"
|
id="source-username"
|
||||||
@@ -247,7 +247,7 @@ export function CalendarSourceForm({
|
|||||||
htmlFor="source-password"
|
htmlFor="source-password"
|
||||||
className="mb-1 block text-sm text-foreground"
|
className="mb-1 block text-sm text-foreground"
|
||||||
>
|
>
|
||||||
Password
|
{t('calendar.formFieldPassword')}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="source-password"
|
id="source-password"
|
||||||
@@ -261,7 +261,7 @@ export function CalendarSourceForm({
|
|||||||
|
|
||||||
{/* Color */}
|
{/* Color */}
|
||||||
<div>
|
<div>
|
||||||
<label className="mb-1 block text-sm text-foreground">Color</label>
|
<label className="mb-1 block text-sm text-foreground">{t('calendar.formFieldColor')}</label>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
{SOURCE_COLOR_PALETTE.map((c) => (
|
{SOURCE_COLOR_PALETTE.map((c) => (
|
||||||
<button
|
<button
|
||||||
@@ -288,14 +288,14 @@ export function CalendarSourceForm({
|
|||||||
disabled={!isFormValid || isSaving}
|
disabled={!isFormValid || isSaving}
|
||||||
className="rounded bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed"
|
className="rounded bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
>
|
>
|
||||||
{isSaving ? 'Saving...' : 'Save'}
|
{isSaving ? t('calendar.formSaving') : t('calendar.formSave')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onCancel}
|
onClick={onCancel}
|
||||||
className="rounded border border-border px-4 py-2 text-sm text-foreground transition-colors hover:bg-muted"
|
className="rounded border border-border px-4 py-2 text-sm text-foreground transition-colors hover:bg-muted"
|
||||||
>
|
>
|
||||||
{t('calendar.addSource') === 'Add source' ? 'Cancel' : 'Abbrechen'}
|
{t('calendar.formCancel')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -124,6 +124,15 @@
|
|||||||
"uploadCta": "Bild hochladen",
|
"uploadCta": "Bild hochladen",
|
||||||
"uploadSuccess": "Profilbild wurde erfolgreich aktualisiert.",
|
"uploadSuccess": "Profilbild wurde erfolgreich aktualisiert.",
|
||||||
"uploadError": "Hochladen fehlgeschlagen. Bitte pruefen Sie das Dateiformat und die Dateigröße.",
|
"uploadError": "Hochladen fehlgeschlagen. Bitte pruefen Sie das Dateiformat und die Dateigröße.",
|
||||||
|
"deleteAvatarCta": "Bild löschen",
|
||||||
|
"deleteAvatarSuccess": "Profilbild wurde gelöscht.",
|
||||||
|
"deleteAvatarError": "Löschen fehlgeschlagen.",
|
||||||
|
"accentColorLabel": "Akzentfarbe",
|
||||||
|
"accentColorHelp": "Wird für Buttons, Highlights und aktive Elemente verwendet. Standard: #ffed00.",
|
||||||
|
"accentColorSave": "Farbe speichern",
|
||||||
|
"accentColorReset": "Zurücksetzen",
|
||||||
|
"accentColorSuccess": "Akzentfarbe wurde gespeichert.",
|
||||||
|
"accentColorError": "Speichern fehlgeschlagen.",
|
||||||
"ldapManagedNotice": "Ihr Passwort wird ueber das Verzeichnis (LDAP) verwaltet. Eine Aenderung ist hier nicht moeglich.",
|
"ldapManagedNotice": "Ihr Passwort wird ueber das Verzeichnis (LDAP) verwaltet. Eine Aenderung ist hier nicht moeglich.",
|
||||||
"passwordSectionTitle": "Passwort aendern"
|
"passwordSectionTitle": "Passwort aendern"
|
||||||
},
|
},
|
||||||
@@ -185,13 +194,27 @@
|
|||||||
"connectionSuccess": "Verbindung erfolgreich",
|
"connectionSuccess": "Verbindung erfolgreich",
|
||||||
"connectionError": "Verbindung fehlgeschlagen. Bitte ueberpruefen Sie die URL und Zugangsdaten.",
|
"connectionError": "Verbindung fehlgeschlagen. Bitte ueberpruefen Sie die URL und Zugangsdaten.",
|
||||||
"addSource": "Quelle hinzufuegen",
|
"addSource": "Quelle hinzufuegen",
|
||||||
"sourceEmpty": "Keine Kalenderquellen eingerichtet. Fuegen Sie eine Quelle hinzu, um Termine anzuzeigen."
|
"sourceEmpty": "Keine Kalenderquellen eingerichtet. Fuegen Sie eine Quelle hinzu, um Termine anzuzeigen.",
|
||||||
|
"formFieldName": "Name",
|
||||||
|
"formFieldType": "Typ",
|
||||||
|
"formFieldUrl": "URL",
|
||||||
|
"formFieldUsername": "Benutzername",
|
||||||
|
"formFieldPassword": "Passwort",
|
||||||
|
"formFieldColor": "Farbe",
|
||||||
|
"formFieldExchangeMode": "Exchange-Modus",
|
||||||
|
"formSave": "Speichern",
|
||||||
|
"formSaving": "Wird gespeichert...",
|
||||||
|
"formCancel": "Abbrechen",
|
||||||
|
"formUrlErrorHttps": "URL muss HTTPS verwenden",
|
||||||
|
"formUrlErrorInvalid": "Ungültiges URL-Format"
|
||||||
},
|
},
|
||||||
"note": {
|
"note": {
|
||||||
"name": "Notizen",
|
"name": "Notizen",
|
||||||
"description": "Freitext-Notizen mit Markdown",
|
"description": "Freitext-Notizen mit Markdown",
|
||||||
"defaultTitle": "Notiz",
|
"defaultTitle": "Notiz",
|
||||||
"autosaveError": "Speichern fehlgeschlagen"
|
"autosaveError": "Speichern fehlgeschlagen",
|
||||||
|
"editMode": "Bearbeiten",
|
||||||
|
"viewMode": "Vorschau"
|
||||||
},
|
},
|
||||||
"calculator": {
|
"calculator": {
|
||||||
"name": "Taschenrechner",
|
"name": "Taschenrechner",
|
||||||
@@ -434,6 +457,7 @@
|
|||||||
"backToMarketplace": "Zurueck zum Marktplatz",
|
"backToMarketplace": "Zurueck zum Marktplatz",
|
||||||
"detailVersion": "Version {version}",
|
"detailVersion": "Version {version}",
|
||||||
"detailStatusActive": "Aktiviert fuer diesen Mandanten",
|
"detailStatusActive": "Aktiviert fuer diesen Mandanten",
|
||||||
"detailStatusInactive": "Nicht aktiviert"
|
"detailStatusInactive": "Nicht aktiviert",
|
||||||
|
"accessDenied": "Zugriff verweigert"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,6 +124,15 @@
|
|||||||
"uploadCta": "Upload picture",
|
"uploadCta": "Upload picture",
|
||||||
"uploadSuccess": "Profile picture updated successfully.",
|
"uploadSuccess": "Profile picture updated successfully.",
|
||||||
"uploadError": "Upload failed. Please check the file format and size.",
|
"uploadError": "Upload failed. Please check the file format and size.",
|
||||||
|
"deleteAvatarCta": "Delete picture",
|
||||||
|
"deleteAvatarSuccess": "Profile picture deleted.",
|
||||||
|
"deleteAvatarError": "Delete failed.",
|
||||||
|
"accentColorLabel": "Accent Color",
|
||||||
|
"accentColorHelp": "Used for buttons, highlights and active elements. Default: #ffed00.",
|
||||||
|
"accentColorSave": "Save color",
|
||||||
|
"accentColorReset": "Reset",
|
||||||
|
"accentColorSuccess": "Accent color saved.",
|
||||||
|
"accentColorError": "Save failed.",
|
||||||
"ldapManagedNotice": "Your password is managed via the directory (LDAP) and cannot be changed here.",
|
"ldapManagedNotice": "Your password is managed via the directory (LDAP) and cannot be changed here.",
|
||||||
"passwordSectionTitle": "Change Password"
|
"passwordSectionTitle": "Change Password"
|
||||||
},
|
},
|
||||||
@@ -185,13 +194,27 @@
|
|||||||
"connectionSuccess": "Connection successful",
|
"connectionSuccess": "Connection successful",
|
||||||
"connectionError": "Connection failed. Please check the URL and credentials.",
|
"connectionError": "Connection failed. Please check the URL and credentials.",
|
||||||
"addSource": "Add source",
|
"addSource": "Add source",
|
||||||
"sourceEmpty": "No calendar sources configured. Add a source to display events."
|
"sourceEmpty": "No calendar sources configured. Add a source to display events.",
|
||||||
|
"formFieldName": "Name",
|
||||||
|
"formFieldType": "Type",
|
||||||
|
"formFieldUrl": "URL",
|
||||||
|
"formFieldUsername": "Username",
|
||||||
|
"formFieldPassword": "Password",
|
||||||
|
"formFieldColor": "Color",
|
||||||
|
"formFieldExchangeMode": "Exchange Mode",
|
||||||
|
"formSave": "Save",
|
||||||
|
"formSaving": "Saving...",
|
||||||
|
"formCancel": "Cancel",
|
||||||
|
"formUrlErrorHttps": "URL must use HTTPS protocol",
|
||||||
|
"formUrlErrorInvalid": "Invalid URL format"
|
||||||
},
|
},
|
||||||
"note": {
|
"note": {
|
||||||
"name": "Notes",
|
"name": "Notes",
|
||||||
"description": "Free-text notes with Markdown",
|
"description": "Free-text notes with Markdown",
|
||||||
"defaultTitle": "Note",
|
"defaultTitle": "Note",
|
||||||
"autosaveError": "Save failed"
|
"autosaveError": "Save failed",
|
||||||
|
"editMode": "Edit",
|
||||||
|
"viewMode": "Preview"
|
||||||
},
|
},
|
||||||
"calculator": {
|
"calculator": {
|
||||||
"name": "Calculator",
|
"name": "Calculator",
|
||||||
@@ -434,6 +457,7 @@
|
|||||||
"backToMarketplace": "Back to Marketplace",
|
"backToMarketplace": "Back to Marketplace",
|
||||||
"detailVersion": "Version {version}",
|
"detailVersion": "Version {version}",
|
||||||
"detailStatusActive": "Activated for this tenant",
|
"detailStatusActive": "Activated for this tenant",
|
||||||
"detailStatusInactive": "Not activated"
|
"detailStatusInactive": "Not activated",
|
||||||
|
"accessDenied": "Access denied"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user