feat(xo6): refacto backup folder in backup-job and backup-log (#10636)

* refacto backup job

* refacto ok

* refacto for PR

* rebase ok

* fix bild
This commit is contained in:
Marie Garde
2026-10-27 15:58:38 +01:00
committed by GitHub
parent 3359eb898f
commit 4cfe9e81bd
115 changed files with 256 additions and 3851 deletions

View File

@@ -184,7 +184,6 @@
"and": "A",
"any-property": "Jakákoli vlastnost",
"api-error-details": "Podrobnosti o chybě API rozhraní",
"api-info-details": "Podrobnosti o informaci z API",
"api-warning-details": "Podrobnosti o varování z API",
"appearance": "Vzhled",
"aria:breadcrumb:label": "Drobečková navigace",
@@ -198,7 +197,6 @@
"available-properties-for-advanced-filter:": "Vlastnosti pro pokročilý filtr, které jsou k dispozici:",
"back-pool-dashboard": "Přejít zpět na přehled fondu",
"back-site-dashboard": "Přejít zpět na přehled lokality",
"backed-up-pools": "Zálohované fondy",
"backed-up-vms": "Zazálohované virt. stroje",
"backup": "Záloha",
"backup-archive-status": "Stav archivu zálohy",
@@ -211,13 +209,7 @@
"backup-repository": "Repozitář pro zálohy",
"backup-repository-type": "Repozitář pro zálohy (lokální, NFS, SMB)",
"backup-targets": "Cíle zálohování",
"backup:full": "Plná záloha",
"backup:full-replication": "Úplná replikace",
"backup:incremental": "Přírůstková záloha",
"backup:incremental-replication": "Přírůstková replikace",
"backup:last-replication": "Poslední replikace",
"backup:mirror:full": "Zrcadlová úplná záloha",
"backup:mirror:incremental": "Zrcadlová přírůstková záloha",
"backup:pool-metadata": "Metadata fondu",
"backup:rolling-snapshot": "Průběžně zachycovaný stav",
"backup:xo-config": "Nastavení XO",
@@ -254,12 +246,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Storno",
"cbt-destroy-snapshot-data": "Při používání průběžného sledování změn bloků odstranit data zachyceného stavu",
"change-block-tracking": "Sledování změn bloků (CBT)",
"character-limit": "{count}/{max} znak | {count}/{max} znaků",
"check-errors:": "Zkontrolujte chyby:",
"check-summing": "Kontrolní součty odesílání",
"checkpoint-snapshot": "Zachycený stav – kontrolní bod",
"click-to-display-alarms:": "Kliknutím zobrazíte výstrahy:",
"click-to-return-default-pool": "Kliknutím sem se vrátíte na výchozí fond",
"cloud-config": "Cloud config",
@@ -359,7 +349,6 @@
"disconnected-pbd-number": "Odpojeno PBD č. {n}",
"disconnecting": "Odpojování",
"disk-name": "Název disku",
"disk-size": "Velikost disku",
"disk-space": "Prostor na disku",
"dns": "DNS",
"do-you-have-needs": "Něco potřebujete a/nebo očekáváte? Dejte nám vědět",
@@ -375,7 +364,6 @@
"email": "E-mail",
"empty": "Prázdné",
"enabled": "Povoleno",
"end-date": "Konečné datum",
"ended": "Skončilo",
"engines-off": "Motory vypnuté, oběžná dráha stabilní",
"eol": "Po životnosti",
@@ -427,7 +415,6 @@
"hardware-specifications": "Hardwarové specifikace",
"heartbeat-storage-repository": "Repozitář úložiště kontroly stavu",
"here": "Zde",
"hide-successful-items": "V hlášeních o nezdarech skrýt ty položky, u kterých hlášen úspěch",
"high-availability": "Vysoká dostupnost (HA)",
"host": "Hostitel",
"host-currently-shutdown": "Tento hostitel je v tuto chvíli vypnutý, takže není možné získat jakékoli údaje.",
@@ -481,7 +468,6 @@
"iscsi-iqn": "iSCSI IQN název",
"iso-dvd": "ISO/DVD",
"job": "Úloha",
"job-name": "Název úlohy",
"job:arg:allocated-space-required": "Přidělené místo je třeba zadat",
"job:arg:bond-mode-required": "@:bond-mode-required",
"job:arg:direction-required": "Směr je třeba zadat",
@@ -729,7 +715,6 @@
"modal:vm-reboot-message": "Provede korektní restart virtuálního stroje jeho vypnutím a opětovným spuštěním. Spuštěné procesy budou korektně ukončeny.",
"modal:vm-shutdown-message": "Provede korektní vypnutí virtuálního stroje. Veškeré spuštěné procesy budou ukončeny a uživatelé odpojeni. Virt. stroj je později možné znovu spustit z webového rozhraní.",
"mode": "Režim",
"modes": "Režimy",
"more-actions": "Další akce",
"more-information": "Další informace",
"mtu": "MTU",
@@ -757,7 +742,6 @@
"n-vms": "1 virt. stroj | {n} virt. strojů",
"name": "Název",
"name-required": "Je zapotřebí název.",
"nbd-concurrency": "Souběžnost síť. blokového zařízení (NBD)",
"nested-virtualization": "Vnořená virtualizace",
"netmask": "Maska sítě",
"network": "Síť",
@@ -815,7 +799,6 @@
"no-active-backup-jobs": "Na této lokalitě nejsou žádné aktivní úlohy zálohování.",
"no-alarm-detected": "Nezjištěny žádné výstrahy",
"no-alarm-triggered": "Nespuštěna žádná výstraha",
"no-backed-up-vm-detected": "Nezjištěny žádné zálohované virt. stroje",
"no-backup-job-available": "Nejsou k dispozici žádné úlohy zálohování",
"no-backup-repository-detected": "Nezjištěny žádné repozitáře záloh",
"no-backup-run-available": "Nejsou k dispozici žádné běhy zálohy",
@@ -835,7 +818,6 @@
"no-result": "Nic nenalezeno",
"no-role-applied": "Neuplatněna žádná role",
"no-running-vm-detected": "Nezjištěny žádné spuštěné virt. stroje",
"no-schedule-available": "Nejsou k dispozici žádná naplánování",
"no-selected-vm-can-be-exported": "Žádný z označených virt. strojů není možné exportovat",
"no-selected-vm-can-be-migrated": "Žádný z označených virt. strojů není možné přestěhovat",
"no-server-detected": "Nezjištěny žádné servery",
@@ -862,7 +844,6 @@
"off": "Vypnuto",
"offline": "Bez připojení",
"offline-backup": "Offline záloha",
"offline-snapshot": "Offline zachycený stav",
"ok": "OK",
"on": "Zapnuto",
"on-object": "na {object}",
@@ -893,7 +874,6 @@
"os-name": "Název operačního systému",
"other": "Ostatní",
"other-properties": "Ostatní vlastnosti",
"other-settings": "Ostatní nastavení",
"ova": "OVA",
"page-not-found": "Tato stránka není k nalezení…",
"page-please-wait": "Držte se pevně, astronaute! Tato stránka se připravuje odstartovat.{newline}Jen ještě zarovnáváme trysky a kalibrujeme systémy. Nebude to už dlouho trvat, zůstaňte na příjmu!",
@@ -1012,7 +992,6 @@
"relative-time:past": "před {str}",
"relative-time:second": "1 sekunda | {n} sekund",
"relative-time:year": "1 rok | {n} let",
"remaining-space": "Zbývající prostor",
"remote-syslog": "Vzdálený syslog",
"report-recipients": "Příjemci hlášení",
"report-when": "Hlásit když",
@@ -1032,7 +1011,6 @@
"rule-type": "Typ pravidla",
"run": "Spustit",
"running-vm": "Spuštěný virt. stroj | Spuštěné virt. stroje",
"runs": "Běhy",
"s3-backup-repository": "S3 repozitář záloh",
"scan-pifs": "Skenovat fyzická rozhraní",
"schedule": "Plán",
@@ -1068,7 +1046,6 @@
"software": "Software",
"software-tooling": "Software a nástroje",
"source": "Zdroj",
"source-backup-repository": "Zdrojový repozitář záloh",
"space": "Prostor",
"speed": "Rychlost",
"speed-limit": "Nastavené omezení využívání přenosové rychlosti",
@@ -1096,7 +1073,6 @@
"stacked-cpu-usage": "Celkem využití procesoru",
"stacked-ram-usage": "Celkem využítí opearční paměti",
"start-console": "Aby bylo možné přistupovat ke konzoli a navázat ve fungování, {type} zapněte!",
"start-date": "Počáteční datum",
"start-delay": "Prodleva zapnutí",
"start-host": "Aby začal znovu fungovat, hostitele zapněte (případně sem zavítejte později, až bude zapnutý).",
"start-vm": "Aby bylo možné přistupovat k jeho konzoli a podrobnostem k nastavení, je třeba ho spustit.",
@@ -1171,12 +1147,10 @@
"topology": "Topologie",
"total": "Celkem",
"total-assigned": "Celkem přiděleno",
"total-capacity": "Celková kapacita",
"total-cpus": "Celkem procesorů",
"total-free": "Celkem volno",
"total-free:": "Celkem volno:",
"total-memory": "Celková operační paměť",
"total-schedules": "Celkem plánů",
"total-space": "Celkový prostor",
"total-space-on-sr": "Celkový prostor na repozitáři úložiště",
"total-storage-repository": "Celkové úložiště repozitáře",
@@ -1192,7 +1166,6 @@
"traffic-rules:info-message": "Implementování pořadí pravidel pro provoz teprve probíhá. Chování může být nebezpečné.",
"traffic-rules:no-traffic-rules-detected": "Nezjištěna žádná pravidla pro provoz",
"traffic-rules:xapi-plugin-required": "Vyžaduje režim XAPI zásuvného modulu",
"transfer-size": "Objem přenosu",
"translation-tool": "Nástroj pro překládání",
"treeview": "Stromové zobrazení",
"trigger": "Spouštěč",

View File

@@ -101,7 +101,6 @@
"all-quiet-launchpad": "Ingen alarmer - alt er OK",
"allow-self-signed-ssl": "Du skal muligvis tillade selvsignerede SSL-certifikater i din browser",
"api-error-details": "API fejloplysninger",
"api-info-details": "API Info detaljer",
"api-warning-details": "API advarsels detaljer",
"appearance": "Udseende",
"aria:breadcrumb:label": "Brødkrumme",
@@ -111,10 +110,6 @@
"back-pool-dashboard": "Gå tilbage til dit Pool dashboard",
"backup": "Backup",
"backup-network": "Backup netværk",
"backup:full": "Fuld backup",
"backup:full-replication": "Fuld replikering",
"backup:incremental": "Inkrementel sikkerhedskopiering",
"backup:incremental-replication": "Inkrementel replikering",
"backup:pool-metadata": "Pool metadata",
"backup:xo-config": "XO konfiguration",
"backups:jobs:disabled": "Deaktiveret",
@@ -124,7 +119,6 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Annuller",
"cbt-destroy-snapshot-data": "Slet snapshotdata når CBT benyttes",
"check-errors:": "Tjek fejlene:",
"check-summing": "TX kontrolsum",
"click-to-display-alarms:": "Klik for at vise alamer:",
@@ -181,7 +175,6 @@
"disabled": "Deaktiveret",
"disconnected": "Frakoblet",
"disk-name": "Disk navn",
"disk-size": "Disk størrelse",
"disk-space": "Disk plads",
"dns": "DNS",
"do-you-have-needs": "Har du behov og/eller forventninger? Fortæl os det",
@@ -190,7 +183,6 @@
"done": "Færdig",
"duration": "Varighed",
"enabled": "Aktiveret",
"end-date": "Slut dato",
"ended": "Afsluttet",
"error": "Fejl",
"error-no-data": "Fejl, data kan ikke indsamles.",
@@ -239,7 +231,6 @@
"is-primary-host": "{name} er primær host",
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job-name": "Job navn",
"job:delete:in-progress": "Sletning er i gang…",
"job:vm-copy:bad-power-state": "VM skal stoppes",
"job:vm-copy:in-progress": "Kopiering i gang…",
@@ -293,7 +284,6 @@
"missing-patches": "Manglende opdateringer",
"missing-translations?": "Manglende eller forkert oversættelse?",
"mode": "Mode",
"modes": "Tilstande",
"more-actions": "Flere handlinger",
"mtu": "MTU",
"n-gb-left": "{n} GB tilbage",
@@ -344,7 +334,6 @@
"os-name": "OS navn",
"other": "Andet",
"other-properties": "Andre ejendomme",
"other-settings": "Andre indstillinger",
"page-not-found": "Denne side kan ikke findes…",
"password": "Password",
"patches": "Opdateringer",
@@ -397,7 +386,6 @@
"relative-time:now": "Lige nu",
"relative-time:second": "1 sekund | {n} sekunder",
"relative-time:year": "1 år | {n} år",
"remaining-space": "Resterende plads",
"remote-syslog": "Ekstern syslog",
"report-when:always": "Altid",
"report-when:error": "Fejl",
@@ -427,7 +415,6 @@
"ssh-password": "SSH password",
"ssh-password-confirm": "Bekræft SSH password",
"start-console": "Start din {type} for at få adgang til konsollen og genoptage operationerne!",
"start-date": "Start dato",
"started": "Startet",
"state": "Tilstand",
"static": "Statisk",
@@ -461,7 +448,6 @@
"timezone": "Tidszone",
"topology": "Topologi",
"total": "Total",
"total-capacity": "Samlet kapacitet",
"total-space": "Total plads",
"translation-tool": "Oversættelsesværktøj",
"unable-to-connect-to": "Kan ikke foirbinde til {ip}",

View File

@@ -139,7 +139,6 @@
"and": "Und",
"any-property": "Jede Eigenschaft",
"api-error-details": "API Fehler Details",
"api-info-details": "API Infos anzeigen",
"api-warning-details": "API Warnungen",
"appearance": "Aussehen",
"aria:breadcrumb:label": "Brotkrümelnavigation",
@@ -150,7 +149,6 @@
"available-properties-for-advanced-filter:": "Verfügbare Felder für erweiterten Filter:",
"back-pool-dashboard": "Zurück zum Pooldashboard",
"back-site-dashboard": "Gehen zurück Zum Dashboard",
"backed-up-pools": "Gesicherte Pools",
"backed-up-vms": "Gesicherte VMs",
"backup": "Sicherung",
"backup-archive-status": "Status des Sicherungsarchivs",
@@ -163,13 +161,7 @@
"backup-repository": "Sicherungsort",
"backup-repository-type": "Sicherungsort (Lokal, NFS, SMB)",
"backup-targets": "Backup Ziele",
"backup:full": "Vollbackup",
"backup:full-replication": "Vollständige Replikation",
"backup:incremental": "Inkrementelles Backup",
"backup:incremental-replication": "Inkrementelle Replikation",
"backup:last-replication": "Letzte Replikation",
"backup:mirror:full": "Vollständiges Mirror-Backup",
"backup:mirror:incremental": "Inkrementelles Mirror-Backup",
"backup:pool-metadata": "Pool Metadaten",
"backup:rolling-snapshot": "Rolling Snapshot",
"backup:xo-config": "XO Konfiguration",
@@ -203,12 +195,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Abbrechen",
"cbt-destroy-snapshot-data": "Snapshot-Daten bei Verwendung von CBT löschen",
"change-block-tracking": "Blockverfolgung ändern (CBT)",
"character-limit": "{count}/{max} Zeichen | {count}/{max} Zeichen",
"check-errors:": "Überprüfe die Fehler:",
"check-summing": "TX-Prüfsummen",
"checkpoint-snapshot": "Checkpoint Snapshot",
"click-to-display-alarms:": "Hier klicken um Alarme anzuzeigen:",
"click-to-return-default-pool": "Hier klicken um zum Standardpool zurückzukehren",
"cloud-config": "Cloud-Konfiguration",
@@ -290,7 +280,6 @@
"disconnected-from-physical-device": "Vom physischen Gerät getrennt",
"disconnected-pbd-number": "Getrennter PBD #{n}",
"disk-name": "Datenträgername",
"disk-size": "Festplattengröße",
"disk-space": "Festplattenspeicher",
"dns": "DNS",
"do-you-have-needs": "Vermisst du Funktionen oder hast Vorschläge? Sag uns Bescheid",
@@ -300,7 +289,6 @@
"drop": "Fallen lassen",
"duration": "Dauer",
"enabled": "Aktiviert",
"end-date": "Enddatum",
"ended": "Beendet",
"engines-off": "Engines deaktiviert, Umlauf stabil",
"eol": "EOL",
@@ -337,7 +325,6 @@
"hardware-specifications": "Hardware Spezifikationen",
"heartbeat-storage-repository": "Heartbeat Speicher Repository",
"here": "Hier",
"hide-successful-items": "Erfolgreiche Elemente in Fehlerberichten ausblenden",
"high-availability": "Hohe Verfügbarkeit",
"host": "Host",
"host-currently-shutdown": "Dieser Host ist derzeit heruntergefahren, daher können wir keine Daten abrufen.",
@@ -379,7 +366,6 @@
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job": "Job",
"job-name": "Job Name",
"job:arg:bond-mode-required": "Bond-modus erforderlich",
"job:arg:host-required": "Host ist erforderlich",
"job:arg:missing-payload": "Nutzlast fehlt",
@@ -528,7 +514,6 @@
"modal:vm-reboot-message": "Startet die virtuelle Maschine ordnungsgemäß neu, indem sie heruntergefahren und erneut gestartet wird. Laufende Prozesse werden ordnungsgemäß geschlossen.",
"modal:vm-shutdown-message": "Dadurch wird die virtuelle Maschine ordnungsgemäß heruntergefahren. Alle laufenden Prozesse werden gestoppt und die Verbindung der Benutzer wird möglicherweise getrennt. Sie können die VM später über die Schnittstelle neu starten.",
"mode": "Modus",
"modes": "Modis",
"more-actions": "Weitere Aktionen",
"mtu": "MTU",
"mtu-default-value-message": "Standardwert: 1500",
@@ -551,7 +536,6 @@
"n-vifs": "1 VIF | {n} VIFs",
"n-vms": "1 VM | {n} VMs",
"name": "Name",
"nbd-concurrency": "NBD Parallelität",
"nested-virtualization": "Verschachtelte Virtualisierung",
"netmask": "Netzmaske",
"network": "Netzwerk",
@@ -593,7 +577,6 @@
"no-active-backup-jobs": "Es gibt keine aktiven Backup Jobs auf dieser Seite.",
"no-alarm-detected": "Keine Alarme erkannt",
"no-alarm-triggered": "Kein Alarm ausgelöst",
"no-backed-up-vm-detected": "Keine gesicherten VMs erkannt",
"no-backup-job-available": "Keine Backup-Jobs verfügbar",
"no-backup-repository-detected": "Keine Backup-Repositorys erkannt",
"no-backup-run-available": "Keine Backup-Ausführungen verfügbar",
@@ -610,7 +593,6 @@
"no-pools-detected": "Keine Pools erkannt",
"no-replicated-vm": "Diese VM wird nicht repliziert. Konfigurieren Sie einen Replikationsjob zum aktivieren.",
"no-result": "Kein Ergebnis | Keine Ergebnisse",
"no-schedule-available": "Keine Zeitpläne verfügbar",
"no-selected-vm-can-be-exported": "Keine der ausgewählten VMs kann exportiert werden",
"no-selected-vm-can-be-migrated": "Keine der ausgewählten VMs kann migriert werden",
"no-server-detected": "Keine Server gefunden",
@@ -635,7 +617,6 @@
"off": "Ausgeschaltet",
"offline": "Offline",
"offline-backup": "Offline Backup",
"offline-snapshot": "Offline Snapshot",
"ok": "OK",
"on": "Eingeschaltet",
"on-object": "auf {object}",
@@ -657,7 +638,6 @@
"os-name": "Betriebssystem-Name",
"other": "Andere",
"other-properties": "Sonstige Eigenschaften",
"other-settings": "Weitere Einstellungen",
"page-not-found": "Diese Seite wurde nicht gefunden…",
"page-please-wait": "Halte fest, Astraunaut! Diese Seite ist gerade noch in Vorbereitung und wird bald abheben.{newline}Wir sind noch dabei die Raketenmotoren auszurichten und die Systeme zu kalibrieren. Es wird nicht mehr lange dauern, bleiben sie dran!",
"pagination:all": "Alle",
@@ -766,7 +746,6 @@
"relative-time:past": "Vor {str}",
"relative-time:second": "1 Sekunde | {n} Sekunden",
"relative-time:year": "1 Jahr | {n} Jahre",
"remaining-space": "Verbleibender Speicherplatz",
"remote-syslog": "Externer Syslog",
"report-recipients": "Berichtsempfänger",
"report-when": "Bericht, wenn",
@@ -783,7 +762,6 @@
"root-by-default": "Standardmäßig \"root\".",
"run": "Start",
"running-vm": "VM eingeschalten | VMs eingeschalten",
"runs": "Läufe",
"s3-backup-repository": "S3-Backupdepot",
"scan-pifs": "PIFs scannen",
"schedule": "Zeitplan",
@@ -814,7 +792,6 @@
"sockets-with-cores-per-socket": "{nSockets} Sockel × {nCores} Kerne/Sockel",
"software": "Software",
"software-tooling": "Software & Werkzeuge",
"source-backup-repository": "Quell-Backup-Repository",
"space": "Platz",
"speed": "Geschwindigkeit",
"speed-limit": "Geschwindigkeitsbegrenzung",
@@ -827,7 +804,6 @@
"stacked-cpu-usage": "Prozessorauslastung gestapelt",
"stacked-ram-usage": "Arbeitsspeicherbelegung gestapelt",
"start-console": "Starte dein {type}, um auf die Konsole zuzugreifen und den Betrieb fortzusetzen!",
"start-date": "Startdatum",
"start-delay": "Verzögerter Start",
"start-host": "Starten Sie den Host, um den Betrieb fortzusetzen, oder versuchen Sie es später erneut, sobald er eingeschaltet ist.",
"start-vm": "Starten Sie es, um auf die Konsole und die Konfigurationsdetails zuzugreifen.",
@@ -901,12 +877,10 @@
"topology": "Topologie",
"total": "Gesamt",
"total-assigned": "Gesamt zugewiesen",
"total-capacity": "Gesamtkapazität",
"total-cpus": "Gesamt CPUs",
"total-free": "Gesamt frei",
"total-free:": "Gesamt frei:",
"total-memory": "Gesamtarbeitsspeicher",
"total-schedules": "Gesamtpläne",
"total-space": "Gesamter Platz",
"total-storage-repository": "Gesamtspeicherort",
"total-used": "Gesamt genutzt",
@@ -915,7 +889,6 @@
"traffic-rules": "Traffic Regeln",
"traffic-rules:info-message": "Reihenfolge der Traffic Regeln wird implementiert. Es kann zu unvorgesehenen Verhalten führen.",
"traffic-rules:no-traffic-rules-detected": "Keine Traffic Regeln erkannt",
"transfer-size": "Übertragungsgröße",
"translation-tool": "Übersetzungstool",
"trigger": "Trigger",
"type": "Typ",

View File

@@ -210,7 +210,6 @@
"and": "And",
"any-property": "Any property",
"api-error-details": "API Error details",
"api-info-details": "API Info details",
"api-warning-details": "API Warning details",
"appearance": "Appearance",
"archives": "Archives",
@@ -228,7 +227,6 @@
"azurite": "Azurite",
"back-pool-dashboard": "Go back to your Pool dashboard",
"back-site-dashboard": "Go back to your site dashboard",
"backed-up-pools": "Backed up Pools",
"backed-up-vms": "Backed up VMs",
"backup": "Backup",
"backup-and-replication": "Backup & Replication",
@@ -246,13 +244,7 @@
"backup-repository-path": "Backup repository path",
"backup-repository-type": "Backup repository (local, NFS, SMB)",
"backup-targets": "Backup targets",
"backup:full": "Full backup",
"backup:full-replication": "Full replication",
"backup:incremental": "Incremental backup",
"backup:incremental-replication": "Incremental replication",
"backup:last-replication": "Last replication",
"backup:mirror:full": "Mirror full backup",
"backup:mirror:incremental": "Mirror incremental backup",
"backup:pool-metadata": "Pool metadata",
"backup:rolling-snapshot": "Rolling snapshot",
"backup:vms-backup": "VMs backup",
@@ -297,12 +289,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Cancel",
"cbt-destroy-snapshot-data": "Purge snapshot data when using CBT",
"change-block-tracking": "Change block tracking (CBT)",
"character-limit": "{count}/{max} character | {count}/{max} characters",
"check-errors:": "Check out the errors:",
"check-summing": "TX checksumming",
"checkpoint-snapshot": "Checkpoint snapshot",
"click-test-br-speed": "Click to test BR speed",
"click-to-display-alarms:": "Click to display alarms:",
"click-to-return-default-pool": "Click here to return to the default pool",
@@ -407,7 +397,6 @@
"disconnected-pbd-number": "Disconnected PBD #{n}",
"disconnecting": "Disconnecting",
"disk-name": "Disk name",
"disk-size": "Disk size",
"disk-space": "Disk space",
"dns": "DNS",
"do-you-have-needs": "You have needs and/or expectations? Let us know",
@@ -429,7 +418,6 @@
"encryption-available-for-block-modes-only": "Encryption is available for block modes only.",
"encryption-key-invalid": "The key must contain exactly {n} hexadecimal characters.",
"encryption-key-loss-warning": "If you lose the encryption key, your data cannot be recovered.",
"end-date": "End date",
"ended": "Ended",
"endpoint-url": "Endpoint URL",
"engines-off": "Engines off, orbit stable",
@@ -494,7 +482,6 @@
"health-check-sr": "@:health-check SR",
"heartbeat-storage-repository": "Heartbeat storage repository",
"here": "Here",
"hide-successful-items": "Hide successful items in failure reports",
"high-availability": "High availability (HA)",
"host": "Host",
"host-currently-shutdown": "This host is currently shut down, so we can’t retrieve any data.",
@@ -555,7 +542,6 @@
"iso-dvd": "ISO/DVD",
"item": "Item",
"job": "Job",
"job-name": "Job name",
"job:arg:allocated-space-required": "Allocated space is required",
"job:arg:backup-repository-required": "Backup repository is required",
"job:arg:bond-mode-required": "@:bond-mode-required",
@@ -862,7 +848,6 @@
"modal:vm-reboot-message": "Restarts the virtual machine gracefully by shutting it down and starting it again. Running processes will be closed properly.",
"modal:vm-shutdown-message": "This will gracefully shut down the virtual machine. All running processes will stop, and users may be disconnected. You can restart the VM later from the interface.",
"mode": "Mode",
"modes": "Modes",
"more-actions": "More actions",
"more-information": "More information",
"mtu": "MTU",
@@ -897,7 +882,6 @@
"name": "Name",
"name-required": "Name is required.",
"native": "Native",
"nbd-concurrency": "NBD concurrency",
"nbd:disabled": "Disabled",
"nbd:insecure": "Insecure (not encrypted)",
"nbd:insecure-warning": "The disk data of the backups will travel unencrypted on this network. Only enable it on a network dedicated to backups and isolated from the VMs and the users (dedicated VLAN or physical network).",
@@ -962,7 +946,6 @@
"no-active-backup-jobs": "There are no active backup jobs on this site.",
"no-alarm-detected": "No alarms detected",
"no-alarm-triggered": "No alarm triggered",
"no-backed-up-vm-detected": "No backed up VMs detected",
"no-backup-job-available": "No backup jobs available",
"no-backup-repository-detected": "No backup repositories detected",
"no-backup-run-available": "No backup runs available",
@@ -985,7 +968,6 @@
"no-role-applied": "No role applied",
"no-run": "No run",
"no-running-vm-detected": "No running VMs detected",
"no-schedule-available": "No schedules available",
"no-selected-vm-can-be-exported": "No selected VM can be exported",
"no-selected-vm-can-be-migrated": "No selected VM can be migrated",
"no-server-detected": "No servers detected",
@@ -1012,7 +994,6 @@
"off": "Off",
"offline": "Offline",
"offline-backup": "Offline backup",
"offline-snapshot": "Offline snapshot",
"ok": "OK",
"on": "On",
"on-object": "on {object}",
@@ -1044,7 +1025,6 @@
"os-name": "OS name",
"other": "Other",
"other-properties": "Other properties",
"other-settings": "Other settings",
"ova": "OVA",
"page-not-found": "This page is not to be found…",
"page-please-wait": "Hold tight, astronaut! The page is getting ready to take off.{newline}We're just aligning the thrusters and calibrating the systems. It won't be long now, stay tuned!",
@@ -1184,7 +1164,6 @@
"relative-time:past": "{str} ago",
"relative-time:second": "1 second | {n} seconds",
"relative-time:year": "1 year | {n} years",
"remaining-space": "Remaining space",
"remote-syslog": "Remote syslog",
"report-recipients": "Report recipients",
"report-when": "Report when",
@@ -1206,7 +1185,6 @@
"run": "Run",
"run-interrupted": "The run was interrupted before completion",
"running-vm": "Running VM | Running VMs",
"runs": "Runs",
"s3": "S3",
"s3-backup-repository": "S3 backup repository",
"s3-endpoint-sample": "Example: s3.us-west-1.amazonaws.com",
@@ -1251,7 +1229,6 @@
"software": "Software",
"software-tooling": "Software & tooling",
"source": "Source",
"source-backup-repository": "Source backup repository",
"space": "Space",
"speed": "Speed",
"speed-limit": "Speed limit",
@@ -1279,7 +1256,6 @@
"stacked-cpu-usage": "Stacked CPU usage",
"stacked-ram-usage": "Stacked RAM usage",
"start-console": "Start your {type} to access the console and resume operations!",
"start-date": "Start date",
"start-delay": "Start delay",
"start-host": "Start the host to resume operations, or check back later once it’s powered on.",
"start-vm": "Start it to access its console, and configuration details.",
@@ -1366,12 +1342,10 @@
"topology": "Topology",
"total": "Total",
"total-assigned": "Total assigned",
"total-capacity": "Total capacity",
"total-cpus": "Total CPUs",
"total-free": "Total free",
"total-free:": "Total free:",
"total-memory": "Total memory",
"total-schedules": "Total schedules",
"total-space": "Total space",
"total-space-on-sr": "Total space on SR",
"total-storage-repository": "Total storage repository",
@@ -1387,7 +1361,6 @@
"traffic-rules:info-message": "Traffic rules order is being implemented. Behaviour may be hazardous.",
"traffic-rules:no-traffic-rules-detected": "No traffic rules detected",
"traffic-rules:xapi-plugin-required": "Requires XAPI plugin mode",
"transfer-size": "Transfer size",
"translation-tool": "Translation tool",
"treeview": "Treeview",
"trigger": "Trigger",

View File

@@ -161,7 +161,6 @@
"and": "Y",
"any-property": "Cualquier propiedad",
"api-error-details": "Detalles de errores de la API",
"api-info-details": "Información detallada de la API",
"api-warning-details": "Detalles de advertencia de la API",
"appearance": "Apariencia",
"aria:breadcrumb:label": "Rastro de migas",
@@ -175,7 +174,6 @@
"available-properties-for-advanced-filter:": "Propriedades disponibles para filtros avanzados:",
"back-pool-dashboard": "Regresa a tu panel del pool",
"back-site-dashboard": "Regresar al panel del sitio",
"backed-up-pools": "Pools con copia de seguridad",
"backed-up-vms": "VMs con copia de seguridad",
"backup": "Copia de seguridad",
"backup-archive-status": "Estado del archivo de respaldo",
@@ -188,13 +186,7 @@
"backup-repository": "Repositorio de copia de seguridad",
"backup-repository-type": "Repositorio de copia de seguridad (local, NFS, SMB)",
"backup-targets": "Objetos de copia de seguridad",
"backup:full": "Copia de seguridad completa",
"backup:full-replication": "Replicación completa",
"backup:incremental": "Copia de seguridad incremental",
"backup:incremental-replication": "Replicación incremental",
"backup:last-replication": "Última replicación",
"backup:mirror:full": "Copia de seguridad completa espejo",
"backup:mirror:incremental": "Copia de seguridad incremental espejo",
"backup:pool-metadata": "Metadatos del pool",
"backup:rolling-snapshot": "Instantánea contínua (rolling snapshot)",
"backup:xo-config": "Configuración XO",
@@ -228,12 +220,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Cancelar",
"cbt-destroy-snapshot-data": "Borrar instantánea cuando se utiliza CBT",
"change-block-tracking": "Seguimiento de bloques modificados (CBT)",
"character-limit": "{count}/{max} carácter | {count}/{max} caracteres",
"check-errors:": "Revisar los errores:",
"check-summing": "Suma de comprobación TX",
"checkpoint-snapshot": "Instantáneo de punto de control",
"click-to-display-alarms:": "Haga clic para mostrar las alarmas:",
"click-to-return-default-pool": "Haga clic para regresar al pool predeterminado",
"cloud-config": "Configuración de la nube",
@@ -314,7 +304,6 @@
"disconnected-from-physical-device": "Desconectado del dispositivo físico",
"disconnected-pbd-number": "PBD #{n} desconectado",
"disk-name": "Nombre del disco",
"disk-size": "Tamaño del disco",
"disk-space": "Espacio disco",
"dns": "DNS",
"do-you-have-needs": "¿Tienes necesidades y/o expectativas? Cuéntanos",
@@ -323,7 +312,6 @@
"done": "Terminadas",
"duration": "Duración",
"enabled": "Activado",
"end-date": "Fecha final",
"ended": "Finalizado",
"engines-off": "Motores apagados, órbita estable",
"eol": "EOL",
@@ -363,7 +351,6 @@
"hardware-specifications": "Especificaciones de hardware",
"heartbeat-storage-repository": "Repositorio de almacenamiento de heartbeat",
"here": "Aquí",
"hide-successful-items": "Ocultar elementos exitosos en informes de fallos",
"high-availability": "Alta disponibilidad (HA)",
"host": "Servidor",
"host-currently-shutdown": "Este equipo está actualmente apagado, por lo que no podemos recuperar ningún dato.",
@@ -406,7 +393,6 @@
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job": "Tarea",
"job-name": "Nombre del trabajo",
"job:arg:host-required": "Se requiere un host",
"job:arg:missing-payload": "Falta el payload",
"job:arg:name-required": "El nombre de la etiqueta es obligatorio",
@@ -530,7 +516,6 @@
"modal:vm-reboot-message": "Reinicia la máquina virtual correctamente, apagando y encendiendo de nuevo. Los procesos en ejecución se cerrarán correctamente.",
"modal:vm-shutdown-message": "Esto apagará la máquina virtual correctamente. Todos los procesos en ejecución se detendrán y los usuarios podrían desconectarse. Puede reiniciar la máquina virtual más tarde desde la interfaz.",
"mode": "Modo",
"modes": "Modos",
"more-actions": "Acciones adicionales",
"mtu": "MTU",
"multi-creation": "Creación múltiple",
@@ -545,7 +530,6 @@
"n-subtasks": "1 subtarea | {n} subtareas",
"n-vms": "1 VM | {n} VMs",
"name": "Nombre",
"nbd-concurrency": "Concurrencia NBD",
"nested-virtualization": "Virtualización anidada",
"netmask": "Máscara de red",
"network": "Red",
@@ -579,7 +563,6 @@
"no-active-backup-jobs": "No hay trabajos de copia de seguridad activos en este site.",
"no-alarm-detected": "No se detectan alarmas",
"no-alarm-triggered": "No hay alarma",
"no-backed-up-vm-detected": "No se detecta ninguna VM salvaguardada",
"no-backup-job-available": "No hay disponible tareas de backup",
"no-backup-repository-detected": "No se detecta ningún repositorio de copias de seguridad",
"no-backup-run-available": "No hay ejecuciones de copia de seguridad disponibles.",
@@ -596,7 +579,6 @@
"no-pools-detected": "No se han detectado pools",
"no-replicated-vm": "Esta VM no está siendo replicada. Configura una tarea de replicación para habilitarlo.",
"no-result": "Sin resultados",
"no-schedule-available": "No hay programaciones disponibles",
"no-selected-vm-can-be-exported": "Ninguna máquina virtual selectionada puede exportarse",
"no-selected-vm-can-be-migrated": "Ninguna VM seleccionada puede migrarse",
"no-server-detected": "Ningún servidores detectado",
@@ -621,7 +603,6 @@
"off": "Apagado",
"offline": "Fuera de línea",
"offline-backup": "Salvaguarda fuera de línea",
"offline-snapshot": "Instantáneo fuera de línea",
"ok": "OK",
"on": "Encendido",
"on-object": "encendido {object}",
@@ -643,7 +624,6 @@
"os-name": "Nombre del SO",
"other": "Otro",
"other-properties": "Otras propiedades",
"other-settings": "Otros parámetros",
"page-not-found": "No se encuentra esta página…",
"page-please-wait": "¡Aguanta, astronauta! La página se está preparando para despegar.{newline}Solo estamos alineando los propulsores y calibrando los sistemas. ¡No faltará mucho, mantente atento!",
"pagination:all": "@:all",
@@ -748,7 +728,6 @@
"relative-time:past": "Hace {str}",
"relative-time:second": "1 segundo | {n} segundos",
"relative-time:year": "1 año | {n} años",
"remaining-space": "Espacio restante",
"remote-syslog": "Syslog remoto",
"report-recipients": "Destinatarios del informe",
"report-when": "Informar cuando",
@@ -765,7 +744,6 @@
"root-by-default": "\"root\" por defecto.",
"run": "Ejecutar",
"running-vm": "VM ejecutando | VMs ejecutando",
"runs": "Ejecuciones",
"s3-backup-repository": "Repositorio S3 de salvaguardas",
"scan-pifs": "Escanear PIFs",
"schedule": "Planificación",
@@ -795,7 +773,6 @@
"sockets-with-cores-per-socket": "{nSockets} zócalos × {nCores} núcleos/zócalo",
"software": "Programa",
"software-tooling": "Software y herramientas",
"source-backup-repository": "Repositorio de copia de seguridad de origen",
"space": "Espacio",
"speed": "Velocidad",
"speed-limit": "Límite de velocidad",
@@ -808,7 +785,6 @@
"stacked-cpu-usage": "Uso CPU acumulado",
"stacked-ram-usage": "Uso RAM acumulado",
"start-console": "¡Activar el {type} para acceder a la cónsola y continuar las operaciones!",
"start-date": "Fecha inicial",
"start-delay": "Arranque diferido",
"start-host": "Arrancar el servidor para continuar las operaciones, o vuelve más tarde una vez que se termina el arranque.",
"start-vm": "Arrancarla para acceder a la cónsola y sus parámetros de configuración.",
@@ -880,17 +856,14 @@
"topology": "Topologia",
"total": "Total",
"total-assigned": "Total asignado",
"total-capacity": "Capacidad total",
"total-cpus": "CPUs totales",
"total-free": "Total libre",
"total-free:": "Total libre:",
"total-memory": "Memoria total",
"total-schedules": "Planificaciones totales",
"total-space": "Espacio total",
"total-storage-repository": "Total reposito de almacenamiento",
"total-used": "Total usado",
"total-used:": "Total usado:",
"transfer-size": "Tamaño de transferencia",
"translation-tool": "Herramienta de traducción",
"trigger": "Disparador",
"unable-to-connect-to": "Imposible conectarse al {ip}",

View File

@@ -90,7 +90,6 @@
"disabled": "Pois käytöstä",
"disconnected": "Yhteys katkaistu",
"disconnected-from-physical-device": "Irrotettu fyysisestä laitteesta",
"disk-size": "Tiedoston koko",
"disk-space": "Levytila",
"dns": "DNS",
"do-you-have-needs": "Onko sinulla tarpeita ja/tai odotuksia? Kerro meille",
@@ -98,7 +97,6 @@
"done": "Tehty",
"duration": "Kesto",
"enabled": "Käytössä",
"end-date": "Päättymispäivä",
"ended": "Päättynyt",
"eol": "EOL",
"error": "Virhe",
@@ -153,7 +151,6 @@
"message": "Viesti",
"missing-translations?": "Puuttuvia tai virheellisiä käännöksiä?",
"mode": "Tila",
"modes": "Tilat",
"more-actions": "Lisää toimintoja",
"mtu": "MTU",
"n-percent": "{n}%",
@@ -185,7 +182,6 @@
"or": "Tai",
"other": "Muu",
"other-properties": "Muut ominaisuudet",
"other-settings": "Muut asetukset",
"ova": "OVA",
"page-not-found": "Tätä sivua ei löydy…",
"password": "Salasana",
@@ -227,7 +223,6 @@
"speed": "Nopeus",
"sr": "SR",
"ssh-key": "SSH-avain",
"start-date": "Aloituspäivä",
"started": "Aloitettu",
"state": "Tila",
"static": "Staattinen",
@@ -264,7 +259,6 @@
"timezone": "Aikavyöhyke",
"topology": "Topologia",
"total": "Yhteensä",
"total-capacity": "Kokonaiskapasiteetti",
"total-memory": "Muistia yhteensä",
"translation-tool": "Käännöstyökalu",
"unknown": "Tuntematon",

View File

@@ -210,7 +210,6 @@
"and": "Et",
"any-property": "N'importe quelle propriété",
"api-error-details": "Détails de l'erreur API",
"api-info-details": "Détails de l'information API",
"api-warning-details": "Détails de l'avertissement API",
"appearance": "Apparence",
"archives": "Archives",
@@ -228,7 +227,6 @@
"azurite": "Azurite",
"back-pool-dashboard": "Revenez au tableau de bord de votre pool",
"back-site-dashboard": "Revenir au tableau de bord du site",
"backed-up-pools": "Pools sauvegardés",
"backed-up-vms": "VMs sauvegardées",
"backup": "Sauvegarde",
"backup-and-replication": "Sauvegarde et réplication",
@@ -246,13 +244,7 @@
"backup-repository-path": "Chemin du backup repository",
"backup-repository-type": "Dépôt de sauvegarde (local, NFS, SMB)",
"backup-targets": "Cibles de sauvegarde",
"backup:full": "Sauvegarde complète",
"backup:full-replication": "Réplication complète",
"backup:incremental": "Sauvegarde incrémentielle",
"backup:incremental-replication": "Réplication incrémentielle",
"backup:last-replication": "Dernière réplication",
"backup:mirror:full": "Sauvegarde complète en miroir",
"backup:mirror:incremental": "Sauvegarde incrémentielle en miroir",
"backup:pool-metadata": "Métadonnées du pool",
"backup:rolling-snapshot": "Instantané continu",
"backup:vms-backup": "Sauvegarde des VMs",
@@ -297,12 +289,10 @@
"bytes:ki": "Kio",
"bytes:mi": "Mio",
"cancel": "Annuler",
"cbt-destroy-snapshot-data": "Supprimer les données de l'instantané quand CBT est utilisé",
"change-block-tracking": "Change block tracking (CBT)",
"character-limit": "{count}/{max} caractère | {count}/{max} caractères",
"check-errors:": "Consultez les erreurs :",
"check-summing": "TX checksumming",
"checkpoint-snapshot": "Instantané de point de contrôle",
"click-test-br-speed": "Cliquez pour tester la vitesse du BR",
"click-to-display-alarms:": "Cliquer pour afficher les alarmes :",
"click-to-return-default-pool": "Cliquer ici pour revenir au pool par défaut",
@@ -407,7 +397,6 @@
"disconnected-pbd-number": "PBD déconnecté #{n}",
"disconnecting": "Déconnexion",
"disk-name": "Nom du disque",
"disk-size": "Taille du disque",
"disk-space": "Espace disque",
"dns": "DNS",
"do-you-have-needs": "Vous avez des besoins et/ou des attentes ? Faites-le-nous savoir",
@@ -429,7 +418,6 @@
"encryption-available-for-block-modes-only": "Le cryptage est disponible uniquement pour les modes par blocs.",
"encryption-key-invalid": "La clé doit contenir exactement {n} caractères hexadécimaux.",
"encryption-key-loss-warning": "Si vous perdez la clé de cryptage, vos données ne peuvent pas être récupérées.",
"end-date": "Date de fin",
"ended": "Terminé",
"endpoint-url": "URL du endpoint",
"engines-off": "Moteurs arrêtés, orbite stable",
@@ -494,7 +482,6 @@
"health-check-sr": "SR du contrôle de santé",
"heartbeat-storage-repository": "Dépôt de stockage pour le heartbeat de la haute disponibilité",
"here": "Ici",
"hide-successful-items": "Masquer les éléments réussis des rapports d'erreur",
"high-availability": "Haute Disponibilité (HA)",
"host": "Hôte",
"host-currently-shutdown": "Cet hôte est actuellement à l’arrêt, nous ne pouvons donc pas récupérer de données.",
@@ -555,7 +542,6 @@
"iso-dvd": "ISO/DVD",
"item": "Élément",
"job": "Job",
"job-name": "Nom du job",
"job:arg:allocated-space-required": "L'espace alloué est obligatoire",
"job:arg:backup-repository-required": "Le dépôt de sauvegarde est obligatoire",
"job:arg:bond-mode-required": "@:bond-mode-required",
@@ -862,7 +848,6 @@
"modal:vm-reboot-message": "Redémarre la VM de manière propre en l'éteignant puis en la redémarrant. Les processus en cours seront fermés correctement.",
"modal:vm-shutdown-message": "Cela éteindra la VM de manière propre. Tous les processus en cours seront arrêtés et les utilisateurs pourront être déconnectés. Vous pourrez redémarrer la VM plus tard depuis l'interface.",
"mode": "Mode",
"modes": "Modes",
"more-actions": "Plus d'actions",
"more-information": "Plus d'informations",
"mtu": "MTU",
@@ -897,7 +882,6 @@
"name": "Nom",
"name-required": "Le nom est requis.",
"native": "Native",
"nbd-concurrency": "Concurrence NBD",
"nbd:disabled": "Désactivé",
"nbd:insecure": "Non sécurisé (non chiffré)",
"nbd:insecure-warning": "Les données des disques sauvegardés transiteront en clair sur ce réseau. À n'activer que sur un réseau dédié aux sauvegardes et isolé des VMs et des utilisateurs (VLAN ou réseau physique dédié).",
@@ -962,7 +946,6 @@
"no-active-backup-jobs": "Il n'y a aucune tâche de sauvegarde active sur ce site.",
"no-alarm-detected": "Aucune alarme détectée",
"no-alarm-triggered": "Aucune alarme déclenchée",
"no-backed-up-vm-detected": "Aucune VM sauvegardée détectée",
"no-backup-job-available": "Aucun job de sauvegarde disponible",
"no-backup-repository-detected": "Aucun dépôt de sauvegarde détecté",
"no-backup-run-available": "Aucune exécution de sauvegarde disponible",
@@ -985,7 +968,6 @@
"no-role-applied": "Pas de rôle appliqué",
"no-run": "Aucun run",
"no-running-vm-detected": "Aucune VM en cours d'exécution détectée",
"no-schedule-available": "Aucune planification disponible",
"no-selected-vm-can-be-exported": "Aucune VM sélectionnée ne peut être exportée",
"no-selected-vm-can-be-migrated": "Aucune VM sélectionnée ne peut être migrée",
"no-server-detected": "Aucun serveur détecté",
@@ -1012,7 +994,6 @@
"off": "Éteint",
"offline": "Hors ligne",
"offline-backup": "Sauvegarde hors ligne",
"offline-snapshot": "Instantané hors ligne",
"ok": "OK",
"on": "Allumé",
"on-object": "sur {object}",
@@ -1044,7 +1025,6 @@
"os-name": "Nom de l'OS",
"other": "Autre",
"other-properties": "Autres propriétés",
"other-settings": "Autres paramètres",
"ova": "OVA",
"page-not-found": "Cette page est introuvable…",
"page-please-wait": "Accrochez-vous, astronaute ! La page est sur le point de décoller.{newline}Nous alignons les propulseurs et calibrons les systèmes. Plus que quelques instants, restez à l'écoute !",
@@ -1184,7 +1164,6 @@
"relative-time:past": "Il y a {str}",
"relative-time:second": "1 seconde | {n} secondes",
"relative-time:year": "1 an | {n} ans",
"remaining-space": "Espace restant",
"remote-syslog": "Syslog distant",
"report-recipients": "Destinataires du rapport",
"report-when": "Rapporter quand",
@@ -1206,7 +1185,6 @@
"run": "Run",
"run-interrupted": "Le run a été interrompu avant la fin",
"running-vm": "VM en cours d'exécution | VMs en cours d'exécution",
"runs": "Runs",
"s3": "S3",
"s3-backup-repository": "Dépôt de sauvegarde S3",
"s3-endpoint-sample": "Exemple : s3.us-west-1.amazonaws.com",
@@ -1251,7 +1229,6 @@
"software": "Logiciel",
"software-tooling": "Logiciels et outils",
"source": "Source",
"source-backup-repository": "Dépôt de sauvegarde source",
"space": "Espace",
"speed": "Vitesse",
"speed-limit": "Limite de vitesse",
@@ -1279,7 +1256,6 @@
"stacked-cpu-usage": "Utilisation CPU empilée",
"stacked-ram-usage": "Utilisation RAM empilée",
"start-console": "Démarrez votre {type} pour accéder à la console et reprendre les opérations !",
"start-date": "Date de début",
"start-delay": "Départ différé",
"start-host": "Démarrez l’hôte pour reprendre les opérations, ou revenez plus tard une fois qu’il sera allumé.",
"start-vm": "Démarrez-la pour accéder à sa console et à ses paramètres de configuration.",
@@ -1366,12 +1342,10 @@
"topology": "Topologie",
"total": "Total",
"total-assigned": "Total assigné",
"total-capacity": "Espace total",
"total-cpus": "Total CPUs",
"total-free": "Total libre",
"total-free:": "Total libre :",
"total-memory": "Mémoire totale",
"total-schedules": "Nombre total de planifications",
"total-space": "Espace total",
"total-space-on-sr": "Espace total sur le SR",
"total-storage-repository": "Total dépôt de stockage",
@@ -1387,7 +1361,6 @@
"traffic-rules:info-message": "Les règles de trafic sont en cours d'application. Certains comportements peuvent être hasardeux.",
"traffic-rules:no-traffic-rules-detected": "Aucune règle de trafic détectée",
"traffic-rules:xapi-plugin-required": "Nécessite le mode plugin XAPI",
"transfer-size": "Taille transférée",
"translation-tool": "Outil de traduction",
"treeview": "Arborescence",
"trigger": "Déclencheur",

View File

@@ -196,7 +196,6 @@
"documentation-name": "Documentazione {name}",
"duration": "Durata",
"enabled": "Abilitato",
"end-date": "Data di fine",
"ended": "Finito",
"eol": "EOL",
"error": "Errore",
@@ -298,7 +297,6 @@
"memory-usage": "Utilizzo memoria",
"message": "Messaggio",
"missing-translations?": "Traduzioni mancanti o errate?",
"modes": "Modi",
"n-gb-left": "{n} GB rimanenti",
"n-gb-required": "{n} GB richiesti",
"n-hosts": "1 host | {n} host",
@@ -337,7 +335,6 @@
"object": "Oggetto",
"options": "Opzioni",
"other-properties": "Altre caratteristiche",
"other-settings": "Altre impostazioni",
"page-not-found": "Questa pagina non è disponibile…",
"pagination:all": "Tutti",
"partially-connected": "Parzialmente connesso",
@@ -377,7 +374,6 @@
"relative-time:past": "{str} fa",
"relative-time:second": "1 secondo | {n} secondi",
"relative-time:year": "1 anno | {n} anni",
"remaining-space": "Spazio rimanente",
"report-when:always": "Sempre",
"report-when:error": "Errore",
"report-when:never": "Mai",
@@ -392,7 +388,6 @@
"speed": "Velocità",
"ssh-password": "Password SSH",
"ssh-password-confirm": "Conferma la password SSH",
"start-date": "Data di inizio",
"status": "Stato",
"status:active": "Attivo",
"status:halted": "Spento",
@@ -414,7 +409,6 @@
"timezone": "Fuso orario",
"topology": "Topologia",
"total": "Totale",
"total-capacity": "Capacità totale",
"unable-to-connect-to": "Impossibile connettersi a {ip}",
"unknown": "Sconosciuto",
"unlocked": "Sbloccato",

View File

@@ -131,7 +131,6 @@
"and": "그리고",
"any-property": "모든 속성",
"api-error-details": "API 오류 상세",
"api-info-details": "API 정보 상세",
"api-warning-details": "API 경고 상세",
"appearance": "외형",
"aria:breadcrumb:label": "경로 표시",
@@ -142,7 +141,6 @@
"available-properties-for-advanced-filter:": "고급 필터에 사용 가능한 속성:",
"back-pool-dashboard": "풀 대시보드로 돌아가기",
"back-site-dashboard": "사이트 대시보드로 돌아가기",
"backed-up-pools": "백업된 풀",
"backed-up-vms": "백업된 VM",
"backup": "백업",
"backup-archive-status": "백업 아카이브 상태",
@@ -155,13 +153,7 @@
"backup-repository": "백업 저장소",
"backup-repository-type": "백업 저장소 (로컬, NFS, SMB)",
"backup-targets": "백업 대상",
"backup:full": "전체 백업",
"backup:full-replication": "전체 복제",
"backup:incremental": "증분 백업",
"backup:incremental-replication": "증분 복제",
"backup:last-replication": "마지막 복제",
"backup:mirror:full": "미러 전체 백업",
"backup:mirror:incremental": "미러 증분 백업",
"backup:pool-metadata": "풀 메타데이터",
"bios-default": "bios (기본값)",
"bios-info": "BIOS 정보",
@@ -196,7 +188,6 @@
"description": "설명",
"dhcp": "DHCP",
"disk-name": "디스크 이름",
"disk-size": "디스크 크기",
"disk-space": "디스크 공간",
"dns": "DNS",
"documentation": "문서",

View File

@@ -103,7 +103,6 @@
"all-quiet-launchpad": "Alt er rolig på launchpad",
"allow-self-signed-ssl": "Du må kanskje tillate selvsignerte SSL-sertifikater i nettleseren",
"api-error-details": "API-feildetaljer",
"api-info-details": "API-informasjonsdetaljer",
"api-warning-details": "API-advarselsdetaljer",
"appearance": "Utseende",
"aria:breadcrumb:label": "Breadcrumb",
@@ -114,7 +113,6 @@
"available-properties-for-advanced-filter:": "Tilgjengelige egenskaper for avansert filter:",
"back-pool-dashboard": "Gå tilbake til Pool Dashboard",
"back-site-dashboard": "Gå tilbake til site dashboard",
"backed-up-pools": "Sikkerhetskopierte pooler",
"backed-up-vms": "Sikkerhetskopierte VM-er",
"backup": "Sikkerhetskopi",
"backup-issues": "Problemer med sikkerhetskopiering",
@@ -137,12 +135,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Avbryt",
"cbt-destroy-snapshot-data": "Slett øyeblikksbildedata ved bruk av CBT",
"change-block-tracking": "Endre blokksporing (CBT)",
"character-limit": "{count}/{max} tegn | {count}/{max} tegn",
"check-errors:": "Se feilene:",
"check-summing": "TX-checksumming",
"checkpoint-snapshot": "Kontrollpunkt-øyeblikksbilde",
"click-to-display-alarms:": "Klikk for å vise alarmer:",
"click-to-return-default-pool": "Klikk her for å gå tilbake til standardpool",
"cloud-init-config": "Tilpasset konfigurasjon",
@@ -215,7 +211,6 @@
"disconnected-from-physical-device": "Frakoblet fra fysisk enhet",
"disconnected-pbd-number": "Frakoblet PBD #{n}",
"disk-name": "Disknavn",
"disk-size": "Diskstørrelse",
"disk-space": "Diskplass",
"dns": "DNS",
"do-you-have-needs": "Har du behov og/eller forventninger? Gi oss beskjed",
@@ -224,7 +219,6 @@
"done": "Ferdig",
"duration": "Varighet",
"enabled": "Aktivert",
"end-date": "Sluttdato",
"ended": "Avsluttet",
"engines-off": "Motorer av, stabil bane",
"eol": "EOL",
@@ -256,7 +250,6 @@
"hardware-specifications": "Maskinvarespesifikasjoner",
"heartbeat-storage-repository": "Lager for heartbeat",
"here": "Her",
"hide-successful-items": "Skjul vellykkede elementer i feilrapporter",
"high-availability": "Høy tilgjengelighet (HA)",
"host": "Vert",
"host-currently-shutdown": "Denne verten er for øyeblikket slått av, data kan derfor ikke hentes.",
@@ -290,7 +283,6 @@
"is-primary-host": "{name} er primær vert",
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job-name": "Jobbnavn",
"keep-me-logged": "Hold meg innlogget",
"keep-page-open": "Ikke oppdater eller lukk fanen før utrullingen er fullført.",
"language": "Språk",
@@ -332,7 +324,6 @@
"minimum-static-memory": "Minste mengde statisk minne",
"missing-patches": "Manglende oppdateringer",
"mode": "Modus",
"modes": "Moduser",
"more-actions": "Flere handlinger",
"mtu": "MTU",
"multi-creation": "Masseopprettelse",
@@ -345,7 +336,6 @@
"n-percent": "{n}%",
"n-vms": "1 VM | {n} VM-er",
"name": "Navn",
"nbd-concurrency": "NBD-samtidighet",
"nested-virtualization": "Nestet virtualisering",
"netmask": "Nettmaske",
"network": "Nettverk",
@@ -365,7 +355,6 @@
"nic-type": "NIC-type",
"no-alarm-detected": "Ingen alarmer oppdaget",
"no-alarm-triggered": "Ingen alarm utløst",
"no-backed-up-vm-detected": "Ingen sikkerhetskopierte VM-er oppdaget",
"no-backup-job-available": "Ingen sikkerhetskopi-jobber er tilgjengelige",
"no-backup-repository-detected": "Ingen sikkerhetskopi-lagre oppdaget",
"no-backup-run-available": "Ingen sikkerhetskopi-kjøringer tilgjengelige",
@@ -379,7 +368,6 @@
"no-pbd-attached": "Ingen PBD-er tilkoblet",
"no-pif-detected": "Ingen PIFer oppdaget",
"no-result": "Ikke noe resultat",
"no-schedule-available": "Ingen tidsplaner tilgjengelig",
"no-selected-vm-can-be-exported": "Ingen valgte VM-er kan eksporteres",
"no-selected-vm-can-be-migrated": "Ingen valgte VM-er kan migreres",
"no-server-detected": "Ingen servere oppdaget",
@@ -401,7 +389,6 @@
"off": "Av",
"offline": "Frakoblet",
"offline-backup": "Frakoblet sikkerhetskopi",
"offline-snapshot": "Frakoblet øyeblikksbilde",
"ok": "OK",
"on": "På",
"on-object": "på {object}",
@@ -411,7 +398,6 @@
"os-name": "OS-navn",
"other": "Annet",
"other-properties": "Andre egenskaper",
"other-settings": "Andre innstillinger",
"page-not-found": "Denne siden finnes ikke…",
"pagination:all": "Alle",
"partially-connected": "Delvis tilkoblet",
@@ -484,7 +470,6 @@
"relative-time:past": "{str} siden",
"relative-time:second": "1 sekund | {n} sekunder",
"relative-time:year": "1 år | {n} år",
"remaining-space": "Gjenværende plass",
"remote-syslog": "Fjernsyslogg",
"report-recipients": "Rapportmottakere",
"report-when": "Rapporter når",
@@ -500,7 +485,6 @@
"root-by-default": "«root» som standard.",
"run": "Kjør",
"running-vm": "Kjørende VM | Kjørende VM-er",
"runs": "Kjøringer",
"s3-backup-repository": "S3-sikkerhetskopilager",
"scan-pifs": "Skann PIF-er",
"schedule": "Tidsplan",
@@ -527,7 +511,6 @@
"sockets-with-cores-per-socket": "{nSockets} sokler × {nCores} kjerner/sokkel",
"software": "Programvare",
"software-tooling": "Programvare og verktøy",
"source-backup-repository": "Kilde for sikkerhetskopilager",
"space": "Plass",
"speed": "Hastighet",
"speed-limit": "Hastighetsgrense",
@@ -540,7 +523,6 @@
"stacked-cpu-usage": "Stablet CPU-bruk",
"stacked-ram-usage": "Stablet RAM-bruk",
"start-console": "Start {type} for å få tilgang til konsollen og gjenoppta operasjoner!",
"start-date": "Startdato",
"start-delay": "Startforsinkelse",
"start-host": "Start verten for å gjenoppta operasjoner, eller sjekk igjen senere når den er slått på.",
"start-vm": "Start den for å få tilgang til konsollen og konfigurasjonsdetaljer.",
@@ -599,17 +581,14 @@
"topology": "Topologi",
"total": "Totalt",
"total-assigned": "Totalt tildelt",
"total-capacity": "Total kapasitet",
"total-cpus": "Totalt antall CPU-er",
"total-free": "Totalt ledig",
"total-free:": "Totalt ledig:",
"total-memory": "Totalt minne",
"total-schedules": "Totalt antall tidsplaner",
"total-space": "Total plass",
"total-storage-repository": "Totalt lagringsrepository",
"total-used": "Totalt brukt",
"total-used:": "Totalt brukt:",
"transfer-size": "Overføringsstørrelse",
"translation-tool": "Oversettelsesverktøy",
"unable-to-connect-to": "Kan ikke koble til {ip}",
"unable-to-connect-to-the-pool": "Kan ikke koble til poolen",

View File

@@ -184,7 +184,6 @@
"and": "En",
"any-property": "Elke eigenschap",
"api-error-details": "API foutdetails",
"api-info-details": "API-info details",
"api-warning-details": "API-waarschuwing details",
"appearance": "Uiterlijk",
"aria:breadcrumb:label": "Broodkruimel",
@@ -198,7 +197,6 @@
"available-properties-for-advanced-filter:": "Beschikbare eigenschappen voor geavanceerd filter:",
"back-pool-dashboard": "Ga terug naar je Pool dashboard",
"back-site-dashboard": "Ga terug naar je omgeving dashboard",
"backed-up-pools": "Geback-upte Pools",
"backed-up-vms": "Geback-upte VM's",
"backup": "Back-up",
"backup-archive-status": "Backup archief status",
@@ -211,13 +209,7 @@
"backup-repository": "Back-up opslag repository",
"backup-repository-type": "Back-up opslag repository (lokaal, NFS, SMB)",
"backup-targets": "Back-updoelen",
"backup:full": "Volledige back-up",
"backup:full-replication": "Volledige replicatie",
"backup:incremental": "Incrementele back-up",
"backup:incremental-replication": "Incrementele replicatie",
"backup:last-replication": "Laatste replicatie",
"backup:mirror:full": "kopieer volledige back-up",
"backup:mirror:incremental": "kopieer incrementele back-up",
"backup:pool-metadata": "Pool metadata",
"backup:rolling-snapshot": "Rollende snapshot",
"backup:xo-config": "XO-configuratie",
@@ -254,12 +246,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Annuleren",
"cbt-destroy-snapshot-data": "Snapshotgegevens verwijderen bij gebruik van CBT",
"change-block-tracking": "Blokwijzigingen bijhouden (CBT)",
"character-limit": "{count}/{max} karakter | {count}/{max} karakters",
"check-errors:": "Bekijk de fouten:",
"check-summing": "TX Controle sommen",
"checkpoint-snapshot": "Checkpoint snapshot",
"click-to-display-alarms:": "Klik om alarmen weer te geven:",
"click-to-return-default-pool": "Klik hier om terug te gaan naar de standaard pool",
"cloud-config": "Cloudconfiguratie",
@@ -359,7 +349,6 @@
"disconnected-pbd-number": "Losgekoppelde PBD #{n}",
"disconnecting": "Verbinding verbreken",
"disk-name": "Schijfnaam",
"disk-size": "Schijfgrootte",
"disk-space": "Schijfruimte",
"dns": "DNS",
"do-you-have-needs": "Heb je behoeften en/of verwachtingen? Laat het ons weten",
@@ -375,7 +364,6 @@
"email": "E-mail",
"empty": "Leeg",
"enabled": "Ingeschakeld",
"end-date": "Einddatum",
"ended": "Beëindigd",
"engines-off": "Motoren uit, baan stabiel",
"eol": "EOL",
@@ -427,7 +415,6 @@
"hardware-specifications": "Hardwarespecificaties",
"heartbeat-storage-repository": "Hartslag opslagrepository",
"here": "Hier",
"hide-successful-items": "Verberg succesvolle items in foutrapporten",
"high-availability": "Hoge beschikbaarheid (HA)",
"host": "Host",
"host-currently-shutdown": "Deze host is momenteel uitgeschakeld, dus we kunnen geen gegevens ophalen.",
@@ -481,7 +468,6 @@
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job": "Taak",
"job-name": "Taak naam",
"job:arg:allocated-space-required": "Er is toegewezen opslagruimte nodig",
"job:arg:bond-mode-required": "@:bond-mode-required",
"job:arg:direction-required": "Richting is vereist",
@@ -729,7 +715,6 @@
"modal:vm-reboot-message": "Start de virtuele machine op een correcte manier opnieuw op door deze af te sluiten en opnieuw te starten. Actieve processen worden op de juiste manier afgesloten.",
"modal:vm-shutdown-message": "Hiermee wordt de virtuele machine op een correcte manier afgesloten. Alle actieve processen worden gestopt en gebruikers kunnen worden verbroken. U kunt de VM later opnieuw opstarten via de interface.",
"mode": "Modus",
"modes": "Modi",
"more-actions": "Meer acties",
"more-information": "Meer informatie",
"mtu": "MTU",
@@ -757,7 +742,6 @@
"n-vms": "1 VM | {n} VMs",
"name": "Naam",
"name-required": "Naam is verplicht.",
"nbd-concurrency": "NBD-gelijktijdigheid",
"nested-virtualization": "Geneste virtualisatie",
"netmask": "Netmask",
"network": "Netwerk",
@@ -815,7 +799,6 @@
"no-active-backup-jobs": "Er zijn geen actieve back-uptaken op deze site.",
"no-alarm-detected": "Geen alarmen gedetecteerd",
"no-alarm-triggered": "Geen alarm geactiveerd",
"no-backed-up-vm-detected": "Er zijn geen geback-upte VM's gedetecteerd",
"no-backup-job-available": "Geen back-uptaken beschikbaar",
"no-backup-repository-detected": "Geen back-upopslagplaatsen gedetecteerd",
"no-backup-run-available": "Geen back-up runs beschikbaar",
@@ -835,7 +818,6 @@
"no-result": "Geen resultaten",
"no-role-applied": "Geen rol toegepast",
"no-running-vm-detected": "Er zijn geen actieve VM’s gedetecteerd",
"no-schedule-available": "Geen planningen beschikbaar",
"no-selected-vm-can-be-exported": "Geen van de geselecteerde VM's kan worden geëxporteerd",
"no-selected-vm-can-be-migrated": "Geen van de geselecteerde VM's kan worden gemigreerd",
"no-server-detected": "Geen servers gedetecteerd",
@@ -862,7 +844,6 @@
"off": "Uit",
"offline": "Offline",
"offline-backup": "Offline back-up",
"offline-snapshot": "Offline snapshot",
"ok": "OK",
"on": "Aan",
"on-object": "op {object}",
@@ -893,7 +874,6 @@
"os-name": "OS-naam",
"other": "Andere",
"other-properties": "Overige eigenschappen",
"other-settings": "Andere instellingen",
"ova": "OVA",
"page-not-found": "Deze pagina kan niet worden gevonden…",
"page-please-wait": "Houd je vast, astronaut! De pagina maakt zich klaar om op te stijgen.{newline}We zijn net bezig de stuwraketten uit te lijnen en de systemen te kalibreren. Het duurt niet lang meer, hou ons in de gaten!",
@@ -1012,7 +992,6 @@
"relative-time:past": "{str} geleden",
"relative-time:second": "1 seconde | {n} seconden",
"relative-time:year": "1 jaar | {n} jaren",
"remaining-space": "Resterende ruimte",
"remote-syslog": "Externe syslog",
"report-recipients": "Rapportontvangers",
"report-when": "Wanneer rapporteren",
@@ -1032,7 +1011,6 @@
"rule-type": "Regeltype",
"run": "Uitvoeren",
"running-vm": "Actieve VM | Actieve VM's",
"runs": "Uitvoeringen",
"s3-backup-repository": "S3-back-up opslag repository",
"scan-pifs": "Scan PIF's",
"schedule": "Planning",
@@ -1068,7 +1046,6 @@
"software": "Software",
"software-tooling": "Software & hulpmiddelen",
"source": "Bron",
"source-backup-repository": "Bronback-up repository",
"space": "Ruimte",
"speed": "Snelheid",
"speed-limit": "Snelheidslimiet",
@@ -1096,7 +1073,6 @@
"stacked-cpu-usage": "Gestapeld processor gebruik",
"stacked-ram-usage": "Gestapeld geheugen gebruik",
"start-console": "Start je {type} om toegang te krijgen tot de console en de activiteiten te hervatten!",
"start-date": "Startdatum",
"start-delay": "Startuitstel",
"start-host": "Start de host om de activiteiten te hervatten, of kom later terug zodra deze is ingeschakeld.",
"start-vm": "Start het om toegang te krijgen tot de console en configuratiegegevens.",
@@ -1171,12 +1147,10 @@
"topology": "Topologie",
"total": "Totaal",
"total-assigned": "Totaal toegewezen",
"total-capacity": "Totale capaciteit",
"total-cpus": "Totaal CPU's",
"total-free": "Totaal vrij",
"total-free:": "Totaal vrij:",
"total-memory": "Totaal geheugen",
"total-schedules": "Totale schema's",
"total-space": "Totale ruimte",
"total-space-on-sr": "Totale ruimte op SR",
"total-storage-repository": "Totale opslagrepository",
@@ -1192,7 +1166,6 @@
"traffic-rules:info-message": "De verkeersregels worden gehandhaafd. Het gedrag kan gevaarlijk zijn.",
"traffic-rules:no-traffic-rules-detected": "Er zijn geen verkeersregels gevonden",
"traffic-rules:xapi-plugin-required": "Vereist de XAPI-plug-in modus",
"transfer-size": "Overdrachtsgrootte",
"translation-tool": "Vertaalprogramma",
"treeview": "Boomstructuurweergave",
"trigger": "Trigger",

View File

@@ -110,14 +110,12 @@
"disabled": "Wyłączono",
"disconnected": "Rozłączono",
"disk-name": "Nazwa dysku",
"disk-size": "Rozmiar dysku",
"disk-space": "Miejsce na dysku",
"dns": "DNS",
"documentation": "Dokumentacja",
"done": "Gotowe",
"duration": "Czas trwania",
"enabled": "Włączono",
"end-date": "Data zakończenia",
"ended": "Zakończono",
"error": "Błąd",
"error-occurred": "Wystąpił błąd",
@@ -171,7 +169,6 @@
"message": "Wiadomość",
"missing-patches": "Brakujące łatki",
"mode": "Tryb",
"modes": "Tryby",
"more-actions": "Więcej akcji",
"mtu": "MTU",
"n-missing": "{n} brakujące",
@@ -199,7 +196,6 @@
"os-kernel": "Kernel systemu",
"os-name": "Nazwa systemu",
"other": "Inne",
"other-settings": "Inne ustawienia",
"password": "Hasło",
"password-invalid": "Nieprawidłowe hasło",
"patches": "Łatki",
@@ -223,7 +219,6 @@
"resources": "Zasoby",
"rest-api": "REST API",
"run": "Uruchomione",
"runs": "Przebiegi",
"schedule": "Harmonogram",
"schedules": "Harmonogramy",
"see-details": "Zobacz szczegóły",
@@ -241,7 +236,6 @@
"speed-limit": "Limit prędkości",
"ssh-account": "SSH konto",
"ssh-key": "Klucz SSH",
"start-date": "Data rozpoczęcia",
"started": "Uruchomiono",
"state": "Stan",
"static": "Statyczne",
@@ -278,7 +272,6 @@
"timezone": "Strefa czasowa",
"topology": "Topologia",
"total": "Łącznie",
"total-capacity": "Calkowita objętość",
"total-memory": "Pamięć ogółem",
"unknown": "Nieznane",
"unlocked": "Odblokowane",

View File

@@ -121,7 +121,6 @@
"and": "e",
"any-property": "Qualquer propriedade",
"api-error-details": "Detalhe de erros da API",
"api-info-details": "Detalhes da informação da API",
"api-warning-details": "Detalhes de aviso da API",
"appearance": "Aparência",
"aria:breadcrumb:label": "Migalhas de pão",
@@ -132,7 +131,6 @@
"available-properties-for-advanced-filter:": "Propriedades disponíveis para filtro avançado:",
"back-pool-dashboard": "Voltar ao painel do Pool",
"back-site-dashboard": "Voltar ao painel do seu site",
"backed-up-pools": "Pools com backup",
"backed-up-vms": "VMs com backup",
"backup": "Backup",
"backup-archive-status": "Estado do arquivo de cópia de segurança",
@@ -145,12 +143,6 @@
"backup-repository": "Repositório de backup",
"backup-repository-type": "Repositório de backup (local, NFS, SMB)",
"backup-targets": "Destinos de backup",
"backup:full": "Backup completo",
"backup:full-replication": "Replicação Completa",
"backup:incremental": "Backup incremental",
"backup:incremental-replication": "Replicação incremental",
"backup:mirror:full": "Espelho, backup total",
"backup:mirror:incremental": "Cópia de segurança incremental em espelho",
"backup:pool-metadata": "Metadata do pool",
"backup:rolling-snapshot": "Snapshot contínuo",
"backup:xo-config": "Configuração XO",
@@ -183,12 +175,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Cancelar",
"cbt-destroy-snapshot-data": "Excluir dados do snapshot quando utilizar CBT",
"change-block-tracking": "Rastreamento de blocos alterados (CBT)",
"character-limit": "{count}/{max} carácter | {count}/{max} caracteres",
"check-errors:": "Verificar os erros:",
"check-summing": "TX checksum",
"checkpoint-snapshot": "Ponto de controlo da snapshot",
"click-to-display-alarms:": "Clique para visualizar os alarmes:",
"click-to-return-default-pool": "Clique aqui para voltar para a pool padrão",
"cloud-config": "Configuração da nuvem",
@@ -266,7 +256,6 @@
"disconnected-from-physical-device": "Desligado do dispositivo físico",
"disconnected-pbd-number": "Desligado PBD #{n}",
"disk-name": "Nome do disco",
"disk-size": "Tamanho do disco",
"disk-space": "Tamanho do disco",
"dns": "DNS",
"do-you-have-needs": "Você tem necessidades e/ou expectativas? Informe-nos",
@@ -275,7 +264,6 @@
"done": "Concluído",
"duration": "Duração",
"enabled": "Ativado",
"end-date": "Data final",
"ended": "Terminou",
"engines-off": "Motores desligados, órbita estável",
"eol": "EOL",
@@ -312,7 +300,6 @@
"hardware-specifications": "Especificações de hardware",
"heartbeat-storage-repository": "Repositório de armazenamento Heartbeat",
"here": "Aqui",
"hide-successful-items": "Ocultar itens bem-sucedidos nos relatórios de falhas",
"high-availability": "Alta disponibilidade (HA)",
"host": "Servidor",
"host-currently-shutdown": "Este servidor está atualmente desligado, pelo que não conseguimos recuperar quaisquer dados.",
@@ -352,7 +339,6 @@
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job": "Trabalho",
"job-name": "Nome do trabalho",
"job:arg:host-required": "É necessário um servidor",
"job:arg:missing-payload": "Payload está faltando",
"job:arg:name-required": "O rótulo do nome esta em falta",
@@ -472,7 +458,6 @@
"modal:vm-reboot-message": "Reinicia a máquina virtual de forma controlada, desligando-a e ligando-a novamente. Os processos em execução serão encerrados corretamente.",
"modal:vm-shutdown-message": "Isto irá encerrar a máquina virtual de forma controlada. Todos os processos em execução serão interrompidos e os utilizadores poderão ser desconectados. Pode reiniciar a VM mais tarde a partir da interface.",
"mode": "Modo",
"modes": "Modos",
"more-actions": "Mais ações",
"mtu": "MTU",
"multi-creation": "Criação múltipla",
@@ -497,7 +482,6 @@
"not-yet-available": "As informações ainda não estão disponíveis",
"options": "Opções",
"other-properties": "Outras propriedades",
"other-settings": "Outras configurações",
"page-not-found": "Esta página não foi encontrada…",
"pending": "Pendente",
"progress": "Progresso",
@@ -524,7 +508,6 @@
"settings": "Configurações",
"size": "Tamanho",
"skipped": "",
"start-date": "Data de início",
"success": "Sucesso",
"summary": "Resumo",
"support": "Apoiar",
@@ -539,7 +522,6 @@
"timezone": "Fuso horário",
"topology": "Topologia",
"total-assigned": "Total atribuído",
"total-capacity": "Capacidade total",
"total-used": "Total utilizado",
"total-used:": "Total utilizado:",
"untitled": "Sem título",

View File

@@ -182,7 +182,6 @@
"and": "e",
"any-property": "Qualquer propriedade",
"api-error-details": "Detalhe do erro da API",
"api-info-details": "Detalhes da API",
"api-warning-details": "Detalhes do aviso da API",
"appearance": "Visual",
"aria:breadcrumb:label": "Migalhas de pão",
@@ -193,7 +192,6 @@
"available-properties-for-advanced-filter:": "Propriedades disponíveis para filtro avançado:",
"back-pool-dashboard": "Volta ao painel de controlo do Pool",
"back-site-dashboard": "Voltar ao painel de controlo do seu site",
"backed-up-pools": "Pools com backup",
"backed-up-vms": "VMs com backup",
"backup": "Backup",
"backup-archive-status": "Estado do arquivo de cópia de segurança",
@@ -206,12 +204,6 @@
"backup-repository": "Repositório de backup",
"backup-repository-type": "Repositório de backup (local, NFS, SMB)",
"backup-targets": "Destinos de backup",
"backup:full": "Backup completo",
"backup:full-replication": "Replicação Completa",
"backup:incremental": "Backup incremental",
"backup:incremental-replication": "Replicação incremental",
"backup:mirror:full": "Espelho, backup total",
"backup:mirror:incremental": "Cópia de segurança incremental em espelho",
"backup:pool-metadata": "Metadata do pool",
"backup:rolling-snapshot": "Snapshot contínuo",
"backup:xo-config": "Configuração XO",
@@ -244,12 +236,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Cancelar",
"cbt-destroy-snapshot-data": "Excluir dados do snapshot quando utilizar CBT",
"change-block-tracking": "Rastreamento de blocos alterados (CBT)",
"character-limit": "{count}/{max} carácter | {count}/{max} caracteres",
"check-errors:": "Verificar os erros:",
"check-summing": "TX checksum",
"checkpoint-snapshot": "Ponto de controlo da snapshot",
"click-to-display-alarms:": "Clique para visualizar os alarmes:",
"click-to-return-default-pool": "Clique aqui para voltar para a pool padrão",
"cloud-config": "Configuração da cloud",
@@ -327,7 +317,6 @@
"disconnected-from-physical-device": "Desligado do dispositivo físico",
"disconnected-pbd-number": "Desligado PBD #{n}",
"disk-name": "Nome do disco",
"disk-size": "Tamanho do disco",
"disk-space": "Espaço do disco",
"dns": "DNS",
"do-you-have-needs": "Você tem necessidades e/ou expectativas? Informe-nos",
@@ -336,7 +325,6 @@
"done": "Concluído",
"duration": "Duração",
"enabled": "Ativado",
"end-date": "Data final",
"ended": "Terminou",
"engines-off": "Motores desligados, órbita estável",
"eol": "EOL",
@@ -373,7 +361,6 @@
"hardware-specifications": "Especificações de hardware",
"heartbeat-storage-repository": "Heartbeat - Repositório de armazenamento",
"here": "Aqui",
"hide-successful-items": "Ocultar itens bem-sucedidos nos relatórios de falhas",
"high-availability": "Alta disponibilidade (HA)",
"host": "Servidor",
"host-currently-shutdown": "Este servidor está atualmente desligado, pelo que não conseguimos recuperar quaisquer dados.",
@@ -413,7 +400,6 @@
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job": "Trabalho",
"job-name": "Nome do trabalho",
"job:arg:host-required": "O servidor é obrigatório",
"job:arg:missing-payload": "Falta o Payload",
"job:arg:name-required": "O rótulo do nome esta em falta",
@@ -533,7 +519,6 @@
"modal:vm-reboot-message": "Reinicia a máquina virtual de forma controlada, desligando-a e ligando-a novamente. Os processos em execução serão encerrados corretamente.",
"modal:vm-shutdown-message": "Isto irá encerrar a máquina virtual de forma controlada. Todos os processos em execução serão interrompidos e os utilizadores poderão ser desconectados. Pode reiniciar a VM mais tarde a partir da interface.",
"mode": "Modo",
"modes": "Modos",
"more-actions": "Mais ações",
"mtu": "MTU",
"multi-creation": "Criação múltipla",
@@ -548,7 +533,6 @@
"n-subtasks": "1 subtarefa | {n} subtarefas",
"n-vms": "1 VM | {n} VMs",
"name": "Nome",
"nbd-concurrency": "Concorrência NBD",
"nested-virtualization": "Nested virtualization",
"netmask": "Netmask",
"network": "Rede",
@@ -582,7 +566,6 @@
"no-active-backup-jobs": "Não existem tarefas de cópia de segurança ativas neste local.",
"no-alarm-detected": "Nenhum alarme detectado",
"no-alarm-triggered": "Nenhum alarme foi acionado",
"no-backed-up-vm-detected": "Não foram detetadas máquinas virtuais com cópias de segurança",
"no-backup-job-available": "Não há tarefas de cópia de segurança disponíveis",
"no-backup-repository-detected": "Não foram detetados repositórios de cópias de segurança",
"no-backup-run-available": "Não há execuções de cópia de segurança disponíveis",
@@ -599,7 +582,6 @@
"no-pools-detected": "Não foram detetadas pools",
"no-replicated-vm": "Esta máquina virtual não está a ser replicada. Configure uma tarefa de replicação para ativar essa funcionalidade.",
"no-result": "Sem resultados",
"no-schedule-available": "Não há horários disponíveis",
"no-selected-vm-can-be-exported": "Não é possível exportar nenhuma máquina virtual selecionada",
"no-selected-vm-can-be-migrated": "Não é possível migrar nenhuma máquina virtual selecionada",
"no-server-detected": "Nenhum servidor detectado",
@@ -622,7 +604,6 @@
"off": "Desligado",
"offline": "Offline",
"offline-backup": "Cópia de segurança offline",
"offline-snapshot": "Offline snapshot",
"ok": "OK",
"on": "Ligado",
"on-object": "ligado {object}",
@@ -644,7 +625,6 @@
"os-name": "OS nome",
"other": "Outros",
"other-properties": "Outras propriedades",
"other-settings": "Outras configurações",
"page-not-found": "Esta página não foi encontrada…",
"pagination:all": "@:all",
"partially-connected": "Parcialmente conectado",
@@ -747,7 +727,6 @@
"relative-time:past": "{str} atrás",
"relative-time:second": "1 segundo | {n} segundos",
"relative-time:year": "1 ano | {n} anos",
"remaining-space": "Espaço restante",
"remote-syslog": "Syslog remoto",
"report-recipients": "Destinatários do relatório",
"report-when": "Indique quando",
@@ -764,7 +743,6 @@
"root-by-default": "«root» por predefinição.",
"run": "Executar",
"running-vm": "VM em execução | VMs em execução",
"runs": "Ações",
"s3-backup-repository": "Repositório de cópias de segurança do S3",
"scan-pifs": "Digitalizar PIFs",
"schedule": "Calendário",
@@ -793,7 +771,6 @@
"sockets-with-cores-per-socket": "{nSockets} soquetes × {nCores} núcleos/soquete",
"software": "Software",
"software-tooling": "Software e ferramentas",
"source-backup-repository": "Repositório de cópias de segurança do código-fonte",
"space": "Espaço",
"speed": "Velocidade",
"speed-limit": "Limite de velocidade",
@@ -806,7 +783,6 @@
"stacked-cpu-usage": "Utilização acumulada da CPU",
"stacked-ram-usage": "Utilização da memória RAM acumulada",
"start-console": "Inicie o seu {type} para aceder à consola e retomar as operações!",
"start-date": "Data de início",
"start-delay": "Arranque atrasado",
"start-host": "Inicie o servidor para retomar as operações ou volte mais tarde, assim que estiver ligado.",
"start-vm": "Inicie-o para aceder à sua consola e aos detalhes de configuração.",
@@ -877,17 +853,14 @@
"topology": "Topologia",
"total": "Total",
"total-assigned": "Total atribuído",
"total-capacity": "Capacidade total",
"total-cpus": "Total de CPUs",
"total-free": "Total livre",
"total-free:": "Total livre:",
"total-memory": "Memória total",
"total-schedules": "Total de horários",
"total-space": "Espaço total",
"total-storage-repository": "Repositório de armazenamento total",
"total-used": "Total utilizado",
"total-used:": "Total utilizado:",
"transfer-size": "Tamanho da transferência",
"translation-tool": "Ferramenta de tradução",
"unable-to-connect-to": "Não é possível estabelecer ligação com {ip}",
"unable-to-connect-to-the-pool": "Não é possível estabelecer ligação a pool",

View File

@@ -164,7 +164,6 @@
"and": "И",
"any-property": "Любое свойство",
"api-error-details": "Детали ошибки API",
"api-info-details": "Детали информации API",
"api-warning-details": "Подробности предупреждений API",
"appearance": "Внешний вид",
"aria:breadcrumb:label": "Хлебные крошки",
@@ -175,7 +174,6 @@
"available-properties-for-advanced-filter:": "Доступные свойства расширенного фильтра:",
"back-pool-dashboard": "Возврат к панели управления пулом",
"back-site-dashboard": "Вернитесь на панель управления вашего сайта",
"backed-up-pools": "Резервные копии пулов",
"backed-up-vms": "ВМ с резервными копиями",
"backup": "Резервное копирование",
"backup-archive-status": "Статус архива резервной копии",
@@ -188,13 +186,7 @@
"backup-repository": "Хранилище резервных копий",
"backup-repository-type": "Хранилище резервных копий (local, NFS, SMB)",
"backup-targets": "Назначение для резервной копии",
"backup:full": "Полная резервная копия",
"backup:full-replication": "Полная репликация",
"backup:incremental": "Инкрементальная резервная копия",
"backup:incremental-replication": "инкрементальная репликация",
"backup:last-replication": "Последняя репликация",
"backup:mirror:full": "Полная зеркальная резервная копия",
"backup:mirror:incremental": "Зеркальная инкрементная резервная копия",
"backup:pool-metadata": "Метаданные пула",
"backup:rolling-snapshot": "Скользящий снимок",
"backup:xo-config": "Конфигурация XO",
@@ -227,12 +219,10 @@
"bytes:ki": "КиБ",
"bytes:mi": "МиБ",
"cancel": "Отмена",
"cbt-destroy-snapshot-data": "Удаление данных моментального снимка при использовании CBT",
"change-block-tracking": "Отслеживание изменений блоков (CBT)",
"character-limit": "{count}/{max} символ | {count}/{max} символов",
"check-errors:": "Проверьте ошибки:",
"check-summing": "Контрольная сумма TX",
"checkpoint-snapshot": "Моментальный снимок контрольной точки",
"click-to-display-alarms:": "Нажмите, чтобы отобразить тревоги:",
"click-to-return-default-pool": "Нажмите здесь для возвращения в пул по-умолчанию",
"cloud-config": "Облачная конфигурация",
@@ -311,7 +301,6 @@
"disconnected-from-physical-device": "Отключено от физического устройства",
"disconnected-pbd-number": "PBD отключен #{n}",
"disk-name": "Имя диска",
"disk-size": "Размер диска",
"disk-space": "Свободное место на диске",
"dns": "DNS",
"do-you-have-needs": "Есть замечания/предложения? Дайте нам знать",
@@ -320,7 +309,6 @@
"done": "Завершено",
"duration": "Продолжительность",
"enabled": "Включено",
"end-date": "Дата окончания",
"ended": "Закончено",
"engines-off": "Двигатели выключены, орбита стабильна",
"eol": "EOL",
@@ -357,7 +345,6 @@
"hardware-specifications": "Характеристики аппаратного обеспечения",
"heartbeat-storage-repository": "Репозиторий heartbeat-хранилищ",
"here": "Здесь",
"hide-successful-items": "Скрывать успешно выполненные элементы в отчетах о сбоях",
"high-availability": "Высокая доступность (HA)",
"host": "Узел",
"host-currently-shutdown": "Этот хост в данный момент отключен, поэтому мы не можем получить никаких данных.",
@@ -398,7 +385,6 @@
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job": "Задание",
"job-name": "Название работы",
"job:arg:host-required": "Требуется хост",
"job:arg:missing-payload": "Отсутствует пейлоуд",
"job:arg:name-required": "Требуется название",
@@ -492,7 +478,6 @@
"missing-patches": "Отсутствующие патчи",
"missing-translations?": "Отсутствует или неверный перевод?",
"mode": "Режим",
"modes": "Режимы",
"more-actions": "Больше действий",
"mtu": "MTU",
"n-gb-left": "{n} Гб осталось",

View File

@@ -184,7 +184,6 @@
"and": "A",
"any-property": "Akákoľvek vlastnosť",
"api-error-details": "Podrobnosti o chybe rozhrania API",
"api-info-details": "Podrobnosti o informácii z API",
"api-warning-details": "Podrobnosti o varovaní z API",
"appearance": "Vzhľad",
"aria:breadcrumb:label": "Omrvinková navigácia",
@@ -198,7 +197,6 @@
"available-properties-for-advanced-filter:": "Vlastnosti pre pokročilý filter, ktoré sú k dispozícii:",
"back-pool-dashboard": "Prejsť späť na prehľad fondu",
"back-site-dashboard": "Prejsť späť na prehľad lokality",
"backed-up-pools": "Zálohované fondy",
"backed-up-vms": "Zálohované VM",
"backup": "Záloha",
"backup-archive-status": "Stav archívu zálohy",
@@ -211,13 +209,7 @@
"backup-repository": "Záložné úložisko",
"backup-repository-type": "Repozitár pre zálohy (lokálne, NFS, SMB)",
"backup-targets": "Ciele zálohovania",
"backup:full": "Úplná záloha",
"backup:full-replication": "Úplná replikácia",
"backup:incremental": "Prírastková záloha",
"backup:incremental-replication": "Inkrementálna replikácia",
"backup:last-replication": "Posledná replikácia",
"backup:mirror:full": "Zrkadlová úplná záloha",
"backup:mirror:incremental": "Zrkadlová prírastková záloha",
"backup:pool-metadata": "Metadáta fondu",
"backup:rolling-snapshot": "Priebežne zachytávaný stav",
"backup:xo-config": "Konfigurácia XO",
@@ -254,12 +246,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Zrušiť",
"cbt-destroy-snapshot-data": "Pri používaní priebežného sledovania zmien blokov odstrániť dáta zachyteného stavu",
"change-block-tracking": "Sledovanie zmien blokov (CBT)",
"character-limit": "{count}/{max} znak | {count}/{max} znakov",
"check-errors:": "Pozrite si chyby:",
"check-summing": "Kontrolné súčty odosielania",
"checkpoint-snapshot": "Zachytený stav – kontrolný bod",
"click-to-display-alarms:": "Kliknutím zobrazíte výstrahy:",
"click-to-return-default-pool": "Kliknutím sem sa vrátite na východiskový fond",
"cloud-config": "Cloud config",
@@ -359,7 +349,6 @@
"disconnected-pbd-number": "Odpojené PBD č. {n}",
"disconnecting": "Odpájanie",
"disk-name": "Názov disku",
"disk-size": "Veľkosť disku",
"disk-space": "Miesto na disku",
"dns": "DNS",
"do-you-have-needs": "Máte potreby a/alebo očakávania? Dajte nám vedieť",
@@ -375,7 +364,6 @@
"email": "E-mail",
"empty": "Prázdne",
"enabled": "Povolené",
"end-date": "Dátum ukončenia",
"ended": "Ukončené",
"engines-off": "Motory vypnuté, orbita stabilná",
"eol": "EOL",
@@ -427,7 +415,6 @@
"hardware-specifications": "Hardvérové špecifikácie",
"heartbeat-storage-repository": "Repozitár úložiska kontroly stavu",
"here": "Tu",
"hide-successful-items": "V hláseniach o nezdaroch skryť tie položky, pri ktorých hlásený úspech",
"high-availability": "Vysoká dostupnosť (HA)",
"host": "Hostiteľ",
"host-currently-shutdown": "Tento hostiteľ je momentálne vypnutý, takže nemôžeme načítať žiadne údaje.",
@@ -481,7 +468,6 @@
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job": "Úloha",
"job-name": "Názov úlohy",
"job:arg:allocated-space-required": "Pridelené miesto treba zadať",
"job:arg:bond-mode-required": "@:bond-mode-required",
"job:arg:direction-required": "Smer treba zadať",
@@ -729,7 +715,6 @@
"modal:vm-reboot-message": "Vykoná korektný reštart virtuálneho stroja jeho vypnutím a opätovným spustením. Spustené procesy budú korektne ukončené.",
"modal:vm-shutdown-message": "Vykoná korektné vypnutie virtuálneho stroja. Všetky spustené procesy budú ukončené a používatelia odpojení. Virt. stroj je neskôr možné znova spustiť z webového rozhrania.",
"mode": "Režim",
"modes": "Režimy",
"more-actions": "Viac akcií",
"more-information": "Ďalšie informácie",
"mtu": "MTU",
@@ -757,7 +742,6 @@
"n-vms": "1 virt. stroj | {n} virt. strojov",
"name": "Názov",
"name-required": "Je potrebný názov.",
"nbd-concurrency": "Súbežnosť sieť. blokového zariadenia (NBD)",
"nested-virtualization": "Vnorená virtualizácia",
"netmask": "Maska podsiete",
"network": "Sieť",
@@ -815,7 +799,6 @@
"no-active-backup-jobs": "Na tejto lokalite nie sú žiadne aktívne úlohy zálohovania.",
"no-alarm-detected": "Neboli zistené žiadne alarmy",
"no-alarm-triggered": "Nie je spustený žiadny alarm",
"no-backed-up-vm-detected": "Nezistené žiadne zálohované virt. stroje",
"no-backup-job-available": "Nie sú k dispozícii žiadne úlohy zálohovania",
"no-backup-repository-detected": "Nezistené žiadne repozitáre záloh",
"no-backup-run-available": "Nie sú k dispozícii žiadne behy zálohy",
@@ -835,7 +818,6 @@
"no-result": "Žiadne výsledky",
"no-role-applied": "Neuplatnená žiadna rola",
"no-running-vm-detected": "Nezistené žiadne spustené virt. stroje",
"no-schedule-available": "Nie sú k dispozícii žiadne naplánovania",
"no-selected-vm-can-be-exported": "Žiadny z označených virt. strojov nie je možné exportovať",
"no-selected-vm-can-be-migrated": "Žiadny z označených virt. strojov nie je možné presťahovať",
"no-server-detected": "Neboli zistené žiadne servery",
@@ -862,7 +844,6 @@
"off": "Vypnuté",
"offline": "Offline",
"offline-backup": "Zálohovanie offline",
"offline-snapshot": "Offline zachycený stav",
"ok": "OK",
"on": "Zapnuté",
"on-object": "na {object}",
@@ -893,7 +874,6 @@
"os-name": "Názov OS",
"other": "Iné",
"other-properties": "Ostatné vlastnosti",
"other-settings": "Ďalšie nastavenia",
"ova": "OVA",
"page-not-found": "Táto stránka sa nedá nájsť…",
"page-please-wait": "Drž sa pevne, astronaut! Stránka sa pripravuje na start.{newline}Práve nastavujeme trysky a kalibrujeme systémy. Už to dlho nepotrvá, zostaňte naladení!",
@@ -1012,7 +992,6 @@
"relative-time:past": "Pred {str}",
"relative-time:second": "1 sekunda | {n} sekúnd",
"relative-time:year": "1 rok | {n} rokov",
"remaining-space": "Zostávajúci priestor",
"remote-syslog": "Vzdialený syslog",
"report-recipients": "Príjemcovia hlásení",
"report-when": "Nahlásiť kedy",
@@ -1032,7 +1011,6 @@
"rule-type": "Typ pravidla",
"run": "Spustiť",
"running-vm": "Spustený virt. stroj | Spustené virt. stroje",
"runs": "Behy",
"s3-backup-repository": "S3 repozitár záloh",
"scan-pifs": "Skenovať PIFs",
"schedule": "Plán",
@@ -1068,7 +1046,6 @@
"software": "Softvér",
"software-tooling": "Softvér a nástroje",
"source": "Zdroj",
"source-backup-repository": "Zdrojový repozitár záloh",
"space": "Priestor",
"speed": "Rýchlosť",
"speed-limit": "Rýchlostný limit",
@@ -1096,7 +1073,6 @@
"stacked-cpu-usage": "Celkom využitie procesora",
"stacked-ram-usage": "Celkom využitie operačnej pamäte",
"start-console": "Aby bolo možné pristupovať ku konzole a nadviazať vo fungovaní, {type} zapnite!",
"start-date": "Dátum začiatku",
"start-delay": "Oneskorenie štartu",
"start-host": "Aby začal znovu fungovať, hostiteľa zapnite (prípadne sem zavítajte neskôr, až bude zapnutý).",
"start-vm": "Spustite ho, aby ste získali prístup ku konzole a podrobnostiam konfigurácie.",
@@ -1171,12 +1147,10 @@
"topology": "Topológia",
"total": "Celkom",
"total-assigned": "Celkom pridelených",
"total-capacity": "Celková kapacita",
"total-cpus": "Celkový počet CPU",
"total-free": "Celkom voľno",
"total-free:": "Celkom voľno:",
"total-memory": "Celková pamäť",
"total-schedules": "Celkom plánov",
"total-space": "Celkový priestor",
"total-space-on-sr": "Celkový priestor na repozitári úložiska",
"total-storage-repository": "Celkové úložisko repozitára",
@@ -1192,7 +1166,6 @@
"traffic-rules:info-message": "Implementácia poradia pravidiel pre prevádzku ešte prebieha. Chovanie môže byť nebezpečné.",
"traffic-rules:no-traffic-rules-detected": "Nezjištěná žiadna pravidla pre prevádzku",
"traffic-rules:xapi-plugin-required": "Vyžaduje režim XAPI zásuvného modulu",
"transfer-size": "Objem prenosu",
"translation-tool": "Prekladový nástroj",
"treeview": "Stromové zobrazenie",
"trigger": "Spúšťač",

View File

@@ -180,7 +180,6 @@
"and": "Och",
"any-property": "Oavsett egenskap",
"api-error-details": "API fel-detaljer",
"api-info-details": "API Info-detaljer",
"api-warning-details": "API Varnings-detaljer",
"appearance": "Utseende",
"aria:breadcrumb:label": "Spår",
@@ -194,7 +193,6 @@
"available-properties-for-advanced-filter:": "Tillgängliga egenskaper för avancerade filter:",
"back-pool-dashboard": "Gå tillbaka till din Pool-översikt",
"back-site-dashboard": "Gå tillbaka till din översikt",
"backed-up-pools": "Säkerhetskopierade Pooler",
"backed-up-vms": "Säkerhetskopierade VM:ar",
"backup": "Säkerhetskopiera",
"backup-archive-status": "Status för säkerhetskopieringsarkiv",
@@ -207,13 +205,7 @@
"backup-repository": "Säkerhetskopieringsförvaring",
"backup-repository-type": "Säkerhetskopieringsförvaring (lokalt, NFS, SMB)",
"backup-targets": "Säkerhetskopieringsmål",
"backup:full": "Fullständig säkerhetskopiering",
"backup:full-replication": "Fullständig replikering",
"backup:incremental": "Inkrementell säkerhetskopiering",
"backup:incremental-replication": "Inkrementell replikering",
"backup:last-replication": "Senaste replikering",
"backup:mirror:full": "Spegla fullständig backup",
"backup:mirror:incremental": "Spegla inkrementell backup",
"backup:pool-metadata": "Pool-metadata",
"backup:rolling-snapshot": "Rullande ögonblicksbild",
"backup:xo-config": "XO-konfig",
@@ -250,12 +242,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "Avbryt",
"cbt-destroy-snapshot-data": "Rensa ögonblicksdata när CBT används",
"change-block-tracking": "Spårning av förändrade block (CBT)",
"character-limit": "{count}/{max} tecken | {count}/{max} tecken",
"check-errors:": "Kontrollera felen:",
"check-summing": "TX checksumma",
"checkpoint-snapshot": "Kontrollpunkt för ögonblicksbild",
"click-to-display-alarms:": "Klicka för att visa larm:",
"click-to-return-default-pool": "Klicka här för att återgå till standardpoolen",
"cloud-config": "Molnkonfig",
@@ -353,7 +343,6 @@
"disconnected-from-physical-device": "Koppla från fysisk enhet",
"disconnected-pbd-number": "Frånkopplad PBD #{n}",
"disk-name": "Disk-namn",
"disk-size": "Diskstorlek",
"disk-space": "Diskutrymme",
"dns": "DNS",
"do-you-have-needs": "Har du behov och/eller förväntningar? Berätta för oss",
@@ -369,7 +358,6 @@
"email": "Email",
"empty": "Tomt",
"enabled": "Aktiverad",
"end-date": "Slutdatum",
"ended": "Avslutad",
"engines-off": "Motor avslagen, satellitbana stabil",
"eol": "EOL",
@@ -421,7 +409,6 @@
"hardware-specifications": "Hårdvaruspecifikationer",
"heartbeat-storage-repository": "Lagringsplats för hjärtslag",
"here": "Här",
"hide-successful-items": "Göm lyckade objekt i misslyckanderapporter",
"high-availability": "Hög tillgänglighet (HA)",
"host": "Host",
"host-currently-shutdown": "Denna host är i nuläget nedstängd, data kan inte hämtas.",
@@ -475,7 +462,6 @@
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job": "Jobb",
"job-name": "Jobbnamn",
"job:arg:allocated-space-required": "Allokerat utrymme krävs",
"job:arg:bond-mode-required": "@:bond-mode-required",
"job:arg:direction-required": "Riktning krävs",
@@ -717,7 +703,6 @@
"modal:vm-reboot-message": "Startar om den virtuella maskinen korrekt genom att stänga ned den och starta upp den igen. Processer stängs ner korrekt.",
"modal:vm-shutdown-message": "Stänger ned den virtuella maskinen korrekt. Alla körande processer stoppas och användare kan kopplas ifrån. Du kan starta om VMen senare från gränssnittet.",
"mode": "Läge",
"modes": "Lägen",
"more-actions": "Fler åtgärder",
"mtu": "MTU",
"mtu-default-value-message": "1500 som standard",
@@ -744,7 +729,6 @@
"n-vms": "1 VM | {n} VM:ar",
"name": "Namn",
"name-required": "Namn krävs.",
"nbd-concurrency": "NBD-parallellitet",
"nested-virtualization": "Nästlad virtualisering",
"netmask": "Nätmaskadress",
"network": "Nätverk",
@@ -797,7 +781,6 @@
"no-active-backup-jobs": "Det finns inga aktiva säkerhetskoperingsjobb på den här nätverksplatsen.",
"no-alarm-detected": "Inga larm upptäckta",
"no-alarm-triggered": "Inga larm",
"no-backed-up-vm-detected": "Inga säkerhetskopierade VMar upptäckta",
"no-backup-job-available": "Inga säkerhetskopieringsjobb tillgängliga",
"no-backup-repository-detected": "Ingen säkerhetskopieringsförvaring upptäckt",
"no-backup-run-available": "Inga säkerhetskoperingskörningar tillgängliga",
@@ -814,7 +797,6 @@
"no-pools-detected": "Ingen pool upptäckt",
"no-replicated-vm": "VM:en replikeras inte. Konfigurera ett replikeringsjobb för att aktivera replikering.",
"no-result": "Inget resultat | Inga resultat",
"no-schedule-available": "Inget schema tillgängligt",
"no-selected-vm-can-be-exported": "Inga markerade VMar kan exporteras",
"no-selected-vm-can-be-migrated": "Inga markerade VMar kan migreras",
"no-server-detected": "Inga servrar upptäckta",
@@ -839,7 +821,6 @@
"off": "Av",
"offline": "Offline",
"offline-backup": "Offlinesäkerhetskopia",
"offline-snapshot": "Offlineögonblicksbild",
"ok": "OK",
"on": "På",
"on-object": "på {object}",
@@ -861,7 +842,6 @@
"os-name": "OS-namn",
"other": "Annat",
"other-properties": "Andra fastigheter",
"other-settings": "Andra inställningar",
"page-not-found": "Den här sidan kan inte hittas…",
"page-please-wait": "Håll i hårt, astronaut! Den här sidan förbereder för take off.{newline}Vi rättar raketerna och kalibrerar systemen. Det kommer inte ta lång tid, häng kvar!",
"pagination:all": "@:all",
@@ -970,7 +950,6 @@
"relative-time:past": "{str} sedan",
"relative-time:second": "1 sekund | {n} sekunder",
"relative-time:year": "1 år | {n} år",
"remaining-space": "Kvarvarande utrymme",
"remote-syslog": "Fjärr-syslog",
"report-recipients": "Rapportera mottagare",
"report-when": "Rapportera när",
@@ -987,7 +966,6 @@
"root-by-default": "\"root\" som standard.",
"run": "Körning",
"running-vm": "Startad VM | Startade VMar",
"runs": "Körningar",
"s3-backup-repository": "S3 säkerhetskopieringsförvar",
"scan-pifs": "Skanna PIF",
"schedule": "Schema",
@@ -1018,7 +996,6 @@
"sockets-with-cores-per-socket": "{nSockets} socklar × {nCores} kärnor/sockel",
"software": "Mjukvara",
"software-tooling": "Mjukvara & verktyg",
"source-backup-repository": "Källa för säkerhetskopieringsförvaring",
"space": "Utrymme",
"speed": "Hastighet",
"speed-limit": "Hastighetsbegränsning",
@@ -1031,7 +1008,6 @@
"stacked-cpu-usage": "Staplad CPU-användning",
"stacked-ram-usage": "Staplad RAM-användning",
"start-console": "Starta din {type} av access till konsolen och återuppta operationer!",
"start-date": "Startdatum",
"start-delay": "Startfördröjning",
"start-host": "Starta hosten för att återuppta operationer, och återkom senare när den är påslagen.",
"start-vm": "Starta det för att komma åt konsollen, och konfigurationsdetaljer.",
@@ -1105,12 +1081,10 @@
"topology": "Topologi",
"total": "Totalt",
"total-assigned": "Totalt tilldelat",
"total-capacity": "Total kapacitet",
"total-cpus": "Totalt antal CPUer",
"total-free": "Totalt ledigt",
"total-free:": "Totalt ledigt:",
"total-memory": "Totalt minne",
"total-schedules": "Totala scheman",
"total-space": "Totalt utrymme",
"total-storage-repository": "Totalt lagringsutrymme",
"total-used": "Totalt använt",
@@ -1119,7 +1093,6 @@
"traffic-rules": "Trafikregler",
"traffic-rules:info-message": "Trafikreglernas ordning införs. Beteendet kan vara farligt.",
"traffic-rules:no-traffic-rules-detected": "Inga trafikregler upptäckta",
"transfer-size": "Överföringsstorlek",
"translation-tool": "Översättningsverktyg",
"trigger": "Utlösare",
"type": "Typ",

View File

@@ -184,7 +184,6 @@
"and": "Ve",
"any-property": "Herhangi bir özellik",
"api-error-details": "API hata ayrıntıları",
"api-info-details": "API bilgi ayrıntıları",
"api-warning-details": "API uyarı ayrıntıları",
"appearance": "Görünüm",
"aria:breadcrumb:label": "Gezinti yolu",
@@ -198,7 +197,6 @@
"available-properties-for-advanced-filter:": "Gelişmiş filtre için kullanılabilir özellikler:",
"back-pool-dashboard": "Havuz gösterge panelinize geri dönün",
"back-site-dashboard": "Site gösterge panelinize geri dönün",
"backed-up-pools": "Yedeklenen havuzlar",
"backed-up-vms": "Yedeklenmiş VM'ler",
"backup": "Yedekleme",
"backup-archive-status": "Yedek arşivi durumu",
@@ -211,13 +209,7 @@
"backup-repository": "Yedekleme deposu",
"backup-repository-type": "Yedekleme deposu (yerel, NFS, SMB)",
"backup-targets": "Yedekleme hedefleri",
"backup:full": "Tam yedekleme",
"backup:full-replication": "Tam replikasyon",
"backup:incremental": "Artımlı yedekleme",
"backup:incremental-replication": "Artımlı replikasyon",
"backup:last-replication": "Son replikasyon",
"backup:mirror:full": "Ayna tam yedekleme",
"backup:mirror:incremental": "Ayna artımlı yedekleme",
"backup:pool-metadata": "Havuz metadata",
"backup:rolling-snapshot": "Yuvarlanan anlık görüntü",
"backup:xo-config": "XO yapılandırması",
@@ -254,12 +246,10 @@
"bytes:ki": "KiB",
"bytes:mi": "MiB",
"cancel": "İptal",
"cbt-destroy-snapshot-data": "CBT kullanırken anlık görüntü verilerini temizle",
"change-block-tracking": "Blok değişiklik takibi (CBT)",
"character-limit": "{count}/{max} karakter | {count}/{max} karakter",
"check-errors:": "Hataları kontrol edin:",
"check-summing": "TX sağlama toplamı",
"checkpoint-snapshot": "Checkpoint anlık görüntüsü",
"click-to-display-alarms:": "Alarmları görüntülemek için tıklayın:",
"click-to-return-default-pool": "Varsayılan havuza dönmek için buraya tıklayın",
"cloud-config": "Bulut yapılandırması",
@@ -359,7 +349,6 @@
"disconnected-pbd-number": "Bağlantısı kesilmiş PBD #{n}",
"disconnecting": "Bağlantı kesiliyor",
"disk-name": "Disk adı",
"disk-size": "Disk boyutu",
"disk-space": "Disk alanı",
"dns": "DNS",
"do-you-have-needs": "İhtiyaçlarınız ve/veya beklentileriniz mi var? Bize bildirin",
@@ -375,7 +364,6 @@
"email": "E-posta",
"empty": "Boş",
"enabled": "Etkin",
"end-date": "Bitiş tarihi",
"ended": "Sona erdi",
"engines-off": "Motorlar kapalı, yörünge kararlı",
"eol": "EOL",
@@ -427,7 +415,6 @@
"hardware-specifications": "Donanım özellikleri",
"heartbeat-storage-repository": "Heartbeat depolama deposu",
"here": "Burada",
"hide-successful-items": "Hata raporlarında başarılı öğeleri gizle",
"high-availability": "Yüksek kullanılabilirlik (HA)",
"host": "Host",
"host-currently-shutdown": "Bu host şu anda kapalı, bu nedenle veri alınamıyor.",
@@ -481,7 +468,6 @@
"iscsi-iqn": "iSCSI IQN",
"iso-dvd": "ISO/DVD",
"job": "İş",
"job-name": "İş adı",
"job:arg:allocated-space-required": "Ayrılmış alan gerekli",
"job:arg:bond-mode-required": "@:bond-mode-required",
"job:arg:direction-required": "Yön gerekli",
@@ -729,7 +715,6 @@
"modal:vm-reboot-message": "VM'yi düzgün şekilde kapatıp yeniden başlatır. Çalışan süreçler düzgün kapatılır.",
"modal:vm-shutdown-message": "Bu işlem VM'yi düzgün şekilde kapatır. Tüm çalışan süreçler durur ve kullanıcıların bağlantısı kesilebilir. VM'yi daha sonra arayüzden yeniden başlatabilirsiniz.",
"mode": "Mod",
"modes": "Modlar",
"more-actions": "Diğer işlemler",
"mtu": "MTU",
"mtu-default-value-message": "Varsayılan olarak 1500",
@@ -756,7 +741,6 @@
"n-vms": "1 VM | {n} VM",
"name": "Ad",
"name-required": "Ad gerekli.",
"nbd-concurrency": "NBD eşzamanlılığı",
"nested-virtualization": "İç içe sanallaştırma",
"netmask": "Ağ maskesi",
"network": "Ağ",
@@ -814,7 +798,6 @@
"no-active-backup-jobs": "Bu sitede etkin yedekleme işi yok.",
"no-alarm-detected": "Alarm tespit edilmedi",
"no-alarm-triggered": "Tetiklenen alarm yok",
"no-backed-up-vm-detected": "Yedeklenmiş VM tespit edilmedi",
"no-backup-job-available": "Kullanılabilir yedekleme işi yok",
"no-backup-repository-detected": "Yedekleme deposu tespit edilmedi",
"no-backup-run-available": "Kullanılabilir yedekleme çalışması yok",
@@ -834,7 +817,6 @@
"no-result": "Sonuç yok",
"no-role-applied": "Uygulanan rol yok",
"no-running-vm-detected": "Çalışan VM tespit edilmedi",
"no-schedule-available": "Kullanılabilir zamanlama yok",
"no-selected-vm-can-be-exported": "Seçili VM'lerden hiçbiri dışa aktarılamaz",
"no-selected-vm-can-be-migrated": "Seçili VM'lerden hiçbiri taşınamaz",
"no-server-detected": "Sunucu tespit edilmedi",
@@ -861,7 +843,6 @@
"off": "Kapalı",
"offline": "Çevrimdışı",
"offline-backup": "Çevrimdışı yedekleme",
"offline-snapshot": "Çevrimdışı anlık görüntü",
"ok": "Tamam",
"on": "Açık",
"on-object": "{object} üzerinde",
@@ -892,7 +873,6 @@
"os-name": "İşletim sistemi adı",
"other": "Diğer",
"other-properties": "Diğer özellikler",
"other-settings": "Diğer ayarlar",
"ova": "OVA",
"page-not-found": "Bu sayfa bulunamadı…",
"page-please-wait": "Sıkı tutunun, astronot! Sayfa kalkışa hazırlanıyor.{newline}İticileri hizalıyor ve sistemleri kalibre ediyoruz. Çok sürmeyecek, takipte kalın!",
@@ -1011,7 +991,6 @@
"relative-time:past": "{str} önce",
"relative-time:second": "1 saniye | {n} saniye",
"relative-time:year": "1 yıl | {n} yıl",
"remaining-space": "Kalan alan",
"remote-syslog": "Uzak syslog",
"report-recipients": "Rapor alıcıları",
"report-when": "Raporlama zamanı",
@@ -1031,7 +1010,6 @@
"rule-type": "Kural türü",
"run": "Çalıştır",
"running-vm": "Çalışan VM | Çalışan VM'ler",
"runs": "Çalıştırmalar",
"s3-backup-repository": "S3 yedek deposu",
"scan-pifs": "PIF'leri tara",
"schedule": "Zamanlama",
@@ -1067,7 +1045,6 @@
"software": "Yazılım",
"software-tooling": "Yazılım ve araçlar",
"source": "Kaynak",
"source-backup-repository": "Kaynak yedekleme deposu",
"space": "Alan",
"speed": "Hız",
"speed-limit": "Hız sınırı",
@@ -1095,7 +1072,6 @@
"stacked-cpu-usage": "Yığılmış CPU kullanımı",
"stacked-ram-usage": "Yığılmış RAM kullanımı",
"start-console": "Konsola erişmek ve işlemlere devam etmek için {type} başlatın!",
"start-date": "Başlangıç tarihi",
"start-delay": "Başlatma gecikmesi",
"start-host": "İşlemlere devam etmek için hostu başlatın veya açıldıktan sonra daha sonra tekrar kontrol edin.",
"start-vm": "Konsoluna ve yapılandırma ayrıntılarına erişmek için başlatın.",
@@ -1170,12 +1146,10 @@
"topology": "Topoloji",
"total": "Toplam",
"total-assigned": "Toplam atanan",
"total-capacity": "Toplam kapasite",
"total-cpus": "Toplam CPU",
"total-free": "Toplam boş",
"total-free:": "Toplam boş:",
"total-memory": "Toplam bellek",
"total-schedules": "Toplam zamanlama",
"total-space": "Toplam alan",
"total-space-on-sr": "SR üzerindeki toplam alan",
"total-storage-repository": "Toplam depolama deposu",
@@ -1191,7 +1165,6 @@
"traffic-rules:info-message": "Trafik kurallarının sırası henüz uygulanıyor. Davranış riskli olabilir.",
"traffic-rules:no-traffic-rules-detected": "Trafik kuralı bulunamadı",
"traffic-rules:xapi-plugin-required": "XAPI eklenti modu gerekir",
"transfer-size": "Aktarım boyutu",
"translation-tool": "Çeviri aracı",
"treeview": "Ağaç görünümü",
"trigger": "Tetikleyici",

View File

@@ -88,8 +88,6 @@
"backup-repository": "Сховище резервних копій",
"backup-repository-type": "Сховище резервних копій (local, NFS, SMB)",
"backup-targets": "Призначення для резервної копії",
"backup:full": "Повна резервна копія",
"backup:incremental": "Інкрементальна резервна копія",
"backup:pool-metadata": "Метадані пулу",
"backup:rolling-snapshot": "Ковзний знімок",
"backup:xo-config": "Конфігурація XO",

View File

@@ -170,7 +170,6 @@
"and": "并且",
"any-property": "任意属性",
"api-error-details": "API错误详情",
"api-info-details": "API信息详情",
"api-warning-details": "API警告详情",
"appearance": "外观设置",
"aria:breadcrumb:label": "面包屑导航",
@@ -184,7 +183,6 @@
"available-properties-for-advanced-filter:": "高级筛选可用属性:",
"back-pool-dashboard": "返回资源池面板",
"back-site-dashboard": "返回站点面板",
"backed-up-pools": "已备份资源池",
"backed-up-vms": "已备份虚拟机",
"backup": "备份",
"backup-archive-status": "备份归档状态",
@@ -197,13 +195,7 @@
"backup-repository": "备份仓库",
"backup-repository-type": "备份仓库类型(本地、NFS、SMB)",
"backup-targets": "备份目标",
"backup:full": "全量备份",
"backup:full-replication": "全量复制",
"backup:incremental": "增量备份",
"backup:incremental-replication": "增量复制",
"backup:last-replication": "上次复制时间",
"backup:mirror:full": "镜像全量备份",
"backup:mirror:incremental": "镜像增量备份",
"backup:pool-metadata": "资源池元数据备份",
"backup:rolling-snapshot": "滚动快照备份",
"backup:xo-config": "XO配置备份",
@@ -239,12 +231,10 @@
"bytes:ki": "千字节",
"bytes:mi": "兆字节",
"cancel": "取消",
"cbt-destroy-snapshot-data": "使用变更块追踪时清理快照数据",
"change-block-tracking": "变更块追踪(CBT)",
"character-limit": "{count}/{max}个字符 | {count}/{max}个字符",
"check-errors:": "查看错误信息:",
"check-summing": "发送端校验和",
"checkpoint-snapshot": "检查点快照",
"click-to-display-alarms:": "点击查看告警:",
"click-to-return-default-pool": "点击返回默认资源池",
"cloud-config": "云端配置",
@@ -342,7 +332,6 @@
"disconnected-from-physical-device": "已断开物理设备连接",
"disconnected-pbd-number": "已断开物理块设备 #{n}",
"disk-name": "磁盘名称",
"disk-size": "磁盘容量",
"disk-space": "磁盘空间",
"dns": "域名服务器",
"do-you-have-needs": "有使用建议或需求欢迎反馈",
@@ -358,7 +347,6 @@
"email": "邮箱",
"empty": "空",
"enabled": "已启用",
"end-date": "结束日期",
"ended": "已结束",
"engines-off": "系统待机稳定",
"eol": "停服终止",
@@ -407,7 +395,6 @@
"hardware-specifications": "硬件规格",
"heartbeat-storage-repository": "心跳检测存储仓库",
"here": "此处",
"hide-successful-items": "在异常报表中隐藏正常项目",
"high-availability": "高可用(HA)",
"host": "物理主机",
"host-currently-shutdown": "该主机已关机,无法获取数据。",
@@ -456,7 +443,6 @@
"iscsi-iqn": "iSCSI设备标识",
"iso-dvd": "ISO镜像/光驱",
"job": "后台任务",
"job-name": "任务名称",
"job:arg:allocated-space-required": "必须填写分配容量",
"job:arg:bond-mode-required": "请选择聚合模式",
"job:arg:direction-required": "流量方向为必填项",
@@ -659,7 +645,6 @@
"modal:vm-reboot-message": "优雅重启虚拟机,正常保存并关闭业务进程。",
"modal:vm-shutdown-message": "优雅关机,停止所有进程,可随时重新启动。",
"mode": "运行模式",
"modes": "模式列表",
"more-actions": "更多操作",
"mtu": "最大传输单元",
"mtu-default-value-message": "默认1500",
@@ -685,7 +670,6 @@
"n-vifs": "1个虚拟网卡 | {n}个虚拟网卡",
"n-vms": "1台虚拟机 | {n}台虚拟机",
"name": "名称",
"nbd-concurrency": "网络块设备并发数",
"nested-virtualization": "嵌套虚拟化",
"netmask": "子网掩码",
"network": "网络",
@@ -743,7 +727,6 @@
"no-active-backup-jobs": "当前无启用的备份任务。",
"no-alarm-detected": "未检测到任何告警",
"no-alarm-triggered": "无触发告警",
"no-backed-up-vm-detected": "暂无配置备份的虚拟机",
"no-backup-job-available": "暂无可用备份任务",
"no-backup-repository-detected": "未发现备份仓库",
"no-backup-run-available": "暂无备份执行记录",
@@ -762,7 +745,6 @@
"no-replicated-vm": "该虚拟机未配置数据复制任务。",
"no-result": "无搜索结果",
"no-role-applied": "未分配角色",
"no-schedule-available": "暂无定时计划",
"no-selected-vm-can-be-exported": "选中虚拟机均无法导出",
"no-selected-vm-can-be-migrated": "选中虚拟机均无法迁移",
"no-server-detected": "未发现服务节点",
@@ -788,7 +770,6 @@
"off": "关闭",
"offline": "离线",
"offline-backup": "离线备份",
"offline-snapshot": "离线快照",
"ok": "确定",
"on": "开启",
"on-object": "作用于{object}",
@@ -813,7 +794,6 @@
"os-name": "操作系统",
"other": "其他",
"other-properties": "其他属性",
"other-settings": "其他配置",
"ova": "OVA",
"page-not-found": "页面不存在.…",
"page-please-wait": "稍等,正在加载页面{newline}系统正在初始化,请耐心等待!",
@@ -929,7 +909,6 @@
"relative-time:past": "{str}前",
"relative-time:second": "1秒前 | {n}秒前",
"relative-time:year": "1年前 | {n}年前",
"remaining-space": "剩余存储空间",
"remote-syslog": "远程系统日志",
"report-recipients": "报表接收人",
"report-when": "报表推送时机",
@@ -949,7 +928,6 @@
"rule-type": "规则类型",
"run": "执行",
"running-vm": "运行中虚拟机",
"runs": "执行记录",
"s3-backup-repository": "S3对象存储备份仓库",
"scan-pifs": "扫描物理网卡",
"schedule": "定时计划",
@@ -985,7 +963,6 @@
"software": "软件服务",
"software-tooling": "软件与运维工具",
"source": "源",
"source-backup-repository": "源端备份仓库",
"space": "存储空间",
"speed": "传输速率",
"speed-limit": "速率限制",
@@ -1010,7 +987,6 @@
"stacked-cpu-usage": "堆叠式CPU使用率",
"stacked-ram-usage": "堆叠式内存使用率",
"start-console": "启动{type}后即可打开控制台恢复业务!",
"start-date": "开始日期",
"start-delay": "启动延迟",
"start-host": "启动主机后继续操作,或稍后刷新页面。",
"start-vm": "开启虚拟机查看控制台与配置。",
@@ -1084,12 +1060,10 @@
"topology": "网络拓扑",
"total": "总计",
"total-assigned": "已分配总量",
"total-capacity": "总容量",
"total-cpus": "物理CPU总数",
"total-free": "空闲总量",
"total-free:": "空闲总量:",
"total-memory": "总内存",
"total-schedules": "定时计划总数",
"total-space": "总存储空间",
"total-storage-repository": "存储仓库总容量",
"total-used": "已使用总量",
@@ -1101,7 +1075,6 @@
"traffic-rules:format-warning:check-doc": "查阅最新文档",
"traffic-rules:info-message": "流量规则优先级正在优化,运行逻辑可能存在异常。",
"traffic-rules:no-traffic-rules-detected": "暂无流量管控规则",
"transfer-size": "单次传输大小",
"translation-tool": "词条翻译工具",
"treeview": "树形视图",
"trigger": "触发条件",

View File

@@ -1,23 +0,0 @@
import { defineColumns } from '@core/packages/table/define-columns.ts'
import { useLinkColumn } from '@core/tables/column-definitions/link-column.ts'
import { useSelectItemColumn } from '@core/tables/column-definitions/select-item-column.ts'
import { useStatusColumn } from '@core/tables/column-definitions/status-column.ts'
import { useTextColumn } from '@core/tables/column-definitions/text-column.ts'
import { useI18n } from 'vue-i18n'
export const useAdminBackupJobColumns = defineColumns(() => {
const { t } = useI18n()
return {
backupJob: useLinkColumn({ headerLabel: () => t('backup-job') }),
type: useTextColumn({ headerLabel: () => t('type') }),
mode: useTextColumn({ headerLabel: () => t('mode') }),
lastRuns: useStatusColumn({
headerLabel: () => t('last-n-runs', { n: 3 }),
iconOnly: true,
progressiveSize: true,
}),
healthCheck: useStatusColumn({ headerLabel: () => t('health-check') }),
selectItem: useSelectItemColumn(),
}
})

View File

@@ -1,20 +0,0 @@
import { defineColumns } from '@core/packages/table/define-columns.ts'
import { useDateColumn } from '@core/tables/column-definitions/date-column.ts'
import { useLinkColumn } from '@core/tables/column-definitions/link-column.ts'
import { useLinkOrTextColumn } from '@core/tables/column-definitions/link-or-text-column.ts'
import { useSelectItemColumn } from '@core/tables/column-definitions/select-item-column.ts'
import { useStatusColumn } from '@core/tables/column-definitions/status-column.ts'
import { useI18n } from 'vue-i18n'
export const useAdminBackupLogColumns = defineColumns(() => {
const { t } = useI18n()
return {
job: useLinkColumn({ headerLabel: () => t('job') }),
backupDate: useDateColumn({ headerLabel: () => t('backup-date') }),
vm: useLinkOrTextColumn({ headerLabel: () => t('vm') }),
sr: useLinkOrTextColumn({ headerLabel: () => t('sr') }),
status: useStatusColumn(),
selectItem: useSelectItemColumn(),
}
})

View File

@@ -1,23 +1,23 @@
import { defineColumns } from '@core/packages/table/define-columns.ts'
import { useCollapsedListColumn } from '@core/tables/column-definitions/collapsed-list-column.ts'
import { useLinkColumn } from '@core/tables/column-definitions/link-column.ts'
import { useNumberColumn } from '@core/tables/column-definitions/number-column.ts'
import { useSelectItemColumn } from '@core/tables/column-definitions/select-item-column.ts'
import { useStatusColumn } from '@core/tables/column-definitions/status-column.ts'
import { useTextColumn } from '@core/tables/column-definitions/text-column.ts'
import { useI18n } from 'vue-i18n'
export const useBackupJobColumns = defineColumns(() => {
const { t } = useI18n()
return {
job: useLinkColumn({ headerLabel: t('job-name') }),
mode: useCollapsedListColumn({ headerLabel: t('mode') }),
backupJob: useLinkColumn({ headerLabel: () => t('backup-job') }),
type: useTextColumn({ headerLabel: () => t('type') }),
mode: useTextColumn({ headerLabel: () => t('mode') }),
lastRuns: useStatusColumn({
headerLabel: t('last-n-runs', { n: 3 }),
headerLabel: () => t('last-n-runs', { n: 3 }),
iconOnly: true,
progressiveSize: true,
}),
schedules: useNumberColumn({ headerLabel: t('total-schedules') }),
healthCheck: useStatusColumn({ headerLabel: () => t('health-check') }),
selectItem: useSelectItemColumn(),
}
})

View File

@@ -1,21 +0,0 @@
import { defineColumns } from '@core/packages/table/define-columns.ts'
import { useLinkColumn } from '@core/tables/column-definitions/link-column.ts'
import { useStatusColumn } from '@core/tables/column-definitions/status-column.ts'
import { useTextColumn } from '@core/tables/column-definitions/text-column.ts'
import { useI18n } from 'vue-i18n'
export const useBackupJobScheduleColumns = defineColumns(() => {
const { t } = useI18n()
return {
schedule: useLinkColumn({ headerLabel: () => t('schedule') }),
id: useTextColumn({ headerLabel: () => t('id') }),
status: useStatusColumn(),
cronPattern: useTextColumn({ headerLabel: () => t('cron-pattern') }),
lastThreeRuns: useStatusColumn({
headerLabel: () => t('last-n-runs', { n: 3 }),
iconOnly: true,
progressiveSize: true,
}),
}
})

View File

@@ -1,19 +1,20 @@
import { defineColumns } from '@core/packages/table/define-columns.ts'
import { useDateColumn } from '@core/tables/column-definitions/date-column.ts'
import { useNumberColumn } from '@core/tables/column-definitions/number-column.ts'
import { useLinkColumn } from '@core/tables/column-definitions/link-column.ts'
import { useLinkOrTextColumn } from '@core/tables/column-definitions/link-or-text-column.ts'
import { useSelectItemColumn } from '@core/tables/column-definitions/select-item-column.ts'
import { useStatusColumn } from '@core/tables/column-definitions/status-column.ts'
import { useI18n } from 'vue-i18n'
export const useBackupLogsColumns = defineColumns(() => {
export const useBackupLogColumns = defineColumns(() => {
const { t } = useI18n()
return {
startDate: useDateColumn({ headerLabel: () => t('start-date') }),
endDate: useDateColumn({ headerLabel: () => t('end-date') }),
duration: useNumberColumn({ headerLabel: () => t('duration') }),
job: useLinkColumn({ headerLabel: () => t('job') }),
backupDate: useDateColumn({ headerLabel: () => t('backup-date') }),
vm: useLinkOrTextColumn({ headerLabel: () => t('vm') }),
sr: useLinkOrTextColumn({ headerLabel: () => t('sr') }),
status: useStatusColumn(),
transferSize: useNumberColumn({ headerLabel: () => t('transfer-size') }),
selectItem: useSelectItemColumn(),
}
})

View File

@@ -1,23 +0,0 @@
<template>
<VtsSidePanel :has-selection="!!backupLog" @close="emit('close')">
<template v-if="backupLog">
<AdminBackupLogInfosCard :backup-log />
<AdminBackupLogSizeAndSpeedCard :backup-log />
</template>
</VtsSidePanel>
</template>
<script lang="ts" setup>
import AdminBackupLogInfosCard from '@/modules/admin-backup-log/components/list/panel/cards/AdminBackupLogInfosCard.vue'
import AdminBackupLogSizeAndSpeedCard from '@/modules/admin-backup-log/components/list/panel/cards/AdminBackupLogSizeAndSpeedCard.vue'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import VtsSidePanel from '@core/components/panel/VtsSidePanel.vue'
const { backupLog } = defineProps<{
backupLog?: FrontXoBackupLog
}>()
const emit = defineEmits<{
close: []
}>()
</script>

View File

@@ -1,5 +0,0 @@
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
export type BackupLogFilterableData = FrontXoBackupLog & {
jobName: string | undefined
}

View File

@@ -1,6 +1,6 @@
import type { useXoBackupLogCollection } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import BackupJobsTable from '@/modules/backup-job/components/list/BackupJobsTable.vue'
import type { FrontAnyXoBackupJob } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import type { useXoBackupLogCollection } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import type { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import { createMetadataBackupJob, createMirrorBackupJob, createVmBackupJob } from '@/test/create-backup-job.ts'
import { createBackupLog } from '@/test/create-backup-log.ts'
@@ -27,7 +27,7 @@ vi.mock(import('@/shared/remote-resources/use-xo-routes.ts'), () => ({
})) as unknown as typeof useXoRoutes,
}))
vi.mock(import('@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'), () => ({
vi.mock(import('@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'), () => ({
useXoBackupLogCollection: (() => ({
areBackupLogsReady: ref(areBackupLogsReady.value),
getLastNBackupLogsByJobId,

View File

@@ -23,12 +23,12 @@
</template>
<script setup lang="ts">
import { useXoBackupLogCollection } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import { useXoBackupJobLastRuns } from '@/modules/backup-job/composables/use-xo-backup-job-last-runs.composable.ts'
import { useXoBackupJobModeLabel } from '@/modules/backup-job/composables/use-xo-backup-job-mode-label.composable.ts'
import { useXoBackupJobTypeLabels } from '@/modules/backup-job/composables/use-xo-backup-job-type-labels.composable.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import { getBackupJobHealthCheckStatus } from '@/modules/backup-job/utils/xo-backup-job.util.ts'
import { useXoBackupLogCollection } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import VtsQueryBuilder from '@core/components/query-builder/VtsQueryBuilder.vue'
import VtsRow from '@core/components/table/VtsRow.vue'
@@ -39,7 +39,7 @@ import { useRouteQuery } from '@core/composables/route-query.composable.ts'
import { useTableState } from '@core/composables/table-state.composable.ts'
import { useQueryBuilderSchema } from '@core/packages/query-builder/schema/use-query-builder-schema.ts'
import { useQueryBuilderFilter } from '@core/packages/query-builder/use-query-builder-filter.ts'
import { useAdminBackupJobColumns } from '@core/tables/column-sets/admin-backup-job-columns.ts'
import { useBackupJobColumns } from '@core/tables/column-sets/backup-job-columns.ts'
import { renderLoadingCell } from '@core/tables/helpers/render-loading-cell.ts'
import { useStringSchema } from '@core/utils/query-builder/use-string-schema.ts'
import { computed } from 'vue'
@@ -81,7 +81,7 @@ const state = useTableState({
const jobOverviewHref = computed(() => buildXo5Route('/backup/overview'))
const { HeadCells, BodyCells } = useAdminBackupJobColumns({
const { HeadCells, BodyCells } = useBackupJobColumns({
body: (backupJob: FrontAnyXoBackupJob) => {
const typeLabels = useXoBackupJobTypeLabels(() => backupJob)
const modeLabel = useXoBackupJobModeLabel(() => backupJob)

View File

@@ -1,7 +1,3 @@
import type {
FrontXoBackupLog,
useXoBackupLogCollection,
} from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import BackupJobSidePanel from '@/modules/backup-job/components/list/panel/BackupJobSidePanel.vue'
import BackupJobBackedUpVmsCard from '@/modules/backup-job/components/list/panel/cards/BackupJobBackedUpVmsCard.vue'
import BackupJobInfosCard from '@/modules/backup-job/components/list/panel/cards/BackupJobInfosCard.vue'
@@ -10,6 +6,10 @@ import BackupJobSchedulesCard from '@/modules/backup-job/components/list/panel/c
import BackupJobSettingsCard from '@/modules/backup-job/components/list/panel/cards/BackupJobSettingsCard.vue'
import BackupJobTargetsCard from '@/modules/backup-job/components/list/panel/cards/BackupJobTargetsCard.vue'
import type { FrontAnyXoBackupJob } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import type {
FrontXoBackupLog,
useXoBackupLogCollection,
} from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import type { useXoBackupRepositoryCollection } from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import type { useXoHostCollection } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import type { useXoPbdCollection } from '@/modules/pbd/remote-resources/use-xo-pbd-collection.ts'
@@ -53,7 +53,7 @@ vi.mock(import('@/modules/schedule/remote-resources/use-xo-schedule-collection.t
}
})
vi.mock(import('@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'), () => ({
vi.mock(import('@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'), () => ({
useXoBackupLogCollection: (() => ({
getLastNBackupLogsByJobId: (jobId: string) => backupLogsByJobId.get(jobId) ?? [],
})) as unknown as typeof useXoBackupLogCollection,

View File

@@ -16,7 +16,6 @@
</template>
<script lang="ts" setup>
import { useXoBackupLogCollection } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import BackupJobBackedUpVmsCard from '@/modules/backup-job/components/list/panel/cards/BackupJobBackedUpVmsCard.vue'
import BackupJobInfosCard from '@/modules/backup-job/components/list/panel/cards/BackupJobInfosCard.vue'
import BackupJobLogsCard from '@/modules/backup-job/components/list/panel/cards/BackupJobLogsCard.vue'
@@ -25,6 +24,7 @@ import BackupJobSettingsCard from '@/modules/backup-job/components/list/panel/ca
import BackupJobTargetsCard from '@/modules/backup-job/components/list/panel/cards/BackupJobTargetsCard.vue'
import type { FrontAnyXoBackupJob } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import { BACKUP_JOB_LAST_RUNS_COUNT } from '@/modules/backup-job/utils/xo-backup-job.util.ts'
import { useXoBackupLogCollection } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import {
useXoBackupRepositoryCollection,
type FrontXoBackupRepository,

View File

@@ -1,5 +1,5 @@
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import BackupJobRunItem from '@/modules/backup-job/components/list/panel/card-items/BackupJobRunItem.vue'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import type {
FrontXoSchedule,
useXoScheduleCollection,

View File

@@ -49,8 +49,8 @@
</template>
<script lang="ts" setup>
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import { getBackupLogError } from '@/modules/backup-job/utils/xo-backup-log.util.ts'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import { getBackupLogError } from '@/modules/backup-log/utils/xo-backup-log.util.ts'
import {
type FrontXoSchedule,
useXoScheduleCollection,

View File

@@ -1,6 +1,6 @@
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import BackupJobRunItem from '@/modules/backup-job/components/list/panel/card-items/BackupJobRunItem.vue'
import BackupJobLogsCard from '@/modules/backup-job/components/list/panel/cards/BackupJobLogsCard.vue'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import type { useXoScheduleCollection } from '@/modules/schedule/remote-resources/use-xo-schedule-collection.ts'
import type { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import { createBackupLog } from '@/test/create-backup-log.ts'

View File

@@ -13,9 +13,9 @@
</template>
<script lang="ts" setup>
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import BackupJobRunItem from '@/modules/backup-job/components/list/panel/card-items/BackupJobRunItem.vue'
import { BACKUP_JOB_LAST_RUNS_COUNT } from '@/modules/backup-job/utils/xo-backup-job.util.ts'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import VtsDivider from '@core/components/divider/VtsDivider.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'

View File

@@ -1,5 +1,6 @@
import { useXoBackupLogCollection } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import { useXoBackupLogCollection } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import { formatDateTime } from '@core/utils/time.util.ts'
import { toComputed } from '@core/utils/to-computed.util.ts'
import { computed, type MaybeRefOrGetter } from 'vue'
import { useI18n } from 'vue-i18n'
@@ -7,14 +8,14 @@ import { useI18n } from 'vue-i18n'
export function useXoBackupJobLastRuns(rawBackupJob: MaybeRefOrGetter<FrontAnyXoBackupJob>) {
const backupJob = toComputed(rawBackupJob)
const { t, d } = useI18n()
const { t } = useI18n()
const { getLastNBackupLogsByJobId } = useXoBackupLogCollection()
return computed(() =>
getLastNBackupLogsByJobId(backupJob.value.id).map((backupLog, index) => ({
status: backupLog.status,
tooltip: `${t('last-run-number', { n: index + 1 })}: ${d(backupLog.end ?? backupLog.start, 'datetime_short')}, ${t(backupLog.status)}`,
tooltip: `${t('last-run-number', { n: index + 1 })}: ${formatDateTime(backupLog.end ?? backupLog.start)}, ${t(backupLog.status)}`,
}))
)
}

View File

@@ -1,16 +1,17 @@
import type { useXoBackupLogCollection } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import { useXoBackupJobLastRuns } from '@/modules/backup-job/composables/use-xo-backup-job-last-runs.composable.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import type { useXoBackupLogCollection } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import { createVmBackupJob } from '@/test/create-backup-job.ts'
import { createBackupLog } from '@/test/create-backup-log.ts'
import { mountComposable } from '@/test/mount-composable.ts'
import { formatDateTime } from '@core/utils/time.util.ts'
import { useI18n } from 'vue-i18n'
const { getLastNBackupLogsByJobId } = vi.hoisted(() => ({
getLastNBackupLogsByJobId: vi.fn(),
}))
vi.mock(import('@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'), () => ({
vi.mock(import('@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'), () => ({
useXoBackupLogCollection: (() => ({ getLastNBackupLogsByJobId })) as unknown as typeof useXoBackupLogCollection,
}))
@@ -21,9 +22,9 @@ beforeEach(() => {
function mountLastRuns(backupJob: FrontAnyXoBackupJob) {
return mountComposable(() => {
const { t, d } = useI18n()
const { t } = useI18n()
return { lastRuns: useXoBackupJobLastRuns(backupJob), t, d }
return { lastRuns: useXoBackupJobLastRuns(backupJob), t }
}).wrapper.vm
}
@@ -49,11 +50,11 @@ describe('useXoBackupJobLastRuns', () => {
expect(result.lastRuns).toEqual([
{
status: 'failure',
tooltip: `${result.t('last-run-number', { n: 1 })}: ${result.d(1_700_000_300_000, 'datetime_short')}, ${result.t('failure')}`,
tooltip: `${result.t('last-run-number', { n: 1 })}: ${formatDateTime(1_700_000_300_000)}, ${result.t('failure')}`,
},
{
status: 'success',
tooltip: `${result.t('last-run-number', { n: 2 })}: ${result.d(1_700_000_100_000, 'datetime_short')}, ${result.t('success')}`,
tooltip: `${result.t('last-run-number', { n: 2 })}: ${formatDateTime(1_700_000_100_000)}, ${result.t('success')}`,
},
])
})
@@ -68,7 +69,7 @@ describe('useXoBackupJobLastRuns', () => {
expect(result.lastRuns).toEqual([
{
status: 'pending',
tooltip: `${result.t('last-run-number', { n: 1 })}: ${result.d(1_700_000_000_000, 'datetime_short')}, ${result.t('pending')}`,
tooltip: `${result.t('last-run-number', { n: 1 })}: ${formatDateTime(1_700_000_000_000)}, ${result.t('pending')}`,
},
])
})

View File

@@ -45,7 +45,6 @@ const mirrorBackupJobFields = [
'proxy',
] as const satisfies readonly (keyof XoMirrorBackupJob)[]
// Ensure fields are unique
export const anyBackupJobFields = Array.from(
new Set([...vmBackupJobFields, ...metadataBackupJobFields, ...mirrorBackupJobFields])
)
@@ -53,8 +52,7 @@ export const anyBackupJobFields = Array.from(
export const useXoBackupJobCollection = defineRemoteResource({
url: `${BASE_URL}/backup-jobs?fields=${anyBackupJobFields.join(',')}&ndjson=true`,
stream: true,
initWatchCollection: () =>
useWatchCollection({ collectionId: 'adminBackupJob', resource: 'backup-job', fields: anyBackupJobFields }),
initWatchCollection: () => useWatchCollection({ resource: 'backup-job', fields: anyBackupJobFields }),
initialData: () => [] as FrontAnyXoBackupJob[],
state: (backupJobs, context) =>
useXoCollectionState(backupJobs, {

View File

@@ -1,28 +0,0 @@
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import type { XoTask } from '@vates/types'
function findTaskErrorRecursively(tasks: XoTask[]): XoTask['result'] {
for (const task of tasks) {
if (task.status !== 'success' && task.status !== 'pending' && task.result !== undefined) {
return task.result
}
const subTaskError = findTaskErrorRecursively(task.tasks ?? [])
if (subTaskError !== undefined) {
return subTaskError
}
}
return undefined
}
export function getBackupLogError(backupLog: FrontXoBackupLog): XoTask['result'] {
switch (backupLog.status) {
case 'success':
case 'pending':
return undefined
default:
return (backupLog.result as XoTask['result']) ?? findTaskErrorRecursively(backupLog.tasks ?? [])
}
}

View File

@@ -1,72 +0,0 @@
import { getBackupLogError } from '@/modules/backup-job/utils/xo-backup-log.util.ts'
import { createBackupLog, createBackupLogTask } from '@/test/create-backup-log.ts'
const jobError = { message: 'no VMs match this pattern' }
const taskError = { message: 'Disk write error' }
describe('getBackupLogError', () => {
it('has no error for a successful or pending run', () => {
expect(getBackupLogError(createBackupLog({ status: 'success', result: jobError }))).toBeUndefined()
expect(getBackupLogError(createBackupLog({ status: 'pending', result: jobError }))).toBeUndefined()
})
it('gives the error of the job first', () => {
const backupLog = createBackupLog({
status: 'failure',
result: jobError,
tasks: [createBackupLogTask({ status: 'failure', result: taskError })],
})
expect(getBackupLogError(backupLog)).toEqual(jobError)
})
it('looks for the error in the tasks when the job has none', () => {
const backupLog = createBackupLog({
status: 'failure',
tasks: [
createBackupLogTask({ status: 'success' }),
createBackupLogTask({
status: 'failure',
tasks: [
createBackupLogTask({
status: 'failure',
tasks: [createBackupLogTask({ status: 'failure', result: taskError })],
}),
],
}),
],
})
expect(getBackupLogError(backupLog)).toEqual(taskError)
})
it('gives the first error found in the tasks', () => {
const backupLog = createBackupLog({
status: 'failure',
tasks: [
createBackupLogTask({ status: 'failure', result: taskError }),
createBackupLogTask({ status: 'failure', result: { message: 'Another error' } }),
],
})
expect(getBackupLogError(backupLog)).toEqual(taskError)
})
it('reads the error of an interrupted run from its tasks', () => {
const backupLog = createBackupLog({
status: 'interrupted',
tasks: [createBackupLogTask({ status: 'interrupted', result: taskError })],
})
expect(getBackupLogError(backupLog)).toEqual(taskError)
})
it('ignores the result of the successful tasks', () => {
const backupLog = createBackupLog({
status: 'failure',
tasks: [createBackupLogTask({ status: 'success', result: { size: 1024 } })],
})
expect(getBackupLogError(backupLog)).toBeUndefined()
})
})

View File

@@ -1,6 +1,6 @@
import AdminBackupLogsTable from '@/modules/admin-backup-log/components/list/AdminBackupLogsTable.vue'
import type { useXoBackupJobCollection } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import type { useXoBackupJobCollection } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import BackupLogsTable from '@/modules/backup-log/components/list/BackupLogsTable.vue'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import type { useXoHostCollection } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import type { useXoPbdCollection } from '@/modules/pbd/remote-resources/use-xo-pbd-collection.ts'
import type { useXoSrCollection } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
@@ -26,7 +26,7 @@ vi.mock(import('@/shared/remote-resources/use-xo-routes.ts'), () => ({
})) as unknown as typeof useXoRoutes,
}))
vi.mock(import('@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'), () => ({
vi.mock(import('@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'), () => ({
useXoBackupJobCollection: (() => ({ getBackupJobById })) as unknown as typeof useXoBackupJobCollection,
}))
@@ -66,7 +66,7 @@ function mockVms(vms: FrontXoVm[]) {
}
function mountTable(backupLog: FrontXoBackupLog) {
return mount(AdminBackupLogsTable, {
return mount(BackupLogsTable, {
props: { backupLogs: [backupLog], busy: false, error: false },
global: createGlobalTestConfig(),
})

View File

@@ -19,10 +19,10 @@
</template>
<script setup lang="ts">
import type { BackupLogFilterableData } from '@/modules/admin-backup-log/types.ts'
import { useXoBackupJobCollection } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import { getBackupLogSrIds, getBackupLogVmIds } from '@/modules/backup/utils/xo-backup-log.util.ts'
import { useXoBackupJobCollection } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import type { BackupLogFilterableData } from '@/modules/backup-log/types/xo-backup-log.type.ts'
import { getBackupLogSrIds, getBackupLogVmIds } from '@/modules/backup-log/utils/xo-backup-log.util.ts'
import { useXoSrUtils } from '@/modules/storage-repository/composables/xo-sr-utils.composable.ts'
import { useXoSrCollection } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import { useXoVmCollection } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
@@ -37,7 +37,7 @@ import { useTableState } from '@core/composables/table-state.composable.ts'
import { objectIcon } from '@core/icons'
import { useQueryBuilderSchema } from '@core/packages/query-builder/schema/use-query-builder-schema.ts'
import { useQueryBuilderFilter } from '@core/packages/query-builder/use-query-builder-filter.ts'
import { useAdminBackupLogColumns } from '@core/tables/column-sets/admin-backup-log-columns.ts'
import { useBackupLogColumns } from '@core/tables/column-sets/backup-log-columns.ts'
import { useStringSchema } from '@core/utils/query-builder/use-string-schema.ts'
import { toLower } from 'lodash-es'
import { computed } from 'vue'
@@ -68,7 +68,7 @@ const filterableBackupLogs = computed(() =>
)
const { items: filteredBackupLogs, filter } = useQueryBuilderFilter<BackupLogFilterableData>(
'admin-backup-logs',
'backup-logs',
() => filterableBackupLogs.value
)
@@ -84,7 +84,7 @@ const schema = useQueryBuilderSchema<BackupLogFilterableData>({
}),
})
const { pageRecords: paginatedBackupLogs, paginationBindings } = usePagination('admin-backup-logs', filteredBackupLogs)
const { pageRecords: paginatedBackupLogs, paginationBindings } = usePagination('backup-logs', filteredBackupLogs)
const state = useTableState({
busy: () => busy,
@@ -97,7 +97,7 @@ const state = useTableState({
: false,
})
const { HeadCells, BodyCells } = useAdminBackupLogColumns({
const { HeadCells, BodyCells } = useBackupLogColumns({
body: (log: BackupLogFilterableData) => {
const href = computed(() => buildXo5Route(`/backup/${log.jobId}/edit`))

View File

@@ -0,0 +1,23 @@
<template>
<VtsSidePanel :has-selection="!!backupLog" @close="emit('close')">
<template v-if="backupLog">
<BackupLogInfosCard :backup-log />
<BackupLogSizeAndSpeedCard :backup-log />
</template>
</VtsSidePanel>
</template>
<script lang="ts" setup>
import BackupLogInfosCard from '@/modules/backup-log/components/list/panel/cards/BackupLogInfosCard.vue'
import BackupLogSizeAndSpeedCard from '@/modules/backup-log/components/list/panel/cards/BackupLogSizeAndSpeedCard.vue'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import VtsSidePanel from '@core/components/panel/VtsSidePanel.vue'
const { backupLog } = defineProps<{
backupLog?: FrontXoBackupLog
}>()
const emit = defineEmits<{
close: []
}>()
</script>

View File

@@ -1,6 +1,6 @@
import AdminBackupLogInfosCard from '@/modules/admin-backup-log/components/list/panel/cards/AdminBackupLogInfosCard.vue'
import type { useXoBackupJobCollection } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import type { useXoBackupJobCollection } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import BackupLogInfosCard from '@/modules/backup-log/components/list/panel/cards/BackupLogInfosCard.vue'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import type { useXoHostCollection } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import type { useXoPbdCollection } from '@/modules/pbd/remote-resources/use-xo-pbd-collection.ts'
import type {
@@ -33,7 +33,7 @@ vi.mock(import('@/shared/remote-resources/use-xo-routes.ts'), () => ({
useXoRoutes: (() => ({ buildXo5Route })) as unknown as typeof useXoRoutes,
}))
vi.mock(import('@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'), () => ({
vi.mock(import('@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'), () => ({
useXoBackupJobCollection: (() => ({ useGetBackupJobById })) as unknown as typeof useXoBackupJobCollection,
}))
@@ -81,7 +81,7 @@ function mockSrs(srs: FrontXoSr[]) {
}
function mountCard(backupLog: FrontXoBackupLog = createBackupLog()) {
return mount(AdminBackupLogInfosCard, {
return mount(BackupLogInfosCard, {
props: { backupLog },
global: createGlobalTestConfig(),
})

View File

@@ -1,5 +1,5 @@
<template>
<UiPanelCard class="admin-backup-log-infos-card">
<UiPanelCard class="backup-log-infos-card">
<UiPanelCardTitle :id="backupLog.id" size="medium" :label="logName" :href="logHref" icon="object:backup-run" />
<div class="content">
<VtsCardRowKeyValue>
@@ -90,10 +90,10 @@
</template>
<script lang="ts" setup>
import { useXoBackupLogsUtils } from '@/modules/backup/composables/xo-backup-log-utils.composable.ts'
import { useXoBackupJobCollection } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import { getBackupLogSrIds, getBackupLogVmIds } from '@/modules/backup/utils/xo-backup-log.util.ts'
import { useXoBackupJobCollection } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import { useXoBackupLogsUtils } from '@/modules/backup-log/composables/use-xo-backup-log-utils.composable.ts'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import { getBackupLogSrIds, getBackupLogVmIds } from '@/modules/backup-log/utils/xo-backup-log.util.ts'
import { useXoSrUtils } from '@/modules/storage-repository/composables/xo-sr-utils.composable.ts'
import { useXoSrCollection } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import { useXoVmCollection } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
@@ -158,7 +158,7 @@ const srs = computed(() =>
</script>
<style scoped lang="postcss">
.admin-backup-log-infos-card {
.backup-log-infos-card {
.content {
display: flex;
flex-direction: column;

View File

@@ -1,5 +1,5 @@
import AdminBackupLogSizeAndSpeedCard from '@/modules/admin-backup-log/components/list/panel/cards/AdminBackupLogSizeAndSpeedCard.vue'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import BackupLogSizeAndSpeedCard from '@/modules/backup-log/components/list/panel/cards/BackupLogSizeAndSpeedCard.vue'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import {
createBackupLog,
createBackupLogExportTask,
@@ -14,7 +14,7 @@ import { formatSpeed } from '@core/utils/speed.util.ts'
import { mount } from '@vue/test-utils'
function mountCard(backupLog: FrontXoBackupLog = createBackupLog()) {
return mount(AdminBackupLogSizeAndSpeedCard, {
return mount(BackupLogSizeAndSpeedCard, {
props: { backupLog },
global: createGlobalTestConfig(),
})

View File

@@ -1,5 +1,5 @@
<template>
<UiPanelCard class="admin-backup-log-size-and-speed-card">
<UiPanelCard class="backup-log-size-and-speed-card">
<UiPanelCardTitle size="medium" :label="t('size-and-speed')" />
<div class="content">
<VtsCardRowKeyValue>
@@ -21,8 +21,8 @@
</template>
<script lang="ts" setup>
import { useXoBackupLogsUtils } from '@/modules/backup/composables/xo-backup-log-utils.composable.ts'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import { useXoBackupLogsUtils } from '@/modules/backup-log/composables/use-xo-backup-log-utils.composable.ts'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
import VtsCopyButton from '@core/components/copy-button/VtsCopyButton.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
@@ -54,7 +54,7 @@ const speed = computed(() => {
</script>
<style scoped lang="postcss">
.admin-backup-log-size-and-speed-card {
.backup-log-size-and-speed-card {
.content {
display: flex;
flex-direction: column;

View File

@@ -1,4 +1,4 @@
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import { formatSizeRaw } from '@core/utils/size.util.ts'
import { formatDateTime } from '@core/utils/time.util.ts'
import type { Info, Scale } from 'human-format'

View File

@@ -1,4 +1,4 @@
import { useXoBackupLogsUtils } from '@/modules/backup/composables/xo-backup-log-utils.composable.ts'
import { useXoBackupLogsUtils } from '@/modules/backup-log/composables/use-xo-backup-log-utils.composable.ts'
import {
createBackupLog,
createBackupLogExportTask,

View File

@@ -0,0 +1,5 @@
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
export type BackupLogFilterableData = FrontXoBackupLog & {
jobName: string | undefined
}

View File

@@ -0,0 +1,48 @@
import type { FrontXoBackupLog } from '@/modules/backup-log/remote-resources/use-xo-backup-log-collection.ts'
import type { FrontXoSr } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import type { XoTask } from '@vates/types'
function getBackupLogVmTasks(backupLog: FrontXoBackupLog) {
return (backupLog.tasks ?? []).filter(task => task.data?.type === 'VM')
}
export function getBackupLogVmIds(backupLog: FrontXoBackupLog) {
return getBackupLogVmTasks(backupLog).map(vmTask => vmTask.data?.id as FrontXoVm['id'])
}
export function getBackupLogSrIds(backupLog: FrontXoBackupLog) {
return [
...new Set(
getBackupLogVmTasks(backupLog)
.flatMap(vmTask => vmTask.tasks ?? [])
.flatMap(task => (task.data?.type === 'SR' ? [task.data.id as FrontXoSr['id']] : []))
),
]
}
function findTaskErrorRecursively(tasks: XoTask[]): XoTask['result'] {
for (const task of tasks) {
if (task.status !== 'success' && task.status !== 'pending' && task.result !== undefined) {
return task.result
}
const subTaskError = findTaskErrorRecursively(task.tasks ?? [])
if (subTaskError !== undefined) {
return subTaskError
}
}
return undefined
}
export function getBackupLogError(backupLog: FrontXoBackupLog): XoTask['result'] {
switch (backupLog.status) {
case 'success':
case 'pending':
return undefined
default:
return (backupLog.result as XoTask['result']) ?? findTaskErrorRecursively(backupLog.tasks ?? [])
}
}

View File

@@ -1,9 +1,8 @@
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import {
getBackupLogRunRoute,
getBackupLogError,
getBackupLogSrIds,
getBackupLogVmIds,
} from '@/modules/backup/utils/xo-backup-log.util.ts'
} from '@/modules/backup-log/utils/xo-backup-log.util.ts'
import {
createBackupLog,
createBackupLogExportTask,
@@ -12,6 +11,9 @@ import {
createBackupLogVmTask,
} from '@/test/create-backup-log.ts'
const jobError = { message: 'no VMs match this pattern' }
const taskError = { message: 'Disk write error' }
describe('getBackupLogVmIds', () => {
it('returns the id of every backed up VM, in order', () => {
const backupLog = createBackupLog({ tasks: [createBackupLogVmTask('vm-1'), createBackupLogVmTask('vm-2')] })
@@ -74,21 +76,69 @@ describe('getBackupLogSrIds', () => {
})
})
describe('getBackupLogRunRoute', () => {
it('points to the run of the log in the runs of its job', () => {
const backupLog = createBackupLog({
id: 'backup-log-42' as FrontXoBackupLog['id'],
jobId: 'backup-job-7' as NonNullable<FrontXoBackupLog['jobId']>,
})
expect(getBackupLogRunRoute(backupLog)).toEqual({
name: '/backup/[id]/runs',
params: { id: 'backup-job-7' },
query: { id: 'backup-log-42' },
})
describe('getBackupLogError', () => {
it('has no error for a successful or pending run', () => {
expect(getBackupLogError(createBackupLog({ status: 'success', result: jobError }))).toBeUndefined()
expect(getBackupLogError(createBackupLog({ status: 'pending', result: jobError }))).toBeUndefined()
})
it('returns undefined for a log without job', () => {
expect(getBackupLogRunRoute(createBackupLog({ jobId: undefined }))).toBeUndefined()
it('gives the error of the job first', () => {
const backupLog = createBackupLog({
status: 'failure',
result: jobError,
tasks: [createBackupLogTask({ status: 'failure', result: taskError })],
})
expect(getBackupLogError(backupLog)).toEqual(jobError)
})
it('looks for the error in the tasks when the job has none', () => {
const backupLog = createBackupLog({
status: 'failure',
tasks: [
createBackupLogTask({ status: 'success' }),
createBackupLogTask({
status: 'failure',
tasks: [
createBackupLogTask({
status: 'failure',
tasks: [createBackupLogTask({ status: 'failure', result: taskError })],
}),
],
}),
],
})
expect(getBackupLogError(backupLog)).toEqual(taskError)
})
it('gives the first error found in the tasks', () => {
const backupLog = createBackupLog({
status: 'failure',
tasks: [
createBackupLogTask({ status: 'failure', result: taskError }),
createBackupLogTask({ status: 'failure', result: { message: 'Another error' } }),
],
})
expect(getBackupLogError(backupLog)).toEqual(taskError)
})
it('reads the error of an interrupted run from its tasks', () => {
const backupLog = createBackupLog({
status: 'interrupted',
tasks: [createBackupLogTask({ status: 'interrupted', result: taskError })],
})
expect(getBackupLogError(backupLog)).toEqual(taskError)
})
it('ignores the result of the successful tasks', () => {
const backupLog = createBackupLog({
status: 'failure',
tasks: [createBackupLogTask({ status: 'success', result: { size: 1024 } })],
})
expect(getBackupLogError(backupLog)).toBeUndefined()
})
})

View File

@@ -1,5 +1,5 @@
import type { XoBackupFormat } from '@/modules/backup/types/xo-backup.ts'
import { useXoBackupRepositoryTypeLabel } from '@/modules/backup-repository/composables/use-xo-backup-repository-type-label.composable.ts'
import type { XoBackupFormat } from '@/modules/backup-repository/types/xo-backup-repository.type.ts'
import { type FrontXoProxy, useXoProxyCollection } from '@/modules/proxy/remote-resources/use-xo-proxy-collection.ts'
import type { InputType } from '@core/components/ui/input/UiInput.vue'
import { type FormValidationConfig, mergeValidationConfigs, required, requiredIf } from '@core/packages/form-validation'

View File

@@ -1,4 +1,4 @@
import { useXoBackupJobCollection } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import { useXoBackupJobCollection } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import { xoBackupRepositoriesArg } from '@/modules/backup-repository/jobs/xo-backup-repository-args.ts'
import type { FrontXoBackupRepository } from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import { getBackupJobsUsingBackupRepository } from '@/modules/backup-repository/utils/xo-backup-repository-backup-jobs.util.ts'

View File

@@ -1,7 +1,7 @@
import type {
FrontAnyXoBackupJob,
useXoBackupJobCollection,
} from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
} from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import { useXoBackupRepositoryForgetJob } from '@/modules/backup-repository/jobs/xo-backup-repository-forget.job.ts'
import type { FrontXoBackupRepository } from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import type { useXoTaskUtils } from '@/shared/composables/xo-task-utils.composable.ts'
@@ -26,7 +26,7 @@ vi.mock(import('@/shared/composables/xo-task-utils.composable.ts'), () => ({
useXoTaskUtils: (() => ({ monitorTask })) as unknown as typeof useXoTaskUtils,
}))
vi.mock(import('@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'), () => ({
vi.mock(import('@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'), () => ({
useXoBackupJobCollection: (() => ({
backupJobs: ref(backupJobs.value),
})) as unknown as typeof useXoBackupJobCollection,

View File

@@ -0,0 +1 @@
export type XoBackupFormat = 'block' | 'vhd'

View File

@@ -1,4 +1,4 @@
import type { FrontAnyXoBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontXoBackupRepository } from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import { extractIdsFromSimplePattern } from '@xen-orchestra/backups/extractIdsFromSimplePattern.mjs'

View File

@@ -1,4 +1,4 @@
import type { FrontAnyXoBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import { getBackupJobsUsingBackupRepository } from '@/modules/backup-repository/utils/xo-backup-repository-backup-jobs.util.ts'
import { createBr } from '@/test/create-br.ts'

View File

@@ -1,97 +0,0 @@
<template>
<div class="breadcrumb-container">
<UiBreadcrumb :size>
<span class="breadcrumb-item">
<VtsIcon name="fa:satellite" size="current" />
<UiLink :size :to="{ name: '/(site)/dashboard' }">{{ XOA_NAME }}</UiLink>
</span>
<UiLink :size :to="{ name: '/(site)/backups' }">{{ t('backups') }}</UiLink>
<span class="breadcrumb-item">
<VtsIcon name="object:backup-job" size="current" />
{{ backupJob.name }}
</span>
</UiBreadcrumb>
<UiLink :size :href="newBackupRoute">{{ t('configure-in-xo-5') }}</UiLink>
</div>
<UiHeadBar>
<template #icon>
<VtsIcon name="object:backup-job" size="current" />
</template>
{{ backupJob.name }}
</UiHeadBar>
<TabList>
<RouterLink v-slot="{ isActive, href }" :to="{ name: '/backup/[id]/runs', params: { id: backupJob.id } }" custom>
<UiTabItem :active="isActive" :href tag="a">
{{ t('runs') }}
</UiTabItem>
</RouterLink>
<RouterLink
v-slot="{ isActive, href }"
:to="{ name: '/backup/[id]/configuration', params: { id: backupJob.id } }"
custom
>
<UiTabItem :active="isActive" :href tag="a">
{{ t('configuration') }}
</UiTabItem>
</RouterLink>
<RouterLink
v-slot="{ isActive, href }"
:to="{ name: '/backup/[id]/backed-up-vms', params: { id: backupJob.id } }"
custom
>
<UiTabItem :active="isActive" :href tag="a" :disabled="backupJob.type !== 'backup'">
{{ t('backed-up-vms') }}
</UiTabItem>
</RouterLink>
<RouterLink v-slot="{ isActive, href }" :to="{ name: '/backup/[id]/targets', params: { id: backupJob.id } }" custom>
<UiTabItem :active="isActive" :href tag="a">
{{ t('backup-targets') }}
</UiTabItem>
</RouterLink>
</TabList>
</template>
<script lang="ts" setup>
import type { FrontAnyXoBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import { XOA_NAME } from '@/shared/constants.ts'
import { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import TabList from '@core/components/tab-list/TabList.vue'
import UiBreadcrumb from '@core/components/ui/breadcrumb/UiBreadcrumb.vue'
import UiHeadBar from '@core/components/ui/head-bar/UiHeadBar.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTabItem from '@core/components/ui/tab-item/UiTabItem.vue'
import { useUiStore } from '@core/stores/ui.store.ts'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
defineProps<{ backupJob: FrontAnyXoBackupJob }>()
const { t } = useI18n()
const uiStore = useUiStore()
const { buildXo5Route } = useXoRoutes()
const newBackupRoute = computed(() => buildXo5Route('/backup/new'))
const size = computed(() => (uiStore.isSmall ? 'small' : 'medium'))
</script>
<style lang="postcss" scoped>
.breadcrumb-container {
min-height: 5.6rem;
padding: 1.2rem 1.6rem;
display: flex;
gap: 1.6rem;
align-items: center;
border-bottom: 0.1rem solid var(--color-neutral-border);
background-color: var(--color-neutral-background-primary);
justify-content: space-between;
overflow-y: auto;
.breadcrumb-item {
display: flex;
align-items: center;
gap: 0.8rem;
}
}
</style>

View File

@@ -1,102 +0,0 @@
<template>
<UiCard>
<UiTitle>
{{ t('configuration') }}
</UiTitle>
<template v-if="!isSmartModeEnabled">
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('smart-mode')">
<template #value>
<VtsStatus status="disabled" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</template>
<VtsColumns v-else>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('smart-mode')">
<template #value>
<VtsStatus status="enabled" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('vms-tags')">
<template v-if="smartModeTags?.included !== undefined && smartModeTags.included.length > 0" #value>
<UiTagsList>
<VtsTag v-for="tag in smartModeTags.included" :key="tag" :value="tag" />
</UiTagsList>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('resident-on')">
<template v-if="smartModePools !== undefined" #value>
<UiLink
v-for="pool in smartModePools.included"
:key="pool.id"
size="small"
icon="object:pool"
:to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }"
>
{{ pool.name_label }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('excluded-vms-tags')">
<template v-if="smartModeTags !== undefined && smartModeTags.excluded.length > 0" #value>
<UiTagsList>
<VtsTag v-for="tag in smartModeTags.excluded" :key="tag" :value="tag" />
</UiTagsList>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('not-resident-on')">
<template v-if="smartModePools !== undefined" #value>
<UiLink
v-for="pool in smartModePools.excluded"
:key="pool.id"
size="small"
icon="object:pool"
:to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }"
>
{{ pool.name_label }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('power-state')">
<template v-if="smartModePowerState !== undefined" #value>
<VtsIcon size="small" :name="`object:vm:${toLower(smartModePowerState)}`" />
{{ smartModePowerState }}
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</VtsColumns>
</UiCard>
</template>
<script lang="ts" setup>
import { useXoBackedUpVmsUtils } from '@/modules/backup/composables/xo-backed-up-vms-utils.composable.ts'
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import VtsColumns from '@core/components/columns/VtsColumns.vue'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import VtsTag from '@core/components/tag/VtsTag.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { toLower } from 'lodash-es'
import { useI18n } from 'vue-i18n'
const { backupJob } = defineProps<{
backupJob: FrontXoVmBackupJob
}>()
const { t } = useI18n()
const { isSmartModeEnabled, smartModePools, smartModeTags, smartModePowerState } = useXoBackedUpVmsUtils(
() => backupJob.vms
)
</script>

View File

@@ -1,143 +0,0 @@
<template>
<UiCard class="backed-up-vms-table">
<UiTitle>{{ t('backed-up-vms') }}</UiTitle>
<div class="container">
<div class="table-actions">
<UiQuerySearchBar @search="value => (searchQuery = value)" />
</div>
<VtsTable :state :pagination-bindings>
<thead>
<tr>
<HeadCells />
</tr>
</thead>
<tbody>
<VtsRow v-for="vm of paginatedBackedUpVms" :key="vm.id">
<BodyCells :item="vm" />
</VtsRow>
</tbody>
</VtsTable>
</div>
</UiCard>
</template>
<script setup lang="ts">
import { useXoBackedUpVmsUtils } from '@/modules/backup/composables/xo-backed-up-vms-utils.composable.ts'
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontXoBackupRepository } from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import { useXoVmBackupArchiveCollection } from '@/modules/vm/remote-resources/use-xo-vm-backup-archive-collection.ts'
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import VtsRow from '@core/components/table/VtsRow.vue'
import VtsTable from '@core/components/table/VtsTable.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiQuerySearchBar from '@core/components/ui/query-search-bar/UiQuerySearchBar.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { usePagination } from '@core/composables/pagination.composable.ts'
import { useTableState } from '@core/composables/table-state.composable.ts'
import { objectIcon } from '@core/icons'
import { defineColumns } from '@core/packages/table/define-columns.ts'
import { useLinkColumn } from '@core/tables/column-definitions/link-column.ts'
import { useNumberColumn } from '@core/tables/column-definitions/number-column.ts'
import { renderLoadingCell } from '@core/tables/helpers/render-loading-cell.ts'
import { formatSizeRaw } from '@core/utils/size.util.ts'
import { extractIdsFromSimplePattern } from '@xen-orchestra/backups/extractIdsFromSimplePattern.mjs'
import { toLower } from 'lodash-es'
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
const { backupJob, busy, error } = defineProps<{
backupJob: FrontXoVmBackupJob
busy?: boolean
error?: boolean
}>()
const { t } = useI18n()
const { backedUpVms } = useXoBackedUpVmsUtils(() => backupJob.vms)
const backupRepositoriesIds = computed(() =>
extractIdsFromSimplePattern<FrontXoBackupRepository['id']>(backupJob.remotes)
)
const { backupArchives, areBackupArchivesReady } = useXoVmBackupArchiveCollection({}, () => backupRepositoriesIds.value)
const searchQuery = ref('')
const filteredBackedUpVms = computed(() => {
const searchTerm = searchQuery.value.trim().toLocaleLowerCase()
if (!searchTerm) {
return backedUpVms.value
}
return backedUpVms.value.filter(backedUpVm =>
Object.values(backedUpVm).some(value => String(value).toLocaleLowerCase().includes(searchTerm))
)
})
const state = useTableState({
busy: () => busy,
error: () => error,
empty: () =>
backedUpVms.value.length === 0
? t('no-backed-up-vm-detected')
: filteredBackedUpVms.value.length === 0
? { type: 'no-result' }
: false,
})
const getDiskSize = (vm: FrontXoVm) =>
formatSizeRaw(
backupArchives.value
.filter(archive => archive.vm.uuid === vm.id)
.reduce((total, archive) => total + archive.size, 0),
0
)
const { pageRecords: paginatedBackedUpVms, paginationBindings } = usePagination('backed-up-vms', filteredBackedUpVms)
const useBackedUpVmColumns = defineColumns(() => {
const { t } = useI18n()
return {
vm: useLinkColumn({ headerLabel: () => t('vm') }),
diskSize: useNumberColumn({ headerLabel: () => t('disk-size') }),
}
})
const { HeadCells, BodyCells } = useBackedUpVmColumns({
body: (vm: FrontXoVm) => {
const diskSize = computed(() => getDiskSize(vm))
return {
vm: r =>
r({
label: vm.name_label,
icon: objectIcon('vm', toLower(vm.power_state)),
to: `/vm/${vm.id}/dashboard`,
}),
diskSize: r =>
areBackupArchivesReady.value ? r(diskSize.value.value, diskSize.value.prefix) : renderLoadingCell(),
}
},
})
</script>
<style lang="postcss" scoped>
.backed-up-vms-table,
.table-actions,
.container {
display: flex;
flex-direction: column;
}
.backed-up-vms-table {
gap: 2.4rem;
.container,
.table-actions {
gap: 0.8rem;
}
}
</style>

View File

@@ -1,53 +0,0 @@
<template>
<UiCard>
<UiTitle>{{ t('general-information') }}</UiTitle>
<VtsColumns>
<VtsColumn>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('name')" :value="backupJob.name" />
</VtsKeyValueList>
</VtsColumn>
<VtsColumn>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('id')" :value="backupJob.id" />
</VtsKeyValueList>
</VtsColumn>
<VtsColumn>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('modes')">
<template v-if="modeLabels.length > 0" #value>
<UiTagsList>
<VtsTag v-for="label in modeLabels" :key="label" :value="label" />
</UiTagsList>
</template>
</VtsKeyValueRow>
</VtsKeyValueList>
</VtsColumn>
</VtsColumns>
</UiCard>
</template>
<script setup lang="ts">
import { useXoBackupUtils } from '@/modules/backup/composables/xo-backup-utils.composable.ts'
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import VtsColumn from '@core/components/column/VtsColumn.vue'
import VtsColumns from '@core/components/columns/VtsColumns.vue'
import VtsKeyValueList from '@core/components/key-value-list/VtsKeyValueList.vue'
import VtsKeyValueRow from '@core/components/key-value-row/VtsKeyValueRow.vue'
import VtsTag from '@core/components/tag/VtsTag.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { backupJob } = defineProps<{
backupJob: FrontXoVmBackupJob
}>()
const { t } = useI18n()
const { getModeLabels } = useXoBackupUtils()
const modeLabels = computed(() => getModeLabels(backupJob))
</script>

View File

@@ -1,122 +0,0 @@
<template>
<UiCard class="backup-job-schedules-table">
<UiTitle>{{ t('schedules') }}</UiTitle>
<div class="container">
<div class="table-actions">
<UiQuerySearchBar @search="value => (searchQuery = value)" />
</div>
<VtsTable :state :pagination-bindings>
<thead>
<tr>
<HeadCells />
</tr>
</thead>
<tbody>
<VtsRow v-for="schedule of paginatedSchedules" :key="schedule.id">
<BodyCells :item="schedule" />
</VtsRow>
</tbody>
</VtsTable>
</div>
</UiCard>
</template>
<script setup lang="ts">
import { useXoBackupJobSchedulesUtils } from '@/modules/backup/composables/xo-backup-job-schedules-utils.composable.ts'
import { useXoBackupJobCollection } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontXoSchedule } from '@/modules/schedule/remote-resources/use-xo-schedule-collection.ts'
import { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import VtsRow from '@core/components/table/VtsRow.vue'
import VtsTable from '@core/components/table/VtsTable.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiQuerySearchBar from '@core/components/ui/query-search-bar/UiQuerySearchBar.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { usePagination } from '@core/composables/pagination.composable.ts'
import { useTableState } from '@core/composables/table-state.composable.ts'
import { useBackupJobScheduleColumns } from '@core/tables/column-sets/backup-job-schedule-columns.ts'
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
const {
backupJobSchedules: rawSchedules,
busy,
error,
} = defineProps<{
backupJobSchedules: FrontXoSchedule[]
busy?: boolean
error?: boolean
}>()
const { t } = useI18n()
const { getBackupJobById } = useXoBackupJobCollection()
const { getLastThreeRunsStatuses } = useXoBackupJobSchedulesUtils()
const { buildXo5Route } = useXoRoutes()
const searchQuery = ref('')
const filteredSchedules = computed(() => {
const searchTerm = searchQuery.value.trim().toLocaleLowerCase()
if (!searchTerm) {
return rawSchedules
}
return rawSchedules.filter(schedules =>
Object.values(schedules).some(value => String(value).toLocaleLowerCase().includes(searchTerm))
)
})
const state = useTableState({
busy: () => busy,
error: () => error,
empty: () =>
rawSchedules.length === 0
? t('no-schedule-available')
: filteredSchedules.value.length === 0
? { type: 'no-result' }
: false,
})
const { pageRecords: paginatedSchedules, paginationBindings } = usePagination('backup-job-schedules', filteredSchedules)
const { HeadCells, BodyCells } = useBackupJobScheduleColumns({
body: (schedule: FrontXoSchedule) => {
const job = computed(() => getBackupJobById(schedule.jobId))
const href = computed(() => buildXo5Route(`/backup/${schedule.jobId}/edit`))
const lastRuns = computed(() => getLastThreeRunsStatuses(job.value))
return {
schedule: r =>
r({
label: schedule.name || t('untitled'),
icon: 'object:backup-schedule',
href: href.value,
}),
id: r => r(schedule.id),
status: r => r(schedule.enabled),
cronPattern: r => r(schedule.cron),
lastThreeRuns: r => r(lastRuns.value),
}
},
})
</script>
<style lang="postcss" scoped>
.backup-job-schedules-table,
.table-actions,
.container {
display: flex;
flex-direction: column;
}
.backup-job-schedules-table {
gap: 2.4rem;
.container,
.table-actions {
gap: 0.8rem;
}
}
</style>

View File

@@ -1,95 +0,0 @@
<template>
<UiCard>
<UiTitle>{{ t('settings') }}</UiTitle>
<VtsColumns>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('proxy')" :value="proxy?.name" />
<VtsTabularKeyValueRow :label="t('snapshot-mode')">
<template v-if="backupJob.mode" #value>
<UiTag variant="secondary" accent="info">{{ snapshotModeTranslation }}</UiTag>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow
:label="t('vm-backup-failure-number-of-retries')"
:value="
settings.nRetriesVmBackupFailures !== undefined ? String(settings.nRetriesVmBackupFailures) : undefined
"
/>
<VtsTabularKeyValueRow :label="t('timeout')" :value="formattedTimeout" />
</VtsTabularKeyValueList>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow
:label="t('speed-limit')"
:value="maxExportRate ? `${maxExportRate.value} ${maxExportRate.prefix}` : undefined"
/>
<VtsTabularKeyValueRow :label="t('report-when')" :value="reportWhenValueTranslation" />
<VtsTabularKeyValueRow :label="t('report-recipients')">
<template #value>
<UiTagsList v-if="settings.reportRecipients">
<UiTag
v-for="(recipient, index) in settings.reportRecipients"
:key="index"
variant="secondary"
accent="info"
>
{{ recipient }}
</UiTag>
</UiTagsList>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow
:label="t('concurrency')"
:value="settings.concurrency !== undefined ? String(settings.concurrency) : undefined"
/>
</VtsTabularKeyValueList>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('compression')" :value="compression" />
<VtsTabularKeyValueRow :label="t('offline-backup')">
<template #value>
<VtsEnabledState :enabled="!!settings.offlineBackup" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('shorter-backup-reports')">
<template #value>
<VtsEnabledState :enabled="settings.backupReportTpl ? settings.backupReportTpl === 'compactMjml' : false" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('merge-backups-synchronously')">
<template #value>
<VtsEnabledState :enabled="!!settings.mergeBackupsSynchronously" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</VtsColumns>
</UiCard>
</template>
<script setup lang="ts">
import { useXoBackupJobSettingsUtils } from '@/modules/backup/composables/backup-job-settings/xo-backup-job-settings.composable.ts'
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import VtsColumns from '@core/components/columns/VtsColumns.vue'
import VtsEnabledState from '@core/components/enabled-state/VtsEnabledState.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { useI18n } from 'vue-i18n'
const { backupJob } = defineProps<{
backupJob: FrontXoVmBackupJob
}>()
const { t } = useI18n()
const {
maxExportRate,
formattedTimeout,
compression,
proxy,
settings,
reportWhenValueTranslation,
snapshotModeTranslation,
} = useXoBackupJobSettingsUtils(() => backupJob)
</script>

View File

@@ -1,126 +0,0 @@
<template>
<div class="backup-jobs-table">
<UiTitle>
{{ t('backup-jobs') }}
</UiTitle>
<UiQuerySearchBar @search="value => (searchQuery = value)" />
<div class="container">
<VtsTable :state :pagination-bindings sticky="right">
<thead>
<tr>
<HeadCells />
</tr>
</thead>
<tbody>
<VtsRow v-for="job of paginatedBackupJobs" :key="job.id" :selected="selectedBackupJobId === job.id">
<BodyCells :item="job" />
</VtsRow>
</tbody>
</VtsTable>
</div>
</div>
</template>
<script setup lang="ts">
import { useXoBackupJobSchedulesUtils } from '@/modules/backup/composables/xo-backup-job-schedules-utils.composable.ts'
import { useXoBackupUtils } from '@/modules/backup/composables/xo-backup-utils.composable.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import { useXoBackupLogCollection } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import { useXoScheduleCollection } from '@/modules/schedule/remote-resources/use-xo-schedule-collection.ts'
import VtsRow from '@core/components/table/VtsRow.vue'
import VtsTable from '@core/components/table/VtsTable.vue'
import UiQuerySearchBar from '@core/components/ui/query-search-bar/UiQuerySearchBar.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { usePagination } from '@core/composables/pagination.composable.ts'
import { useRouteQuery } from '@core/composables/route-query.composable.ts'
import { useTableState } from '@core/composables/table-state.composable.ts'
import { useBackupJobColumns } from '@core/tables/column-sets/backup-job-columns.ts'
import { renderLoadingCell } from '@core/tables/helpers/render-loading-cell.ts'
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
const {
backupJobs: rawBackupJobs,
busy,
error,
} = defineProps<{
backupJobs: FrontAnyXoBackupJob[]
busy?: boolean
error?: boolean
}>()
const { t } = useI18n()
const { areSchedulesReady } = useXoScheduleCollection()
const { areBackupLogsReady } = useXoBackupLogCollection()
const { getLastThreeRunsStatuses, getTotalSchedules } = useXoBackupJobSchedulesUtils()
const { getModeLabels } = useXoBackupUtils()
const selectedBackupJobId = useRouteQuery('id')
const searchQuery = ref('')
const filteredBackupJobs = computed(() => {
const searchTerm = searchQuery.value.trim().toLocaleLowerCase()
if (!searchTerm) {
return rawBackupJobs
}
return rawBackupJobs.filter(backupJob =>
Object.values(backupJob).some(value => String(value).toLocaleLowerCase().includes(searchTerm))
)
})
const state = useTableState({
busy: () => busy,
error: () => error,
empty: () =>
rawBackupJobs.length === 0
? t('no-backup-job-available')
: filteredBackupJobs.value.length === 0
? { type: 'no-result' }
: false,
})
const { pageRecords: paginatedBackupJobs, paginationBindings } = usePagination('backups-jobs', filteredBackupJobs)
const { HeadCells, BodyCells } = useBackupJobColumns({
body: (job: FrontAnyXoBackupJob) => {
const modeLabels = computed(() => getModeLabels(job))
const lastRuns = computed(() => getLastThreeRunsStatuses(job))
const totalSchedules = computed(() => getTotalSchedules(job))
return {
job: r =>
r({
label: job.name ?? t('untitled'),
to: `/backup/${job.id}/runs`,
icon: 'object:backup-job',
}),
mode: r => r(modeLabels.value),
lastRuns: r => (areBackupLogsReady.value ? r(lastRuns.value) : renderLoadingCell()),
schedules: r => (areSchedulesReady.value ? r(totalSchedules.value) : renderLoadingCell()),
selectItem: r => r(() => (selectedBackupJobId.value = job.id)),
}
},
})
</script>
<style scoped lang="postcss">
.backup-jobs-table,
.table-actions,
.container {
display: flex;
flex-direction: column;
}
.backup-jobs-table {
gap: 2.4rem;
.container,
.table-actions {
gap: 0.8rem;
}
}
</style>

View File

@@ -1,100 +0,0 @@
<template>
<VtsSidePanel :has-selection="!!backupJob" @close="emit('close')">
<template v-if="backupJob">
<BackupJobInfosCard :backup-job />
<BackupJobSchedulesCard :backup-job-schedules />
<BackupJobLogsCard v-if="lastThreeLogs.length > 0" :backup-logs="lastThreeLogs" />
<BackupJobBackedUpVmsCard v-if="backupJob.type === 'backup' && backupJob.vms" :backed-up-vms="backupJob.vms" />
<BackupJobBackedUpPoolsCard v-if="backedUpPools.length > 0" :backed-up-pools />
<BackupJobSourceRepositoryCard v-if="backupJob.type === 'mirrorBackup'" :mirror-backup-job="backupJob" />
<BackupJobTargetsCard :storage-repository-targets :backup-repository-targets />
<BackupJobSettingsCard v-if="hasSettings" :backup-job />
</template>
</VtsSidePanel>
</template>
<script setup lang="ts">
import BackupJobInfosCard from '@/modules/backup/components/jobs/panel/cards/BackupJobInfosCard.vue'
import BackupJobSettingsCard from '@/modules/backup/components/jobs/panel/cards/BackupJobSettingsCard.vue'
import BackupJobBackedUpPoolsCard from '@/modules/backup/components/panel/cards/BackupJobBackedUpPoolsCard.vue'
import BackupJobBackedUpVmsCard from '@/modules/backup/components/panel/cards/BackupJobBackedUpVmsCard.vue'
import BackupJobLogsCard from '@/modules/backup/components/panel/cards/BackupJobLogsCard.vue'
import BackupJobSchedulesCard from '@/modules/backup/components/panel/cards/BackupJobSchedulesCard.vue'
import BackupJobSourceRepositoryCard from '@/modules/backup/components/panel/cards/BackupJobSourceRepositoryCard.vue'
import BackupJobTargetsCard from '@/modules/backup/components/panel/cards/BackupJobTargetsCard.vue'
import { getMetadataBackupJobSettings } from '@/modules/backup/composables/backup-job-settings/get-metadata-backup-job-settings.ts'
import { getMirrorBackupJobSettings } from '@/modules/backup/composables/backup-job-settings/get-mirror-backup-job-settings.ts'
import { getVmBackupJobSettings } from '@/modules/backup/composables/backup-job-settings/get-vm-backup-job-settings.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import { useXoBackupLogCollection } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import {
useXoBackupRepositoryCollection,
type FrontXoBackupRepository,
} from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import { useXoPoolCollection, type FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import { useXoScheduleCollection } from '@/modules/schedule/remote-resources/use-xo-schedule-collection.ts'
import {
useXoSrCollection,
type FrontXoSr,
} from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import VtsSidePanel from '@core/components/panel/VtsSidePanel.vue'
import { extractIdsFromSimplePattern } from '@xen-orchestra/backups/extractIdsFromSimplePattern.mjs'
import { computed } from 'vue'
const { backupJob } = defineProps<{
backupJob?: FrontAnyXoBackupJob
}>()
const emit = defineEmits<{
close: []
}>()
const { getSrsByIds } = useXoSrCollection()
const { getBackupRepositoriesByIds } = useXoBackupRepositoryCollection()
const { getLastNBackupLogsByJobId } = useXoBackupLogCollection()
const { schedulesByJobId } = useXoScheduleCollection()
const { getPoolsByIds } = useXoPoolCollection()
const backupJobSchedules = computed(() =>
backupJob !== undefined ? (schedulesByJobId.value.get(backupJob.id) ?? []) : []
)
const lastThreeLogs = computed(() => (backupJob !== undefined ? getLastNBackupLogsByJobId(backupJob.id) : []))
const backedUpPools = computed(() => {
if (backupJob?.type !== 'metadataBackup' || backupJob.pools === undefined) {
return []
}
return getPoolsByIds(extractIdsFromSimplePattern<FrontXoPool['id']>(backupJob.pools))
})
const backupRepositoryTargets = computed(() =>
backupJob !== undefined
? getBackupRepositoriesByIds(extractIdsFromSimplePattern<FrontXoBackupRepository['id']>(backupJob.remotes))
: []
)
const storageRepositoryTargets = computed(() => {
if (!(backupJob?.type === 'backup' && backupJob.srs)) {
return []
}
return getSrsByIds(extractIdsFromSimplePattern<FrontXoSr['id']>(backupJob.srs))
})
const hasSettings = computed(() => {
if (backupJob === undefined) {
return false
}
const settings =
backupJob.type === 'backup'
? getVmBackupJobSettings(backupJob)
: backupJob.type === 'metadataBackup'
? getMetadataBackupJobSettings(backupJob)
: getMirrorBackupJobSettings(backupJob)
return Object.values(settings).some(value => value !== undefined)
})
</script>

View File

@@ -1,63 +0,0 @@
<template>
<UiPanelCard class="backup-job-infos-card">
<UiPanelCardTitle
:id="backupJob.id"
size="medium"
:to="{ name: `/backup/[id]/runs`, params: { id: backupJob.id } }"
:label="backupJob.name"
icon="object:backup-job"
/>
<div class="content">
<VtsCardRowKeyValue v-for="(mode, index) in backupJobModes" :key="mode">
<template #key>
<template v-if="index === 0">{{ t('mode', backupJobModes.length) }}</template>
</template>
<template #value>{{ mode }}</template>
<template #addons>
<VtsCopyButton :value="mode" />
<UiButtonIcon
v-if="index === 0 && backupJobModes.length > 1"
v-tooltip="t('coming-soon!')"
disabled
icon="fa:ellipsis"
size="small"
accent="brand"
/>
</template>
</VtsCardRowKeyValue>
</div>
</UiPanelCard>
</template>
<script lang="ts" setup>
import { useXoBackupUtils } from '@/modules/backup/composables/xo-backup-utils.composable.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
import VtsCopyButton from '@core/components/copy-button/VtsCopyButton.vue'
import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
import { vTooltip } from '@core/directives/tooltip.directive.ts'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { backupJob } = defineProps<{
backupJob: FrontAnyXoBackupJob
}>()
const { t } = useI18n()
const { getModeLabels } = useXoBackupUtils()
const backupJobModes = computed(() => getModeLabels(backupJob).filter(mode => mode))
</script>
<style scoped lang="postcss">
.backup-job-infos-card {
.content {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
}
</style>

View File

@@ -1,142 +0,0 @@
<template>
<UiPanelCard class="backup-job-settings-card">
<UiPanelCardTitle size="medium" :label="t('settings')" />
<div class="content">
<!-- Known settings -->
<VtsCardRowKeyValue v-if="proxy !== undefined">
<template #key>{{ t('proxy') }}</template>
<template #value>{{ proxy.name }}</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="settings.reportWhen !== undefined">
<template #key>{{ t('report-when') }}</template>
<template #value>{{ reportWhenValueTranslation }}</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="settings.backupReportTpl !== undefined">
<template #key>{{ t('shorter-backup-reports') }}</template>
<template #value>
<VtsStatus :status="settings.backupReportTpl === 'compactMjml'" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="settings.hideSuccessfulItems !== undefined">
<template #key>{{ t('hide-successful-items') }}</template>
<template #value>
<VtsStatus :status="!!settings.hideSuccessfulItems" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="settings.concurrency !== undefined">
<template #key>{{ t('concurrency') }}</template>
<template #value>{{ settings.concurrency }}</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="nbdConcurrency !== undefined">
<template #key>{{ t('nbd-concurrency') }}</template>
<template #value>{{ nbdConcurrency }}</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="cbtDestroySnapshotData !== undefined">
<template #key>{{ t('cbt-destroy-snapshot-data') }}</template>
<template #value>
<VtsStatus :status="cbtDestroySnapshotData" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="maxExportRate !== undefined">
<template #key>{{ t('speed-limit') }}</template>
<template #value>{{ `${maxExportRate.value} ${maxExportRate.prefix}` }}</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="settings.checkpointSnapshot !== undefined">
<template #key>{{ t('checkpoint-snapshot') }}</template>
<template #value>
<VtsStatus :status="!!settings.checkpointSnapshot" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="settings.nRetriesVmBackupFailures !== undefined">
<template #key>{{ t('vm-backup-failure-number-of-retries') }}</template>
<template #value>{{ settings.nRetriesVmBackupFailures }}</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="compression !== undefined">
<template #key>{{ t('compression') }}</template>
<template #value>{{ compression }}</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="settings.offlineBackup !== undefined">
<template #key>{{ t('offline-backup') }}</template>
<template #value>
<VtsStatus :status="!!settings.offlineBackup" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="settings.offlineSnapshot !== undefined">
<template #key>{{ t('offline-snapshot') }}</template>
<template #value>
<VtsStatus :status="!!settings.offlineSnapshot" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="settings.mergeBackupsSynchronously !== undefined">
<template #key>{{ t('merge-backups-synchronously') }}</template>
<template #value>
<VtsStatus :status="!!settings.mergeBackupsSynchronously" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="settings.timezone">
<template #key>{{ t('timezone') }}</template>
<template #value>{{ settings.timezone }}</template>
</VtsCardRowKeyValue>
<template v-if="settings.reportRecipients && settings.reportRecipients.length > 0">
<VtsCardRowKeyValue v-for="(recipient, index) in settings.reportRecipients" :key="index">
<template #key>
<template v-if="index === 0">{{ t('report-recipients') }}</template>
</template>
<!-- TODO: use UiCollapsibleList when VtsCardRowKeyValue is updated -->
<template #value>{{ recipient }}</template>
</VtsCardRowKeyValue>
</template>
<VtsCardRowKeyValue v-if="formattedTimeout !== undefined">
<template #key>{{ t('timeout') }}</template>
<template #value>{{ formattedTimeout }}</template>
</VtsCardRowKeyValue>
<!-- Settings rest -->
<UiLogEntryViewer
v-if="settings.other && Object.keys(settings.other).length > 0"
:content="settings.other"
:label="t('other-settings')"
size="small"
accent="info"
/>
</div>
</UiPanelCard>
</template>
<script lang="ts" setup>
import { useXoBackupJobSettingsUtils } from '@/modules/backup/composables/backup-job-settings/xo-backup-job-settings.composable.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import UiLogEntryViewer from '@core/components/ui/log-entry-viewer/UiLogEntryViewer.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
import { useI18n } from 'vue-i18n'
const { backupJob } = defineProps<{
backupJob: FrontAnyXoBackupJob
}>()
const { t } = useI18n()
const {
cbtDestroySnapshotData,
compression,
formattedTimeout,
maxExportRate,
nbdConcurrency,
proxy,
reportWhenValueTranslation,
settings,
} = useXoBackupJobSettingsUtils(() => backupJob)
</script>
<style scoped lang="postcss">
.backup-job-settings-card {
.content {
display: flex;
flex-direction: column;
gap: 1.6rem;
}
}
</style>

View File

@@ -1,117 +0,0 @@
<template>
<div class="backup-logs-table">
<UiTitle>
{{ t('runs') }}
</UiTitle>
<div class="container">
<div class="table-actions">
<UiQuerySearchBar @search="value => (searchQuery = value)" />
</div>
<VtsTable :state :pagination-bindings sticky="right">
<thead>
<tr>
<HeadCells />
</tr>
</thead>
<tbody>
<VtsRow v-for="log of paginatedBackupLogs" :key="log.id" :selected="log.id === selectedBackupLogId">
<BodyCells :item="log" />
</VtsRow>
</tbody>
</VtsTable>
</div>
</div>
</template>
<script setup lang="ts">
import { useXoBackupLogsUtils } from '@/modules/backup/composables/xo-backup-log-utils.composable.ts'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import VtsRow from '@core/components/table/VtsRow.vue'
import VtsTable from '@core/components/table/VtsTable.vue'
import UiQuerySearchBar from '@core/components/ui/query-search-bar/UiQuerySearchBar.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { usePagination } from '@core/composables/pagination.composable.ts'
import { useRouteQuery } from '@core/composables/route-query.composable.ts'
import { useTableState } from '@core/composables/table-state.composable.ts'
import { useBackupLogsColumns } from '@core/tables/column-sets/backup-log-columns.ts'
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
const {
backupLogs: rawBackupLogs,
error,
busy,
} = defineProps<{
backupLogs: FrontXoBackupLog[]
error?: boolean
busy?: boolean
}>()
const { t } = useI18n()
const selectedBackupLogId = useRouteQuery('id')
const searchQuery = ref('')
const filteredBackupLogs = computed(() => {
const searchTerm = searchQuery.value.trim().toLocaleLowerCase()
if (!searchTerm) {
return rawBackupLogs
}
return rawBackupLogs.filter(backupLog =>
Object.values(backupLog).some(value => String(value).toLocaleLowerCase().includes(searchTerm))
)
})
const state = useTableState({
busy: () => busy,
error: () => error,
empty: () =>
rawBackupLogs.length === 0
? t('no-backup-run-available')
: filteredBackupLogs.value.length === 0
? { type: 'no-result' }
: false,
})
const { getBackupLogDuration, getTransferSize } = useXoBackupLogsUtils()
const { pageRecords: paginatedBackupLogs, paginationBindings } = usePagination('backups-logs', filteredBackupLogs)
const { HeadCells, BodyCells } = useBackupLogsColumns({
body: (log: FrontXoBackupLog) => {
const transferSize = computed(() => getTransferSize(log))
const duration = computed(() => getBackupLogDuration(log))
return {
startDate: r => r(log.start),
endDate: r => r(log.end),
duration: r => r(duration.value),
status: r => r(log.status),
transferSize: r => r(transferSize.value?.value, transferSize.value?.prefix),
selectItem: r => r(() => (selectedBackupLogId.value = log.id)),
}
},
})
</script>
<style scoped lang="postcss">
.backup-logs-table,
.table-actions,
.container {
display: flex;
flex-direction: column;
}
.backup-logs-table {
gap: 2.4rem;
.container,
.table-actions {
gap: 0.8rem;
}
}
</style>

View File

@@ -1,71 +0,0 @@
<template>
<VtsSidePanel :has-selection="!!backupLog" @close="emit('close')">
<template v-if="backupLog">
<BackupLogInfosCard :backup-log />
<BackupJobSchedulesCard :backup-job-schedules />
<template v-if="backupLogResults !== undefined">
<template v-for="[type, data] of Object.entries(backupLogResults)" :key="type">
<BackupLogResultsCard v-if="data.length > 0" :results="data" :type="type as BackupLogResultType" />
</template>
</template>
<BackupJobBackedUpVmsCard v-if="backupJob?.type === 'backup' && backupJob.vms" :backed-up-vms="backupJob.vms" />
<BackupJobBackedUpPoolsCard v-if="backedUpPools.length > 0" :backed-up-pools />
</template>
</VtsSidePanel>
</template>
<script setup lang="ts">
import BackupLogInfosCard from '@/modules/backup/components/logs/panel/cards/BackupLogInfosCard.vue'
import BackupLogResultsCard, {
type BackupLogResultType,
} from '@/modules/backup/components/logs/panel/cards/BackupLogResultsCard.vue'
import BackupJobBackedUpPoolsCard from '@/modules/backup/components/panel/cards/BackupJobBackedUpPoolsCard.vue'
import BackupJobBackedUpVmsCard from '@/modules/backup/components/panel/cards/BackupJobBackedUpVmsCard.vue'
import BackupJobSchedulesCard from '@/modules/backup/components/panel/cards/BackupJobSchedulesCard.vue'
import { useXoBackupJobCollection } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import { useXoPoolCollection, type FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import { useXoScheduleCollection } from '@/modules/schedule/remote-resources/use-xo-schedule-collection.ts'
import { getTasksResultsRecursively } from '@/modules/task/utils/xo-task.util.ts'
import VtsSidePanel from '@core/components/panel/VtsSidePanel.vue'
import { extractIdsFromSimplePattern } from '@xen-orchestra/backups/extractIdsFromSimplePattern.mjs'
import { computed } from 'vue'
const { backupLog } = defineProps<{
backupLog?: FrontXoBackupLog
}>()
const emit = defineEmits<{
close: []
}>()
const { useGetBackupJobById } = useXoBackupJobCollection()
const { schedulesByJobId } = useXoScheduleCollection()
const { getPoolsByIds } = useXoPoolCollection()
const backupJob = useGetBackupJobById(() => backupLog?.jobId)
const backupJobSchedules = computed(() =>
backupJob.value ? (schedulesByJobId.value.get(backupJob.value.id) ?? []) : []
)
const backedUpPools = computed(() => {
if (backupJob.value?.type !== 'metadataBackup' || backupJob.value.pools === undefined) {
return []
}
return getPoolsByIds(extractIdsFromSimplePattern<FrontXoPool['id']>(backupJob.value.pools))
})
const backupLogResults = computed(() => {
if (backupLog?.tasks === undefined) {
return undefined
}
return {
info: backupLog.tasks.flatMap(task => getTasksResultsRecursively(task, 'info')),
warning: backupLog.tasks.flatMap(task => getTasksResultsRecursively(task, 'warning')),
error: backupLog.tasks.flatMap(task => getTasksResultsRecursively(task, 'failure')),
}
})
</script>

View File

@@ -1,88 +0,0 @@
<template>
<UiPanelCard class="backup-log-infos-card">
<UiPanelCardTitle :id="backupLog.id" size="medium" :label="backupLog.id" icon="object:backup-run" />
<div class="content">
<VtsCardRowKeyValue>
<template #key>{{ t('start-date') }}</template>
<template #value>{{ formattedStartDate }}</template>
<template v-if="formattedStartDate !== undefined" #addons>
<VtsCopyButton :value="formattedStartDate" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue>
<template #key>{{ t('end-date') }}</template>
<template #value>{{ formattedEndDate }}</template>
<template v-if="formattedEndDate !== undefined" #addons>
<VtsCopyButton :value="formattedEndDate" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue>
<template #key>{{ t('duration') }}</template>
<template #value>{{ duration }}</template>
<template v-if="duration !== undefined" #addons>
<VtsCopyButton :value="duration" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue>
<template #key>{{ t('status') }}</template>
<template #value>
<VtsStatus :status="backupLog.status" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue>
<template #key>{{ t('transfer-size') }}</template>
<template #value>{{ transferSize }}</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue v-if="backupLog.tasks !== undefined && backupLog.tasks.length > 0">
<template #key>{{ t('task') }}</template>
<template #value>
<!-- TODO: add link to task when Tasks page will be available -->
<UiLink size="small">{{ backupLog.tasks[0].id }}</UiLink>
</template>
</VtsCardRowKeyValue>
</div>
</UiPanelCard>
</template>
<script lang="ts" setup>
import { useXoBackupLogsUtils } from '@/modules/backup/composables/xo-backup-log-utils.composable.ts'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
import VtsCopyButton from '@core/components/copy-button/VtsCopyButton.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
import { formatSize } from '@core/utils/size.util.ts'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { backupLog } = defineProps<{
backupLog: FrontXoBackupLog
}>()
const { t } = useI18n()
const { getBackupLogDate, getBackupLogDuration, findTransferTaskSize } = useXoBackupLogsUtils()
const formattedStartDate = computed(() => getBackupLogDate(backupLog.start))
const formattedEndDate = computed(() => getBackupLogDate(backupLog.end))
const duration = computed(() => getBackupLogDuration(backupLog))
const transferSize = computed(() => {
const size = findTransferTaskSize(backupLog.tasks)
return size !== undefined ? formatSize(size, 2) : undefined
})
</script>
<style scoped lang="postcss">
.backup-log-infos-card {
.content {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
}
</style>

View File

@@ -1,90 +0,0 @@
<template>
<UiPanelCard class="backup-log-results-card">
<UiPanelCardTitle
size="medium"
:label="cardMetadata.title"
:counter="{ value: results.length, accent: cardMetadata.accent }"
/>
<div class="content">
<template v-for="(result, index) in results" :key="index">
<VtsCardRowKeyValue>
<template #key>{{ t('message') }}</template>
<template #value>{{ result.message }}</template>
<template #addons>
<VtsCopyButton :value="result.message" />
</template>
</VtsCardRowKeyValue>
<UiLogEntryViewer
v-if="result.stack"
:label="cardMetadata.logEntryTitle"
size="small"
:accent="cardMetadata.accent"
:content="JSON.stringify(result.stack, null, 2)"
class="stack"
/>
<VtsDivider v-if="results.length > 1 && index < results.length - 1" class="divider" type="stretch" />
</template>
</div>
</UiPanelCard>
</template>
<script lang="ts" setup>
import type { BackupLogResult } from '@/modules/task/utils/xo-task.util.ts'
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
import VtsCopyButton from '@core/components/copy-button/VtsCopyButton.vue'
import VtsDivider from '@core/components/divider/VtsDivider.vue'
import UiLogEntryViewer from '@core/components/ui/log-entry-viewer/UiLogEntryViewer.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
import { useMapper } from '@core/packages/mapper'
import { useI18n } from 'vue-i18n'
export type BackupLogResultType = 'info' | 'warning' | 'error'
const { type } = defineProps<{
type: 'info' | 'warning' | 'error'
results: BackupLogResult[]
}>()
const { t } = useI18n()
const cardMetadata = useMapper(
() => type,
{
info: {
title: t('infos'),
logEntryTitle: t('api-info-details'),
accent: 'info',
},
warning: {
title: t('warnings'),
logEntryTitle: t('api-warning-details'),
accent: 'warning',
},
error: {
title: t('errors'),
logEntryTitle: t('api-error-details'),
accent: 'danger',
},
},
'info'
)
</script>
<style scoped lang="postcss">
.backup-log-results-card {
.content {
display: flex;
flex-direction: column;
gap: 0.4rem;
.stack {
margin-block-start: 1.6rem;
}
.divider {
margin-block: 1.6rem;
}
}
}
</style>

View File

@@ -1,23 +0,0 @@
<template>
<VtsCardRowKeyValue>
<template #key>
{{ label }}
</template>
<template #value>
<UiLink size="small" icon="object:pool" :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }">
{{ pool.name_label }}
</UiLink>
</template>
</VtsCardRowKeyValue>
</template>
<script lang="ts" setup>
import type { FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
defineProps<{
pool: FrontXoPool
label?: string
}>()
</script>

View File

@@ -1,23 +0,0 @@
<template>
<VtsCardRowKeyValue>
<template #key>
{{ label }}
</template>
<template #value>
<UiTagsList v-if="tags.length > 0">
<VtsTag v-for="tag in tags" :key="tag" :value="tag" />
</UiTagsList>
</template>
</VtsCardRowKeyValue>
</template>
<script lang="ts" setup>
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
import VtsTag from '@core/components/tag/VtsTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'
defineProps<{
tags: string[]
label: string
}>()
</script>

View File

@@ -1,22 +0,0 @@
<template>
<li>
<UiLink size="small" :icon :href>
{{ br.name }}
</UiLink>
</li>
</template>
<script setup lang="ts">
import type { FrontXoBackupRepository } from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import UiLink from '@core/components/ui/link/UiLink.vue'
import { computed } from 'vue'
const { br } = defineProps<{
br: FrontXoBackupRepository
}>()
const { buildXo5Route } = useXoRoutes()
const href = computed(() => buildXo5Route('/settings/remotes'))
const icon = computed(() => (br.enabled ? 'object:br:connected' : 'object:br:disconnected'))
</script>

View File

@@ -1,41 +0,0 @@
<template>
<div class="content">
<UiPanelCardTitle size="small" :label class="subtitle" />
<UiCollapsibleList tag="ul" :total-items="targets.length">
<template v-for="target in targets" :key="target.id">
<BackupJobTargetSrItem v-if="isSr(target)" :sr="target" />
<BackupJobTargetBrItem v-else :br="target" />
</template>
</UiCollapsibleList>
</div>
</template>
<script setup lang="ts">
import BackupJobTargetBrItem from '@/modules/backup/components/panel/card-items/BackupJobTargetsBrItem.vue'
import BackupJobTargetSrItem from '@/modules/backup/components/panel/card-items/BackupJobTargetsSrItem.vue'
import type { FrontXoBackupRepository } from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import type { FrontXoSr } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import UiCollapsibleList from '@core/components/ui/collapsible-list/UiCollapsibleList.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
const { targets } = defineProps<{
targets: FrontXoSr[] | FrontXoBackupRepository[]
label: string
}>()
function isSr(target: FrontXoSr | FrontXoBackupRepository): target is FrontXoSr {
return 'type' in target && target.type === 'SR'
}
</script>
<style scoped lang="postcss">
.content {
display: flex;
flex-direction: column;
gap: 0.4rem;
.subtitle {
margin-bottom: 1.6rem;
}
}
</style>

View File

@@ -1,24 +0,0 @@
<template>
<li>
<UiLink size="small" :icon="srStatusIcon" :href>
{{ sr.name_label }}
</UiLink>
</li>
</template>
<script setup lang="ts">
import { useXoSrUtils } from '@/modules/storage-repository/composables/xo-sr-utils.composable.ts'
import type { FrontXoSr } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import UiLink from '@core/components/ui/link/UiLink.vue'
import { computed } from 'vue'
const { sr } = defineProps<{
sr: FrontXoSr
}>()
const { buildXo5Route } = useXoRoutes()
const href = computed(() => buildXo5Route(`/srs/${sr.id}/general`))
const { srStatusIcon } = useXoSrUtils(() => sr)
</script>

View File

@@ -1,93 +0,0 @@
<template>
<VtsCardRowKeyValue>
<template #key>
{{ t('run') }}
</template>
<template #value>
<UiLink size="small" icon="object:backup-run" :to="backupRunRoute">
{{ backupRun.id }}
</UiLink>
</template>
<template #addons>
<VtsCopyButton :value="backupRun.id" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue>
<template #key>
{{ t('date') }}
</template>
<template #value>
{{ formattedRunDate }}
</template>
<template #addons>
<VtsCopyButton :value="formattedRunDate" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue>
<template #key>
{{ t('status') }}
</template>
<template #value>
<VtsStatus :status="backupRun.status" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue>
<template #key>
{{ t('schedule') }}
</template>
<template #value>
<UiLink size="small" icon="object:backup-schedule" :href>
{{ scheduleName || backupRun.jobId }}
</UiLink>
</template>
</VtsCardRowKeyValue>
<UiLogEntryViewer
v-if="logContent"
:content="logContent"
:label="t('api-error-details')"
size="small"
:accent="backupRun.status === 'skipped' ? 'warning' : 'danger'"
/>
</template>
<script lang="ts" setup>
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import { getBackupLogRunRoute } from '@/modules/backup/utils/xo-backup-log.util.ts'
import { useXoScheduleCollection } from '@/modules/schedule/remote-resources/use-xo-schedule-collection.ts'
import { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
import VtsCopyButton from '@core/components/copy-button/VtsCopyButton.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiLogEntryViewer from '@core/components/ui/log-entry-viewer/UiLogEntryViewer.vue'
import { formatDateTime } from '@core/utils/time.util.ts'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { backupRun } = defineProps<{
backupRun: FrontXoBackupLog
}>()
const { t } = useI18n()
const { buildXo5Route } = useXoRoutes()
const href = computed(() => buildXo5Route(`/backup/${backupRun.jobId}/edit`))
const { schedules } = useXoScheduleCollection()
const runDate = computed(() => backupRun.end ?? backupRun.start)
const formattedRunDate = computed(() => formatDateTime(runDate.value))
const logContent = computed(() => {
if (backupRun.status !== 'success' && backupRun.status !== 'pending' && backupRun.tasks && backupRun.tasks[0]) {
return backupRun.tasks[0].result?.stack
}
return undefined
})
const scheduleName = computed(() => schedules.value.find(schedule => schedule.jobId === backupRun.jobId)?.name)
const backupRunRoute = computed(() => getBackupLogRunRoute(backupRun))
</script>

View File

@@ -1,29 +0,0 @@
<template>
<UiPanelCard>
<UiPanelCardTitle size="medium" :label="t('backed-up-pools')" :counter="backedUpPools.length" />
<div>
<UiCollapsibleList tag="ul" :total-items="backedUpPools.length">
<li v-for="pool in backedUpPools" :key="pool.id">
<UiLink size="small" icon="object:pool" :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }">
{{ pool.name_label }}
</UiLink>
</li>
</UiCollapsibleList>
</div>
</UiPanelCard>
</template>
<script lang="ts" setup>
import type { FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import UiCollapsibleList from '@core/components/ui/collapsible-list/UiCollapsibleList.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
import { useI18n } from 'vue-i18n'
const { backedUpPools } = defineProps<{
backedUpPools: FrontXoPool[]
}>()
const { t } = useI18n()
</script>

View File

@@ -1,114 +0,0 @@
<template>
<UiPanelCard class="backup-job-backed-up-vms-card">
<UiPanelCardTitle size="medium" :label="t('backed-up-vms')" :counter="backedUpVmsCount" />
<div>
<!-- Smart mode state -->
<VtsCardRowKeyValue>
<template #key>
{{ t('smart-mode') }}
</template>
<template #value>
<VtsStatus :status="isSmartModeEnabled" />
</template>
</VtsCardRowKeyValue>
<template v-if="isSmartModeEnabled">
<VtsDivider class="divider" type="stretch" />
<div class="content">
<!-- Power state -->
<VtsCardRowKeyValue v-if="smartModePowerState !== undefined">
<template #key>
{{ t('power-state') }}
</template>
<template #value>
<span class="smart-mode-power-state-value">
<VtsIcon size="small" :name="`object:vm:${toLower(smartModePowerState)}`" />
{{ smartModePowerState }}
</span>
</template>
</VtsCardRowKeyValue>
<!-- Pools -->
<template v-if="smartModePools !== undefined">
<BackupJobSmartModePools
v-for="(pool, index) in smartModePools.included"
:key="pool.id"
:pool
:label="index === 0 ? t('resident-on') : undefined"
/>
<BackupJobSmartModePools
v-for="(pool, index) in smartModePools.excluded"
:key="pool.id"
:pool
:label="index === 0 ? t('not-resident-on') : undefined"
/>
</template>
<!-- Tags -->
<template v-if="smartModeTags !== undefined">
<BackupJobSmartModeTags :tags="smartModeTags.included ?? []" :label="t('vms-tags')" />
<BackupJobSmartModeTags :tags="smartModeTags.excluded ?? []" :label="t('excluded-vms-tags')" />
</template>
</div>
</template>
<template v-if="backedUpVmsCount > 0">
<VtsDivider class="divider" type="stretch" />
<!-- Backed up VMs list -->
<UiCollapsibleList tag="ul" :total-items="backedUpVmsCount">
<li v-for="vm in backedUpVms" :key="vm.id">
<UiLink
size="small"
:icon="`object:vm:${toLower(vm.power_state)}`"
:to="{ name: '/vm/[id]/dashboard', params: { id: vm.id } }"
>
{{ vm.name_label }}
</UiLink>
</li>
</UiCollapsibleList>
</template>
</div>
</UiPanelCard>
</template>
<script lang="ts" setup>
import BackupJobSmartModePools from '@/modules/backup/components/panel/card-items/BackupJobSmartModePools.vue'
import BackupJobSmartModeTags from '@/modules/backup/components/panel/card-items/BackupJobSmartModeTags.vue'
import { useXoBackedUpVmsUtils } from '@/modules/backup/composables/xo-backed-up-vms-utils.composable.ts'
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
import VtsDivider from '@core/components/divider/VtsDivider.vue'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import UiCollapsibleList from '@core/components/ui/collapsible-list/UiCollapsibleList.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
import { toLower } from 'lodash-es'
import { useI18n } from 'vue-i18n'
const { backedUpVms: rawBackedUpVms } = defineProps<{
backedUpVms: FrontXoVmBackupJob['vms']
}>()
const { t } = useI18n()
const { backedUpVms, backedUpVmsCount, smartModePools, smartModePowerState, smartModeTags, isSmartModeEnabled } =
useXoBackedUpVmsUtils(() => rawBackedUpVms)
</script>
<style scoped lang="postcss">
.backup-job-backed-up-vms-card {
.divider {
margin-block: 1.6rem;
}
.content {
display: flex;
flex-direction: column;
gap: 1.6rem;
.smart-mode-power-state-value {
display: flex;
align-items: center;
gap: 0.8rem;
}
}
}
</style>

View File

@@ -1,41 +0,0 @@
<template>
<UiPanelCard class="backup-job-logs-card">
<UiPanelCardTitle size="medium" :label="t('last-n-runs', { n: backupLogs.length })" />
<div class="content">
<template v-for="(backupRun, index) in backupLogs" :key="backupRun.id">
<VtsDivider v-if="index > 0" class="divider" type="stretch" />
<UiPanelCardTitle size="small" :label="t('last-run-number', { n: index + 1 })" />
<BackupRunItem :backup-run />
</template>
</div>
</UiPanelCard>
</template>
<script lang="ts" setup>
import BackupRunItem from '@/modules/backup/components/panel/card-items/BackupRunItem.vue'
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import VtsDivider from '@core/components/divider/VtsDivider.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
import { useI18n } from 'vue-i18n'
const { backupLogs } = defineProps<{
backupLogs: FrontXoBackupLog[]
}>()
const { t } = useI18n()
</script>
<style scoped lang="postcss">
.backup-job-logs-card {
.content {
display: flex;
flex-direction: column;
gap: 0.6rem;
.divider {
margin-block: 1.6rem;
}
}
}
</style>

View File

@@ -1,93 +0,0 @@
<template>
<UiPanelCard class="backup-job-schedules-card">
<UiPanelCardTitle size="medium" :label="t('schedules')" :counter="backupJobSchedules.length" />
<div class="content">
<template v-for="(schedule, index) in backupJobSchedules" :key="schedule.id">
<VtsDivider v-if="index > 0" class="divider" type="stretch" />
<VtsCardRowKeyValue>
<template #key>
{{ t('name') }}
</template>
<template #value>
<UiLink
v-if="schedule.name"
size="small"
icon="object:backup-schedule"
:href="buildXo5Route(`/backup/${schedule.jobId}/edit`)"
>
{{ schedule.name }}
</UiLink>
</template>
<template v-if="schedule.name" #addons>
<VtsCopyButton :value="schedule.name" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue>
<template #key>
{{ t('id') }}
</template>
<template #value>
{{ schedule.id }}
</template>
<template #addons>
<VtsCopyButton :value="schedule.id" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue>
<template #key>
{{ t('status') }}
</template>
<template #value>
<VtsStatus :status="schedule.enabled" />
</template>
</VtsCardRowKeyValue>
<VtsCardRowKeyValue>
<template #key>
{{ t('cron-pattern') }}
</template>
<template #value>
{{ schedule.cron }}
</template>
<template #addons>
<VtsCopyButton :value="schedule.cron" />
</template>
</VtsCardRowKeyValue>
</template>
</div>
</UiPanelCard>
</template>
<script lang="ts" setup>
import type { FrontXoSchedule } from '@/modules/schedule/remote-resources/use-xo-schedule-collection.ts'
import { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
import VtsCopyButton from '@core/components/copy-button/VtsCopyButton.vue'
import VtsDivider from '@core/components/divider/VtsDivider.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
import { useI18n } from 'vue-i18n'
const { backupJobSchedules } = defineProps<{
backupJobSchedules: FrontXoSchedule[]
}>()
const { t } = useI18n()
const { buildXo5Route } = useXoRoutes()
</script>
<style scoped lang="postcss">
.backup-job-schedules-card {
.content {
display: flex;
flex-direction: column;
gap: 0.6rem;
.divider {
margin-block: 1.6rem;
}
}
}
</style>

View File

@@ -1,36 +0,0 @@
<template>
<UiPanelCard v-if="sourceBackupRepository !== undefined">
<UiPanelCardTitle size="medium" :label="t('source-backup-repository')" />
<UiLink size="small" :icon="sourceBackupRepositoryIcon" :href>
{{ sourceBackupRepository.name }}
</UiLink>
</UiPanelCard>
</template>
<script lang="ts" setup>
import type { FrontXoMirrorBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import { useXoBackupRepositoryCollection } from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { mirrorBackupJob } = defineProps<{
mirrorBackupJob: FrontXoMirrorBackupJob
}>()
const { t } = useI18n()
const { buildXo5Route } = useXoRoutes()
const href = computed(() => buildXo5Route('/settings/remotes'))
const { useGetBackupRepositoryById } = useXoBackupRepositoryCollection()
const sourceBackupRepository = useGetBackupRepositoryById(() => mirrorBackupJob.sourceRemote)
const sourceBackupRepositoryIcon = computed(() =>
sourceBackupRepository.value?.enabled ? 'object:br:connected' : 'object:br:disconnected'
)
</script>

View File

@@ -1,36 +0,0 @@
<template>
<UiPanelCard>
<UiPanelCardTitle size="medium" :label="t('backup-targets')" :counter="backupTargetsCount" />
<BackupJobTargetsSection
v-if="backupRepositoryTargets.length > 0"
:targets="backupRepositoryTargets"
:label="t('backup-repositories')"
/>
<VtsDivider v-if="storageRepositoryTargets.length > 0 && backupRepositoryTargets.length > 0" type="stretch" />
<BackupJobTargetsSection
v-if="storageRepositoryTargets.length > 0"
:targets="storageRepositoryTargets"
:label="t('storage-repositories')"
/>
</UiPanelCard>
</template>
<script lang="ts" setup>
import BackupJobTargetsSection from '@/modules/backup/components/panel/card-items/BackupJobTargetsSection.vue'
import type { FrontXoBackupRepository } from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import type { FrontXoSr } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import VtsDivider from '@core/components/divider/VtsDivider.vue'
import UiPanelCard from '@core/components/ui/panel-card/UiPanelCard.vue'
import UiPanelCardTitle from '@core/components/ui/panel-card-title/UiPanelCardTitle.vue'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { storageRepositoryTargets, backupRepositoryTargets } = defineProps<{
storageRepositoryTargets: FrontXoSr[]
backupRepositoryTargets: FrontXoBackupRepository[]
}>()
const { t } = useI18n()
const backupTargetsCount = computed(() => backupRepositoryTargets.length + storageRepositoryTargets.length)
</script>

View File

@@ -1,120 +0,0 @@
<template>
<div class="backup-repositories-targets-table">
<UiTitle>
{{ t('backup-repositories') }}
</UiTitle>
<div class="container">
<div class="table-actions">
<UiQuerySearchBar @search="value => (searchQuery = value)" />
</div>
<VtsTable :state :pagination-bindings>
<thead>
<tr>
<HeadCells />
</tr>
</thead>
<tbody>
<VtsRow v-for="repository of paginatedRepositories" :key="repository.id">
<BodyCells :item="repository" />
</VtsRow>
</tbody>
</VtsTable>
</div>
</div>
</template>
<script setup lang="ts">
import { useXoBackupRepositoryParsedUrl } from '@/modules/backup-repository/composables/use-xo-backup-repository-parsed-url.composable.ts'
import type { FrontXoBackupRepository } from '@/modules/backup-repository/remote-resources/use-xo-backup-repository-collection.ts'
import { getBackupRepositoryIcon } from '@/modules/backup-repository/utils/xo-backup-repository.util.ts'
import { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import VtsRow from '@core/components/table/VtsRow.vue'
import VtsTable from '@core/components/table/VtsTable.vue'
import UiQuerySearchBar from '@core/components/ui/query-search-bar/UiQuerySearchBar.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { usePagination } from '@core/composables/pagination.composable.ts'
import { useTableState } from '@core/composables/table-state.composable.ts'
import { defineColumns } from '@core/packages/table/define-columns.ts'
import { useLinkColumn } from '@core/tables/column-definitions/link-column.ts'
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
const { backupRepositories, busy, error } = defineProps<{
backupRepositories: FrontXoBackupRepository[]
busy?: boolean
error?: boolean
}>()
const { t } = useI18n()
const searchQuery = ref('')
const filteredRepositories = computed(() => {
const searchTerm = searchQuery.value.trim().toLocaleLowerCase()
if (!searchTerm) {
return backupRepositories
}
return backupRepositories.filter(backupRepository =>
Object.values(backupRepository).some(value => String(value).toLocaleLowerCase().includes(searchTerm))
)
})
const state = useTableState({
busy: () => busy,
error: () => error,
empty: () =>
backupRepositories.length === 0
? t('no-backup-repository-detected')
: filteredRepositories.value.length === 0
? { type: 'no-result' }
: false,
})
const { pageRecords: paginatedRepositories, paginationBindings } = usePagination(
'backup-repositories-targets',
filteredRepositories
)
const useColumns = defineColumns(() => {
const { t } = useI18n()
return {
backupRepository: useLinkColumn({ headerLabel: () => t('backup-repository') }),
}
})
const { HeadCells, BodyCells } = useColumns({
body: (br: FrontXoBackupRepository) => {
const { buildXo5Route } = useXoRoutes()
const href = computed(() => buildXo5Route('/settings/remotes'))
const parsedBrUrl = useXoBackupRepositoryParsedUrl(() => br)
const statusIcon = computed(() => getBackupRepositoryIcon(br, parsedBrUrl.value?.type))
return {
backupRepository: r => r({ label: br.name, href: href.value, icon: statusIcon.value }),
}
},
})
</script>
<style lang="postcss" scoped>
.backup-repositories-targets-table,
.table-actions,
.container {
display: flex;
flex-direction: column;
}
.backup-repositories-targets-table {
gap: 2.4rem;
.container,
.table-actions {
gap: 0.8rem;
}
}
</style>

View File

@@ -1,127 +0,0 @@
<template>
<div class="storage-repositories-targets-table">
<UiTitle>
{{ t('storage-repositories') }}
</UiTitle>
<div class="container">
<div class="table-actions">
<UiQuerySearchBar @search="value => (searchQuery = value)" />
</div>
<VtsTable :state :pagination-bindings>
<thead>
<tr>
<HeadCells />
</tr>
</thead>
<tbody>
<VtsRow v-for="sr of paginatedSrs" :key="sr.id">
<BodyCells :item="sr" />
</VtsRow>
</tbody>
</VtsTable>
</div>
</div>
</template>
<script setup lang="ts">
import { useXoSrUtils } from '@/modules/storage-repository/composables/xo-sr-utils.composable.ts'
import type { FrontXoSr } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import { useXoRoutes } from '@/shared/remote-resources/use-xo-routes.ts'
import VtsRow from '@core/components/table/VtsRow.vue'
import VtsTable from '@core/components/table/VtsTable.vue'
import UiQuerySearchBar from '@core/components/ui/query-search-bar/UiQuerySearchBar.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { usePagination } from '@core/composables/pagination.composable.ts'
import { useTableState } from '@core/composables/table-state.composable.ts'
import { defineColumns } from '@core/packages/table/define-columns.ts'
import { useLinkColumn } from '@core/tables/column-definitions/link-column.ts'
import { useNumberColumn } from '@core/tables/column-definitions/number-column.ts'
import { formatSizeRaw } from '@core/utils/size.util.ts'
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
const { storageRepositories, busy, error } = defineProps<{
storageRepositories: FrontXoSr[]
busy?: boolean
error?: boolean
}>()
const { t } = useI18n()
const searchQuery = ref('')
const filteredSrs = computed(() => {
const searchTerm = searchQuery.value.trim().toLocaleLowerCase()
if (!searchTerm) {
return storageRepositories
}
return storageRepositories.filter(storageRepository =>
Object.values(storageRepository).some(value => String(value).toLocaleLowerCase().includes(searchTerm))
)
})
const state = useTableState({
busy: () => busy,
error: () => error,
empty: () =>
storageRepositories.length === 0
? t('no-storage-repository-detected')
: filteredSrs.value.length === 0
? { type: 'no-result' }
: false,
})
const { pageRecords: paginatedSrs, paginationBindings } = usePagination('storage-repositories-targets', filteredSrs)
const useColumns = defineColumns(() => {
const { t } = useI18n()
return {
storageRepository: useLinkColumn({ headerLabel: () => t('storage-repository') }),
usedSpace: useNumberColumn({ headerLabel: () => t('used-space') }),
remainingSpace: useNumberColumn({ headerLabel: () => t('remaining-space') }),
totalCapacity: useNumberColumn({ headerLabel: () => t('total-capacity') }),
}
})
const { HeadCells, BodyCells } = useColumns({
body: (sr: FrontXoSr) => {
const { buildXo5Route } = useXoRoutes()
const href = computed(() => buildXo5Route(`/srs/${sr.id}/general`))
const usedSpace = computed(() => formatSizeRaw(sr.physical_usage, 2))
const remainingSpace = computed(() => formatSizeRaw(sr.size - sr.physical_usage, 2))
const totalCapacity = computed(() => formatSizeRaw(sr.size, 2))
const { srStatusIcon } = useXoSrUtils(() => sr)
return {
storageRepository: r => r({ label: sr.name_label, href: href.value, icon: srStatusIcon.value }),
usedSpace: r => r(usedSpace.value.value, usedSpace.value.prefix),
remainingSpace: r => r(remainingSpace.value.value, remainingSpace.value.prefix),
totalCapacity: r => r(totalCapacity.value.value, totalCapacity.value.prefix),
}
},
})
</script>
<style lang="postcss" scoped>
.storage-repositories-targets-table,
.table-actions,
.container {
display: flex;
flex-direction: column;
}
.storage-repositories-targets-table {
gap: 2.4rem;
.container,
.table-actions {
gap: 0.8rem;
}
}
</style>

View File

@@ -1,19 +0,0 @@
import type { FrontXoMetadataBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { XoBackupJobSettings } from '@/modules/backup/types/xo-backup.ts'
export function getMetadataBackupJobSettings(job: FrontXoMetadataBackupJob): XoBackupJobSettings {
if (!job.settings['']) {
return {}
}
const { hideSuccessfulItems, backupReportTpl, reportWhen, reportRecipients, ...other } = job.settings['']
return {
proxy: job.proxy,
hideSuccessfulItems,
backupReportTpl,
reportWhen,
reportRecipients,
other,
}
}

View File

@@ -1,35 +0,0 @@
import type { FrontXoMirrorBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { XoBackupJobSettings } from '@/modules/backup/types/xo-backup.ts'
export function getMirrorBackupJobSettings(job: FrontXoMirrorBackupJob): XoBackupJobSettings {
if (!job.settings['']) {
return {}
}
const {
concurrency,
maxExportRate,
nRetriesVmBackupFailures,
hideSuccessfulItems,
backupReportTpl,
reportWhen,
timeout,
reportRecipients,
mergeBackupsSynchronously,
...other
} = job.settings['']
return {
proxy: job.proxy,
concurrency,
maxExportRate,
nRetriesVmBackupFailures,
hideSuccessfulItems,
backupReportTpl,
reportWhen,
timeout,
reportRecipients,
mergeBackupsSynchronously,
other,
}
}

View File

@@ -1,50 +0,0 @@
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { XoBackupJobSettings } from '@/modules/backup/types/xo-backup.ts'
export function getVmBackupJobSettings(job: FrontXoVmBackupJob): XoBackupJobSettings {
if (!job.settings['']) {
return {}
}
const {
preferNbd,
cbtDestroySnapshotData,
concurrency,
nbdConcurrency,
maxExportRate,
nRetriesVmBackupFailures,
hideSuccessfulItems,
backupReportTpl,
reportWhen,
timeout,
checkpointSnapshot,
offlineBackup,
offlineSnapshot,
mergeBackupsSynchronously,
timezone,
reportRecipients,
...other
} = job.settings['']
return {
compression: job.compression,
proxy: job.proxy,
preferNbd,
cbtDestroySnapshotData,
concurrency,
nbdConcurrency,
maxExportRate,
nRetriesVmBackupFailures,
hideSuccessfulItems,
backupReportTpl,
reportWhen,
timeout,
checkpointSnapshot,
offlineBackup,
offlineSnapshot,
mergeBackupsSynchronously,
timezone,
reportRecipients,
other,
}
}

View File

@@ -1,97 +0,0 @@
import { getMetadataBackupJobSettings } from '@/modules/backup/composables/backup-job-settings/get-metadata-backup-job-settings.ts'
import { getMirrorBackupJobSettings } from '@/modules/backup/composables/backup-job-settings/get-mirror-backup-job-settings.ts'
import { getVmBackupJobSettings } from '@/modules/backup/composables/backup-job-settings/get-vm-backup-job-settings.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { ReportWhen } from '@/modules/backup/types/xo-backup.ts'
import { useXoProxyCollection } from '@/modules/proxy/remote-resources/use-xo-proxy-collection.ts'
import { useMapper } from '@core/packages/mapper'
import { formatSpeedRaw } from '@core/utils/speed.util.ts'
import { formatTimeout } from '@core/utils/time.util.ts'
import { toComputed } from '@core/utils/to-computed.util.ts'
import { reactiveComputed } from '@vueuse/shared'
import type humanFormat from 'human-format'
import type { Info } from 'human-format'
import { computed, type MaybeRefOrGetter } from 'vue'
import { useI18n } from 'vue-i18n'
export function useXoBackupJobSettingsUtils(rawBackupJob: MaybeRefOrGetter<FrontAnyXoBackupJob>) {
const { locale, t } = useI18n()
const { useGetProxyById } = useXoProxyCollection()
const backupJob = toComputed(rawBackupJob)
const settings = reactiveComputed(() => {
switch (backupJob.value.type) {
case 'backup':
return getVmBackupJobSettings(backupJob.value)
case 'metadataBackup':
return getMetadataBackupJobSettings(backupJob.value)
case 'mirrorBackup':
return getMirrorBackupJobSettings(backupJob.value)
default:
throw new Error(`Unsupported backup job type: ${(backupJob.value as FrontAnyXoBackupJob).type}`)
}
})
const nbdConcurrency = computed(() => (settings.preferNbd ? (settings.nbdConcurrency ?? 1) : undefined))
const cbtDestroySnapshotData = computed(() =>
!!settings.preferNbd && settings.cbtDestroySnapshotData !== undefined ? settings.cbtDestroySnapshotData : undefined
)
const maxExportRate = computed<Info<humanFormat.Scale<'B/s' | 'KiB/s' | 'MiB/s' | 'GiB/s' | 'TiB/s'>> | undefined>(
() => (settings.maxExportRate ? formatSpeedRaw(settings.maxExportRate, { maxDecimals: 2 }) : undefined)
)
const formattedTimeout = computed(() =>
settings.timeout !== undefined ? formatTimeout(Number(settings.timeout), locale.value) : undefined
)
const compression = computed(() => {
switch (settings.compression) {
case undefined:
return undefined
case 'native':
return 'GZIP'
default:
return settings.compression
}
})
const proxy = useGetProxyById(() => backupJob.value.proxy)
const reportWhenValueTranslation = useMapper<ReportWhen, string>(
() => settings.reportWhen as ReportWhen | undefined,
{
always: t('report-when:always'),
failure: t('report-when:skipped-and-failure'),
error: t('report-when:error'),
never: t('report-when:never'),
},
'never'
)
const snapshotModeTranslation = computed(() => {
if (settings.checkpointSnapshot === true && settings.offlineSnapshot === false) {
return t('with-memory')
}
if (settings.checkpointSnapshot === false && settings.offlineSnapshot === true) {
return t('offline')
} else {
return t('normal')
}
})
return {
settings,
maxExportRate,
nbdConcurrency,
cbtDestroySnapshotData,
formattedTimeout,
compression,
reportWhenValueTranslation,
snapshotModeTranslation,
proxy,
}
}

View File

@@ -1,93 +0,0 @@
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import { useXoPoolCollection } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import { useXoVmCollection, type FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import { vmContainsNoBakTag } from '@/modules/vm/utils/xo-vm.util.ts'
import { destructSmartPattern } from '@/shared/utils/pattern.util.ts'
import { toComputed } from '@core/utils/to-computed.util.ts'
import type { VM_POWER_STATE } from '@vates/types'
import { extractIdsFromSimplePattern } from '@xen-orchestra/backups/extractIdsFromSimplePattern.mjs'
import * as ValueMatcher from 'value-matcher'
import { computed, type MaybeRefOrGetter } from 'vue'
export type VmsSmartModeEnabled = {
$pool?: Record<string, unknown>
power_state?: VM_POWER_STATE
tags?: Record<string, unknown>
type: 'VM'
}
export function useXoBackedUpVmsUtils(rawBackedUpVmsConfig: MaybeRefOrGetter<FrontXoVmBackupJob['vms']>) {
const { getPoolsByIds } = useXoPoolCollection()
const { getVmsByIds, vms } = useXoVmCollection()
const backedUpVmsConfig = toComputed(rawBackedUpVmsConfig)
function checkSmartModeEnabled(value: FrontXoVmBackupJob['vms'] | undefined): value is VmsSmartModeEnabled {
if (value === undefined || typeof value !== 'object' || value === null) {
return false
}
return !('id' in value)
}
const isSmartModeEnabled = computed(() => checkSmartModeEnabled(backedUpVmsConfig.value))
const backedUpVms = computed(() => {
if (checkSmartModeEnabled(backedUpVmsConfig.value)) {
const predicate = ValueMatcher.createPredicate(backedUpVmsConfig.value)
return vms.value.filter(vm => predicate(vm) && !vmContainsNoBakTag(vm))
}
return getVmsByIds(extractIdsFromSimplePattern<FrontXoVm['id']>(backedUpVmsConfig.value))
})
const backedUpVmsCount = computed(() => backedUpVms.value.length)
const smartModePools = computed(() => {
if (!checkSmartModeEnabled(backedUpVmsConfig.value) || backedUpVmsConfig.value.$pool === undefined) {
return undefined
}
const poolIds = destructSmartPattern(backedUpVmsConfig.value.$pool)
if (!poolIds) {
return undefined
}
return {
included: getPoolsByIds(poolIds.values),
excluded: getPoolsByIds(poolIds.notValues),
}
})
const smartModeTags = computed(() => {
if (!checkSmartModeEnabled(backedUpVmsConfig.value) || backedUpVmsConfig.value.tags === undefined) {
return undefined
}
const tags = destructSmartPattern(backedUpVmsConfig.value.tags)
return {
included: tags.values?.flat(),
excluded: [...tags.notValues?.flat(), 'xo:no-bak'],
}
})
const smartModePowerState = computed(() => {
if (!checkSmartModeEnabled(backedUpVmsConfig.value) || backedUpVmsConfig.value.power_state === undefined) {
return undefined
}
return backedUpVmsConfig.value.power_state
})
return {
backedUpVms,
backedUpVmsCount,
isSmartModeEnabled,
smartModePools,
smartModePowerState,
smartModeTags,
}
}

View File

@@ -1,37 +0,0 @@
import type { FrontAnyXoBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import {
useXoBackupLogCollection,
type FrontXoBackupLog,
} from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import { useXoScheduleCollection } from '@/modules/schedule/remote-resources/use-xo-schedule-collection.ts'
import { formatDateTime } from '@core/utils/time.util.ts'
import { useI18n } from 'vue-i18n'
export function useXoBackupJobSchedulesUtils() {
const { t } = useI18n()
const { getLastNBackupLogsByJobId } = useXoBackupLogCollection()
const { schedulesByJobId } = useXoScheduleCollection()
const getRunInfo = (backupLog: FrontXoBackupLog, index: number) => ({
status: backupLog.status,
tooltip: `${t('last-run-number', { n: index + 1 })}: ${formatDateTime(backupLog.end ?? backupLog.start)}, ${t(backupLog.status)}`,
})
function getLastThreeRunsStatuses(backupJob: FrontAnyXoBackupJob | undefined) {
if (backupJob === undefined) {
return []
}
return getLastNBackupLogsByJobId(backupJob.id).map((backupLog, index) => getRunInfo(backupLog, index))
}
function getTotalSchedules(backupJob: FrontAnyXoBackupJob) {
return schedulesByJobId.value.get(backupJob.id)?.length ?? 0
}
return {
getLastThreeRunsStatuses,
getTotalSchedules,
}
}

View File

@@ -1,117 +0,0 @@
import type {
FrontAnyXoBackupJob,
FrontXoMetadataBackupJob,
FrontXoMirrorBackupJob,
FrontXoVmBackupJob,
} from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import { useI18n } from 'vue-i18n'
export function useXoBackupUtils() {
const { t } = useI18n()
const hasSnapshotRetention = (backupJob: FrontXoVmBackupJob) =>
Object.values(backupJob.settings).some(
settingsGroup =>
settingsGroup &&
'snapshotRetention' in settingsGroup &&
typeof settingsGroup.snapshotRetention === 'number' &&
settingsGroup.snapshotRetention > 0
)
function getVmBackupModes(backupJob: FrontXoVmBackupJob) {
const modes = []
// Rolling Snapshot - check if any settings have snapshotRetention > 0
if (hasSnapshotRetention(backupJob)) {
modes.push(t('backup:rolling-snapshot'))
}
const hasRemotes = hasIds(backupJob.remotes?.id)
const hasSrs = hasIds(backupJob.srs?.id)
if (backupJob.mode === 'full') {
if (hasRemotes) {
modes.push(t('backup:full'))
}
if (hasSrs) {
modes.push(t('backup:full-replication'))
}
} else if (backupJob.mode === 'delta') {
if (hasRemotes) {
modes.push(t('backup:incremental'))
}
if (hasSrs) {
modes.push(t('backup:incremental-replication'))
}
}
return modes
}
function getMetadataBackupModes(backupJob: FrontXoMetadataBackupJob) {
const modes = []
if (hasIds(backupJob.pools?.id)) {
modes.push(t('backup:pool-metadata'))
}
if (backupJob.xoMetadata) {
modes.push(t('backup:xo-config'))
}
return modes
}
function getMirrorBackupModes(backupJob: FrontXoMirrorBackupJob): string[] {
const modes = []
if (backupJob.mode === 'full') {
modes.push(t('backup:mirror:full'))
} else if (backupJob.mode === 'delta') {
modes.push(t('backup:mirror:incremental'))
}
return modes
}
function getModeLabels(backupJob: FrontAnyXoBackupJob): string[] {
switch (backupJob.type) {
case 'mirrorBackup':
return getMirrorBackupModes(backupJob)
case 'backup':
return getVmBackupModes(backupJob)
case 'metadataBackup':
return getMetadataBackupModes(backupJob)
default:
return []
}
}
function toIds<TId extends string>(input: TId | { __or: TId[] } | undefined): TId[] {
if (typeof input === 'string') {
return [input]
}
if (input && '__or' in input) {
return input.__or
}
return []
}
function hasIds<TId extends string>(input: TId | { __or: TId[] } | undefined): boolean {
return toIds(input).length > 0
}
return {
hasIds,
toIds,
getModeLabels,
getVmBackupModes,
getMetadataBackupModes,
getMirrorBackupModes,
hasSnapshotRetention,
}
}

View File

@@ -1,71 +0,0 @@
import { useWatchCollection } from '@/shared/composables/watch-collection.composable.ts'
import { useXoCollectionState } from '@/shared/composables/xo-collection-state/use-xo-collection-state.ts'
import { BASE_URL } from '@/shared/utils/fetch.util.ts'
import { defineRemoteResource } from '@core/packages/remote-resource/define-remote-resource.ts'
import type { XoVmBackupJob, XoMetadataBackupJob, XoMirrorBackupJob } from '@vates/types'
import { useSorted } from '@vueuse/core'
export type FrontXoVmBackupJob = Pick<XoVmBackupJob, (typeof vmBackupJobFields)[number]>
export type FrontXoMetadataBackupJob = Pick<XoMetadataBackupJob, (typeof metadataBackupJobFields)[number]>
export type FrontXoMirrorBackupJob = Pick<XoMirrorBackupJob, (typeof mirrorBackupJobfields)[number]>
export type FrontAnyXoBackupJob = FrontXoVmBackupJob | FrontXoMetadataBackupJob | FrontXoMirrorBackupJob
export const vmBackupJobFields = [
'id',
'name',
'mode',
'type',
'settings',
'remotes',
'srs',
'vms',
'compression',
'proxy',
] as const satisfies readonly (keyof XoVmBackupJob)[]
const metadataBackupJobFields = [
'id',
'name',
'type',
'settings',
'remotes',
'pools',
'xoMetadata',
'proxy',
] as const satisfies readonly (keyof XoMetadataBackupJob)[]
const mirrorBackupJobfields = [
'id',
'name',
'mode',
'type',
'settings',
'sourceRemote',
'remotes',
'proxy',
] as const satisfies readonly (keyof XoMirrorBackupJob)[]
// Ensure fields are unique
export const anyBackupJobFields = Array.from(
new Set([...vmBackupJobFields, ...metadataBackupJobFields, ...mirrorBackupJobfields])
)
export const useXoBackupJobCollection = defineRemoteResource({
url: `${BASE_URL}/backup-jobs?fields=${anyBackupJobFields.join(',')}&ndjson=true`,
stream: true,
initWatchCollection: () => useWatchCollection({ resource: 'backup-job', fields: anyBackupJobFields }),
initialData: () => [] as FrontAnyXoBackupJob[],
state: (rawBackupJobs, context) => {
const backupJobs = useSorted(rawBackupJobs, ({ name: name1 = '' }, { name: name2 = '' }) =>
name1.localeCompare(name2)
)
return {
...useXoCollectionState(backupJobs, {
context,
baseName: 'backupJob',
}),
}
},
})

View File

@@ -1,30 +0,0 @@
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { XoProxy } from '@vates/types'
export type ReportWhen = 'always' | 'failure' | 'error' | 'never'
export type XoBackupReportTemplate = 'compactMjml' | 'mjml'
export type XoBackupFormat = 'block' | 'vhd'
export type XoBackupJobSettings = Partial<{
compression: FrontXoVmBackupJob['compression']
proxy: XoProxy['id']
preferNbd: boolean
cbtDestroySnapshotData: boolean
concurrency: number
nbdConcurrency: number
maxExportRate: number
nRetriesVmBackupFailures: number
hideSuccessfulItems: boolean
backupReportTpl: XoBackupReportTemplate
reportWhen: ReportWhen
timeout: number
checkpointSnapshot: boolean
offlineBackup: boolean
offlineSnapshot: boolean
mergeBackupsSynchronously: boolean
timezone: string
reportRecipients: string[]
other: Record<string, unknown>
}>

View File

@@ -1,34 +0,0 @@
import type { FrontXoBackupLog } from '@/modules/backup/remote-resources/use-xo-backup-log-collection.ts'
import type { FrontXoSr } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import type { RouteLocationAsRelative } from 'vue-router'
function getBackupLogVmTasks(backupLog: FrontXoBackupLog) {
return (backupLog.tasks ?? []).filter(task => task.data?.type === 'VM')
}
export function getBackupLogVmIds(backupLog: FrontXoBackupLog) {
return getBackupLogVmTasks(backupLog).map(vmTask => vmTask.data?.id as FrontXoVm['id'])
}
export function getBackupLogSrIds(backupLog: FrontXoBackupLog) {
return [
...new Set(
getBackupLogVmTasks(backupLog)
.flatMap(vmTask => vmTask.tasks ?? [])
.flatMap(task => (task.data?.type === 'SR' ? [task.data.id as FrontXoSr['id']] : []))
),
]
}
export function getBackupLogRunRoute(backupLog: FrontXoBackupLog): RouteLocationAsRelative | undefined {
if (backupLog.jobId === undefined) {
return undefined
}
return {
name: '/backup/[id]/runs',
params: { id: backupLog.jobId },
query: { id: backupLog.id },
}
}

View File

@@ -1,4 +1,4 @@
import type { FrontAnyXoBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import type { FrontAnyXoBackupJob } from '@/modules/backup-job/remote-resources/use-xo-backup-job-collection.ts'
import { useWatchCollection } from '@/shared/composables/watch-collection.composable.ts'
import { useXoCollectionState } from '@/shared/composables/xo-collection-state/use-xo-collection-state.ts'
import { BASE_URL } from '@/shared/utils/fetch.util.ts'

View File

@@ -13,11 +13,6 @@
{{ t('dashboard') }}
</UiTabItem>
</RouterLink>
<RouterLink v-slot="{ isExactActive, href }" :to="{ name: '/(site)/backups' }" custom>
<UiTabItem :active="isExactActive" :href tag="a">
{{ t('backups') }}
</UiTabItem>
</RouterLink>
<RouterLink v-slot="{ isExactActive, href }" :to="{ name: '/(site)/tasks' }" custom>
<UiTabItem :active="isExactActive" :href tag="a">
{{ t('tasks') }}

View File

@@ -11,7 +11,7 @@
/>
<template v-if="hasBackupIssues" #info>
<!-- TODO Need to be Filter on “Last 3 backups”: “Skipped runs, no errors”, “Errors detected “ -->
<UiLink size="small" :to="{ name: '/(site)/backups' }">{{ t('action:see-all') }}</UiLink>
<UiLink size="small" :to="{ name: '/admin/backup-and-replication/jobs' }">{{ t('action:see-all') }}</UiLink>
</template>
<template #description>{{ t('in-last-three-runs') }}</template>
</UiCardTitle>
@@ -113,7 +113,7 @@ const { HeadCells, BodyCells } = useBackupIssueColumns({
job: r =>
r({
label: issue.name ?? t('untitled'),
to: `/backup/${issue.uuid}/runs`,
to: { name: '/admin/backup-and-replication/jobs', query: { id: issue.uuid } },
icon: 'object:backup-job',
}),
lastRuns: r => r(lastRuns),

Some files were not shown because too many files have changed in this diff Show More