diff --git a/nora-registry/src/registry/pypi.rs b/nora-registry/src/registry/pypi.rs index cdac149..dd6d06b 100644 --- a/nora-registry/src/registry/pypi.rs +++ b/nora-registry/src/registry/pypi.rs @@ -119,12 +119,7 @@ async fn download_file( "application/octet-stream" }; - return ( - StatusCode::OK, - [(header::CONTENT_TYPE, content_type)], - data, - ) - .into_response(); + return (StatusCode::OK, [(header::CONTENT_TYPE, content_type)], data).into_response(); } // Try proxy if configured @@ -161,11 +156,7 @@ async fn download_file( "application/octet-stream" }; - return ( - StatusCode::OK, - [(header::CONTENT_TYPE, content_type)], - data, - ) + return (StatusCode::OK, [(header::CONTENT_TYPE, content_type)], data) .into_response(); } } diff --git a/nora-registry/src/ui/components.rs b/nora-registry/src/ui/components.rs index 180021b..e4ce14e 100644 --- a/nora-registry/src/ui/components.rs +++ b/nora-registry/src/ui/components.rs @@ -158,20 +158,25 @@ fn sidebar_dark(active_page: Option<&str>, t: &Translations) -> String { "#, - nav_html, - t.nav_registries, - VERSION + nav_html, t.nav_registries, VERSION ) } /// Dark theme header with language switcher fn header_dark(lang: Lang) -> String { let (en_class, ru_class) = match lang { - Lang::En => ("text-white font-semibold", "text-slate-400 hover:text-slate-200"), - Lang::Ru => ("text-slate-400 hover:text-slate-200", "text-white font-semibold"), + Lang::En => ( + "text-white font-semibold", + "text-slate-400 hover:text-slate-200", + ), + Lang::Ru => ( + "text-slate-400 hover:text-slate-200", + "text-white font-semibold", + ), }; - format!(r##" + format!( + r##"
- "##, en_class, ru_class) + "##, + en_class, ru_class + ) } /// Render global stats row (5-column grid) @@ -240,11 +247,16 @@ pub fn render_global_stats( "##, - t.stat_downloads, downloads, - t.stat_uploads, uploads, - t.stat_artifacts, artifacts, - t.stat_cache_hit, cache_hit_percent, - t.stat_storage, format_size(storage_bytes) + t.stat_downloads, + downloads, + t.stat_uploads, + uploads, + t.stat_artifacts, + artifacts, + t.stat_cache_hit, + cache_hit_percent, + t.stat_storage, + format_size(storage_bytes) ) } @@ -294,15 +306,22 @@ pub fn render_registry_card( icon_path, t.active, name, - t.artifacts, artifact_count, - t.size, format_size(size_bytes), - t.downloads, downloads, - t.uploads, uploads + t.artifacts, + artifact_count, + t.size, + format_size(size_bytes), + t.downloads, + downloads, + t.uploads, + uploads ) } /// Render mount points table -pub fn render_mount_points_table(mount_points: &[(String, String, Option)], t: &Translations) -> String { +pub fn render_mount_points_table( + mount_points: &[(String, String, Option)], + t: &Translations, +) -> String { let rows: String = mount_points .iter() .map(|(registry, mount_path, proxy)| { @@ -342,11 +361,7 @@ pub fn render_mount_points_table(mount_points: &[(String, String, Option "##, - t.mount_points, - t.registry, - t.mount_path, - t.proxy_upstream, - rows + t.mount_points, t.registry, t.mount_path, t.proxy_upstream, rows ) } @@ -648,7 +663,8 @@ pub fn html_escape(s: &str) -> String { /// Render the "bragging" footer with NORA stats pub fn render_bragging_footer(lang: Lang) -> String { let t = get_translations(lang); - format!(r##" + format!( + r##"
{} diff --git a/nora-registry/src/ui/mod.rs b/nora-registry/src/ui/mod.rs index 3954ac7..b770074 100644 --- a/nora-registry/src/ui/mod.rs +++ b/nora-registry/src/ui/mod.rs @@ -71,7 +71,10 @@ async fn dashboard( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let response = api_dashboard(State(state)).await.0; Html(render_dashboard(&response, lang)) } @@ -82,9 +85,17 @@ async fn docker_list( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let repos = get_docker_repos(&state.storage).await; - Html(render_registry_list("docker", "Docker Registry", &repos, lang)) + Html(render_registry_list( + "docker", + "Docker Registry", + &repos, + lang, + )) } async fn docker_detail( @@ -93,7 +104,10 @@ async fn docker_detail( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let detail = get_docker_detail(&state.storage, &name).await; Html(render_docker_detail(&name, &detail, lang)) } @@ -104,9 +118,17 @@ async fn maven_list( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let repos = get_maven_repos(&state.storage).await; - Html(render_registry_list("maven", "Maven Repository", &repos, lang)) + Html(render_registry_list( + "maven", + "Maven Repository", + &repos, + lang, + )) } async fn maven_detail( @@ -115,7 +137,10 @@ async fn maven_detail( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let detail = get_maven_detail(&state.storage, &path).await; Html(render_maven_detail(&path, &detail, lang)) } @@ -126,7 +151,10 @@ async fn npm_list( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let packages = get_npm_packages(&state.storage).await; Html(render_registry_list("npm", "npm Registry", &packages, lang)) } @@ -137,7 +165,10 @@ async fn npm_detail( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let detail = get_npm_detail(&state.storage, &name).await; Html(render_package_detail("npm", &name, &detail, lang)) } @@ -148,9 +179,17 @@ async fn cargo_list( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let crates = get_cargo_crates(&state.storage).await; - Html(render_registry_list("cargo", "Cargo Registry", &crates, lang)) + Html(render_registry_list( + "cargo", + "Cargo Registry", + &crates, + lang, + )) } async fn cargo_detail( @@ -159,7 +198,10 @@ async fn cargo_detail( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let detail = get_cargo_detail(&state.storage, &name).await; Html(render_package_detail("cargo", &name, &detail, lang)) } @@ -170,9 +212,17 @@ async fn pypi_list( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let packages = get_pypi_packages(&state.storage).await; - Html(render_registry_list("pypi", "PyPI Repository", &packages, lang)) + Html(render_registry_list( + "pypi", + "PyPI Repository", + &packages, + lang, + )) } async fn pypi_detail( @@ -181,7 +231,10 @@ async fn pypi_detail( Query(query): Query, headers: axum::http::HeaderMap, ) -> impl IntoResponse { - let lang = extract_lang(&Query(query), headers.get("cookie").and_then(|v| v.to_str().ok())); + let lang = extract_lang( + &Query(query), + headers.get("cookie").and_then(|v| v.to_str().ok()), + ); let detail = get_pypi_detail(&state.storage, &name).await; Html(render_package_detail("pypi", &name, &detail, lang)) } diff --git a/nora-registry/src/ui/templates.rs b/nora-registry/src/ui/templates.rs index 7360ffc..fe3319e 100644 --- a/nora-registry/src/ui/templates.rs +++ b/nora-registry/src/ui/templates.rs @@ -65,7 +65,10 @@ pub fn render_dashboard(data: &DashboardResponse, lang: Lang) -> String { // Render activity log let activity_rows: String = if data.activity.is_empty() { - format!(r##"{}"##, t.no_activity) + format!( + r##"{}"##, + t.no_activity + ) } else { data.activity .iter() @@ -131,7 +134,13 @@ pub fn render_dashboard(data: &DashboardResponse, lang: Lang) -> String { ); let polling_script = render_polling_script(); - layout_dark(t.dashboard_title, &content, Some("dashboard"), &polling_script, lang) + layout_dark( + t.dashboard_title, + &content, + Some("dashboard"), + &polling_script, + lang, + ) } /// Format timestamp as relative time (e.g., "2 min ago") @@ -154,16 +163,24 @@ fn format_relative_time(timestamp: &chrono::DateTime) -> String { } /// Renders a registry list page (docker, maven, npm, cargo, pypi) -pub fn render_registry_list(registry_type: &str, title: &str, repos: &[RepoInfo], lang: Lang) -> String { +pub fn render_registry_list( + registry_type: &str, + title: &str, + repos: &[RepoInfo], + lang: Lang, +) -> String { let t = get_translations(lang); let icon = get_registry_icon(registry_type); let table_rows = if repos.is_empty() { - format!(r##" + format!( + r##"
📭
{}
{}
- "##, t.no_repos_found, t.push_first_artifact) + "##, + t.no_repos_found, t.push_first_artifact + ) } else { repos .iter() @@ -340,11 +357,22 @@ pub fn render_docker_detail(name: &str, detail: &DockerDetail, lang: Lang) -> St tags_rows ); - layout_dark(&format!("{} - Docker", name), &content, Some("docker"), "", lang) + layout_dark( + &format!("{} - Docker", name), + &content, + Some("docker"), + "", + lang, + ) } /// Renders package detail page (npm, cargo, pypi) -pub fn render_package_detail(registry_type: &str, name: &str, detail: &PackageDetail, lang: Lang) -> String { +pub fn render_package_detail( + registry_type: &str, + name: &str, + detail: &PackageDetail, + lang: Lang, +) -> String { let _t = get_translations(lang); let icon = get_registry_icon(registry_type); let registry_title = get_registry_title(registry_type); @@ -531,7 +559,13 @@ pub fn render_maven_detail(path: &str, detail: &MavenDetail, lang: Lang) -> Stri artifact_rows ); - layout_dark(&format!("{} - Maven", path), &content, Some("maven"), "", lang) + layout_dark( + &format!("{} - Maven", path), + &content, + Some("maven"), + "", + lang, + ) } /// Returns SVG icon path for the registry type