multirow reference in the client

This commit is contained in:
Priec
2026-07-29 11:34:08 +02:00
parent 33a5f47b42
commit 76a5f76194
17 changed files with 105 additions and 90 deletions

View File

@@ -18,8 +18,8 @@ pub(crate) struct CreateTableForm {
pub optional_links: String,
#[serde(default)]
pub base_currency: String,
#[serde(default = "default_row_display_column")]
pub row_display_column: String,
#[serde(default)]
pub row_display_columns: String,
}
pub(crate) struct AddTablePageState {
@@ -121,10 +121,7 @@ impl CreateTableForm {
indexes,
profile_name,
base_currency: if has_money { base_currency } else { String::new() },
row_display_column: {
let value = self.row_display_column.trim();
if value.is_empty() { "id".to_string() } else { value.to_string() }
},
row_display_columns: comma_separated(&self.row_display_columns),
})
}
}
@@ -138,10 +135,6 @@ fn comma_separated(value: &str) -> Vec<String> {
.collect()
}
fn default_row_display_column() -> String {
"id".to_string()
}
#[cfg(test)]
mod tests {
use super::*;
@@ -154,7 +147,7 @@ mod tests {
columns: "number: text:indexed\namount: money:half-up,recompute".into(),
required_links: "customer".into(),
base_currency: "eur".into(),
row_display_column: "number".into(),
row_display_columns: "number, amount".into(),
..Default::default()
}
.into_request()
@@ -164,7 +157,7 @@ mod tests {
assert_eq!(request.links[0].linked_table_name, "customer");
assert!(request.links[0].required);
assert_eq!(request.base_currency, "EUR");
assert_eq!(request.row_display_column, "number");
assert_eq!(request.row_display_columns, vec!["number", "amount"]);
assert!(request.columns[1].recompute_on_dependency_change);
}
}

View File

@@ -21,14 +21,14 @@ pub(crate) fn render_page(page: &AddTablePageState) -> String {
.map(render_submission_error)
.unwrap_or_default();
format!(
"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Add table</title><script src=\"https://cdn.jsdelivr.net/npm/htmx.org@2/dist/htmx.min.js\"></script><style>{ADMIN_CSS}</style></head><body><header class=\"topbar\"><div><strong>Komp Accounting</strong></div><nav><a href=\"/admin\">Admin</a><a href=\"/\">Analytics</a></nav></header><main class=\"form-main\"><a class=\"back-link\" href=\"/admin\">← Admin panel</a><section class=\"form-card\"><p class=\"eyebrow\">Table definition</p><h1>Add table</h1><p>Create a table through the existing gRPC table-definition service.</p><form hx-post=\"/admin/tables\" hx-target=\"#submission-status\" hx-swap=\"innerHTML\" hx-disabled-elt=\"button[type=submit]\"><div class=\"form-grid\"><label>Profile<select name=\"profile_name\" required><option value=\"\">Choose a profile</option>{options}</select></label><label>Table name<input name=\"table_name\" value=\"{}\" required placeholder=\"invoices\"></label><label class=\"wide\">Columns<textarea name=\"columns\" rows=\"9\" required placeholder=\"number: text:indexed&#10;issued_on: date&#10;amount: money:half-up,recompute\">{}</textarea><small>One per line: <code>name: type: optional flags</code>. Flags: indexed, half-up, recompute.</small></label><label>Additional indexed columns<input name=\"indexed_columns\" value=\"{}\" placeholder=\"number, issued_on\"></label><label>Base currency<input name=\"base_currency\" value=\"{}\" maxlength=\"3\" placeholder=\"EUR\"></label><label>Required links<input name=\"required_links\" value=\"{}\" placeholder=\"customer, address\"></label><label>Optional links<input name=\"optional_links\" value=\"{}\" placeholder=\"project\"></label><label>Row display column<input name=\"row_display_column\" value=\"{}\"></label></div><div id=\"submission-status\" aria-live=\"polite\">{error}</div><div class=\"form-actions\"><a href=\"/admin\">Cancel</a><button type=\"submit\">Create table</button></div></form></section></main></body></html>",
"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Add table</title><script src=\"https://cdn.jsdelivr.net/npm/htmx.org@2/dist/htmx.min.js\"></script><style>{ADMIN_CSS}</style></head><body><header class=\"topbar\"><div><strong>Komp Accounting</strong></div><nav><a href=\"/admin\">Admin</a><a href=\"/\">Analytics</a></nav></header><main class=\"form-main\"><a class=\"back-link\" href=\"/admin\">← Admin panel</a><section class=\"form-card\"><p class=\"eyebrow\">Table definition</p><h1>Add table</h1><p>Create a table through the existing gRPC table-definition service.</p><form hx-post=\"/admin/tables\" hx-target=\"#submission-status\" hx-swap=\"innerHTML\" hx-disabled-elt=\"button[type=submit]\"><div class=\"form-grid\"><label>Profile<select name=\"profile_name\" required><option value=\"\">Choose a profile</option>{options}</select></label><label>Table name<input name=\"table_name\" value=\"{}\" required placeholder=\"invoices\"></label><label class=\"wide\">Columns<textarea name=\"columns\" rows=\"9\" required placeholder=\"number: text:indexed&#10;issued_on: date&#10;amount: money:half-up,recompute\">{}</textarea><small>One per line: <code>name: type: optional flags</code>. Flags: indexed, half-up, recompute.</small></label><label>Additional indexed columns<input name=\"indexed_columns\" value=\"{}\" placeholder=\"number, issued_on\"></label><label>Base currency<input name=\"base_currency\" value=\"{}\" maxlength=\"3\" placeholder=\"EUR\"></label><label>Required links<input name=\"required_links\" value=\"{}\" placeholder=\"customer, address\"></label><label>Optional links<input name=\"optional_links\" value=\"{}\" placeholder=\"project\"></label><label>Row display columns<input name=\"row_display_columns\" value=\"{}\" placeholder=\"name, ico\"></label></div><div id=\"submission-status\" aria-live=\"polite\">{error}</div><div class=\"form-actions\"><a href=\"/admin\">Cancel</a><button type=\"submit\">Create table</button></div></form></section></main></body></html>",
crate::escape_html(&page.form.table_name),
crate::escape_html(&page.form.columns),
crate::escape_html(&page.form.indexed_columns),
crate::escape_html(&page.form.base_currency),
crate::escape_html(&page.form.required_links),
crate::escape_html(&page.form.optional_links),
crate::escape_html(&page.form.row_display_column),
crate::escape_html(&page.form.row_display_columns),
)
}

View File

@@ -69,7 +69,7 @@ pub(crate) async fn load_admin_page(
.map(|table| TableView {
name: table.name.clone(),
depends_on: table.depends_on.clone(),
row_display_column: table.row_display_column.clone(),
row_display_columns: table.row_display_columns.clone(),
})
.collect::<Vec<_>>()
})

View File

@@ -26,7 +26,7 @@ pub(crate) struct ProfileView {
pub(crate) struct TableView {
pub name: String,
pub depends_on: Vec<String>,
pub row_display_column: String,
pub row_display_columns: Vec<String>,
}
#[derive(Debug)]

View File

@@ -69,7 +69,7 @@ fn render_tables(page: &AdminPageState) -> String {
crate::escape_html(&table.name),
crate::escape_html(&table.name),
crate::escape_html(&dependencies),
crate::escape_html(&table.row_display_column),
crate::escape_html(&table.row_display_columns.join(", ")),
)
})
.collect()