Skip to content

Commit 05b8a80

Browse files
cpcloudclaude
andauthored
fix(ui): use row locale for extraction preview phone formatting (#886)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent fba7c4a commit 05b8a80

3 files changed

Lines changed: 93 additions & 15 deletions

File tree

internal/app/extraction_render.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,26 @@ func groupOperationsByTable(ops []extract.Operation, cur locale.Currency) []prev
830830
keyByTitle[d.spec.Title] = d.dataKey
831831
}
832832

833+
// For vendor rows with a locale, override the phone formatter
834+
// to use the row-level locale instead of the system default.
835+
if op.Table == data.TableVendors {
836+
if loc, _ := op.Data[data.ColLocale].(string); loc != "" {
837+
for _, d := range allDefs {
838+
if d.dataKey == data.ColPhone {
839+
region := strings.ToUpper(loc)
840+
fmtByTitle[d.spec.Title] = func(v any) string {
841+
s, ok := v.(string)
842+
if !ok || s == "" {
843+
return fmtAnyText(v)
844+
}
845+
return locale.FormatPhoneNumber(s, region)
846+
}
847+
break
848+
}
849+
}
850+
}
851+
}
852+
833853
row := make([]cell, len(g.specs))
834854
for i, spec := range g.specs {
835855
key := keyByTitle[spec.Title]

internal/app/extraction_render_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"testing"
88

99
"github.com/micasa-dev/micasa/internal/data"
10+
"github.com/micasa-dev/micasa/internal/extract"
1011
"github.com/micasa-dev/micasa/internal/locale"
1112
"github.com/stretchr/testify/assert"
1213
"github.com/stretchr/testify/require"
@@ -34,3 +35,49 @@ func TestPreviewColumnsVendorFormatsPhone(t *testing.T) {
3435
assert.Equal(t, "(555) 123-4567", phoneFmt("5551234567"))
3536
assert.Equal(t, "not a phone", phoneFmt("not a phone"))
3637
}
38+
39+
func TestGroupOperationsByTableUsesRowLocale(t *testing.T) {
40+
// Not parallel: t.Setenv modifies process-global state.
41+
t.Setenv("LC_ALL", "en_US.UTF-8")
42+
cur, err := locale.ResolveDefault("")
43+
require.NoError(t, err)
44+
45+
ops := []extract.Operation{
46+
{
47+
Action: extract.ActionCreate,
48+
Table: data.TableVendors,
49+
Data: map[string]any{
50+
data.ColName: "UK Plumber",
51+
data.ColPhone: "02079460958",
52+
data.ColLocale: "GB",
53+
},
54+
},
55+
{
56+
Action: extract.ActionCreate,
57+
Table: data.TableVendors,
58+
Data: map[string]any{
59+
data.ColName: "US Plumber",
60+
data.ColPhone: "5551234567",
61+
},
62+
},
63+
}
64+
65+
groups := groupOperationsByTable(ops, cur)
66+
require.Len(t, groups, 1)
67+
require.Len(t, groups[0].cells, 2)
68+
69+
// Find phone column index.
70+
phoneIdx := -1
71+
for i, spec := range groups[0].specs {
72+
if spec.Title == "Phone" {
73+
phoneIdx = i
74+
break
75+
}
76+
}
77+
require.NotEqual(t, -1, phoneIdx, "phone column not found")
78+
79+
// UK vendor should use GB locale formatting.
80+
assert.Equal(t, "020 7946 0958", groups[0].cells[0][phoneIdx].Value)
81+
// US vendor (no locale) should fall back to system default (US).
82+
assert.Equal(t, "(555) 123-4567", groups[0].cells[1][phoneIdx].Value)
83+
}

internal/app/vendor_test.go

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -218,23 +218,33 @@ func TestVendorLocalePreservedOnEdit(t *testing.T) {
218218
Locale: "GB",
219219
}))
220220

221-
vendors, err := m.store.ListVendors(false)
222-
require.NoError(t, err)
223-
require.Len(t, vendors, 1)
224-
id := vendors[0].ID
221+
// Navigate to vendor tab and reload.
222+
for i, tab := range m.tabs {
223+
if tab.Kind == tabVendors {
224+
m.active = i
225+
break
226+
}
227+
}
228+
require.NoError(t, m.reloadActiveTab())
229+
tab := m.activeTab()
230+
require.NotEmpty(t, tab.Rows)
231+
tab.Table.SetCursor(0)
232+
id := tab.Rows[0].ID
225233

226-
// Open the real edit form -- this calls vendorFormValues(vendor)
227-
// which copies Locale from the DB record into formData.
228-
require.NoError(t, m.startEditVendorForm(id))
229-
m.fs.form.Init()
234+
// Open edit form via keypresses.
235+
sendKey(m, "i")
236+
tab.ColCursor = int(vendorColID)
237+
sendKey(m, "e")
238+
require.Equal(t, modeForm, m.mode, "should open full edit form")
230239

231-
// Change the name through the form data (simulates user editing).
240+
// Change the name through the form data.
232241
values, ok := m.fs.formData.(*vendorFormData)
233242
require.True(t, ok)
234243
values.Name = "UK Plumber Renamed"
235244

236-
// Submit -- parseVendorFormData carries Locale through.
237-
require.NoError(t, m.submitVendorForm())
245+
// Submit via keypress.
246+
sendKey(m, "ctrl+s")
247+
sendKey(m, "esc")
238248

239249
// Reload and verify Locale is preserved.
240250
updated, err := m.store.GetVendor(id)
@@ -273,10 +283,11 @@ func TestVendorInlineEditPhoneUsesRawValue(t *testing.T) {
273283
phoneCell := tab.CellRows[0][int(vendorColPhone)]
274284
assert.Equal(t, "020 7946 0958", phoneCell.Value, "table should show formatted phone")
275285

276-
id := tab.Rows[0].ID
277-
278-
// Open inline edit for phone column.
279-
require.NoError(t, m.inlineEditVendor(id, vendorColPhone))
286+
// Open inline edit for phone column via keypresses.
287+
tab.Table.SetCursor(0)
288+
sendKey(m, "i")
289+
tab.ColCursor = int(vendorColPhone)
290+
sendKey(m, "e")
280291
require.NotNil(t, m.inlineInput)
281292

282293
// The inline input should contain the raw DB value, not the formatted one.

0 commit comments

Comments
 (0)