feat: alignment on import conflict resolution terms

This commit is contained in:
2026-05-01 18:54:14 +02:00
parent f39fe9c40d
commit b2ced48cc5
5 changed files with 35 additions and 8 deletions

View File

@@ -61,7 +61,7 @@ Goal: align bDS2 with old bDS behavior. Use the Allium specs as the contract onl
- Spec: duplicates `ImportMediaRequested` with conflicting argument order across media specs.
- Action: normalize media specs to one event shape: source path plus project/context, with optional metadata where relevant.
## P2: Import Conflict Resolution Terms
## P2: Import Conflict Resolution Terms (done)
- Old bDS: conflict resolutions are `ignore`, `overwrite`, and `import`.
- bDS2 now: accepts/normalizes `skip -> ignore` and `merge -> overwrite`.

View File

@@ -583,8 +583,8 @@ defmodule BDS.Desktop.ShellLive.ImportEditor do
<input type="hidden" name="item_type" value={Map.get(item, :item_type)} />
<input type="hidden" name="item_name" value={Map.get(item, :slug)} />
<select class="resolution-select" name="resolution">
<option value="skip" selected={Map.get(item, :resolution) == "skip"}><%= translated("importAnalysis.ignore") %></option>
<option value="merge" selected={Map.get(item, :resolution) == "merge"}><%= translated("importAnalysis.overwrite") %></option>
<option value="ignore" selected={conflict_resolution_selected?(item, "ignore")}><%= translated("importAnalysis.ignore") %></option>
<option value="overwrite" selected={conflict_resolution_selected?(item, "overwrite")}><%= translated("importAnalysis.overwrite") %></option>
<option value="import" selected={Map.get(item, :resolution) == "import"}><%= translated("importAnalysis.importNewSlug") %></option>
</select>
</form>
@@ -883,4 +883,12 @@ defmodule BDS.Desktop.ShellLive.ImportEditor do
defp present?(value), do: value not in [nil, ""]
defp blank?(value), do: value in [nil, ""]
defp conflict_resolution_selected?(item, "ignore") do
Map.get(item, :resolution, "ignore") in ["ignore", "skip"]
end
defp conflict_resolution_selected?(item, "overwrite") do
Map.get(item, :resolution) in ["overwrite", "merge"]
end
end

View File

@@ -230,11 +230,12 @@ defmodule BDS.Desktop.ShellLive.ImportEditor.AnalysisState do
def importable_entity_count(items) do
Enum.count(items || [], fn item ->
item.status == "new" or
(item.status == "conflict" and
Map.get(item, :resolution, "ignore") not in ["ignore", "skip"])
(item.status == "conflict" and conflict_importable?(Map.get(item, :resolution, "ignore")))
end)
end
defp conflict_importable?(resolution), do: resolution in ["overwrite", "merge", "import"]
@spec detail_items(term(), term()) :: term()
def detail_items(nil, _bucket), do: []

View File

@@ -697,7 +697,7 @@ value ImportYearDistribution {
value ImportConflict {
item_type: String -- post | page | media
item_name: String
resolution: String -- import | skip | merge
resolution: String -- ignore | overwrite | import
}
value ImportMacro {
@@ -745,8 +745,8 @@ surface ImportAnalysisSurface {
-- Year-by-year bar charts for posts + media.
@guarantee ConflictsSection
-- Collapsible. Per-item dropdown: Import/Skip/Merge.
-- Default: Import for new items, Skip for existing matches.
-- Collapsible. Per-item dropdown: Ignore/Overwrite/Import.
-- Default: Import for new items, Ignore for existing matches.
@guarantee TaxonomySection
-- Collapsible. Category + tag pills.

View File

@@ -56,6 +56,11 @@ defmodule BDS.Desktop.ImportShellLiveTest do
assert html =~ "Ready to import:"
assert html =~ "Import 5 Items"
assert html =~ "Post Slug Conflicts"
assert html =~ ~s(<option value="ignore" selected)
assert html =~ ~s(<option value="overwrite")
assert html =~ ~s(<option value="import")
refute html =~ ~s(<option value="skip")
refute html =~ ~s(<option value="merge")
assert html =~ "Analyze with..."
assert html =~ "Posts (2)"
assert html =~ "Pages (1)"
@@ -64,6 +69,19 @@ defmodule BDS.Desktop.ImportShellLiveTest do
refute html =~ ~s(name="mapped_to")
refute html =~ "Desktop workbench content routed through the Elixir shell."
_html =
render_change(view, "change_import_conflict_resolution", %{
"item_type" => "post",
"item_name" => "conflict-me",
"resolution" => "overwrite"
})
updated_definition = ImportDefinitions.get_definition(definition.id)
updated_report = ImportDefinitions.decode_analysis_result(updated_definition)
assert [%{resolution: "overwrite"}] =
Enum.filter(updated_report.details.posts, &(&1.slug == "conflict-me"))
posts_html =
view
|> element("button[phx-value-section='posts']")