web displays system or user defined columns
This commit is contained in:
@@ -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"),
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user