2026-05-31 19:52:46 +03:00
{{define "admin_storage_tests.html"}}{{template "base" .}}{{end}}
{{define "content"}}
< section class = "app-shell admin-shell" aria-labelledby = "admin-storage-tests-title" >
< aside class = "app-sidebar" >
< nav class = "sidebar-nav" >
< a class = "sidebar-link" href = "/admin" > {{template "icon-dashboard" .}}< span > Overview</ span ></ a >
< a class = "sidebar-link" href = "/admin/files" > {{template "icon-folder" .}}< span > Files</ span ></ a >
< a class = "sidebar-link" href = "/admin/users" > {{template "icon-user-circle" .}}< span > Users</ span ></ a >
< a class = "sidebar-link" href = "/admin/settings" > {{template "icon-settings" .}}< span > Settings</ span ></ a >
< a class = "sidebar-link is-active" href = "/admin/storage" > {{template "icon-database" .}}< span > Storage</ span ></ a >
2026-05-31 21:52:56 +03:00
< a class = "sidebar-link" href = "/admin/logs" > {{template "icon-database" .}}< span > Logs</ span ></ a >
< a class = "sidebar-link" href = "/admin/bans" > {{template "icon-settings" .}}< span > Bans</ span ></ a >
2026-05-31 19:52:46 +03:00
</ nav >
< hr class = "sidebar-sep" >
< nav class = "sidebar-nav" >
< a class = "sidebar-link" href = "/app" > {{template "icon-home-simple" .}}< span > My Files</ span ></ a >
</ nav >
< hr class = "sidebar-sep" >
< form class = "sidebar-logout" action = "/admin/logout" method = "post" >
< input type = "hidden" name = "csrf_token" value = "{{.CSRFToken}}" >
< button class = "button button-outline" type = "submit" > {{template "icon-log-out" .}}< span > Sign out</ span ></ button >
</ form >
</ aside >
< div class = "app-main" >
< div class = "admin-header" >
< div >
< p class = "kicker" > Storage testing</ p >
< h1 id = "admin-storage-tests-title" > {{.Data.PageTitle}}</ h1 >
< p class = "muted-copy" > Connection status, speed-test history, and background benchmark runs for this backend.</ p >
</ div >
< div class = "storage-tests-header-actions" >
< a class = "button button-outline" href = "/admin/storage" > Back</ a >
{{if .Data.StorageTest.CanRun}}
< button class = "button button-primary" type = "button" data-storage-speed-open > New Test</ button >
{{end}}
</ div >
</ div >
{{if .Data.Notice}}< p class = "form-success" > {{.Data.Notice}}</ p > {{end}}
{{if .Data.Error}}< p class = "form-error" > {{.Data.Error}}</ p > {{end}}
< div class = "storage-card" >
< div class = "storage-card-header" >
< div class = "storage-card-identity" >
< div class = "storage-card-icon" >
{{if eq .Data.StorageTest.Config.Type "local"}}{{template "icon-hard-drive" .}}
{{else if eq .Data.StorageTest.Config.Type "sftp"}}{{template "icon-database" .}}
{{else if eq .Data.StorageTest.Config.Type "smb"}}{{template "icon-folder" .}}
{{else if eq .Data.StorageTest.Config.Type "webdav"}}{{template "icon-cloud-sync" .}}
{{else}}{{template "icon-cloud-upload" .}}{{end}}
</ div >
< div >
< strong class = "storage-card-name" > {{.Data.StorageTest.Config.Name}}</ strong >
< div class = "storage-card-meta" >
< span class = "badge" > {{if eq .Data.StorageTest.Config.Provider "contabo"}}Contabo{{else if eq .Data.StorageTest.Config.Type "sftp"}}SFTP{{else if eq .Data.StorageTest.Config.Type "smb"}}Samba{{else if eq .Data.StorageTest.Config.Type "webdav"}}WebDAV{{else if eq .Data.StorageTest.Config.Type "s3"}}S3{{else if eq .Data.StorageTest.Config.Type "local"}}Local files{{else}}{{.Data.StorageTest.Config.Type}}{{end}}</ span >
{{if .Data.StorageTest.Config.LastTestSuccess}}< span class = "badge badge-active" > Connection OK</ span > {{else}}< span class = "badge badge-disabled" > Needs connection test</ span > {{end}}
{{if .Data.StorageTest.UsageLabel}}< span class = "storage-card-usage" > {{.Data.StorageTest.UsageLabel}}</ span > {{end}}
</ div >
</ div >
</ div >
< form action = "/admin/storage/{{.Data.StorageTest.Config.ID}}/test" method = "post" >
< input type = "hidden" name = "csrf_token" value = "{{.CSRFToken}}" >
< input type = "hidden" name = "next" value = "tests" >
< button class = "button button-outline button-sm" type = "submit" > Test Connection</ button >
</ form >
</ div >
{{if not (.Data.StorageTest.Config.LastTestedAt.IsZero)}}
< div class = "storage-card-summary" >
< div class = "storage-detail storage-detail-test {{if .Data.StorageTest.Config.LastTestSuccess}}is-ok{{else}}is-err{{end}}" >
< span > Last test</ span >
< span > {{.Data.StorageTest.Config.LastTestedAt.Format "Jan 2, 15:04"}} · {{if .Data.StorageTest.Config.LastTestSuccess}}Passed{{else}}{{if .Data.StorageTest.Config.LastTestError}}{{.Data.StorageTest.Config.LastTestError}}{{else}}Failed{{end}}{{end}}</ span >
</ div >
</ div >
{{end}}
</ div >
{{if not .Data.StorageTest.CanRun}}
< p class = "form-error" > Run a successful connection test before starting speed tests.</ p >
{{end}}
< div class = "storage-results-list storage-results-page" data-storage-tests-page data-storage-tests-url = "/admin/storage/{{.Data.StorageTest.Config.ID}}/tests.json" >
{{if .Data.StorageTest.Tests}}
{{range .Data.StorageTest.Tests}}
< details class = "storage-result-row" data-storage-test-id = "{{.ID}}" >
< summary >
< span > {{.StartedLabel}}</ span >
< span > {{if eq .Mode "custom"}}{{.CustomFileCount}} files × {{.CustomFileSizeMB}} MB{{else}}{{.ModeLabel}}{{end}}</ span >
< span class = "storage-result-status is-{{.Status}}" > {{.Status}}</ span >
</ summary >
< div class = "storage-test-progress" aria-label = "Test progress" >
< div class = "storage-test-progress-bar" >< span style = "width: {{.ProgressPercent}}%" ></ span ></ div >
< small > {{.ProgressPercent}}%{{if .Stage}} · {{.Stage}}{{end}}</ small >
</ div >
< div class = "storage-result-detail" >
< span >< strong > Finished</ strong > {{.FinishedLabel}}</ span >
< span >< strong > Files</ strong > {{.FilesWritten}}</ span >
< span >< strong > Size</ strong > {{.TotalSizeLabel}}</ span >
< span >< strong > Write</ strong > {{.WriteSpeedLabel}}</ span >
< span >< strong > Read</ strong > {{.ReadSpeedLabel}}</ span >
{{if .Error}}< span class = "storage-result-error" >< strong > Error</ strong > {{.Error}}</ span > {{end}}
</ div >
</ details >
{{end}}
{{else}}
< p class = "muted-copy" > No speed tests have been run for this backend yet.</ p >
{{end}}
</ div >
< div class = "storage-modal" data-storage-speed-modal hidden >
< div class = "storage-modal-backdrop" data-storage-modal-close ></ div >
< div class = "storage-modal-card" role = "dialog" aria-modal = "true" aria-label = "Run storage speed test" >
< div class = "storage-modal-header" >
< strong > New speed test</ strong >
< button type = "button" class = "button button-outline button-sm" data-storage-modal-close > Close</ button >
</ div >
< form action = "/admin/storage/{{.Data.StorageTest.Config.ID}}/speed-test" method = "post" class = "storage-speed-form" >
< input type = "hidden" name = "csrf_token" value = "{{.CSRFToken}}" >
< label class = "storage-speed-option" >
< input type = "radio" name = "mode" value = "small" >
< span >< strong > Many small files test</ strong >< small > Writes, reads, and deletes many tiny objects.</ small ></ span >
</ label >
< label class = "storage-speed-option" >
< input type = "radio" name = "mode" value = "big" >
< span >< strong > One big file test</ strong >< small > Uses one larger object for sequential throughput.</ small ></ span >
</ label >
< label class = "storage-speed-option" >
< input type = "radio" name = "mode" value = "mixed" checked >
< span >< strong > Average Test ( mix )</ strong >< small > Balances small object overhead and larger transfer speed.</ small ></ span >
</ label >
< label class = "storage-speed-option" >
< input type = "radio" name = "mode" value = "custom" data-storage-custom-radio >
< span >< strong > Custom</ strong >< small > Choose how many mock files to create and the size of each file.</ small ></ span >
</ label >
< div class = "storage-custom-fields" data-storage-custom-fields hidden >
< label >< span > Files</ span >< input type = "number" name = "custom_file_count" min = "1" max = "500" value = "10" ></ label >
< label >< span > Size per file (MB)</ span >< input type = "number" name = "custom_file_size_mb" min = "0.001" step = "0.001" value = "1" ></ label >
</ div >
< button class = "button button-primary button-sm" type = "submit" > Run in background</ button >
</ form >
</ div >
</ div >
</ div >
</ section >
{{end}}