Add analysis preview to case list

Introduce a `preview_lines` setting in `users.toml` to control the
number of visible lines for the analysis preview in the case list. This
feature extracts the first paragraph of the `document.md` file, strips
markdown formatting, and displays it, capped by the configured
`preview_lines`. The actual line clamping is handled client-side via CSS
`line-clamp`.
This commit is contained in:
2026-04-21 17:25:14 +02:00
parent 26b202ec07
commit 661ea6215e
18 changed files with 179 additions and 1 deletions
+44
View File
@@ -33,6 +33,14 @@ fn default_window_hours() -> u32 {
72
}
/// Default number of analysis-preview lines rendered under each case on
/// the list view when the user entry omits `preview_lines`. Two lines
/// show the first sentence of the LLM output in most cases without
/// dominating the list row.
fn default_preview_lines() -> u32 {
2
}
/// A single user entry from users.toml.
#[derive(Debug, Deserialize)]
pub struct User {
@@ -51,6 +59,14 @@ pub struct User {
/// apply no additional time filter.
#[serde(default = "default_window_hours")]
pub window_hours: u32,
/// Number of analysis-preview lines rendered under each case row on
/// the list view. The preview itself is always the first paragraph of
/// `document.md`; this value only controls how many *visual* lines
/// the browser will show before truncating with `…`. Applied via a
/// CSS `line-clamp` custom property, so a single server value adapts
/// to any viewport width.
#[serde(default = "default_preview_lines")]
pub preview_lines: u32,
}
/// Wrapper for deserializing the [[user]] array from TOML.
@@ -290,6 +306,7 @@ mod tests {
whisper: WhisperUserSettings::default(),
retention: RetentionUserSettings::default(),
window_hours: default_window_hours(),
preview_lines: default_preview_lines(),
}
}
@@ -344,6 +361,33 @@ mod tests {
assert_eq!(r.auto_delete_days, 30);
}
#[test]
fn parses_user_without_preview_lines_defaults_to_2() {
let toml_str = r#"
[[user]]
slug = "a"
api_key = "k1"
web_password = ""
role = "doctor"
"#;
let parsed: UsersFile = toml::from_str(toml_str).unwrap();
assert_eq!(parsed.user[0].preview_lines, 2);
}
#[test]
fn parses_user_with_explicit_preview_lines() {
let toml_str = r#"
[[user]]
slug = "a"
api_key = "k1"
web_password = ""
role = "doctor"
preview_lines = 5
"#;
let parsed: UsersFile = toml::from_str(toml_str).unwrap();
assert_eq!(parsed.user[0].preview_lines, 5);
}
#[test]
fn parses_user_with_partial_retention_block() {
let toml_str = r#"