Skip to content

feat(split): add save/load templates with address-book autocomplete - #174

Merged
truthixify merged 3 commits into
wraith-protocol:developfrom
JohnOluB:feat/155-batch-templates-address-book
Sep 3, 2026
Merged

feat(split): add save/load templates with address-book autocomplete#174
truthixify merged 3 commits into
wraith-protocol:developfrom
JohnOluB:feat/155-batch-templates-address-book

Conversation

@JohnOluB

@JohnOluB JohnOluB commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Closes #155

What this does
Templates panel on /stellar/split, listed on load, with Save-as-template, Load, Rename, Duplicate, Delete.
Per-row combobox on the recipient rows (shown once a batch is validated) that suggests saved contacts as you type, plus free-text entry for addresses not yet saved.
Export/Import templates as JSON, with a conflict modal when an imported template's id already exists locally with different content.
Add recipient button to build a batch row-by-row without pasting CSV at all.
Loading a template restores the exact row set and amounts; the underlying CSV textarea stays in sync via a new serializeRowsToCsv helper, so the existing validate/submit pipeline is untouched.
⚠️ Two things in the issue didn't match the codebase — flagging before review
"Combobox uses the ARIA pattern already established in address-book send autocomplete" — I couldn't find this anywhere (no address-book page, no combobox/listbox roles anywhere in the repo; the closest thing, AssetPicker.tsx, is a plain filtered dropdown with no ARIA combobox semantics). This PR builds a WAI-ARIA 1.2 combobox from scratch instead. Worth a careful look since it's establishing a pattern rather than reusing a proven one.
"Round-trippable with existing address-book export" — contactsStore.tsx has no export/import today. splitTemplatesStore.tsx already had a // Update the type field to match theirs exactly once you paste that code in TODO waiting on this, confirming it doesn't exist yet either. Kept that TODO as-is.

Neither blocks the feature, but the acceptance checklist as written assumes things that aren't there yet, so I didn't want to silently paper over it.

Implementation note

splitTemplatesStore.tsx already existed with CRUD (save/rename/delete/duplicate/getTemplate) and export. The only functional addition is conflict detection on import — importTemplates now takes an optional overwriteConflicts flag and returns { imported, skipped, conflicts } (was { imported, skipped }), and throws on invalid JSON instead of silently swallowing it. The import-resolution logic is pulled into a pure, exported resolveTemplateImport() so it's unit tested without a browser; everything else in the file — types, other CRUD signatures, localStorage persistence style, export envelope — is unchanged.

Testing
pnpm exec tsc --noEmit — clean
pnpm exec vitest run — 200/201 pass (new tests: splitTemplatesStore.test.ts covers CRUD + the export→import round trip via resolveTemplateImport; batchSend.test.ts covers serializeRowsToCsv + a round trip through parseCsvRows). The one failure, recoveryKit.test.ts › generates filename including meta-address prefix, is pre-existing on develop and unrelated to this change.
pnpm exec vite build — clean
pnpm format:check — clean
Not run here: pnpm test:a11y (Playwright/axe) and Storybook baseline generation for the new ContactCombobox.stories.tsx — no browser available in this environment. I reviewed the new markup carefully against tests/a11y/modals.spec.ts (which axe-scans this exact page post-validation), but please run both in CI before merging per CONTRIBUTING.md.
Files touched

src/store/splitTemplatesStore.tsx (extended), src/store/splitTemplatesStore.test.ts (new), src/components/ContactCombobox.tsx (new), src/components/ContactCombobox.stories.tsx (new), src/components/TemplateImportConflictModal.tsx (new), src/lib/stellar/batchSend.ts, src/lib/stellar/batchSend.test.ts, src/pages/StellarSplit.tsx, src/main.tsx

@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

@JohnOluB is attempting to deploy a commit to the truthixify's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

@JohnOluB Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@truthixify

Copy link
Copy Markdown
Contributor

Thanks @JohnOluB. build is failing on pnpm format:check only, one file:

src/store/splitTemplatesStore.tsx

Fix:

pnpm exec prettier --write src/
git commit -am "style: format"
git push

Worth adding pnpm format:check to your pre-push habit, it is the single most common reason PRs bounce here.

The template save/load itself looks like the right shape for #155. Once CI is green I will review the substance.

@truthixify
truthixify merged commit ed73915 into wraith-protocol:develop Sep 3, 2026
1 of 2 checks passed
@truthixify

Copy link
Copy Markdown
Contributor

Merged @JohnOluB. Templates with save/load/rename/duplicate, JSON export-import round trip and the contacts combobox wired into each row, which is the full scope of #155.

I ran prettier and pushed the formatting commit rather than bouncing it back a second time, since it was purely mechanical. Worth adding pnpm format:check to your pre-push routine though, it is the most common reason PRs stall here.

One thing that is not yours: src/lib/stellar/recoveryKit.test.ts fails on develop already, unrelated to this PR. Tracking that separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Batch send templates and address-book integration

2 participants