e1df092
use axum::extract::{Path, State};
use axum::response::Response;
use maud::html;
use crate::handler::html::{HtmlRepoPath, clone_https_url, clone_ssh_url, resolve, response_html};
use crate::service::GitService;
use crate::share::access::BasicAuth;
#[utoipa::path(
get,
path = "/repos/{space_name}/{repo_name}/html/clone-buttons",
tag = "html",
description = "渲染 HTTPS 与 SSH 克隆地址及复制按钮片段。",
operation_id = "render_clone_buttons",
params(HtmlRepoPath),
responses(
(status = 200, description = "clone buttons html fragment", content_type = "text/html"),
(status = 404, description = "repo not found")
)
)]
pub async fn render_clone_buttons(
State(service): State<GitService>,
Path(path): Path<HtmlRepoPath>,
auth: BasicAuth,
) -> Response {
let ctx = match resolve(service.clone(), path.clone(), auth).await {
Ok(c) => c,
Err(resp) => return resp,
};
let (https_url, https_warn) = clone_https_url(&service, &ctx.space_name, &ctx.repo_name);
let (ssh_url, ssh_warn) = clone_ssh_url(&service, &ctx.space_name, &ctx.repo_name);
let base = "git-clone-buttons flex items-center gap-2";
let cls = if ctx.dto.is_archived {
format!("{base} opacity-60")
} else {
base.to_string()
};
let warn_attr = if https_warn || ssh_warn {
"true"
} else {
"false"
};
let markup = html! {
div class=(cls)
data-component="git-clone-buttons"
data-space=(ctx.space_name)
data-repo=(ctx.repo_name)
data-archived=(if ctx.dto.is_archived { "true" } else { "false" })
data-warn=(warn_attr) {
@if !https_url.is_empty() {
button class="rounded border border-zinc-200 px-2 py-1 text-xs hover:bg-zinc-50"
type="button"
data-protocol="https"
data-url=(https_url) {
"HTTPS"
}
}
@if !ssh_url.is_empty() {
button class="rounded border border-zinc-200 px-2 py-1 text-xs hover:bg-zinc-50"
type="button"
data-protocol="ssh"
data-url=(ssh_url) {
"SSH"
}
}
@if !https_url.is_empty() {
input class="rounded border border-zinc-200 px-2 py-1 font-mono text-xs"
type="text"
readonly
value=(https_url.clone())
aria-label="clone url" {}
button class="rounded border border-zinc-200 px-2 py-1 text-xs hover:bg-zinc-50"
type="button"
data-action="copy"
data-target="input" {
"copy"
}
} @else if !ssh_url.is_empty() {
input class="rounded border border-zinc-200 px-2 py-1 font-mono text-xs"
type="text"
readonly
value=(ssh_url.clone())
aria-label="clone url" {}
button class="rounded border border-zinc-200 px-2 py-1 text-xs hover:bg-zinc-50"
type="button"
data-action="copy"
data-target="input" {
"copy"
}
} @else {
span class="text-xs text-amber-600"
data-warn="missing-base-url" {
"clone url unavailable: base_url not configured"
}
}
}
};
response_html(markup, 30)
}