web displays system or user defined columns

This commit is contained in:
Priec
2026-08-12 16:48:56 +02:00
parent bd76efeaac
commit 771109f61c
8 changed files with 85 additions and 4 deletions

View File

@@ -12,6 +12,12 @@ mod schema;
mod services;
mod ui;
mod authz;
// The server's system column vocabulary, read out of `common` the same way the
// generated protos are: this crate compiles that source tree directly instead
// of depending on the crate. Only `is_system_column` is used here.
#[path = "../../common/src/system_column.rs"]
#[allow(dead_code)]
mod system_column;
mod analytics {
include!(concat!(
env!("CARGO_MANIFEST_DIR"),

View File

@@ -122,6 +122,7 @@ pub(crate) async fn load_admin_page(
nullable: column.is_nullable,
primary_key: column.is_primary_key,
quantity_ledger: column.quantity_ledger,
system: crate::system_column::is_system_column(&column.name),
})
.collect()
}

View File

@@ -20,6 +20,20 @@ pub(crate) struct AdminPageState {
pub can_export: bool,
}
impl AdminPageState {
/// The columns the user defined, in the order the backend reported them.
/// The columns pane renders these first.
pub(crate) fn user_columns(&self) -> Vec<&ColumnView> {
self.columns.iter().filter(|column| !column.system).collect()
}
/// The columns the server puts on every managed table. They are hidden
/// everywhere else, so they trail the user's own here.
pub(crate) fn system_columns(&self) -> Vec<&ColumnView> {
self.columns.iter().filter(|column| column.system).collect()
}
}
#[derive(Debug)]
pub(crate) struct ProfileView {
pub name: String,
@@ -40,12 +54,18 @@ pub(crate) struct ColumnView {
pub nullable: bool,
pub primary_key: bool,
pub quantity_ledger: bool,
/// The server named this column, not the user. Ordinary screens never show
/// it, so the admin panel is the only place it is visible.
pub system: bool,
}
impl ColumnView {
/// The badge list rendered under each column name.
pub(crate) fn flags(&self) -> Vec<&'static str> {
let mut flags = Vec::new();
if self.system {
flags.push("system");
}
if self.primary_key {
flags.push("primary key");
}

View File

@@ -80,4 +80,41 @@ mod tests {
assert!(html.contains(route), "missing admin action route {route}");
}
}
#[test]
fn system_columns_render_after_the_user_defined_ones() {
let column = |name: &str, system: bool| crate::pages::admin::admin::state::ColumnView {
name: name.to_string(),
data_type: "TEXT".to_string(),
nullable: true,
primary_key: false,
quantity_ledger: false,
system,
};
let page = AdminPageState {
nav: Nav::default(),
profiles: Vec::new(),
selected_profile: Some("books".to_string()),
tables: Vec::new(),
selected_table: Some("invoice".to_string()),
// The backend reports the physical order, system columns first.
columns: vec![
column("id", true),
column("title", false),
column("created_at", true),
],
can_manage_tables: true,
can_manage_scripts: true,
can_manage_validations: true,
can_export: true,
};
let html = render_workspace(&page);
let title = html.find(">title<").expect("the user column is rendered");
let label = html
.find("System columns")
.expect("the system group is labelled");
let id = html.find(">id<").expect("the system column is rendered");
assert!(title < label && label < id, "system columns must trail");
}
}