fix(web): update Russian translations for various components
Обновлены переводы на русский язык для компонентов, включая карточки мониторинга, сетевые панели и настройки. Исправлены описания и метки для улучшения пользовательского интерфейса, а также добавлены новые элементы для поддержки локализации в компонентах, таких как DataGrid и ResourcePage.
This commit is contained in:
@@ -61,7 +61,7 @@ function DataGridColumnFilter<TData, TValue>({
|
||||
<div className="hidden space-x-1 lg:flex">
|
||||
{selectedValues.size > 2 ? (
|
||||
<Badge variant="secondary" className="px-1 font-normal">
|
||||
{selectedValues.size} selected
|
||||
{selectedValues.size} выбрано
|
||||
</Badge>
|
||||
) : (
|
||||
options
|
||||
@@ -94,7 +94,7 @@ function DataGridColumnFilter<TData, TValue>({
|
||||
<div className="max-h-[300px] overflow-y-auto">
|
||||
{filteredOptions.length === 0 ? (
|
||||
<div className="text-muted-foreground py-6 text-center text-sm">
|
||||
No results found.
|
||||
Ничего не найдено.
|
||||
</div>
|
||||
) : (
|
||||
<div className="p-1">
|
||||
@@ -170,7 +170,7 @@ function DataGridColumnFilter<TData, TValue>({
|
||||
}}
|
||||
className="hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground rounded-md relative flex cursor-pointer items-center justify-center px-2 py-1.5 text-sm outline-hidden select-none"
|
||||
>
|
||||
Clear filters
|
||||
Сбросить фильтры
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -39,11 +39,11 @@ function DataGridPagination(props: DataGridPaginationProps): React.JSX.Element {
|
||||
sizes: [5, 10, 25, 50, 100],
|
||||
sizesSkeleton: <Skeleton className="h-8 w-44" />,
|
||||
moreLimit: 5,
|
||||
info: "{from} - {to} of {count}",
|
||||
info: "{from}–{to} из {count}",
|
||||
infoSkeleton: <Skeleton className="h-8 w-60" />,
|
||||
rowsPerPageLabel: "Rows per page",
|
||||
previousPageLabel: "Go to previous page",
|
||||
nextPageLabel: "Go to next page",
|
||||
rowsPerPageLabel: "Строк на странице",
|
||||
previousPageLabel: "Предыдущая страница",
|
||||
nextPageLabel: "Следующая страница",
|
||||
ellipsisText: "...",
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ function DataGridTableDndRowHandle({ className }: { className?: string }) {
|
||||
"size-7 cursor-grab opacity-70 hover:bg-transparent hover:opacity-100 active:cursor-grabbing",
|
||||
className
|
||||
)}
|
||||
aria-label="Drag to reorder row"
|
||||
aria-label="Перетащить строку"
|
||||
disabled
|
||||
>
|
||||
<GripHorizontalIcon aria-hidden="true" />
|
||||
@@ -89,7 +89,7 @@ function DataGridTableDndRowHandle({ className }: { className?: string }) {
|
||||
"size-7 cursor-grab opacity-70 hover:bg-transparent hover:opacity-100 active:cursor-grabbing",
|
||||
className
|
||||
)}
|
||||
aria-label="Drag to reorder row"
|
||||
aria-label="Перетащить строку"
|
||||
{...context.attributes}
|
||||
{...context.listeners}
|
||||
>
|
||||
|
||||
@@ -105,7 +105,7 @@ function DataGridTableDndHeader<TData>({
|
||||
className={`-ms-2 size-6 ${isDragging ? "cursor-grabbing" : "cursor-grab active:cursor-grabbing"}`}
|
||||
{...attributes}
|
||||
{...listeners}
|
||||
aria-label="Drag to reorder"
|
||||
aria-label="Перетащить для изменения порядка"
|
||||
>
|
||||
<GripVerticalIcon className="opacity-60 hover:opacity-100" aria-hidden="true" />
|
||||
</Button>
|
||||
|
||||
@@ -397,9 +397,9 @@ function DataGridTableVirtual<TData>({
|
||||
|
||||
const isVirtualizationEnabled = virtualizerOptions?.enabled !== false
|
||||
const loadingMoreMessage =
|
||||
props.fetchingMoreMessage || props.loadingMessage || "Loading..."
|
||||
props.fetchingMoreMessage || props.loadingMessage || "Загрузка…"
|
||||
const allRowsLoadedMessage =
|
||||
props.allRowsLoadedMessage || "All records loaded"
|
||||
props.allRowsLoadedMessage || "Все записи загружены"
|
||||
|
||||
const handleViewportRef = useCallback((node: HTMLDivElement | null) => {
|
||||
setViewportElements({
|
||||
|
||||
@@ -1241,7 +1241,7 @@ function DataGridTableEmpty() {
|
||||
colSpan={Math.max(visibleColumnCount, 1)}
|
||||
className="text-muted-foreground py-6 text-center text-sm"
|
||||
>
|
||||
{props.emptyMessage || "No data available"}
|
||||
{props.emptyMessage || "Нет данных"}
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
@@ -1254,7 +1254,7 @@ function DataGridTableLoader() {
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<div className="text-muted-foreground bg-card rounded-lg flex items-center gap-2 border px-4 py-2 text-sm leading-none font-medium">
|
||||
<Spinner className="size-5 opacity-60" />
|
||||
{props.loadingMessage || "Loading..."}
|
||||
{props.loadingMessage || "Загрузка…"}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -1266,7 +1266,7 @@ function DataGridTableRowPin<TData>({ row }: { row: Row<TData> }) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
aria-label={isPinned ? "Unpin row" : "Pin row"}
|
||||
aria-label={isPinned ? "Открепить строку" : "Закрепить строку"}
|
||||
onClick={() => {
|
||||
if (isPinned) {
|
||||
row.pin(false)
|
||||
@@ -1322,7 +1322,7 @@ function DataGridTableRowSelect<TData>({ row }: { row: Row<TData> }) {
|
||||
<Checkbox
|
||||
checked={row.getIsSelected()}
|
||||
onCheckedChange={(value) => row.toggleSelected(!!value)}
|
||||
aria-label="Select row"
|
||||
aria-label="Выбрать строку"
|
||||
className="align-[inherit]"
|
||||
/>
|
||||
</>
|
||||
@@ -1341,7 +1341,7 @@ function DataGridTableRowSelectAll() {
|
||||
indeterminate={isSomeSelected && !isAllSelected}
|
||||
disabled={isLoading || recordCount === 0}
|
||||
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
|
||||
aria-label="Select all"
|
||||
aria-label="Выбрать все"
|
||||
className="align-[inherit]"
|
||||
/>
|
||||
)
|
||||
@@ -1408,7 +1408,7 @@ function DataGridTableBodyRows<TData>({ table }: { table: Table<TData> }) {
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
></path>
|
||||
</svg>
|
||||
{props.loadingMessage || "Loading..."}
|
||||
{props.loadingMessage || "Загрузка…"}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -123,75 +123,70 @@ export interface FilterI18nConfig {
|
||||
|
||||
// Default English i18n configuration
|
||||
export const DEFAULT_I18N: FilterI18nConfig = {
|
||||
// UI Labels
|
||||
addFilter: "Filter",
|
||||
searchFields: "Filter...",
|
||||
noFieldsFound: "No filters found.",
|
||||
noResultsFound: "No results found.",
|
||||
select: "Select...",
|
||||
true: "True",
|
||||
false: "False",
|
||||
min: "Min",
|
||||
max: "Max",
|
||||
to: "to",
|
||||
typeAndPressEnter: "Type and press Enter to add tag",
|
||||
selected: "selected",
|
||||
selectedCount: "selected",
|
||||
addFilter: "Фильтр",
|
||||
searchFields: "Фильтр…",
|
||||
noFieldsFound: "Поля не найдены.",
|
||||
noResultsFound: "Ничего не найдено.",
|
||||
select: "Выбрать…",
|
||||
true: "Да",
|
||||
false: "Нет",
|
||||
min: "Мин.",
|
||||
max: "Макс.",
|
||||
to: "—",
|
||||
typeAndPressEnter: "Введите и нажмите Enter",
|
||||
selected: "выбрано",
|
||||
selectedCount: "выбрано",
|
||||
percent: "%",
|
||||
defaultCurrency: "$",
|
||||
defaultColor: "#000000",
|
||||
addFilterTitle: "Add filter",
|
||||
addFilterTitle: "Добавить фильтр",
|
||||
|
||||
// Operators
|
||||
operators: {
|
||||
is: "is",
|
||||
isNot: "is not",
|
||||
isAnyOf: "is any of",
|
||||
isNotAnyOf: "is not any of",
|
||||
includesAll: "includes all",
|
||||
excludesAll: "excludes all",
|
||||
before: "before",
|
||||
after: "after",
|
||||
between: "between",
|
||||
notBetween: "not between",
|
||||
contains: "contains",
|
||||
notContains: "does not contain",
|
||||
startsWith: "starts with",
|
||||
endsWith: "ends with",
|
||||
isExactly: "is exactly",
|
||||
equals: "equals",
|
||||
notEquals: "not equals",
|
||||
greaterThan: "greater than",
|
||||
lessThan: "less than",
|
||||
overlaps: "overlaps",
|
||||
includes: "includes",
|
||||
excludes: "excludes",
|
||||
includesAllOf: "includes all of",
|
||||
includesAnyOf: "includes any of",
|
||||
empty: "is empty",
|
||||
notEmpty: "is not empty",
|
||||
is: "равно",
|
||||
isNot: "не равно",
|
||||
isAnyOf: "любое из",
|
||||
isNotAnyOf: "кроме",
|
||||
includesAll: "включает все",
|
||||
excludesAll: "исключает все",
|
||||
before: "до",
|
||||
after: "после",
|
||||
between: "между",
|
||||
notBetween: "вне диапазона",
|
||||
contains: "содержит",
|
||||
notContains: "не содержит",
|
||||
startsWith: "начинается с",
|
||||
endsWith: "заканчивается на",
|
||||
isExactly: "точно",
|
||||
equals: "равно",
|
||||
notEquals: "не равно",
|
||||
greaterThan: "больше",
|
||||
lessThan: "меньше",
|
||||
overlaps: "пересекается",
|
||||
includes: "включает",
|
||||
excludes: "исключает",
|
||||
includesAllOf: "включает все",
|
||||
includesAnyOf: "включает любое",
|
||||
empty: "пусто",
|
||||
notEmpty: "не пусто",
|
||||
},
|
||||
|
||||
// Placeholders
|
||||
placeholders: {
|
||||
enterField: (fieldType: string) => `Enter ${fieldType}...`,
|
||||
selectField: "Select...",
|
||||
searchField: (fieldName: string) => `Search ${fieldName.toLowerCase()}...`,
|
||||
enterKey: "Enter key...",
|
||||
enterValue: "Enter value...",
|
||||
enterField: (fieldType: string) => `Введите ${fieldType}…`,
|
||||
selectField: "Выбрать…",
|
||||
searchField: (fieldName: string) => `Поиск ${fieldName.toLowerCase()}…`,
|
||||
enterKey: "Введите ключ…",
|
||||
enterValue: "Введите значение…",
|
||||
},
|
||||
|
||||
// Helper functions
|
||||
helpers: {
|
||||
formatOperator: (operator: string) => operator.replace(/_/g, " "),
|
||||
},
|
||||
|
||||
// Validation
|
||||
validation: {
|
||||
invalidEmail: "Invalid email format",
|
||||
invalidUrl: "Invalid URL format",
|
||||
invalidTel: "Invalid phone format",
|
||||
invalid: "Invalid input format",
|
||||
invalidEmail: "Некорректный email",
|
||||
invalidUrl: "Некорректный URL",
|
||||
invalidTel: "Некорректный телефон",
|
||||
invalid: "Некорректное значение",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user