deleted = true does enforce requireed fields2

This commit is contained in:
Priec
2026-09-03 10:05:36 +02:00
parent 0c5459ece1
commit 0d20546787
7 changed files with 8 additions and 47 deletions

View File

@@ -122,7 +122,7 @@ pub struct CommitTableDataImportRequest {
#[prost(string, tag = "1")] #[prost(string, tag = "1")]
pub import_id: ::prost::alloc::string::String, pub import_id: ::prost::alloc::string::String,
} }
#[derive(Clone, PartialEq, ::prost::Message)] #[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct CommitTableDataImportResponse { pub struct CommitTableDataImportResponse {
#[prost(bool, tag = "1")] #[prost(bool, tag = "1")]
pub success: bool, pub success: bool,

View File

@@ -616,7 +616,6 @@ import-success-message = Vloženo { $inserted ->
[few] { $source_rows } připravených řádků [few] { $source_rows } připravených řádků
*[other] { $source_rows } připravených řádků *[other] { $source_rows } připravených řádků
}. }.
import-success-warnings = Upozornění: { $warnings }
# --- Import v průběhu ------------------------------------------------------- # --- Import v průběhu -------------------------------------------------------
import-progress-heading = Importuje se do { $table } import-progress-heading = Importuje se do { $table }

View File

@@ -605,7 +605,6 @@ import-success-message = Inserted { $inserted ->
[one] { $source_rows } prepared row [one] { $source_rows } prepared row
*[other] { $source_rows } prepared rows *[other] { $source_rows } prepared rows
}. }.
import-success-warnings = Warnings: { $warnings }
# --- The import while it runs ---------------------------------------------- # --- The import while it runs ----------------------------------------------
import-progress-heading = Importing into { $table } import-progress-heading = Importing into { $table }

View File

@@ -614,7 +614,6 @@ import-success-message = Vložený { $inserted ->
[one] { $source_rows } pripraveného riadka [one] { $source_rows } pripraveného riadka
*[other] { $source_rows } pripravených riadkov *[other] { $source_rows } pripravených riadkov
}. }.
import-success-warnings = Upozornenia: { $warnings }
# --- Import počas behu ------------------------------------------------------ # --- Import počas behu ------------------------------------------------------
import-progress-heading = Importuje sa do { $table } import-progress-heading = Importuje sa do { $table }

View File

@@ -302,12 +302,11 @@ pub(crate) async fn import_progress(
let response = match &snapshot.outcome { let response = match &snapshot.outcome {
None => Html(ui::render_progress(locale, &id, &snapshot)).into_response(), None => Html(ui::render_progress(locale, &id, &snapshot)).into_response(),
Some(Outcome::Succeeded { warnings }) => Html(ui::render_success( Some(Outcome::Succeeded) => Html(ui::render_success(
locale, locale,
snapshot.inserted, snapshot.inserted,
snapshot.total_rows, snapshot.total_rows,
&snapshot.table_name, &snapshot.table_name,
warnings,
)) ))
.into_response(), .into_response(),
Some(Outcome::RowFailed { Some(Outcome::RowFailed {
@@ -448,19 +447,7 @@ async fn run_import(job: Running) {
Ok(response) => { Ok(response) => {
let response = response.into_inner(); let response = response.into_inner();
let inserted = usize::try_from(response.inserted_rows).unwrap_or(staged); let inserted = usize::try_from(response.inserted_rows).unwrap_or(staged);
let warnings = response jobs.finish(&job.id, inserted, Outcome::Succeeded);
.warnings
.into_iter()
.map(|warning| {
format!(
"CSV row {} ({}): {}",
warning.row_index + 2,
warning.table_name,
warning.message,
)
})
.collect();
jobs.finish(&job.id, inserted, Outcome::Succeeded { warnings });
} }
Err(error) => { Err(error) => {
abort_import(&job, &import_id).await; abort_import(&job, &import_id).await;

View File

@@ -34,7 +34,7 @@ const KEEP_FINISHED: Duration = Duration::from_secs(300);
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) enum Outcome { pub(crate) enum Outcome {
/// Every staged row was committed atomically. /// Every staged row was committed atomically.
Succeeded { warnings: Vec<String> }, Succeeded,
/// The backend stopped on one row. No rows from the import were committed. /// The backend stopped on one row. No rows from the import were committed.
RowFailed { RowFailed {
status: StatusCode, status: StatusCode,
@@ -255,7 +255,7 @@ mod tests {
assert!(jobs.is_running("session")); assert!(jobs.is_running("session"));
assert!(!jobs.is_running("other")); assert!(!jobs.is_running("other"));
jobs.finish(&id, 10, Outcome::Succeeded { warnings: Vec::new() }); jobs.finish(&id, 10, Outcome::Succeeded);
assert!(!jobs.is_running("session")); assert!(!jobs.is_running("session"));
} }
@@ -267,7 +267,7 @@ mod tests {
inserted: 0, inserted: 0,
total_rows: 0, total_rows: 0,
elapsed: Duration::from_secs(1), elapsed: Duration::from_secs(1),
outcome: Some(Outcome::Succeeded { warnings: Vec::new() }), outcome: Some(Outcome::Succeeded),
}; };
assert_eq!(snapshot.percent(), 100); assert_eq!(snapshot.percent(), 100);

View File

@@ -169,23 +169,14 @@ pub(crate) fn render_success(
inserted: usize, inserted: usize,
prepared_rows: usize, prepared_rows: usize,
table_name: &str, table_name: &str,
warnings: &[String],
) -> String { ) -> String {
let mut message = tr!( let message = tr!(
locale, locale,
"import-success-message", "import-success-message",
"inserted" => inserted as i64, "inserted" => inserted as i64,
"source_rows" => prepared_rows as i64, "source_rows" => prepared_rows as i64,
"table" => table_name.to_string(), "table" => table_name.to_string(),
); );
if !warnings.is_empty() {
message.push(' ');
message.push_str(&tr!(
locale,
"import-success-warnings",
"warnings" => warnings.join("; "),
));
}
render(&ImportSuccessDialog { render(&ImportSuccessDialog {
locale, locale,
title: &tr!(locale, "import-success-title"), title: &tr!(locale, "import-success-title"),
@@ -495,7 +486,7 @@ mod tests {
/// dialog the user has to actively dismiss, not a toast on its own timer. /// dialog the user has to actively dismiss, not a toast on its own timer.
#[test] #[test]
fn a_finished_import_answers_with_a_dismissible_dialog_not_a_toast() { fn a_finished_import_answers_with_a_dismissible_dialog_not_a_toast() {
let html = render_success(Locale::English, 500, 500, "customers", &[]); let html = render_success(Locale::English, 500, 500, "customers");
assert!(!html.contains("Template error"), "{html}"); assert!(!html.contains("Template error"), "{html}");
assert!(html.contains(r#"role="dialog""#), "{html}"); assert!(html.contains(r#"role="dialog""#), "{html}");
@@ -508,18 +499,4 @@ mod tests {
assert!(html.contains("keydown.esc"), "{html}"); assert!(html.contains("keydown.esc"), "{html}");
} }
#[test]
fn a_finished_import_displays_non_blocking_warnings() {
let html = render_success(
Locale::English,
1,
1,
"customers",
&["CSV row 2 (customers): Deleted row omitted required column 'name'".to_string()],
);
assert!(html.contains("Warnings:"), "{html}");
assert!(html.contains("CSV row 2"), "{html}");
assert!(html.contains("Deleted row omitted required column"), "{html}");
}
} }