1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
require "pro_tacts/admin/phlex"
require "pro_tacts/import/vcf"
module ProTacts
module Admin
# The left-hand card of an import's walk: one contact exactly as
# the file wrote it (docs/plans/2026-09-21-import-a-vcf.md).
#
# Content lines rather than a rendered contact, and in the
# monospace the bytes are actually in. The card beside this one is
# the rendered reading — it is the editor, over what is coming in —
# so a second rendering here would show the same thing twice and
# answer neither question this card is for: what did the source
# actually say, and what of it is not coming with it.
#
# A line that is not coming in is struck in Gloss's danger color
# and says so in words beside it (the plan, "The walk"); the
# blanked editor row wears that color for the same reason
# (admin.css). Nothing here is a control: what to do about a
# struck line is done in the editor beside it.
class ImportOriginal < Phlex::HTML
# @rbs @card: ::ProTacts::VCard
# @rbs @dropped: Array[String]
# `dropped` is the lines that are not coming in (Vcf::Reading),
# matched here by digest. Two byte-identical lines digest alike
# and share a fate — the reading is by property name — so there
# is no pair this cannot tell apart that it would want to.
#: (card: ::ProTacts::VCard, dropped: Array[::ProTacts::VCard::Parser::Line]) -> void
def initialize(card:, dropped:)
@card = card
@dropped = dropped.map(&:digest)
end
def view_template
div(class: "card") do
div(class: "card-body") do
ul(class: "card-lines") do
@card.lines.each { line(it) }
end
end
end
end
private
# A blank line is not a line to show: it carries no property and
# says nothing about what the source held.
#: (::ProTacts::VCard::Parser::Line line) -> void
def line(line)
text = ::ProTacts::Import::Vcf.summary(line)
return if text.strip.empty?
dropped = @dropped.include?(line.digest)
li(**(dropped ? {data: {dropped: true}} : {})) do
span { text }
span(class: "type-label") { "not imported" } if dropped
end
end
end
end
end