feat(dashboard): Allow creating customer and address inline on draft …#4952
feat(dashboard): Allow creating customer and address inline on draft …#4952Ryrahul wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe React dashboard adds inline customer creation to draft orders and inline ad-hoc address entry to draft-order and order-modification flows. Customer and address selectors use tabbed popovers with typed submission callbacks and address-form mapping. Draft-order mutations receive new customer and address inputs, while order modification exposes raw address update handlers. End-to-end tests cover both flows, and localization catalogs are regenerated with updated references and UI strings. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…orders Brings the React dashboard draft order flow to parity with the Angular admin-ui by allowing an admin to create a new customer inline and enter a new/ad-hoc shipping or billing address inline, rather than only selecting existing records. - CustomerSelector gains an opt-in `allowCreateNew` mode rendering a tabbed popover (select existing / create new) that emits a CreateCustomerInput via `onCreateNew`. - CustomerAddressSelector gains a "New address" tab embedding the shared CustomerAddressForm, emitting a CreateAddressInput via `onSubmitNew`. - CustomerAddressForm gains a `hideDefaultAddressFlags` prop (the default shipping/billing flags are not applicable in the draft order context). - Wired into both the draft order page and the order modification page. No backend changes required: setCustomerForDraftOrder already accepts a CreateCustomerInput, and the draft order address mutations accept a CreateAddressInput. Relates to vendurehq#4838
b8092ae to
cfa605f
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx (2)
44-48: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winOpt out of
placeholderData: keepPreviousDatafor this identity-keyed query.
queryKey: ['customerAddresses', customerId]carries identity, matching the guideline's own['customerGroup', id]example. Without opting out, switching to a different/newly-created customer can momentarily render the previous customer's address list before the new query resolves.🛡️ Proposed fix
const { data, isLoading } = useQuery<CustomerAddressesQuery>({ queryKey: ['customerAddresses', customerId], queryFn: () => api.query(getCustomerAddressesDocument, { customerId: customerId ?? '' }), enabled: !!customerId, + placeholderData: undefined, });Based on learnings, "React Query:
placeholderData: keepPreviousDatais configured globally. Opt out per-query (placeholderData: undefined) when the queryKey carries identity (e.g.['customerGroup', id]) and showing previous identity's data would be misleading."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx` around lines 44 - 48, Disable the globally configured keep-previous-data behavior for the identity-keyed query in the customer address selector by setting placeholderData to undefined in the useQuery options for customerAddresses. Keep the customerId-based queryKey and existing loading behavior unchanged.Source: Coding guidelines
44-54: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winTab auto-switches away from "New address" once the addresses query resolves.
canSelectExistingis computed fromaddresses.length > 0, which is always0whileisLoadingistrue— so during loading the tab is forced to'new', then flips back to the storedactiveTab('existing'by default) as soon as the query resolves and the customer turns out to have saved addresses. This can happen right after selecting/creating a customer (this PR's own new flow) and yanks the user out of the "New address" tab mid-entry.🐛 Proposed fix
- const canSelectExisting = !!customerId && addresses.length > 0; + const canSelectExisting = !!customerId && (isLoading || addresses.length > 0);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx` around lines 44 - 54, Prevent the selected tab from changing when the customer-address query transitions from loading to loaded. Update the tab-selection logic around canSelectExisting and effectiveTab in the customer address selector to preserve an explicitly chosen “new” tab during loading and after addresses are fetched, only defaulting to “existing” when appropriate for a newly initialized customer.
🧹 Nitpick comments (2)
packages/dashboard/src/lib/components/shared/customer-selector.tsx (2)
70-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winValidation error messages bypass the i18n system.
createCustomerFormSchemahardcodes English error strings ('First name is required','Last name is required','Email address is required') instead of usingTrans/useLingui'stlike the rest of this component (e.g. placeholders, labels). Given the huge number of locale catalogs in this repo, these validation messages will always render in English regardless of the admin's selected language.♻️ Suggested fix using useLingui's `t`
-const createCustomerFormSchema = z.object({ - title: z.string().optional(), - firstName: z.string().min(1, { message: 'First name is required' }), - lastName: z.string().min(1, { message: 'Last name is required' }), - emailAddress: z.string().min(1, { message: 'Email address is required' }).email(), - phoneNumber: z.string().optional(), -}); +function useCreateCustomerFormSchema() { + const { t } = useLingui(); + return z.object({ + title: z.string().optional(), + firstName: z.string().min(1, { message: t`First name is required` }), + lastName: z.string().min(1, { message: t`Last name is required` }), + emailAddress: z.string().min(1, { message: t`Email address is required` }).email(), + phoneNumber: z.string().optional(), + }); +}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/dashboard/src/lib/components/shared/customer-selector.tsx` around lines 70 - 78, Replace the hardcoded English validation messages in createCustomerFormSchema with localized messages using the component’s useLingui/t pattern. Ensure the schema is created where the translation function is available, and apply localized text to the firstName, lastName, and emailAddress required validations.
70-76: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueZod
.min()messageoption is deprecated in v4 in favor oferror.Confirmed via Zod v4 migration docs: the
messageparam is "still supported but deprecated," replaced by the unifiederrorparameter. Functionally fine today, but worth migrating for forward compatibility.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/dashboard/src/lib/components/shared/customer-selector.tsx` around lines 70 - 76, Update the createCustomerFormSchema validation rules to use Zod v4’s error option instead of the deprecated message option for the firstName, lastName, and emailAddress min-length checks, preserving the existing validation text and behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/dashboard/src/lib/components/shared/customer-selector.tsx`:
- Around line 196-283: Reset activeTab to 'existing' whenever the popover is
closed programmatically: update the onSelect callback in CustomerSearch and the
onSubmit callback in CreateCustomerForm to call setActiveTab('existing')
alongside setOpen(false). Keep the existing onOpenChange reset for user-driven
closures.
---
Outside diff comments:
In
`@packages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx`:
- Around line 44-48: Disable the globally configured keep-previous-data behavior
for the identity-keyed query in the customer address selector by setting
placeholderData to undefined in the useQuery options for customerAddresses. Keep
the customerId-based queryKey and existing loading behavior unchanged.
- Around line 44-54: Prevent the selected tab from changing when the
customer-address query transitions from loading to loaded. Update the
tab-selection logic around canSelectExisting and effectiveTab in the customer
address selector to preserve an explicitly chosen “new” tab during loading and
after addresses are fetched, only defaulting to “existing” when appropriate for
a newly initialized customer.
---
Nitpick comments:
In `@packages/dashboard/src/lib/components/shared/customer-selector.tsx`:
- Around line 70-78: Replace the hardcoded English validation messages in
createCustomerFormSchema with localized messages using the component’s
useLingui/t pattern. Ensure the schema is created where the translation function
is available, and apply localized text to the firstName, lastName, and
emailAddress required validations.
- Around line 70-76: Update the createCustomerFormSchema validation rules to use
Zod v4’s error option instead of the deprecated message option for the
firstName, lastName, and emailAddress min-length checks, preserving the existing
validation text and behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 894f94a2-ab65-41a5-9621-be977d4f371e
📒 Files selected for processing (35)
packages/dashboard/e2e/tests/sales/orders.spec.tspackages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsxpackages/dashboard/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsxpackages/dashboard/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsxpackages/dashboard/src/app/routes/_authenticated/_orders/utils/use-modify-order.tspackages/dashboard/src/i18n/locales/ar.popackages/dashboard/src/i18n/locales/bg.popackages/dashboard/src/i18n/locales/cs.popackages/dashboard/src/i18n/locales/de.popackages/dashboard/src/i18n/locales/en.popackages/dashboard/src/i18n/locales/es.popackages/dashboard/src/i18n/locales/fa.popackages/dashboard/src/i18n/locales/fr.popackages/dashboard/src/i18n/locales/he.popackages/dashboard/src/i18n/locales/hr.popackages/dashboard/src/i18n/locales/hu.popackages/dashboard/src/i18n/locales/it.popackages/dashboard/src/i18n/locales/ja.popackages/dashboard/src/i18n/locales/nb.popackages/dashboard/src/i18n/locales/ne.popackages/dashboard/src/i18n/locales/nl.popackages/dashboard/src/i18n/locales/pl.popackages/dashboard/src/i18n/locales/pt_BR.popackages/dashboard/src/i18n/locales/pt_PT.popackages/dashboard/src/i18n/locales/ro.popackages/dashboard/src/i18n/locales/ru.popackages/dashboard/src/i18n/locales/sv.popackages/dashboard/src/i18n/locales/tr.popackages/dashboard/src/i18n/locales/uk.popackages/dashboard/src/i18n/locales/uz.popackages/dashboard/src/i18n/locales/zh_Hans.popackages/dashboard/src/i18n/locales/zh_Hant.popackages/dashboard/src/lib/components/shared/customer-address-form.tsxpackages/dashboard/src/lib/components/shared/customer-selector.tsxpackages/dev-server/graphql/graphql-env.d.ts
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx (2)
44-48: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winOpt out of
placeholderData: keepPreviousDatafor this identity-keyed query.
queryKey: ['customerAddresses', customerId]carries identity, matching the guideline's own['customerGroup', id]example. Without opting out, switching to a different/newly-created customer can momentarily render the previous customer's address list before the new query resolves.🛡️ Proposed fix
const { data, isLoading } = useQuery<CustomerAddressesQuery>({ queryKey: ['customerAddresses', customerId], queryFn: () => api.query(getCustomerAddressesDocument, { customerId: customerId ?? '' }), enabled: !!customerId, + placeholderData: undefined, });Based on learnings, "React Query:
placeholderData: keepPreviousDatais configured globally. Opt out per-query (placeholderData: undefined) when the queryKey carries identity (e.g.['customerGroup', id]) and showing previous identity's data would be misleading."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx` around lines 44 - 48, Disable the globally configured keep-previous-data behavior for the identity-keyed query in the customer address selector by setting placeholderData to undefined in the useQuery options for customerAddresses. Keep the customerId-based queryKey and existing loading behavior unchanged.Source: Coding guidelines
44-54: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winTab auto-switches away from "New address" once the addresses query resolves.
canSelectExistingis computed fromaddresses.length > 0, which is always0whileisLoadingistrue— so during loading the tab is forced to'new', then flips back to the storedactiveTab('existing'by default) as soon as the query resolves and the customer turns out to have saved addresses. This can happen right after selecting/creating a customer (this PR's own new flow) and yanks the user out of the "New address" tab mid-entry.🐛 Proposed fix
- const canSelectExisting = !!customerId && addresses.length > 0; + const canSelectExisting = !!customerId && (isLoading || addresses.length > 0);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx` around lines 44 - 54, Prevent the selected tab from changing when the customer-address query transitions from loading to loaded. Update the tab-selection logic around canSelectExisting and effectiveTab in the customer address selector to preserve an explicitly chosen “new” tab during loading and after addresses are fetched, only defaulting to “existing” when appropriate for a newly initialized customer.
🧹 Nitpick comments (2)
packages/dashboard/src/lib/components/shared/customer-selector.tsx (2)
70-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winValidation error messages bypass the i18n system.
createCustomerFormSchemahardcodes English error strings ('First name is required','Last name is required','Email address is required') instead of usingTrans/useLingui'stlike the rest of this component (e.g. placeholders, labels). Given the huge number of locale catalogs in this repo, these validation messages will always render in English regardless of the admin's selected language.♻️ Suggested fix using useLingui's `t`
-const createCustomerFormSchema = z.object({ - title: z.string().optional(), - firstName: z.string().min(1, { message: 'First name is required' }), - lastName: z.string().min(1, { message: 'Last name is required' }), - emailAddress: z.string().min(1, { message: 'Email address is required' }).email(), - phoneNumber: z.string().optional(), -}); +function useCreateCustomerFormSchema() { + const { t } = useLingui(); + return z.object({ + title: z.string().optional(), + firstName: z.string().min(1, { message: t`First name is required` }), + lastName: z.string().min(1, { message: t`Last name is required` }), + emailAddress: z.string().min(1, { message: t`Email address is required` }).email(), + phoneNumber: z.string().optional(), + }); +}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/dashboard/src/lib/components/shared/customer-selector.tsx` around lines 70 - 78, Replace the hardcoded English validation messages in createCustomerFormSchema with localized messages using the component’s useLingui/t pattern. Ensure the schema is created where the translation function is available, and apply localized text to the firstName, lastName, and emailAddress required validations.
70-76: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueZod
.min()messageoption is deprecated in v4 in favor oferror.Confirmed via Zod v4 migration docs: the
messageparam is "still supported but deprecated," replaced by the unifiederrorparameter. Functionally fine today, but worth migrating for forward compatibility.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/dashboard/src/lib/components/shared/customer-selector.tsx` around lines 70 - 76, Update the createCustomerFormSchema validation rules to use Zod v4’s error option instead of the deprecated message option for the firstName, lastName, and emailAddress min-length checks, preserving the existing validation text and behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/dashboard/src/lib/components/shared/customer-selector.tsx`:
- Around line 196-283: Reset activeTab to 'existing' whenever the popover is
closed programmatically: update the onSelect callback in CustomerSearch and the
onSubmit callback in CreateCustomerForm to call setActiveTab('existing')
alongside setOpen(false). Keep the existing onOpenChange reset for user-driven
closures.
---
Outside diff comments:
In
`@packages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx`:
- Around line 44-48: Disable the globally configured keep-previous-data behavior
for the identity-keyed query in the customer address selector by setting
placeholderData to undefined in the useQuery options for customerAddresses. Keep
the customerId-based queryKey and existing loading behavior unchanged.
- Around line 44-54: Prevent the selected tab from changing when the
customer-address query transitions from loading to loaded. Update the
tab-selection logic around canSelectExisting and effectiveTab in the customer
address selector to preserve an explicitly chosen “new” tab during loading and
after addresses are fetched, only defaulting to “existing” when appropriate for
a newly initialized customer.
---
Nitpick comments:
In `@packages/dashboard/src/lib/components/shared/customer-selector.tsx`:
- Around line 70-78: Replace the hardcoded English validation messages in
createCustomerFormSchema with localized messages using the component’s
useLingui/t pattern. Ensure the schema is created where the translation function
is available, and apply localized text to the firstName, lastName, and
emailAddress required validations.
- Around line 70-76: Update the createCustomerFormSchema validation rules to use
Zod v4’s error option instead of the deprecated message option for the
firstName, lastName, and emailAddress min-length checks, preserving the existing
validation text and behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 894f94a2-ab65-41a5-9621-be977d4f371e
📒 Files selected for processing (35)
packages/dashboard/e2e/tests/sales/orders.spec.tspackages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsxpackages/dashboard/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsxpackages/dashboard/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsxpackages/dashboard/src/app/routes/_authenticated/_orders/utils/use-modify-order.tspackages/dashboard/src/i18n/locales/ar.popackages/dashboard/src/i18n/locales/bg.popackages/dashboard/src/i18n/locales/cs.popackages/dashboard/src/i18n/locales/de.popackages/dashboard/src/i18n/locales/en.popackages/dashboard/src/i18n/locales/es.popackages/dashboard/src/i18n/locales/fa.popackages/dashboard/src/i18n/locales/fr.popackages/dashboard/src/i18n/locales/he.popackages/dashboard/src/i18n/locales/hr.popackages/dashboard/src/i18n/locales/hu.popackages/dashboard/src/i18n/locales/it.popackages/dashboard/src/i18n/locales/ja.popackages/dashboard/src/i18n/locales/nb.popackages/dashboard/src/i18n/locales/ne.popackages/dashboard/src/i18n/locales/nl.popackages/dashboard/src/i18n/locales/pl.popackages/dashboard/src/i18n/locales/pt_BR.popackages/dashboard/src/i18n/locales/pt_PT.popackages/dashboard/src/i18n/locales/ro.popackages/dashboard/src/i18n/locales/ru.popackages/dashboard/src/i18n/locales/sv.popackages/dashboard/src/i18n/locales/tr.popackages/dashboard/src/i18n/locales/uk.popackages/dashboard/src/i18n/locales/uz.popackages/dashboard/src/i18n/locales/zh_Hans.popackages/dashboard/src/i18n/locales/zh_Hant.popackages/dashboard/src/lib/components/shared/customer-address-form.tsxpackages/dashboard/src/lib/components/shared/customer-selector.tsxpackages/dev-server/graphql/graphql-env.d.ts
🛑 Comments failed to post (1)
packages/dashboard/src/lib/components/shared/customer-selector.tsx (1)
196-283: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
activeTabdoesn't reset when the popover is closed programmatically.
onOpenChangeresetsactiveTabto'existing'only when!isOpen, but theonSelect/onSubmitcallbacks close the popover viasetOpen(false)directly (bypassing the controlled component'sonOpenChangehandler, which typically only fires in response to user-driven interactions like outside-click or Escape, not programmatic prop changes). After successfully creating a new customer,activeTabstays'new'; reopening the popover next time will show the "Create new customer" tab instead of resetting to "Existing customer".🐛 Suggested fix
<TabsContent value="existing"> <div className="mt-2 rounded-md border"> <CustomerSearch onSelect={customer => { props.onSelect(customer); setOpen(false); + setActiveTab('existing'); }} /> </div> </TabsContent> <TabsContent value="new"> <div className="mt-2"> <CreateCustomerForm onSubmit={input => { props.onCreateNew?.(input); setOpen(false); + setActiveTab('existing'); }} /> </div> </TabsContent>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.export function CustomerSelector(props: CustomerSelectorProps) { const [open, setOpen] = useState(false); const [activeTab, setActiveTab] = useState<string>('existing'); const trigger = ( <PopoverTrigger render={ <Button variant="outline" size="sm" type="button" disabled={props.readOnly} className="gap-2" /> } > <Plus className="h-4 w-4" /> {props.label ?? <Trans>Select customer</Trans>} </PopoverTrigger> ); // When inline creation is not enabled, preserve the original lightweight popover behaviour. if (!props.allowCreateNew) { return ( <Popover open={open} onOpenChange={setOpen}> {trigger} <PopoverContent className="p-0 w-[350px]" align="start"> <CustomerSearch onSelect={customer => { props.onSelect(customer); setOpen(false); }} /> </PopoverContent> </Popover> ); } return ( <Popover open={open} onOpenChange={isOpen => { setOpen(isOpen); if (!isOpen) { setActiveTab('existing'); } }} > {trigger} <PopoverContent className="w-[420px] p-0" align="start"> <div className="p-4"> <Tabs value={activeTab} onValueChange={setActiveTab}> <TabsList className="grid w-full grid-cols-2"> <TabsTrigger value="existing"> <Link className="mr-2 h-4 w-4" /> <Trans>Existing customer</Trans> </TabsTrigger> <TabsTrigger value="new"> <Plus className="mr-2 h-4 w-4" /> <Trans>Create new customer</Trans> </TabsTrigger> </TabsList> <TabsContent value="existing"> <div className="mt-2 rounded-md border"> <CustomerSearch onSelect={customer => { props.onSelect(customer); setOpen(false); setActiveTab('existing'); }} /> </div> </TabsContent> <TabsContent value="new"> <div className="mt-2"> <CreateCustomerForm onSubmit={input => { props.onCreateNew?.(input); setOpen(false); setActiveTab('existing'); }} /> </div> </TabsContent> </Tabs> </div> </PopoverContent> </Popover> ); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/dashboard/src/lib/components/shared/customer-selector.tsx` around lines 196 - 283, Reset activeTab to 'existing' whenever the popover is closed programmatically: update the onSelect callback in CustomerSearch and the onSubmit callback in CreateCustomerForm to call setActiveTab('existing') alongside setOpen(false). Keep the existing onOpenChange reset for user-driven closures.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/dashboard/src/i18n/locales/pt_PT.po`:
- Around line 42-44: Translate the newly added customer, address, and
draft-order flow entries in pt_PT.po, replacing every empty msgstr at the
referenced entries with accurate Portuguese translations while preserving the
existing msgid and PO formatting.
In `@packages/dashboard/src/i18n/locales/ro.po`:
- Around line 42-44: Translate every newly added customer/address flow and
draft-order error entry in the Romanian locale, including the primary “Select an
existing customer or create a new one” entry and all referenced locations,
replacing each empty msgstr with accurate, natural Romanian text while
preserving placeholders and formatting.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b33fc3a2-9654-4567-9c24-065a1cb8a33f
📒 Files selected for processing (34)
packages/dashboard/e2e/tests/sales/orders.spec.tspackages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsxpackages/dashboard/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsxpackages/dashboard/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsxpackages/dashboard/src/app/routes/_authenticated/_orders/utils/use-modify-order.tspackages/dashboard/src/i18n/locales/ar.popackages/dashboard/src/i18n/locales/bg.popackages/dashboard/src/i18n/locales/cs.popackages/dashboard/src/i18n/locales/de.popackages/dashboard/src/i18n/locales/en.popackages/dashboard/src/i18n/locales/es.popackages/dashboard/src/i18n/locales/fa.popackages/dashboard/src/i18n/locales/fr.popackages/dashboard/src/i18n/locales/he.popackages/dashboard/src/i18n/locales/hr.popackages/dashboard/src/i18n/locales/hu.popackages/dashboard/src/i18n/locales/it.popackages/dashboard/src/i18n/locales/ja.popackages/dashboard/src/i18n/locales/nb.popackages/dashboard/src/i18n/locales/ne.popackages/dashboard/src/i18n/locales/nl.popackages/dashboard/src/i18n/locales/pl.popackages/dashboard/src/i18n/locales/pt_BR.popackages/dashboard/src/i18n/locales/pt_PT.popackages/dashboard/src/i18n/locales/ro.popackages/dashboard/src/i18n/locales/ru.popackages/dashboard/src/i18n/locales/sv.popackages/dashboard/src/i18n/locales/tr.popackages/dashboard/src/i18n/locales/uk.popackages/dashboard/src/i18n/locales/uz.popackages/dashboard/src/i18n/locales/zh_Hans.popackages/dashboard/src/i18n/locales/zh_Hant.popackages/dashboard/src/lib/components/shared/customer-address-form.tsxpackages/dashboard/src/lib/components/shared/customer-selector.tsx
✅ Files skipped from review due to trivial changes (8)
- packages/dashboard/src/i18n/locales/en.po
- packages/dashboard/src/i18n/locales/nb.po
- packages/dashboard/src/i18n/locales/zh_Hans.po
- packages/dashboard/src/i18n/locales/zh_Hant.po
- packages/dashboard/src/i18n/locales/fr.po
- packages/dashboard/src/i18n/locales/it.po
- packages/dashboard/src/i18n/locales/ru.po
- packages/dashboard/src/i18n/locales/ar.po
🚧 Files skipped from review as they are similar to previous changes (24)
- packages/dashboard/src/app/routes/_authenticated/_orders/utils/use-modify-order.ts
- packages/dashboard/src/app/routes/authenticated/orders/orders.$id.modify.tsx
- packages/dashboard/src/lib/components/shared/customer-address-form.tsx
- packages/dashboard/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx
- packages/dashboard/src/i18n/locales/ja.po
- packages/dashboard/src/i18n/locales/pl.po
- packages/dashboard/src/i18n/locales/tr.po
- packages/dashboard/src/i18n/locales/fa.po
- packages/dashboard/src/i18n/locales/he.po
- packages/dashboard/src/app/routes/_authenticated/orders/orders.draft.$id.tsx
- packages/dashboard/e2e/tests/sales/orders.spec.ts
- packages/dashboard/src/i18n/locales/uz.po
- packages/dashboard/src/lib/components/shared/customer-selector.tsx
- packages/dashboard/src/i18n/locales/cs.po
- packages/dashboard/src/i18n/locales/de.po
- packages/dashboard/src/i18n/locales/uk.po
- packages/dashboard/src/i18n/locales/pt_BR.po
- packages/dashboard/src/i18n/locales/nl.po
- packages/dashboard/src/i18n/locales/bg.po
- packages/dashboard/src/i18n/locales/es.po
- packages/dashboard/src/i18n/locales/hu.po
- packages/dashboard/src/i18n/locales/hr.po
- packages/dashboard/src/i18n/locales/ne.po
- packages/dashboard/src/i18n/locales/sv.po
| #: src/lib/components/shared/customer-selector.tsx:266 | ||
| msgid "Select an existing customer or create a new one" | ||
| msgstr "" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Translate the newly added customer/address flow strings.
These entries still have empty msgstr values, so Portuguese users will see English labels, prompts, and draft-order errors in the new flow. Add translations before merging.
Also applies to: 510-512, 709-711, 739-741, 889-891, 1042-1044, 1161-1163, 1456-1458, 1591-1593, 1734-1736, 2408-2410, 2642-2644, 3448-3450, 3590-3592, 4361-4363, 4536-4538, 4733-4735, 4800-4802, 5843-5845
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/dashboard/src/i18n/locales/pt_PT.po` around lines 42 - 44, Translate
the newly added customer, address, and draft-order flow entries in pt_PT.po,
replacing every empty msgstr at the referenced entries with accurate Portuguese
translations while preserving the existing msgid and PO formatting.
| #: src/lib/components/shared/customer-selector.tsx:266 | ||
| msgid "Select an existing customer or create a new one" | ||
| msgstr "" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Translate the newly added customer/address flow strings.
These entries still have empty msgstr values, so Romanian users will see English labels, prompts, and draft-order errors in the new flow. Add translations before merging.
Also applies to: 482-484, 681-683, 711-713, 861-863, 1010-1012, 1129-1131, 1408-1410, 1538-1540, 1673-1675, 2567-2569, 3352-3354, 3479-3481, 4221-4223, 4380-4382, 4577-4579, 4644-4646, 5635-5637
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/dashboard/src/i18n/locales/ro.po` around lines 42 - 44, Translate
every newly added customer/address flow and draft-order error entry in the
Romanian locale, including the primary “Select an existing customer or create a
new one” entry and all referenced locations, replacing each empty msgstr with
accurate, natural Romanian text while preserving placeholders and formatting.
…ddress selectors Reset the customer selector tab to 'existing' when a customer is selected or created (programmatic close does not trigger onOpenChange), and preserve an explicitly chosen 'new' tab in the address selector while the address query transitions from loading to loaded. Relates to vendurehq#4810
Brings the React dashboard draft order flow to parity with the Angular admin-ui by allowing an admin to create a new customer inline and enter a new/ad-hoc shipping or billing address inline, rather than only selecting existing records.
allowCreateNewmode rendering a tabbed popover (select existing / create new) that emits a CreateCustomerInput viaonCreateNew.onSubmitNew.hideDefaultAddressFlagsprop (the default shipping/billing flags are not applicable in the draft order context).No backend changes required: setCustomerForDraftOrder already accepts a CreateCustomerInput, and the draft order address mutations accept a CreateAddressInput.
Fixes #4951
Description
The React dashboard draft order flow previously only allowed selecting an existing customer and selecting one of the customer's saved addresses. The old Angular admin-ui also supported creating a new customer inline and entering a new/ad-hoc address inline. This PR restores that parity.
The backend already fully supports this —
setCustomerForDraftOrderaccepts an optionalCreateCustomerInput, andsetDraftOrderShippingAddress/setDraftOrderBillingAddressaccept aCreateAddressInput. The React UI simply never used these paths. This PR wires them up:CustomerSelectorgets an opt-inallowCreateNewtabbed popover ("Existing customer" / "Create new customer"). The create form has the same fields as Angular (title, first name, last name, email, phone). The existing select-only behaviour is preserved whenallowCreateNewis not set, so the customer-groups call site is untouched.CustomerAddressSelectorgets an "Existing address" / "New address" tabbed popover. The new-address tab reuses the sharedCustomerAddressForm(default-shipping/billing checkboxes hidden via a newhideDefaultAddressFlagsprop, matching Angular's draft flow). Works with or without a customer set.Added e2e coverage in
sales/orders.spec.tsfor creating a customer inline and entering a new shipping address inline. All 20 order e2e tests pass.Breaking changes
None. The change is additive and backward-compatible —
CustomerSelectorkeeps its original select-only behaviour by default (inline creation is opt-in viaallowCreateNew), and no backend/GraphQL changes are required.Screenshots
Checklist
📌 Always:
👍 Most of the time:
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.