mirror of
https://github.com/perfect-panel/ppanel-web.git
synced 2026-04-19 10:09:55 -04:00
✨ feat: Implement data migration functionality and update localization files
This commit is contained in:
parent
59faeab34a
commit
6d81bfdaeb
@ -26,7 +26,7 @@ import { Combobox } from '@workspace/ui/custom-components/combobox';
|
|||||||
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
|
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
|
||||||
import TagInput from '@workspace/ui/custom-components/tag-input';
|
import TagInput from '@workspace/ui/custom-components/tag-input';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
@ -77,6 +77,7 @@ export default function NodeForm(props: {
|
|||||||
const { trigger, title, loading, initialValues, onSubmit } = props;
|
const { trigger, title, loading, initialValues, onSubmit } = props;
|
||||||
const t = useTranslations('nodes');
|
const t = useTranslations('nodes');
|
||||||
const Scheme = useMemo(() => buildSchema(t), [t]);
|
const Scheme = useMemo(() => buildSchema(t), [t]);
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const form = useForm<NodeFormValues>({
|
const form = useForm<NodeFormValues>({
|
||||||
resolver: zodResolver(Scheme),
|
resolver: zodResolver(Scheme),
|
||||||
@ -159,12 +160,15 @@ export default function NodeForm(props: {
|
|||||||
|
|
||||||
async function submit(values: NodeFormValues) {
|
async function submit(values: NodeFormValues) {
|
||||||
const ok = await onSubmit(values);
|
const ok = await onSubmit(values);
|
||||||
if (ok) form.reset();
|
if (ok) {
|
||||||
|
form.reset();
|
||||||
|
setOpen(false);
|
||||||
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sheet>
|
<Sheet open={open} onOpenChange={setOpen}>
|
||||||
<SheetTrigger asChild>
|
<SheetTrigger asChild>
|
||||||
<Button onClick={() => form.reset()}>{trigger}</Button>
|
<Button onClick={() => form.reset()}>{trigger}</Button>
|
||||||
</SheetTrigger>
|
</SheetTrigger>
|
||||||
@ -295,7 +299,7 @@ export default function NodeForm(props: {
|
|||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
|
||||||
<SheetFooter className='flex-row justify-end gap-2 pt-3'>
|
<SheetFooter className='flex-row justify-end gap-2 pt-3'>
|
||||||
<Button variant='outline' disabled={loading}>
|
<Button variant='outline' disabled={loading} onClick={() => setOpen(false)}>
|
||||||
{t('cancel')}
|
{t('cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@ -5,9 +5,12 @@ import {
|
|||||||
createServer,
|
createServer,
|
||||||
deleteServer,
|
deleteServer,
|
||||||
filterServerList,
|
filterServerList,
|
||||||
|
hasMigrateSeverNode,
|
||||||
|
migrateServerNode,
|
||||||
resetSortWithServer,
|
resetSortWithServer,
|
||||||
updateServer,
|
updateServer,
|
||||||
} from '@/services/admin/server';
|
} from '@/services/admin/server';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { Badge } from '@workspace/ui/components/badge';
|
import { Badge } from '@workspace/ui/components/badge';
|
||||||
import { Button } from '@workspace/ui/components/button';
|
import { Button } from '@workspace/ui/components/button';
|
||||||
import { Card, CardContent } from '@workspace/ui/components/card';
|
import { Card, CardContent } from '@workspace/ui/components/card';
|
||||||
@ -64,14 +67,40 @@ function RegionIpCell({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnlineUsersCell is now a standalone component
|
|
||||||
|
|
||||||
export default function ServersPage() {
|
export default function ServersPage() {
|
||||||
const t = useTranslations('servers');
|
const t = useTranslations('servers');
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [migrating, setMigrating] = useState(false);
|
||||||
const ref = useRef<ProTableActions>(null);
|
const ref = useRef<ProTableActions>(null);
|
||||||
|
|
||||||
|
const { data: hasMigrate, refetch: refetchHasMigrate } = useQuery({
|
||||||
|
queryKey: ['hasMigrateSeverNode'],
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data } = await hasMigrateSeverNode();
|
||||||
|
return data.data?.has_migrate;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleMigrate = async () => {
|
||||||
|
setMigrating(true);
|
||||||
|
try {
|
||||||
|
const { data } = await migrateServerNode();
|
||||||
|
const fail = data.data?.fail || 0;
|
||||||
|
if (fail > 0) {
|
||||||
|
toast.error(data.data?.message);
|
||||||
|
} else {
|
||||||
|
toast.success(t('migrated'));
|
||||||
|
}
|
||||||
|
refetchHasMigrate();
|
||||||
|
ref.current?.refresh();
|
||||||
|
} catch (error) {
|
||||||
|
toast.error(t('migrateFailed'));
|
||||||
|
} finally {
|
||||||
|
setMigrating(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='space-y-4'>
|
<div className='space-y-4'>
|
||||||
<Card>
|
<Card>
|
||||||
@ -84,24 +113,31 @@ export default function ServersPage() {
|
|||||||
header={{
|
header={{
|
||||||
title: t('pageTitle'),
|
title: t('pageTitle'),
|
||||||
toolbar: (
|
toolbar: (
|
||||||
<ServerForm
|
<div className='flex gap-2'>
|
||||||
trigger={t('create')}
|
{!hasMigrate && (
|
||||||
title={t('drawerCreateTitle')}
|
<Button variant='outline' onClick={handleMigrate} disabled={migrating}>
|
||||||
loading={loading}
|
{migrating ? t('migrating') : t('migrate')}
|
||||||
onSubmit={async (values) => {
|
</Button>
|
||||||
setLoading(true);
|
)}
|
||||||
try {
|
<ServerForm
|
||||||
await createServer(values as unknown as API.CreateServerRequest);
|
trigger={t('create')}
|
||||||
toast.success(t('created'));
|
title={t('drawerCreateTitle')}
|
||||||
ref.current?.refresh();
|
loading={loading}
|
||||||
setLoading(false);
|
onSubmit={async (values) => {
|
||||||
return true;
|
setLoading(true);
|
||||||
} catch (e) {
|
try {
|
||||||
setLoading(false);
|
await createServer(values as unknown as API.CreateServerRequest);
|
||||||
return false;
|
toast.success(t('created'));
|
||||||
}
|
ref.current?.refresh();
|
||||||
}}
|
setLoading(false);
|
||||||
/>
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
setLoading(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
columns={[
|
columns={[
|
||||||
@ -156,17 +192,16 @@ export default function ServersPage() {
|
|||||||
id: 'status',
|
id: 'status',
|
||||||
header: t('status'),
|
header: t('status'),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const s = (row.original.status ?? {}) as API.ServerStatus;
|
const offline = row.original.status.status === 'offline';
|
||||||
const on = !!(Array.isArray(s.online) && s.online.length > 0);
|
|
||||||
return (
|
return (
|
||||||
<div className='flex items-center gap-2'>
|
<div className='flex items-center gap-2'>
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
'inline-block h-2.5 w-2.5 rounded-full',
|
'inline-block h-2.5 w-2.5 rounded-full',
|
||||||
on ? 'bg-emerald-500' : 'bg-zinc-400',
|
offline ? 'bg-zinc-400' : 'bg-emerald-500',
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<span className='text-sm'>{on ? t('online') : t('offline')}</span>
|
<span className='text-sm'>{offline ? t('offline') : t('online')}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -33,7 +33,7 @@ import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
|
|||||||
import { Icon } from '@workspace/ui/custom-components/icon';
|
import { Icon } from '@workspace/ui/custom-components/icon';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useFieldArray, useForm, useWatch } from 'react-hook-form';
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import {
|
import {
|
||||||
FINGERPRINTS,
|
FINGERPRINTS,
|
||||||
@ -99,7 +99,6 @@ export default function ServerForm<T extends { [x: string]: any }>({
|
|||||||
|
|
||||||
const form = useForm<any>({ resolver: zodResolver(formSchema), defaultValues });
|
const form = useForm<any>({ resolver: zodResolver(formSchema), defaultValues });
|
||||||
const { control } = form;
|
const { control } = form;
|
||||||
const { fields, append, remove } = useFieldArray({ control, name: 'protocols' });
|
|
||||||
|
|
||||||
const protocolsValues = useWatch({ control, name: 'protocols' });
|
const protocolsValues = useWatch({ control, name: 'protocols' });
|
||||||
|
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP adresy",
|
"ipAddresses": "IP adresy",
|
||||||
"memory": "Paměť",
|
"memory": "Paměť",
|
||||||
|
"migrate": "Migrace dat",
|
||||||
|
"migrateFailed": "Migrace dat se nezdařila",
|
||||||
|
"migrated": "Data byla úspěšně migrována",
|
||||||
|
"migrating": "Probíhá migrace...",
|
||||||
"name": "Název",
|
"name": "Název",
|
||||||
"noData": "Žádná data",
|
"noData": "Žádná data",
|
||||||
"notAvailable": "Není k dispozici",
|
"notAvailable": "Není k dispozici",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP-Adressen",
|
"ipAddresses": "IP-Adressen",
|
||||||
"memory": "Speicher",
|
"memory": "Speicher",
|
||||||
|
"migrate": "Daten migrieren",
|
||||||
|
"migrateFailed": "Datenmigration fehlgeschlagen",
|
||||||
|
"migrated": "Daten erfolgreich migriert",
|
||||||
|
"migrating": "Wird migriert...",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"noData": "Keine Daten",
|
"noData": "Keine Daten",
|
||||||
"notAvailable": "Nicht verfügbar",
|
"notAvailable": "Nicht verfügbar",
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"address": "Address",
|
|
||||||
"address": "Address",
|
"address": "Address",
|
||||||
"address_placeholder": "Server address",
|
"address_placeholder": "Server address",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
@ -57,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP addresses",
|
"ipAddresses": "IP addresses",
|
||||||
"memory": "Memory",
|
"memory": "Memory",
|
||||||
|
"migrate": "Migrate Data",
|
||||||
|
"migrateFailed": "Data migration failed",
|
||||||
|
"migrated": "Data migrated successfully",
|
||||||
|
"migrating": "Migrating...",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"noData": "No data",
|
"noData": "No data",
|
||||||
"notAvailable": "N/A",
|
"notAvailable": "N/A",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "Direcciones IP",
|
"ipAddresses": "Direcciones IP",
|
||||||
"memory": "Memoria",
|
"memory": "Memoria",
|
||||||
|
"migrate": "Migrar datos",
|
||||||
|
"migrateFailed": "La migración de datos falló",
|
||||||
|
"migrated": "Datos migrados con éxito",
|
||||||
|
"migrating": "Migrando...",
|
||||||
"name": "Nombre",
|
"name": "Nombre",
|
||||||
"noData": "Sin datos",
|
"noData": "Sin datos",
|
||||||
"notAvailable": "N/A",
|
"notAvailable": "N/A",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "Direcciones IP",
|
"ipAddresses": "Direcciones IP",
|
||||||
"memory": "Memoria",
|
"memory": "Memoria",
|
||||||
|
"migrate": "Migrar datos",
|
||||||
|
"migrateFailed": "La migración de datos falló",
|
||||||
|
"migrated": "Datos migrados con éxito",
|
||||||
|
"migrating": "Migrando...",
|
||||||
"name": "Nombre",
|
"name": "Nombre",
|
||||||
"noData": "Sin datos",
|
"noData": "Sin datos",
|
||||||
"notAvailable": "N/A",
|
"notAvailable": "N/A",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "شناسه",
|
"id": "شناسه",
|
||||||
"ipAddresses": "آدرسهای IP",
|
"ipAddresses": "آدرسهای IP",
|
||||||
"memory": "حافظه",
|
"memory": "حافظه",
|
||||||
|
"migrate": "انتقال داده",
|
||||||
|
"migrateFailed": "انتقال داده ناموفق بود",
|
||||||
|
"migrated": "داده با موفقیت منتقل شد",
|
||||||
|
"migrating": "در حال انتقال...",
|
||||||
"name": "نام",
|
"name": "نام",
|
||||||
"noData": "هیچ دادهای",
|
"noData": "هیچ دادهای",
|
||||||
"notAvailable": "غیرقابل دسترسی",
|
"notAvailable": "غیرقابل دسترسی",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP-osoitteet",
|
"ipAddresses": "IP-osoitteet",
|
||||||
"memory": "Muisti",
|
"memory": "Muisti",
|
||||||
|
"migrate": "Siirrä tiedot",
|
||||||
|
"migrateFailed": "Tietojen siirto epäonnistui",
|
||||||
|
"migrated": "Tiedot siirretty onnistuneesti",
|
||||||
|
"migrating": "Siirretään...",
|
||||||
"name": "Nimi",
|
"name": "Nimi",
|
||||||
"noData": "Ei tietoja",
|
"noData": "Ei tietoja",
|
||||||
"notAvailable": "Ei saatavilla",
|
"notAvailable": "Ei saatavilla",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "Adresses IP",
|
"ipAddresses": "Adresses IP",
|
||||||
"memory": "Mémoire",
|
"memory": "Mémoire",
|
||||||
|
"migrate": "Migrer les données",
|
||||||
|
"migrateFailed": "Échec de la migration des données",
|
||||||
|
"migrated": "Données migrées avec succès",
|
||||||
|
"migrating": "Migration en cours...",
|
||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
"noData": "Aucune donnée",
|
"noData": "Aucune donnée",
|
||||||
"notAvailable": "N/A",
|
"notAvailable": "N/A",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "आईडी",
|
"id": "आईडी",
|
||||||
"ipAddresses": "आईपी पते",
|
"ipAddresses": "आईपी पते",
|
||||||
"memory": "मेमोरी",
|
"memory": "मेमोरी",
|
||||||
|
"migrate": "डेटा माइग्रेट करें",
|
||||||
|
"migrateFailed": "डेटा माइग्रेशन विफल",
|
||||||
|
"migrated": "डेटा सफलतापूर्वक माइग्रेट किया गया",
|
||||||
|
"migrating": "माइग्रेट किया जा रहा है...",
|
||||||
"name": "नाम",
|
"name": "नाम",
|
||||||
"noData": "कोई डेटा नहीं",
|
"noData": "कोई डेटा नहीं",
|
||||||
"notAvailable": "उपलब्ध नहीं",
|
"notAvailable": "उपलब्ध नहीं",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP címek",
|
"ipAddresses": "IP címek",
|
||||||
"memory": "Memória",
|
"memory": "Memória",
|
||||||
|
"migrate": "Adatok migrálása",
|
||||||
|
"migrateFailed": "Az adatok migrálása sikertelen",
|
||||||
|
"migrated": "Az adatok sikeresen migrálva",
|
||||||
|
"migrating": "Migrálás...",
|
||||||
"name": "Név",
|
"name": "Név",
|
||||||
"noData": "Nincs adat",
|
"noData": "Nincs adat",
|
||||||
"notAvailable": "N/A",
|
"notAvailable": "N/A",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IPアドレス",
|
"ipAddresses": "IPアドレス",
|
||||||
"memory": "メモリ",
|
"memory": "メモリ",
|
||||||
|
"migrate": "データを移行する",
|
||||||
|
"migrateFailed": "データの移行に失敗しました",
|
||||||
|
"migrated": "データが正常に移行されました",
|
||||||
|
"migrating": "移行中...",
|
||||||
"name": "名前",
|
"name": "名前",
|
||||||
"noData": "データなし",
|
"noData": "データなし",
|
||||||
"notAvailable": "利用不可",
|
"notAvailable": "利用不可",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP 주소",
|
"ipAddresses": "IP 주소",
|
||||||
"memory": "메모리",
|
"memory": "메모리",
|
||||||
|
"migrate": "데이터 마이그레이션",
|
||||||
|
"migrateFailed": "데이터 마이그레이션 실패",
|
||||||
|
"migrated": "데이터가 성공적으로 마이그레이션되었습니다",
|
||||||
|
"migrating": "마이그레이션 중...",
|
||||||
"name": "이름",
|
"name": "이름",
|
||||||
"noData": "데이터 없음",
|
"noData": "데이터 없음",
|
||||||
"notAvailable": "사용 불가",
|
"notAvailable": "사용 불가",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP-adresser",
|
"ipAddresses": "IP-adresser",
|
||||||
"memory": "Minne",
|
"memory": "Minne",
|
||||||
|
"migrate": "Migrer data",
|
||||||
|
"migrateFailed": "Datamigrering mislyktes",
|
||||||
|
"migrated": "Data migrert med suksess",
|
||||||
|
"migrating": "Migrerer...",
|
||||||
"name": "Navn",
|
"name": "Navn",
|
||||||
"noData": "Ingen data",
|
"noData": "Ingen data",
|
||||||
"notAvailable": "Ikke tilgjengelig",
|
"notAvailable": "Ikke tilgjengelig",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "Adresy IP",
|
"ipAddresses": "Adresy IP",
|
||||||
"memory": "Pamięć",
|
"memory": "Pamięć",
|
||||||
|
"migrate": "Migracja danych",
|
||||||
|
"migrateFailed": "Migracja danych nie powiodła się",
|
||||||
|
"migrated": "Dane zostały pomyślnie zmigrowane",
|
||||||
|
"migrating": "Migracja...",
|
||||||
"name": "Nazwa",
|
"name": "Nazwa",
|
||||||
"noData": "Brak danych",
|
"noData": "Brak danych",
|
||||||
"notAvailable": "N/D",
|
"notAvailable": "N/D",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "Endereços IP",
|
"ipAddresses": "Endereços IP",
|
||||||
"memory": "Memória",
|
"memory": "Memória",
|
||||||
|
"migrate": "Migrar Dados",
|
||||||
|
"migrateFailed": "A migração de dados falhou",
|
||||||
|
"migrated": "Dados migrados com sucesso",
|
||||||
|
"migrating": "Migrando...",
|
||||||
"name": "Nome",
|
"name": "Nome",
|
||||||
"noData": "Sem dados",
|
"noData": "Sem dados",
|
||||||
"notAvailable": "N/D",
|
"notAvailable": "N/D",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "Adrese IP",
|
"ipAddresses": "Adrese IP",
|
||||||
"memory": "Memorie",
|
"memory": "Memorie",
|
||||||
|
"migrate": "Migrați datele",
|
||||||
|
"migrateFailed": "Migrarea datelor a eșuat",
|
||||||
|
"migrated": "Datele au fost migrate cu succes",
|
||||||
|
"migrating": "Se migrează...",
|
||||||
"name": "Nume",
|
"name": "Nume",
|
||||||
"noData": "Fără date",
|
"noData": "Fără date",
|
||||||
"notAvailable": "N/A",
|
"notAvailable": "N/A",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP-адреса",
|
"ipAddresses": "IP-адреса",
|
||||||
"memory": "Память",
|
"memory": "Память",
|
||||||
|
"migrate": "Перенести данные",
|
||||||
|
"migrateFailed": "Ошибка при переносе данных",
|
||||||
|
"migrated": "Данные успешно перенесены",
|
||||||
|
"migrating": "Перенос данных...",
|
||||||
"name": "Имя",
|
"name": "Имя",
|
||||||
"noData": "Нет данных",
|
"noData": "Нет данных",
|
||||||
"notAvailable": "Недоступно",
|
"notAvailable": "Недоступно",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "ที่อยู่ IP",
|
"ipAddresses": "ที่อยู่ IP",
|
||||||
"memory": "หน่วยความจำ",
|
"memory": "หน่วยความจำ",
|
||||||
|
"migrate": "ย้ายข้อมูล",
|
||||||
|
"migrateFailed": "การย้ายข้อมูลล้มเหลว",
|
||||||
|
"migrated": "ย้ายข้อมูลสำเร็จ",
|
||||||
|
"migrating": "กำลังย้ายข้อมูล...",
|
||||||
"name": "ชื่อ",
|
"name": "ชื่อ",
|
||||||
"noData": "ไม่มีข้อมูล",
|
"noData": "ไม่มีข้อมูล",
|
||||||
"notAvailable": "ไม่สามารถใช้ได้",
|
"notAvailable": "ไม่สามารถใช้ได้",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP adresleri",
|
"ipAddresses": "IP adresleri",
|
||||||
"memory": "Bellek",
|
"memory": "Bellek",
|
||||||
|
"migrate": "Veri Taşı",
|
||||||
|
"migrateFailed": "Veri taşıma işlemi başarısız oldu",
|
||||||
|
"migrated": "Veri başarıyla taşındı",
|
||||||
|
"migrating": "Taşınıyor...",
|
||||||
"name": "İsim",
|
"name": "İsim",
|
||||||
"noData": "Veri yok",
|
"noData": "Veri yok",
|
||||||
"notAvailable": "Mevcut değil",
|
"notAvailable": "Mevcut değil",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP адреси",
|
"ipAddresses": "IP адреси",
|
||||||
"memory": "Пам'ять",
|
"memory": "Пам'ять",
|
||||||
|
"migrate": "Міграція даних",
|
||||||
|
"migrateFailed": "Міграція даних не вдалася",
|
||||||
|
"migrated": "Дані успішно мігрували",
|
||||||
|
"migrating": "Міграція...",
|
||||||
"name": "Ім'я",
|
"name": "Ім'я",
|
||||||
"noData": "Немає даних",
|
"noData": "Немає даних",
|
||||||
"notAvailable": "Н/Д",
|
"notAvailable": "Н/Д",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "Địa chỉ IP",
|
"ipAddresses": "Địa chỉ IP",
|
||||||
"memory": "Bộ nhớ",
|
"memory": "Bộ nhớ",
|
||||||
|
"migrate": "Di chuyển dữ liệu",
|
||||||
|
"migrateFailed": "Di chuyển dữ liệu thất bại",
|
||||||
|
"migrated": "Dữ liệu đã được di chuyển thành công",
|
||||||
|
"migrating": "Đang di chuyển...",
|
||||||
"name": "Tên",
|
"name": "Tên",
|
||||||
"noData": "Không có dữ liệu",
|
"noData": "Không có dữ liệu",
|
||||||
"notAvailable": "Không khả dụng",
|
"notAvailable": "Không khả dụng",
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"address": "地址",
|
|
||||||
"address": "地址",
|
"address": "地址",
|
||||||
"address_placeholder": "服务器地址",
|
"address_placeholder": "服务器地址",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
@ -57,6 +56,10 @@
|
|||||||
"id": "编号",
|
"id": "编号",
|
||||||
"ipAddresses": "IP 地址",
|
"ipAddresses": "IP 地址",
|
||||||
"memory": "内存",
|
"memory": "内存",
|
||||||
|
"migrate": "迁移数据",
|
||||||
|
"migrateFailed": "数据迁移失败",
|
||||||
|
"migrated": "数据迁移成功",
|
||||||
|
"migrating": "迁移中...",
|
||||||
"name": "名称",
|
"name": "名称",
|
||||||
"noData": "暂无数据",
|
"noData": "暂无数据",
|
||||||
"notAvailable": "—",
|
"notAvailable": "—",
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
"id": "ID",
|
"id": "ID",
|
||||||
"ipAddresses": "IP 地址",
|
"ipAddresses": "IP 地址",
|
||||||
"memory": "內存",
|
"memory": "內存",
|
||||||
|
"migrate": "遷移數據",
|
||||||
|
"migrateFailed": "數據遷移失敗",
|
||||||
|
"migrated": "數據已成功遷移",
|
||||||
|
"migrating": "正在遷移...",
|
||||||
"name": "名稱",
|
"name": "名稱",
|
||||||
"noData": "無數據",
|
"noData": "無數據",
|
||||||
"notAvailable": "不可用",
|
"notAvailable": "不可用",
|
||||||
|
|||||||
1
apps/admin/services/admin/typings.d.ts
vendored
1
apps/admin/services/admin/typings.d.ts
vendored
@ -1741,6 +1741,7 @@ declare namespace API {
|
|||||||
disk: number;
|
disk: number;
|
||||||
protocol: string;
|
protocol: string;
|
||||||
online: ServerOnlineUser[];
|
online: ServerOnlineUser[];
|
||||||
|
status: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ServerTotalDataResponse = {
|
type ServerTotalDataResponse = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user