import ui
This commit is contained in:
@@ -109,14 +109,6 @@ pub(crate) async fn prepare_step(
|
||||
.collect::<HashMap<_, _>>();
|
||||
let has_answers = !form.destination.is_empty();
|
||||
|
||||
let positions_by_name = source
|
||||
.header
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(HashMap::<&str, Vec<usize>>::new(), |mut positions, (index, name)| {
|
||||
positions.entry(name.as_str()).or_default().push(index);
|
||||
positions
|
||||
});
|
||||
let rows = destination
|
||||
.columns
|
||||
.iter()
|
||||
@@ -125,10 +117,7 @@ pub(crate) async fn prepare_step(
|
||||
let chosen_index = if has_answers {
|
||||
answered.get(&key).copied()
|
||||
} else {
|
||||
positions_by_name
|
||||
.get(column.name.as_str())
|
||||
.filter(|positions| positions.len() == 1)
|
||||
.and_then(|positions| positions.first().copied())
|
||||
None
|
||||
};
|
||||
MappingRow {
|
||||
key,
|
||||
@@ -148,8 +137,8 @@ pub(crate) async fn prepare_step(
|
||||
|
||||
let step = Step::Mapping(MappingStep {
|
||||
table_name: destination.table_name.clone(),
|
||||
rows,
|
||||
sources: source_options(locale, &source),
|
||||
rows,
|
||||
source_rows: source.rows.len(),
|
||||
mapped,
|
||||
attention,
|
||||
|
||||
@@ -169,11 +169,15 @@ pub(crate) enum Step {
|
||||
|
||||
pub(crate) struct MappingStep {
|
||||
pub table_name: String,
|
||||
/// One fixed row per destination table column.
|
||||
pub rows: Vec<MappingRow>,
|
||||
/// Columns parsed from the CSV's first row, available to connect to a
|
||||
/// destination by dragging or selecting.
|
||||
pub sources: Vec<SourceOption>,
|
||||
/// One fixed row per destination table column.
|
||||
///
|
||||
/// Kept as its own list rather than zipped with `sources`: the two sides
|
||||
/// have no row-for-row relationship, and showing them as if they did makes
|
||||
/// mere adjacency look like a mapping.
|
||||
pub rows: Vec<MappingRow>,
|
||||
pub source_rows: usize,
|
||||
pub mapped: usize,
|
||||
pub attention: usize,
|
||||
|
||||
@@ -223,6 +223,31 @@ mod tests {
|
||||
assert!(html.contains(">Not mapped — leave empty</option>"), "{html}");
|
||||
}
|
||||
|
||||
/// The two sides are two lists, not one zipped table: a source chip carries
|
||||
/// only its own position, and a destination row only its own key. Nothing
|
||||
/// in the markup pairs the two by their displayed order.
|
||||
#[test]
|
||||
fn the_mapping_step_keeps_the_two_sides_apart() {
|
||||
let html = render_step(&page(mapping()));
|
||||
|
||||
assert_eq!(html.matches(r#"class="source-chip""#).count(), 2);
|
||||
assert_eq!(html.matches("data-map-target").count(), 2);
|
||||
// A destination names itself, so the palette can say where a column went.
|
||||
assert!(html.contains(r#"data-destination-name="a""#), "{html}");
|
||||
}
|
||||
|
||||
/// Moving a batch is the point of the step, so both ways of doing it are on
|
||||
/// the page: the whole file at once, and a selection placed by hand.
|
||||
#[test]
|
||||
fn the_mapping_step_offers_the_batch_actions() {
|
||||
let html = render_step(&page(mapping()));
|
||||
|
||||
assert!(html.contains("data-map-in-order"), "{html}");
|
||||
assert!(html.contains("data-clear-all-mappings"), "{html}");
|
||||
assert!(html.contains("data-select-all-sources"), "{html}");
|
||||
assert!(html.contains(r#"draggable="true""#), "{html}");
|
||||
}
|
||||
|
||||
/// The destination travels as its stable identity, never as its name, so a
|
||||
/// rename between the mapping and the import moves with the column.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user