mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-09-21 22:26:48 +00:00
i18n: lokalizované kategórie aplikácií
This commit is contained in:
@@ -9,6 +9,7 @@ import { ThemeAwareLogo } from "./lxc-app-panel"
|
||||
import { CustomLinkEditor, type CustomLink, type GuestOption } from "./custom-link-editor"
|
||||
import { Button } from "./ui/button"
|
||||
import { categoryChipStyle, useIsLightTheme } from "../lib/category-color"
|
||||
import { getCategoryLabel } from "../lib/category-label"
|
||||
|
||||
// ─── Local subset of /api/vms shape ─────────────────────────────
|
||||
// Kept narrow on purpose — this component only needs what feeds a
|
||||
@@ -248,8 +249,8 @@ export function AppsDashboard() {
|
||||
return map
|
||||
}, [links, t])
|
||||
const sortedCategoryEntries = useMemo(
|
||||
() => Array.from(categoryCounts.entries()).sort((a, b) => a[0].localeCompare(b[0])),
|
||||
[categoryCounts],
|
||||
() => Array.from(categoryCounts.entries()).sort((a, b) => getCategoryLabel(t, a[0]).localeCompare(getCategoryLabel(t, b[0]))),
|
||||
[categoryCounts, t],
|
||||
)
|
||||
|
||||
// ─── Controls state ────────────────────────────────────────────
|
||||
@@ -327,7 +328,8 @@ export function AppsDashboard() {
|
||||
l.appName.toLowerCase().includes(q) ||
|
||||
(l.ctName || "").toLowerCase().includes(q) ||
|
||||
(l.vmid != null && String(l.vmid).includes(q)) ||
|
||||
(l.category || "").toLowerCase().includes(q)
|
||||
(l.category || "").toLowerCase().includes(q) ||
|
||||
getCategoryLabel(t, l.category || "").toLowerCase().includes(q)
|
||||
)
|
||||
}
|
||||
const sorted = [...filtered]
|
||||
@@ -344,7 +346,7 @@ export function AppsDashboard() {
|
||||
// category — grouped alphabetically, then by app name inside
|
||||
const catA = a.category || uncatKey
|
||||
const catB = b.category || uncatKey
|
||||
const c = catA.localeCompare(catB)
|
||||
const c = getCategoryLabel(t, catA).localeCompare(getCategoryLabel(t, catB))
|
||||
return c !== 0 ? c : a.appName.localeCompare(b.appName)
|
||||
})
|
||||
return sorted
|
||||
@@ -432,7 +434,7 @@ export function AppsDashboard() {
|
||||
>
|
||||
<option value={ALL_CATEGORIES}>{t("apps.filterAll")}</option>
|
||||
{sortedCategoryEntries.map(([cat, n]) => (
|
||||
<option key={cat} value={cat}>{`${cat} · ${n}`}</option>
|
||||
<option key={cat} value={cat}>{`${getCategoryLabel(t, cat)} · ${n}`}</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
@@ -532,6 +534,7 @@ function CardsGrid({
|
||||
editMode: boolean
|
||||
onEditCustom: (customId: string) => void
|
||||
}) {
|
||||
const t = useT()
|
||||
if (!links.length) {
|
||||
return (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-3">
|
||||
@@ -572,7 +575,7 @@ function CardsGrid({
|
||||
{groups.map(([cat, items]) => (
|
||||
<div key={`grp-${cat}`} className="contents">
|
||||
<h3 className="col-span-full uppercase text-xs tracking-wider text-muted-foreground font-semibold pt-3 pb-1.5 border-b border-border/60 flex items-center gap-2">
|
||||
<span>{cat}</span>
|
||||
<span>{getCategoryLabel(t, cat)}</span>
|
||||
<span className="font-mono tabular-nums text-[10px] px-1.5 py-0.5 rounded bg-card border border-border/60 font-normal">{items.length}</span>
|
||||
</h3>
|
||||
{items.map((link) => (
|
||||
@@ -715,9 +718,9 @@ function AppCard({
|
||||
<span
|
||||
style={categoryChipStyle(link.category, isLightTheme)}
|
||||
className="ml-auto px-1.5 py-0.5 border rounded text-[10px] font-medium flex-shrink-0 truncate max-w-[45%]"
|
||||
title={link.category}
|
||||
title={getCategoryLabel(t, link.category)}
|
||||
>
|
||||
{link.category}
|
||||
{getCategoryLabel(t, link.category)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useEffect, useState } from "react"
|
||||
import { Trash2 } from "lucide-react"
|
||||
import { fetchApi } from "../lib/api-config"
|
||||
import { useT } from "../lib/i18n/provider"
|
||||
import { getCategoryLabel } from "../lib/category-label"
|
||||
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "./ui/dialog"
|
||||
import { Button } from "./ui/button"
|
||||
import { Input } from "./ui/input"
|
||||
@@ -237,7 +238,7 @@ export function CustomLinkEditor({
|
||||
<SelectContent>
|
||||
<SelectItem value="__none__">{t("vmLxc.appEditor.portCategoryNone")}</SelectItem>
|
||||
{categoryPresets.map((c) => (
|
||||
<SelectItem key={c} value={c}>{c}</SelectItem>
|
||||
<SelectItem key={c} value={c}>{getCategoryLabel(t, c)}</SelectItem>
|
||||
))}
|
||||
<SelectItem value="__add__">{t("vmLxc.appEditor.portCategoryAddNew")}</SelectItem>
|
||||
</SelectContent>
|
||||
|
||||
@@ -35,6 +35,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from ".
|
||||
import { fetchApi } from "../lib/api-config"
|
||||
import { fetchLxcApps, getLxcAppsCached, setLxcAppsCached, subscribeLxcApps } from "../lib/lxc-apps-cache"
|
||||
import { categoryChipStyle, useIsLightTheme } from "../lib/category-color"
|
||||
import { getCategoryLabel } from "../lib/category-label"
|
||||
import { useT } from "@/lib/i18n/provider"
|
||||
|
||||
// installed_via is optional now — an empty value means "register only,
|
||||
@@ -1604,7 +1605,7 @@ export function LxcAppPanel({ vmid, ctIp, onChange, managed, initialData }: Prop
|
||||
<SelectContent>
|
||||
<SelectItem value="__none__">{t("vmLxc.appEditor.portCategoryNone")}</SelectItem>
|
||||
{categoryPresets.map((c) => (
|
||||
<SelectItem key={c} value={c}>{c}</SelectItem>
|
||||
<SelectItem key={c} value={c}>{getCategoryLabel(t, c)}</SelectItem>
|
||||
))}
|
||||
<SelectItem value="__add__">{t("vmLxc.appEditor.portCategoryAddNew")}</SelectItem>
|
||||
</SelectContent>
|
||||
@@ -2649,9 +2650,9 @@ export function LxcAppPanel({ vmid, ctIp, onChange, managed, initialData }: Prop
|
||||
<span
|
||||
style={categoryChipStyle(p.category, isLightTheme)}
|
||||
className="flex-shrink-0 px-1.5 py-0.5 border rounded text-[10px] font-medium truncate max-w-[40%]"
|
||||
title={p.category}
|
||||
title={getCategoryLabel(t, p.category)}
|
||||
>
|
||||
{p.category}
|
||||
{getCategoryLabel(t, p.category)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user