[LWDM] feat(contacts): render desktop address label (LIVE-33919) - #20268
[LWDM] feat(contacts): render desktop address label (LIVE-33919)#20268deepyjr wants to merge 2 commits into
Conversation
Web Tools Build Status
|
There was a problem hiding this comment.
Pull request overview
This PR updates the Desktop Contacts “Add address” flow to explicitly render the address naming, review, and success steps within the same dialog, while enforcing a shared 32-character maximum for address labels at both UI and domain levels.
Changes:
- Added shared web UI for the address-name step and a shared completion placeholder (review/success) step.
- Composed the new naming/review/success steps into the Desktop MVVM dialog flow and added i18n labels.
- Enforced and tested a shared 32-character address-label limit in the contact entity schema + validation logic.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| features/flow/contacts/src/steps/AddAddress/web.ts | Re-exports new shared web steps (name + completion) for Desktop composition. |
| features/flow/contacts/src/steps/AddAddress/useAddAddressFlowViewModel.web.test.ts | Adds a test ensuring review is blocked when label exceeds 32 chars. |
| features/flow/contacts/src/steps/AddAddress/Completion/ContactsAddAddressCompletion.web.tsx | Adds a shared web “completion” view used for review/success screens. |
| features/flow/contacts/src/steps/AddAddress/AddressName/useContactsAddAddressNameViewModel.web.ts | New view-model mapping shared state/labels to the web address-name view. |
| features/flow/contacts/src/steps/AddAddress/AddressName/types.ts | Defines props/labels/view-props for the shared address-name web step. |
| features/flow/contacts/src/steps/AddAddress/AddressName/ContactsAddAddressNameView.web.tsx | Implements shared web address-name UI with max length enforcement. |
| features/flow/contacts/src/steps/AddAddress/AddressName/ContactsAddAddressName.web.tsx | Wires view + view-model for the shared address-name step. |
| features/flow/contacts/src/steps/AddAddress/AddressName/ContactsAddAddressName.web.test.tsx | Unit tests for prefill, validation error rendering, and continue gating. |
| domain/entity/contact/src/validation.ts | Adds “too long” validation/exception behavior for address labels. |
| domain/entity/contact/src/validation.test.ts | Updates tests to cover too-long address labels and thrown error class. |
| domain/entity/contact/src/schema.ts | Introduces a shared CONTACT_ADDRESS_LABEL_MAX_LENGTH and schema .max(32). |
| domain/entity/contact/src/schema.test.ts | Adds schema-level test for rejecting labels longer than 32 chars. |
| domain/entity/contact/src/errors.ts | Adds ContactAddressLabelTooLongError + error-name constant to the union. |
| apps/ledger-live-desktop/static/i18n/en/app.json | Adds Desktop translations for naming/review/success steps and errors. |
| apps/ledger-live-desktop/src/mvvm/features/Contacts/screens/Contacts/useContactsViewModel.ts | Composes naming/review/success labels and hooks the new flow actions into the dialog props. |
| apps/ledger-live-desktop/src/mvvm/features/Contacts/screens/Contacts/components/ContactsAddAddressFlowDialog/types.ts | Extends dialog props for entry/name/review labels and new callbacks. |
| apps/ledger-live-desktop/src/mvvm/features/Contacts/screens/Contacts/components/ContactsAddAddressFlowDialog/index.ts | Re-exports the new review-labels type. |
| apps/ledger-live-desktop/src/mvvm/features/Contacts/screens/Contacts/components/ContactsAddAddressFlowDialog/ContactsAddAddressFlowDialog.tsx | Adds “name”, “review”, and “success” screens to the Desktop add-address dialog flow. |
| apps/ledger-live-desktop/src/mvvm/features/Contacts/integrations/Contacts.integration.test.tsx | Integration test validating in-dialog navigation + prefill + validation gating. |
| .changeset/live-33919-desktop-address-label.md | Declares package version bumps for the new shared flow + entity validation changes. |
Suppressed comments (1)
domain/entity/contact/src/validation.ts:90
- Same issue as above:
parseContactAddressLabelchecksdraftLabel.lengthbefore trimming, so a label that becomes <= 32 characters after trimming can incorrectly throwContactAddressLabelTooLongError. Use the trimmed length to stay consistent withContactAddressLabelSchema.
if (draftLabel.length > CONTACT_ADDRESS_LABEL_MAX_LENGTH) {
throw new ContactAddressLabelTooLongError();
}
Rsdoctor Bundle Diff AnalysisFound 7 projects in monorepo, 7 projects with changes. 📊 Quick Summary
📋 Detailed Reports (Click to expand)📁 desktop-mainPath:
📁 desktop-preloaderPath:
📁 desktop-rendererPath:
📁 desktop-webviewDappPreloaderPath:
📁 desktop-webviewPreloaderPath:
📁 desktop-workersPath:
📁 mobilePath:
Generated by Rsdoctor GitHub Action |
65435a1 to
6d92dcc
Compare
6d92dcc to
87c4002
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 26 changed files in this pull request and generated no new comments.
Suppressed comments (3)
domain/entity/contact/src/validation.ts:58
- The new max-length check uses the raw string length, but the schema trims input (NonEmptyStringSchema.trim). This can incorrectly flag labels as too long when they only exceed 32 characters due to leading/trailing spaces (and can also turn an all-spaces draft into a too-long error instead of “no error”). Align the check with the schema by measuring the trimmed length.
const trimmedDraftLabel = draftLabel.trim();
if (trimmedDraftLabel.length > CONTACT_ADDRESS_LABEL_MAX_LENGTH) {
domain/entity/contact/src/validation.ts:90
- Same issue as above: parseContactAddressLabel checks draftLabel.length before the schema trims. This can throw ContactAddressLabelTooLongError for inputs that would be valid after trimming. Use the trimmed length for the pre-check so behavior matches ContactAddressLabelSchema.
existingLabels: readonly ContactAddressLabel[] = [],
): ContactAddressLabel {
const trimmedDraftLabel = draftLabel.trim();
features/flow/contacts/src/steps/AddAddress/AddressName/ContactsAddAddressName.web.test.tsx:96
- This test asserts the validation message via a "helpertext" attribute, which couples the test to a specific DOM implementation detail of TextInput. Elsewhere in the codebase (e.g. apps/ledger-live-desktop/src/mvvm/features/Contacts/integrations/Contacts.integration.test.tsx:288) validation messages are asserted as visible text, which is both user-facing and less brittle.
expect(screen.getByTestId("contacts-add-address-name-input")).toHaveAttribute(
"helpertext",
message,
);
87c4002 to
c8abf08
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 30 changed files in this pull request and generated no new comments.
Suppressed comments (1)
domain/entity/contact/src/schema.ts:16
CONTACT_ADDRESS_LABEL_MAX_LENGTHis now defined in@domain/entity-contact(here) while the add-address flow still has its ownfeatures/flow/contacts/.../model/constants.tswith the same constant. This creates two sources of truth for the same business constraint (the label max length) and makes future changes error-prone (UI and flow validation could drift). Prefer keeping the constant only in the domain entity package and importing it everywhere else (flow + UI), or re-exporting it from the flow package without redefining it.
export const CONTACT_ADDRESS_LABEL_MAX_LENGTH = 32;
ffe3097 to
f20a5e4
Compare
|
Superseded by a focused stacked split: the Flow and compatibility changes move to #20316, while the Desktop integration will be recreated on top of it. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated no new comments.
Suppressed comments (2)
features/flow/contacts/src/steps/AddAddress/useContactsAddAddressEntryViewModel.web.ts:96
isConfirmEnabledis gated byisNameValid, butisNameValidcurrently depends only onaddressLabelbeing defined. Since the view only renders the name input whenaddressLabel && nameLabels && onAddressLabelChange, it’s possible to hide the name field while still blocking confirmation due to an invalidaddressLabel. Consider tying the "name required" logic to the same conditions used for rendering the name input.
const isNameValid = addressLabel === undefined || addressLabel.status === "valid";
return {
value: addressEntry.value,
labels,
domain/entity/contact/src/schema.ts:16
CONTACT_ADDRESS_LABEL_MAX_LENGTHis now defined in@domain/entity-contact(schema), but@features/flow-contactsalso defines/exports the same constant (features/flow/contacts/src/steps/AddAddress/model/constants.ts). Having two sources of truth for the same limit risks them drifting over time; consider consolidating so both domain validation and UI inputs reference a single exported constant.
export const CONTACT_ADDRESS_LABEL_MAX_LENGTH = 32;
|



✅ Checklist
npx changesetwas attached.📝 Description
Contacts on Desktop did not compose the address-label state exposed by the shared flow, so users could not enter the address and its name together before review.
This PR displays the editable address and prefilled address-name inputs together in the Desktop dialog immediately after asset selection. The single Continue to review CTA is enabled only when both fields are valid, and the 32-character maximum is enforced in the shared domain model and input. Review and success states remain in the same dialog.
Cap.2026-07-31.at.11.46.58.mp4
❓ Context
🧐 Checklist for the PR Reviewers