feat(modality): rename "file" modality label "Data" -> "Files"

The fifth user-facing group is now Image, Video, Audio, PDF, Files
(internal modality id stays "file"; section.ts "files" was already
"Files"). Updates modality.ts label + comment, all 21 i18n locales
(categories.data "Data Files"->"Files", modalities.documentsAndFiles
"PDF & Data"->"PDF & Files", dead homePage.data), landing cards/hero
search/tools filter, docs headings, and e2e modality-tab assertions
(/^Data/ -> /^Files/, which had been failing).
This commit is contained in:
SnapOtter
2026-06-21 02:45:56 +08:00
parent 8001ec97f1
commit 71fefc05b0
34 changed files with 80 additions and 80 deletions
+1 -1
View File
@@ -314,7 +314,7 @@ All AI tools run on your hardware (CPU or NVIDIA GPU). No internet required.
| `to-epub` | Convert to EPUB | - (accepts .docx, .md, .html, .txt) |
| `ocr-pdf` | PDF OCR (AI) | `quality` (fast/balanced/best), `language` (auto/en/de/fr/es/zh/ja/ko), `pages` |
### Data Tools
### File Tools
| Tool ID | Name | Key settings |
|---------|------|-------------|
+1 -1
View File
@@ -117,7 +117,7 @@ pnpm dev
| **Video** | 29 | Trim, Crop, Compress, Convert, Merge, Extract Audio, Auto Subtitles, Video to GIF, Resize, Stabilize |
| **Audio** | 17 | Trim, Merge, Convert, Normalize, Noise Reduction, Transcribe, Pitch Shift, Fade, Ringtone Maker |
| **PDF / Document** | 37 | Merge, Split, Compress, OCR, Watermark, Redact, Word to PDF, Excel to PDF, Rotate, Protect, Repair |
| **Data** | 10 | CSV to JSON, JSON to XML, Merge CSVs, Split CSV, Create ZIP, Extract ZIP, Chart Maker, YAML/JSON |
| **Files** | 10 | CSV to JSON, JSON to XML, Merge CSVs, Split CSV, Create ZIP, Extract ZIP, Chart Maker, YAML/JSON |
### Pipelines
+1 -1
View File
@@ -148,7 +148,7 @@ Document processing uses qpdf, LibreOffice, Ghostscript, Pandoc, and WeasyPrint.
| **Input** | PDF, DOCX, DOC, XLSX, XLS, PPTX, PPT, ODT, ODS, ODP, RTF, TXT, Markdown, HTML, EPUB |
| **Output** | PDF, PDF/A, DOCX, HTML, EPUB, images (via PDF to Image) |
## Data Formats
## File Formats
| Type | Formats |
|------|---------|
@@ -51,7 +51,7 @@ const MODALITIES = [
{
id: "file",
section: "files",
label: "Data & Files",
label: "Files",
blurb: "Convert and transform",
icon: "Database",
color: "#5C8642",
+1 -1
View File
@@ -7,7 +7,7 @@ const MODALITY_META: Record<string, { label: string; color: string }> = {
video: { label: "Video", color: "#BE4A3C" },
audio: { label: "Audio", color: "#2C7A75" },
document: { label: "PDF", color: "#44568C" },
file: { label: "Data", color: "#5C8642" },
file: { label: "Files", color: "#5C8642" },
};
function renderIcon(iconName: string): string {
+1 -1
View File
@@ -37,7 +37,7 @@ const modalityFilters = [
label: "PDF & Docs",
count: TOOLS.filter((t) => t.modality === "document").length,
},
{ id: "file", label: "Data", count: TOOLS.filter((t) => t.modality === "file").length },
{ id: "file", label: "Files", count: TOOLS.filter((t) => t.modality === "file").length },
];
const breadcrumbJsonLd = {
+1 -1
View File
@@ -192,7 +192,7 @@ export const TOOL_DISPLAY_MODES: Record<string, DisplayMode> = {
"epub-convert": "no-comparison",
"to-epub": "no-comparison",
// Data tools
// File tools
"chart-maker": "no-comparison",
"csv-excel": "no-comparison",
"csv-json": "no-comparison",
+1 -1
View File
@@ -1106,7 +1106,7 @@ const ENTRY_CONFIG: ReadonlyArray<[string, RegistryEntryConfig]> = [
["html-to-pdf", { accept: ".html,.htm", Settings: HtmlToPdfSettings }],
["markdown-to-pdf", { accept: ".md,.markdown", Settings: MarkdownToPdfSettings }],
// Data tools
// File tools
["chart-maker", { accept: ".csv,.json", Settings: ChartMakerSettings }],
["csv-excel", { accept: ".csv,.tsv,.xlsx", Settings: CsvExcelSettings }],
["csv-json", { accept: ".csv,.tsv,.json", Settings: CsvJsonSettings }],
+3 -3
View File
@@ -63,14 +63,14 @@ export const ar: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2488,7 +2488,7 @@ export const ar: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const de: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2502,7 +2502,7 @@ export const de: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+4 -4
View File
@@ -65,15 +65,15 @@ export const en = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
// Data & Files
data: "Data Files",
// Files
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2452,7 +2452,7 @@ export const en = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const es: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2484,7 +2484,7 @@ export const es: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const fr: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2503,7 +2503,7 @@ export const fr: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const hi: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2485,7 +2485,7 @@ export const hi: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const id: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2497,7 +2497,7 @@ export const id: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const it: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2496,7 +2496,7 @@ export const it: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const ja: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2455,7 +2455,7 @@ export const ja: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const ko: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2440,7 +2440,7 @@ export const ko: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const nl: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2499,7 +2499,7 @@ export const nl: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const pl: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2500,7 +2500,7 @@ export const pl: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const ptBR: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2496,7 +2496,7 @@ export const ptBR: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const ru: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2498,7 +2498,7 @@ export const ru: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const sv: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2495,7 +2495,7 @@ export const sv: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const th: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2477,7 +2477,7 @@ export const th: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const tr: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2500,7 +2500,7 @@ export const tr: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const uk: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2498,7 +2498,7 @@ export const uk: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const vi: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2497,7 +2497,7 @@ export const vi: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const zhCN: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2430,7 +2430,7 @@ export const zhCN: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+3 -3
View File
@@ -63,14 +63,14 @@ export const zhTW: TranslationKeys = {
"pdf-security": "Security",
"pdf-optimize": "Optimize",
"doc-convert": "Convert",
data: "Data Files",
data: "Files",
archives: "Archives",
},
modalities: {
image: "Image",
video: "Video",
audio: "Audio",
documentsAndFiles: "PDF & Data",
documentsAndFiles: "PDF & Files",
},
tools: {
resize: {
@@ -2428,7 +2428,7 @@ export const zhTW: TranslationKeys = {
clearSearch: "Clear search",
all: "All",
documents: "PDF",
data: "Data",
data: "Files",
pdf: "PDF",
files: "Files",
toolCount: "{count} tools",
+2 -2
View File
@@ -8,13 +8,13 @@ export interface ModalityInfo {
}
// Five modality values in code, surfaced as five UI sections:
// Image, Video, Audio, PDF ("document" id) and Data ("file" id).
// Image, Video, Audio, PDF ("document" id) and Files ("file" id).
export const MODALITIES: ModalityInfo[] = [
{ id: "image", name: "Image", icon: "Image", color: "#3B82F6" },
{ id: "video", name: "Video", icon: "Video", color: "#EF4444" },
{ id: "audio", name: "Audio", icon: "AudioLines", color: "#10B981" },
{ id: "document", name: "PDF", icon: "FileText", color: "#8B5CF6" },
{ id: "file", name: "Data", icon: "FileArchive", color: "#F59E0B" },
{ id: "file", name: "Files", icon: "FileArchive", color: "#F59E0B" },
];
// Which BullMQ pool a modality's tools run on. AI tools override to "ai"
+1 -1
View File
@@ -40,7 +40,7 @@ test.describe("Landing Homepage", () => {
});
test("hero modality cards render", async ({ page }) => {
const cards = ["Image Tools", "Video Tools", "Audio Tools", "PDF & Documents", "Data & Files"];
const cards = ["Image Tools", "Video Tools", "Audio Tools", "PDF & Documents", "Files"];
for (const card of cards) {
await expect(page.getByText(card, { exact: true }).first()).toBeVisible();
}
+2 -2
View File
@@ -11,7 +11,7 @@ test.describe("Home Page", () => {
});
test("modality tabs are visible", async ({ loggedInPage: page }) => {
// 2.0 home page has modality tabs: All, Image, Video, Audio, PDF, Data
// 2.0 home page has modality tabs: All, Image, Video, Audio, PDF, Files
// Tab buttons render label + a count span, so the accessible name is e.g.
// "Image5" (no word boundary before the digit) — match on the label prefix.
await expect(page.getByRole("button", { name: /^All/ }).first()).toBeVisible();
@@ -19,7 +19,7 @@ test.describe("Home Page", () => {
await expect(page.getByRole("button", { name: /^Video/ }).first()).toBeVisible();
await expect(page.getByRole("button", { name: /^Audio/ }).first()).toBeVisible();
await expect(page.getByRole("button", { name: /^PDF/ }).first()).toBeVisible();
await expect(page.getByRole("button", { name: /^Data/ }).first()).toBeVisible();
await expect(page.getByRole("button", { name: /^Files/ }).first()).toBeVisible();
});
test("tool categories are visible on home page", async ({ loggedInPage: page }) => {
@@ -132,7 +132,7 @@ const TOOL_FIXTURE: Record<string, FixtureSpec> = {
"convert-presentation": { buffer: PPTX, filename: "test.pptx" },
"epub-convert": { buffer: EPUB, filename: "test.epub" },
"ocr-pdf": PDF_FIX,
// Data tools
// File tools
"csv-excel": CSV_FIX,
"csv-json": CSV_FIX,
"json-xml": { buffer: JSON_F, filename: "test.json" },
@@ -173,8 +173,8 @@ describe("cross-modality launch smoke", () => {
30_000,
);
// ── Data/File: csv-json (pure JS, no binary) ─────────────────────
it("data modality: csv-json", async () => {
// ── Files: csv-json (pure JS, no binary) ─────────────────────
it("file modality: csv-json", async () => {
const file = readFixture(fixtures.data.csv);
const res = await postTool(app, adminToken, "csv-json", file, "tiny.csv", "text/csv", {
direction: "csv-to-json",