Add breadcrumbs to tree view
Diff
templates/base.html | 4 ++++
src/database/indexer.rs | 1 -
src/methods/filters.rs | 8 ++++++++
statics/sass/style.scss | 9 +++++++++
templates/repo/file.html | 5 +++++
templates/repo/tree.html | 5 +++++
src/methods/repo/tree.rs | 16 ++++++++++++----
templates/repo/macros/breadcrumbs.html | 11 +++++++++++
8 files changed, 52 insertions(+), 7 deletions(-)
@@ -30,6 +30,10 @@
</nav>
{%- endblock -%}
<aside>
{%- block subnav %}{% endblock %}
</aside>
<main>
{%- block content %}{% endblock -%}
</main>
@@ -1,5 +1,4 @@
use std::{
borrow::Cow,
collections::HashSet,
ffi::OsStr,
fmt::Debug,
@@ -24,6 +24,14 @@
.map_err(askama::Error::Custom)
}
pub fn branch_query(branch: Option<&str>) -> String {
if let Some(b) = branch {
format!("?h={b}")
} else {
String::new()
}
}
pub fn timeago(s: impl Into<Timestamp>) -> Result<String, askama::Error> {
Ok(timeago::Formatter::new()
.convert((OffsetDateTime::now_utc() - s.into().0).try_into().unwrap()))
@@ -58,6 +58,15 @@
}
}
aside {
background: #f7f7f7;
padding: 0.3rem 2rem;
@media (prefers-color-scheme: dark) {
background: #111;
}
}
main {
padding: 2rem;
margin: 0;
@@ -1,4 +1,5 @@
{% import "macros/link.html" as link %}
{% import "macros/breadcrumbs.html" as breadcrumbs %}
{% extends "repo/base.html" %}
{% block head %}
@@ -7,6 +8,10 @@
{%- endblock %}
{% block tree_nav_class %}active{% endblock %}
{% block subnav %}
{% call breadcrumbs::breadcrumbs(repo_path, filters::branch_query(branch.as_deref())) %}
{% endblock %}
{% block extra_nav_links %}
<a href="?raw=true{% call link::maybe_branch_suffix(branch) %}">plain</a>
@@ -1,6 +1,11 @@
{% import "macros/breadcrumbs.html" as breadcrumbs %}
{% extends "repo/base.html" %}
{% block tree_nav_class %}active{% endblock %}
{% block subnav %}
{% call breadcrumbs::breadcrumbs(repo_path, query) %}
{% endblock %}
{% block content %}
<div class="table-responsive">
@@ -1,12 +1,12 @@
use std::{
fmt::{Display, Formatter},
sync::Arc,
};
use askama::Template;
use axum::{extract::Query, response::IntoResponse, Extension};
use itertools::Itertools;
use serde::Deserialize;
use std::path::PathBuf;
use std::{
fmt::{Display, Formatter},
sync::Arc,
};
use crate::{
git::{FileWithContent, PathDestination, TreeItem},
@@ -51,6 +51,7 @@
pub repo: Repository,
pub items: Vec<TreeItem>,
pub query: UriQuery,
pub repo_path: PathBuf,
pub branch: Option<Arc<str>>,
}
@@ -58,6 +59,7 @@
#[template(path = "repo/file.html")]
pub struct FileView {
pub repo: Repository,
pub repo_path: PathBuf,
pub file: FileWithContent,
pub branch: Option<Arc<str>>,
}
@@ -73,7 +75,7 @@
Ok(
match open_repo
.path(child_path, query.id.as_deref(), !query.raw)
.path(child_path.clone(), query.id.as_deref(), !query.raw)
.await?
{
PathDestination::Tree(items) => {
@@ -82,6 +84,7 @@
items,
branch: query.branch.clone(),
query,
repo_path: child_path.unwrap_or_default(),
})))
}
PathDestination::File(file) if query.raw => ResponseEither::Right(file.content),
@@ -90,6 +93,7 @@
repo,
file,
branch: query.branch,
repo_path: child_path.unwrap_or_default(),
})))
}
},
@@ -1,0 +1,11 @@
{%- macro breadcrumbs(repo_path, query) -%}
path:
<a href="/{{ repo.display() }}/tree/{{ query }}">{{ repo.display() }}</a>
{%- for child in repo_path.ancestors().collect_vec().into_iter().rev() -%}
{%- if let Some(file_name) = child.file_name() -%}
/<a href="/{{ repo.display() }}/tree/{{ child.display() }}{{ query }}">
{{- file_name.to_string_lossy() -}}
</a>
{%- endif -%}
{%- endfor -%}
{%- endmacro -%}