versioning of FK for archiving
This commit is contained in:
@@ -35,6 +35,7 @@ pub(crate) struct TableDraft {
|
||||
/// Profile name typed in when creating a new profile.
|
||||
pub profile_name_input: String,
|
||||
pub creating_new_profile: bool,
|
||||
pub global: bool,
|
||||
pub accounting_currency: String,
|
||||
|
||||
pub table_name: String,
|
||||
@@ -69,11 +70,11 @@ impl TableDraft {
|
||||
// ---- field visibility (the same rules the TUI canvas applies) --------
|
||||
|
||||
pub(crate) fn show_profile_name_input(&self) -> bool {
|
||||
self.creating_new_profile
|
||||
self.creating_new_profile && !self.global
|
||||
}
|
||||
|
||||
pub(crate) fn show_accounting_currency(&self) -> bool {
|
||||
self.creating_new_profile
|
||||
self.creating_new_profile && !self.global
|
||||
}
|
||||
|
||||
// ---- mutations -------------------------------------------------------
|
||||
@@ -211,10 +212,10 @@ impl TableDraft {
|
||||
/// Every check the client runs before it will save.
|
||||
pub(crate) fn validate(&self) -> Result<(), String> {
|
||||
let profile_name = self.effective_profile_name();
|
||||
if self.creating_new_profile && profile_name.is_empty() {
|
||||
if !self.global && self.creating_new_profile && profile_name.is_empty() {
|
||||
return Err("Enter a name for the new profile.".to_string());
|
||||
}
|
||||
if let Some(error) = validate_identifier(&profile_name, "Profile name", false) {
|
||||
if !self.global && let Some(error) = validate_identifier(&profile_name, "Profile name", false) {
|
||||
return Err(error);
|
||||
}
|
||||
if let Some(error) = validate_accounting_currency(self) {
|
||||
@@ -244,18 +245,19 @@ impl TableDraft {
|
||||
profile_name: self.effective_profile_name(),
|
||||
columns: proto_columns(&self.columns.added),
|
||||
indexes: self.columns.selected_index_names(),
|
||||
accounting_currency: if self.creating_new_profile {
|
||||
accounting_currency: if self.creating_new_profile && !self.global {
|
||||
self.accounting_currency.trim().to_ascii_uppercase()
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
row_display_columns: self.row_display_columns.clone(),
|
||||
global: self.global,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate_accounting_currency(draft: &TableDraft) -> Option<String> {
|
||||
if !draft.creating_new_profile {
|
||||
if !draft.creating_new_profile || draft.global {
|
||||
return None;
|
||||
}
|
||||
let currency = draft.accounting_currency.to_ascii_uppercase();
|
||||
|
||||
@@ -60,7 +60,26 @@ pub(crate) async fn load_page(
|
||||
.into_inner();
|
||||
|
||||
let effective_profile = draft.effective_profile_name();
|
||||
match tree
|
||||
if draft.global {
|
||||
let global_tables = tree
|
||||
.profiles
|
||||
.iter()
|
||||
.flat_map(|profile| profile.tables.iter())
|
||||
.filter(|table| table.global)
|
||||
.map(|table| table.name.clone())
|
||||
.collect::<std::collections::BTreeSet<_>>()
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>();
|
||||
draft.existing_profile_tables = tree
|
||||
.profiles
|
||||
.iter()
|
||||
.flat_map(|profile| profile.tables.iter())
|
||||
.map(|table| table.name.clone())
|
||||
.collect::<std::collections::BTreeSet<_>>()
|
||||
.into_iter()
|
||||
.collect();
|
||||
draft.set_available_relation_tables(global_tables);
|
||||
} else { match tree
|
||||
.profiles
|
||||
.iter()
|
||||
.find(|profile| profile.name == effective_profile)
|
||||
@@ -82,7 +101,7 @@ pub(crate) async fn load_page(
|
||||
draft.existing_profile_tables.clear();
|
||||
draft.relation_tables.clear();
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
Ok(AddTablePageState {
|
||||
nav: crate::ui::Nav::new(headers, "admin").with_authorization(&authorization),
|
||||
|
||||
@@ -98,7 +98,8 @@ pub(crate) async fn create_table(
|
||||
};
|
||||
|
||||
let mut definitions = state.definitions;
|
||||
match definitions.post_table_definition(request).await {
|
||||
let result = definitions.post_table_definition(request).await;
|
||||
match result {
|
||||
Ok(response) if response.get_ref().success => {
|
||||
let location = format!(
|
||||
"/admin/table-definition?profile={profile_name}&table={}",
|
||||
|
||||
@@ -34,6 +34,8 @@ pub(crate) struct BuilderForm {
|
||||
#[serde(default)]
|
||||
pub accounting_currency: String,
|
||||
#[serde(default)]
|
||||
pub global: bool,
|
||||
#[serde(default)]
|
||||
pub table_name: String,
|
||||
|
||||
// The pending column being described in the input panel.
|
||||
@@ -134,6 +136,7 @@ impl BuilderForm {
|
||||
profile_name_input: self.profile_name_input.clone(),
|
||||
creating_new_profile,
|
||||
accounting_currency: self.accounting_currency.clone(),
|
||||
global: self.global,
|
||||
table_name: self.table_name.clone(),
|
||||
columns,
|
||||
relation_tables: self.relation_tables.clone(),
|
||||
|
||||
@@ -24,6 +24,15 @@
|
||||
<section class="builder-section">
|
||||
<h2>Table</h2>
|
||||
<div class="form-grid">
|
||||
<label>Scope
|
||||
<span><input type="checkbox" name="global" value="true"
|
||||
{% if page.draft.global %}checked{% endif %}
|
||||
hx-post="/admin/tables/builder" hx-trigger="change"
|
||||
hx-include="#table-form" hx-target="#builder" hx-swap="innerHTML"
|
||||
hx-vals='{"action": "refresh"}'> Shared across profiles</span>
|
||||
</label>
|
||||
|
||||
{% if !page.draft.global %}
|
||||
<label>Profile
|
||||
<select name="profile_name" hx-post="/admin/tables/builder" hx-trigger="change"
|
||||
hx-include="#table-form" hx-target="#builder" hx-swap="innerHTML"
|
||||
@@ -35,6 +44,9 @@
|
||||
<option value="__new__" {% if page.draft.creating_new_profile %}selected{% endif %}>+ New profile…</option>
|
||||
</select>
|
||||
</label>
|
||||
{% else %}
|
||||
<input type="hidden" name="profile_name" value="{{ page.draft.profile_name }}">
|
||||
{% endif %}
|
||||
|
||||
{% if page.draft.show_profile_name_input() %}
|
||||
<label>New profile name
|
||||
|
||||
Reference in New Issue
Block a user