Skip to content

Commit 4888865

Browse files
authored
fix(integrations): enhance combobox to support custom values (#1969)
1 parent c289396 commit 4888865

3 files changed

Lines changed: 64 additions & 20 deletions

File tree

apps/app/src/components/integrations/ConnectIntegrationDialog.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ function CredentialInput({
9696
label: opt.label,
9797
})) || [];
9898

99-
const selectedItem = items.find((item) => item.id === value);
99+
// Find existing item or create synthetic one for custom values
100+
const selectedItem = value
101+
? items.find((item) => item.id === value) ?? { id: value, label: value }
102+
: undefined;
100103

101104
return (
102105
<ComboboxDropdown

apps/app/src/components/integrations/ManageIntegrationDialog.tsx

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -633,27 +633,40 @@ function ConfigurationContent({
633633
className="bg-background border-input ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[80px] w-full rounded-md border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
634634
/>
635635
) : field.type === 'combobox' && field.options ? (
636-
<ComboboxDropdown
637-
items={field.options.map((opt) => ({
636+
(() => {
637+
const items = field.options.map((opt) => ({
638638
id: opt.value,
639639
label: opt.label,
640-
}))}
641-
selectedItem={field.options
642-
.map((opt) => ({ id: opt.value, label: opt.label }))
643-
.find((item) => item.id === credentialValues[field.id])}
644-
onSelect={(item) => setCredentialValues((prev) => ({ ...prev, [field.id]: item.id }))}
645-
onCreate={(customValue) =>
646-
setCredentialValues((prev) => ({ ...prev, [field.id]: customValue }))
647-
}
648-
placeholder={field.placeholder || `Select ${field.label.toLowerCase()}...`}
649-
searchPlaceholder="Search or type custom value..."
650-
renderOnCreate={(customValue) => (
651-
<div className="flex items-center gap-2">
652-
<span className="text-sm">Use custom value:</span>
653-
<span className="font-medium">{customValue}</span>
654-
</div>
655-
)}
656-
/>
640+
}));
641+
const currentValue = credentialValues[field.id];
642+
// Find existing item or create synthetic one for custom values
643+
const selectedItem = currentValue
644+
? items.find((item) => item.id === currentValue) ?? {
645+
id: currentValue,
646+
label: currentValue,
647+
}
648+
: undefined;
649+
return (
650+
<ComboboxDropdown
651+
items={items}
652+
selectedItem={selectedItem}
653+
onSelect={(item) =>
654+
setCredentialValues((prev) => ({ ...prev, [field.id]: item.id }))
655+
}
656+
onCreate={(customValue) =>
657+
setCredentialValues((prev) => ({ ...prev, [field.id]: customValue }))
658+
}
659+
placeholder={field.placeholder || `Select ${field.label.toLowerCase()}...`}
660+
searchPlaceholder="Search or type custom value..."
661+
renderOnCreate={(customValue) => (
662+
<div className="flex items-center gap-2">
663+
<span className="text-sm">Use custom value:</span>
664+
<span className="font-medium">{customValue}</span>
665+
</div>
666+
)}
667+
/>
668+
);
669+
})()
657670
) : field.type === 'select' && field.options ? (
658671
<Select
659672
value={credentialValues[field.id] || ''}

packages/integration-platform/src/manifests/aws/credentials.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,44 @@ export const awsCredentialFields = [
2929
placeholder: 'Select or type a region...',
3030
helpText: 'Select a common region or type your own (e.g., us-east-1, eu-west-1)',
3131
options: [
32+
// US Regions
3233
{ value: 'us-east-1', label: 'US East (N. Virginia)' },
3334
{ value: 'us-east-2', label: 'US East (Ohio)' },
3435
{ value: 'us-west-1', label: 'US West (N. California)' },
3536
{ value: 'us-west-2', label: 'US West (Oregon)' },
37+
// Europe Regions
3638
{ value: 'eu-west-1', label: 'Europe (Ireland)' },
3739
{ value: 'eu-west-2', label: 'Europe (London)' },
40+
{ value: 'eu-west-3', label: 'Europe (Paris)' },
3841
{ value: 'eu-central-1', label: 'Europe (Frankfurt)' },
42+
{ value: 'eu-central-2', label: 'Europe (Zurich)' },
43+
{ value: 'eu-north-1', label: 'Europe (Stockholm)' },
44+
{ value: 'eu-south-1', label: 'Europe (Milan)' },
45+
{ value: 'eu-south-2', label: 'Europe (Spain)' },
46+
// Asia Pacific Regions
47+
{ value: 'ap-east-1', label: 'Asia Pacific (Hong Kong)' },
48+
{ value: 'ap-south-1', label: 'Asia Pacific (Mumbai)' },
49+
{ value: 'ap-south-2', label: 'Asia Pacific (Hyderabad)' },
3950
{ value: 'ap-northeast-1', label: 'Asia Pacific (Tokyo)' },
51+
{ value: 'ap-northeast-2', label: 'Asia Pacific (Seoul)' },
52+
{ value: 'ap-northeast-3', label: 'Asia Pacific (Osaka)' },
4053
{ value: 'ap-southeast-1', label: 'Asia Pacific (Singapore)' },
4154
{ value: 'ap-southeast-2', label: 'Asia Pacific (Sydney)' },
55+
{ value: 'ap-southeast-3', label: 'Asia Pacific (Jakarta)' },
56+
{ value: 'ap-southeast-4', label: 'Asia Pacific (Melbourne)' },
57+
{ value: 'ap-southeast-5', label: 'Asia Pacific (Malaysia)' },
58+
// Canada
59+
{ value: 'ca-central-1', label: 'Canada (Central)' },
60+
{ value: 'ca-west-1', label: 'Canada (Calgary)' },
61+
// South America
62+
{ value: 'sa-east-1', label: 'South America (São Paulo)' },
63+
// Middle East
64+
{ value: 'me-south-1', label: 'Middle East (Bahrain)' },
65+
{ value: 'me-central-1', label: 'Middle East (UAE)' },
66+
// Africa
67+
{ value: 'af-south-1', label: 'Africa (Cape Town)' },
68+
// Israel
69+
{ value: 'il-central-1', label: 'Israel (Tel Aviv)' },
4270
],
4371
},
4472
];

0 commit comments

Comments
 (0)