1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
//! Files view implementation.
use uuid::Uuid;
use crate::daemon::api::ApiClient;
use crate::daemon::tui::app::ListItem;
/// Load files from API
pub async fn load_files(
client: &ApiClient,
contract_id: Uuid,
) -> Result<Vec<ListItem>, Box<dyn std::error::Error>> {
let result = client.contract_files(contract_id).await?;
// Parse JSON response into ListItem
let files: Vec<serde_json::Value> = serde_json::from_value(result.0)?;
let items = files
.into_iter()
.filter_map(|f| {
let id_str = f.get("id")?.as_str()?;
let id = Uuid::parse_str(id_str).ok()?;
Some(ListItem {
id,
name: f
.get("name")
.and_then(|v| v.as_str())
.unwrap_or("Unnamed")
.to_string(),
status: None,
description: f
.get("description")
.and_then(|v| v.as_str())
.map(String::from),
updated_at: f
.get("updatedAt")
.and_then(|v| v.as_str())
.unwrap_or_default()
.to_string(),
extra: f,
})
})
.collect();
Ok(items)
}
/// Get full file details for preview
pub async fn get_file_preview(
client: &ApiClient,
contract_id: Uuid,
file_id: Uuid,
) -> Result<String, Box<dyn std::error::Error>> {
let result = client.contract_file(contract_id, file_id).await?;
let file: serde_json::Value = result.0;
let name = file
.get("name")
.and_then(|v| v.as_str())
.unwrap_or("Unknown");
let description = file
.get("description")
.and_then(|v| v.as_str())
.unwrap_or("-");
// Try to get body content
let body_preview = if let Some(body) = file.get("body") {
if let Some(body_array) = body.as_array() {
body_array
.iter()
.filter_map(|item| {
let text = item.get("text").and_then(|v| v.as_str())?;
Some(text.to_string())
})
.take(5)
.collect::<Vec<_>>()
.join("\n")
} else {
"-".to_string()
}
} else {
"-".to_string()
};
Ok(format!(
"Name: {}\nDescription: {}\n\nContent:\n{}",
name, description, body_preview
))
}
|