multirow FK

This commit is contained in:
Priec
2026-08-07 22:39:59 +02:00
parent c47e236713
commit 0d78556428
10 changed files with 46 additions and 216 deletions

View File

@@ -1,7 +1,7 @@
//! Wire format for the builder form, and the page state the templates read.
//!
//! HTTP is stateless, so the whole draft travels with every interaction: each
//! already-added column, link and display column is posted back as a set of
//! already-added column and display column is posted back as a set of
//! parallel repeated fields. `serde_html_form` (via `axum_extra::extract::Form`)
//! decodes the repeats into `Vec`s, which `to_draft` zips back into a
//! [`TableDraft`].
@@ -13,7 +13,7 @@
use crate::schema::{ColumnCatalog, ColumnDraft, columns_from_rows};
use super::draft::{LinkDefinition, LinkMode, TableDraft};
use super::draft::TableDraft;
/// The `profile_name` option meaning "create a new profile too".
pub(crate) const NEW_PROFILE: &str = "__new__";
@@ -72,11 +72,9 @@ pub(crate) struct BuilderForm {
#[serde(default)]
pub column_currencies: Vec<String>,
// One entry per link target offered by the profile, in order.
// Tables the profile offers as link targets, in order.
#[serde(default)]
pub link_tables: Vec<String>,
#[serde(default)]
pub link_modes: Vec<String>,
pub relation_tables: Vec<String>,
#[serde(default)]
pub row_display_columns: Vec<String>,
@@ -118,14 +116,6 @@ impl BuilderForm {
creating_table: true,
};
let link_count = self.link_tables.len().min(self.link_modes.len());
let links = (0..link_count)
.map(|index| LinkDefinition {
linked_table_name: self.link_tables[index].clone(),
mode: LinkMode::from_label(&self.link_modes[index]),
})
.collect();
// Drop display columns whose column is gone, so a stale post cannot
// send a display column that no longer exists.
let row_display_columns = self
@@ -146,7 +136,7 @@ impl BuilderForm {
accounting_currency: self.accounting_currency.clone(),
table_name: self.table_name.clone(),
columns,
links,
relation_tables: self.relation_tables.clone(),
row_display_columns,
// Filled in by the loader from the live profile tree, never by the
// client: it is what duplicate table names are checked against.
@@ -240,22 +230,20 @@ mod tests {
column_quantity_ledger: vec!["no".into(), "no".into()],
column_rounding: vec!["exact".into(), "half-up".into()],
column_currencies: vec![String::new(), "EUR".into()],
link_tables: vec!["customer".into(), "project".into()],
link_modes: vec!["required".into(), "none".into()],
relation_tables: vec!["customer".into(), "project".into()],
row_display_columns: vec!["number".into()],
..Default::default()
}
}
#[test]
fn round_trips_columns_links_and_display_columns() {
fn round_trips_columns_relation_tables_and_display_columns() {
let draft = posted_form().to_draft();
assert_eq!(draft.columns.added.len(), 2);
assert!(draft.columns.added[0].indexed);
assert_eq!(draft.columns.added[1].money_mode, MoneyMode::Rounded);
assert_eq!(draft.links[0].mode, LinkMode::Required);
assert_eq!(draft.links[1].mode, LinkMode::None);
assert_eq!(draft.relation_tables, vec!["customer", "project"]);
assert_eq!(draft.row_display_columns, vec!["number"]);
assert!(!draft.creating_new_profile);
}