localization/formFill: Improve german translation and add localization (#7255)

# Description of Changes
The formFill tool name and description as well as the notification popup
for forms were missing their german translations. There were also some
hardcoded text elements in the UI.

Added translations of formFill-related tags and new tags and translation
method for hardcoded strings.

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [x] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation
- [x] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have run `task check` to verify linters, typechecks, and tests
pass
- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.

---------

Signed-off-by: Carsten Drewes <c.drewes@stud.uni-hannover.de>
This commit is contained in:
kastenherri
2026-08-09 12:44:16 +01:00
committed by GitHub
parent 0286c716de
commit 3260f5415d
4 changed files with 43 additions and 21 deletions
@@ -4084,10 +4084,15 @@ issues = "GitHub"
[formFill]
allSaved = "Alles gespeichert"
analyzingFields = "Analysiere Formularfelder..."
extractCsvError = "CSV konnte nicht extrahiert werden"
extractXlsxError = "XLSX konnte nicht extrahiert werden"
filled = "ausgefüllt"
flattenAfterFilling = "Nach dem Ausfüllen ebnen"
requiredAbbreviation = "erf."
noFields = "Keine ausfüllbaren Formularfelder gefunden."
placeholderEnter = "Eingabe:"
placeholderSelect = "Auswahl:"
requiredAbbreviation = "erf"
requiredFieldsError = "Bitte füllen Sie alle Pflichtfelder aus"
rescanFields = "Felder erneut scannen"
rescanFormFields = "Formularfelder erneut scannen"
@@ -4416,8 +4421,8 @@ tags = "vereinfachen,entfernen,interaktiv"
title = "Abflachen"
[home.formFill]
desc = "Fill PDF form fields interactively with a visual editor"
title = "Fill Form"
desc = "PDF-Formularfelder interaktiv mit visuellem Editor ausfüllen"
title = "Formular ausfüllen"
[home.getPdfInfo]
desc = "Erfasst alle möglichen Informationen in einer PDF"
@@ -10292,13 +10297,13 @@ viewComment = "Kommentar anzeigen"
noFileProvided = "Fehler: Dem Viewer wurde keine Datei übergeben"
[viewer.formBar]
apply = "Apply Changes"
dismiss = "Dismiss"
download = "Download PDF"
hasFieldsDesc = "This PDF contains fillable fields"
title = "Form Fields"
unsavedBadge = "Unsaved"
unsavedDesc = "You have unsaved changes"
apply = "Änderungen anwenden"
dismiss = "Verwerfen"
download = "PDF herunterladen"
hasFieldsDesc = "Dieses PDF enthält ausfüllbare Felder"
title = "Formularfelder"
unsavedBadge = "Ungespeichert"
unsavedDesc = "Sie haben ungespeicherte Änderungen"
[viewer.layers]
closeSidebar = "Seitenleiste für Ebenen schließen"
@@ -4241,9 +4241,14 @@ issues = "GitHub"
[formFill]
allSaved = "All saved"
analyzingFields = "Analysing form fields..."
extractCsvError = "Failed to extract CSV"
extractXlsxError = "Failed to extract XLSX"
filled = "filled"
flattenAfterFilling = "Flatten after filling"
noFields = "No fillable form fields found in this PDF."
placeholderEnter = "Enter"
placeholderSelect = "Select"
requiredAbbreviation = "req"
requiredFieldsError = "Please fill in all required fields"
rescanFields = "Re-scan fields"
@@ -15,6 +15,7 @@ import {
MultiSelect,
Stack,
} from "@mantine/core";
import { useTranslation } from "react-i18next";
import { useFieldValue } from "@app/tools/formFill/FormFillContext";
import type { FormField } from "@app/tools/formFill/types";
@@ -31,7 +32,7 @@ function FieldInputInner({
(v: string) => onValueChange(field.name, v),
[onValueChange, field.name],
);
const { t } = useTranslation();
switch (field.type) {
case "text":
if (field.multiline) {
@@ -40,7 +41,10 @@ function FieldInputInner({
size="xs"
value={value}
onChange={(e) => onChange(e.currentTarget.value)}
placeholder={field.tooltip || `Enter ${field.label}`}
placeholder={
field.tooltip ||
`${t("formFill.placeholderEnter", "Enter")} ${field.label}`
}
disabled={field.readOnly}
autosize
minRows={2}
@@ -54,7 +58,10 @@ function FieldInputInner({
size="xs"
value={value}
onChange={(e) => onChange(e.currentTarget.value)}
placeholder={field.tooltip || `Enter ${field.label}`}
placeholder={
field.tooltip ||
`${t("formFill.placeholderEnter", "Enter")} ${field.label}`
}
disabled={field.readOnly}
styles={{ input: { fontSize: "0.8125rem" } }}
/>
@@ -85,7 +92,7 @@ function FieldInputInner({
data={comboData}
value={value || null}
onChange={(v) => onChange(v || "")}
placeholder={`Select ${field.label}`}
placeholder={`${t("formFill.placeholderSelect", "Select")} ${field.label}`}
clearable
searchable
disabled={field.readOnly}
@@ -109,7 +116,7 @@ function FieldInputInner({
data={listData}
value={selectedValues}
onChange={(vals) => onChange(vals.join(","))}
placeholder={`Select ${field.label}`}
placeholder={`${t("formFill.placeholderSelect", "Select")} ${field.label}`}
searchable
disabled={field.readOnly}
aria-label={field.label || field.name}
@@ -124,7 +131,7 @@ function FieldInputInner({
data={listData}
value={value || null}
onChange={(v) => onChange(v || "")}
placeholder={`Select ${field.label}`}
placeholder={`${t("formFill.placeholderSelect", "Select")} ${field.label}`}
clearable
searchable
disabled={field.readOnly}
@@ -436,7 +436,7 @@ const FormFill = (_props: BaseToolProps) => {
>
<Loader size={14} />
<Text size="xs" c="dimmed">
Analysing form fields...
{t("formFill.analyzingFields", "Analysing form fields...")}
</Text>
</div>
<Skeleton height={48} radius="sm" />
@@ -464,10 +464,12 @@ const FormFill = (_props: BaseToolProps) => {
<div>
<div className={styles.progressRow}>
<span className={styles.progressLabel}>
{filledCount} / {fillableCount} filled
{filledCount} / {fillableCount}{" "}
{t("formFill.filled", "filled")}
{requiredCount > 0 && (
<span style={{ marginLeft: "0.5rem", opacity: 0.7 }}>
({filledRequiredCount}/{requiredCount} req.)
({filledRequiredCount}/{requiredCount}{" "}
{t("formFill.requiredAbbreviation", "req")}.)
</span>
)}
</span>
@@ -588,7 +590,10 @@ const FormFill = (_props: BaseToolProps) => {
<div className={styles.emptyState}>
<DescriptionIcon className={styles.emptyStateIcon} />
<span className={styles.emptyStateText}>
No fillable form fields found in this PDF.
{t(
"formFill.noFields",
"No fillable form fields found in this PDF.",
)}
</span>
</div>
)}
@@ -605,7 +610,7 @@ const FormFill = (_props: BaseToolProps) => {
style={i === 0 ? { marginTop: 0 } : undefined}
>
<Text className={styles.pageDividerLabel}>
Page {pageIdx + 1}
{t("page", "Page")} {pageIdx + 1}
</Text>
</div>