Skip to content

Commit 0ac1bf8

Browse files
fix(dns-records): restore BIND file import broken by dropdown blur-close (#1329)
## Problem Importing a BIND zone file on the DNS records page did nothing — no preview dialog, no error, no processing. Root cause: `@radix-ui/react-menu` ≥2.1.17 (pulled in by #1321) closes any open menu on **window blur**. The import dropzone lives inside `ResponsiveDropdown` (a Radix DropdownMenu on desktop), so clicking **Select a file** (native picker) or dragging a file in from Finder blurred the window, closed the dropdown, and unmounted the dropzone before `onDrop` fired. ## Fix - **Bump `@datum-cloud/datum-ui` to ^1.3.2** — `ResponsiveDropdown` renders a Radix Popover on desktop (same UX, no blur-close). Upstream: datum-cloud/datum-ui#136. - `handleDrop` reports whether the preview opened; the dropdown only closes on success so parse errors stay visible. - Empty accepted-file drops show an error instead of failing silently. ## Test plan - [ ] Import via file picker — dropdown stays open while the picker is up, preview dialog opens with parsed records - [ ] Import via drag-and-drop from Finder - [ ] Invalid file → error shown inside the dropdown; Export still works ## Note The E2E regression checks are red due to a **separate, pre-existing** control-plane change (org creation now requires a system-assigned `generateName`; `createStandardOrg` fails with 422). It's unrelated to this PR and affects `main` too — tracked/fixed separately.
2 parents ce695f4 + 962e475 commit 0ac1bf8

4 files changed

Lines changed: 20 additions & 10 deletions

File tree

app/features/edge/dns-records/import-export/dns-record-import-action.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,11 @@ export const DnsRecordImportAction = ({
8181
});
8282

8383
const handleDropWithClose = async (droppedFiles: File[]) => {
84-
await handleDrop(droppedFiles);
85-
setPopoverOpen(false);
84+
const dialogOpened = await handleDrop(droppedFiles);
85+
// Keep the dropdown open on parse errors so the dropzone can show them
86+
if (dialogOpened) {
87+
setPopoverOpen(false);
88+
}
8689
};
8790

8891
const handleContactSupport = () => {

app/features/edge/dns-records/import-export/hooks/use-dns-record-import.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,14 @@ export function useDnsRecordImport({ projectId, dnsZoneId, onSuccess }: UseDnsRe
116116
resetDialog();
117117
};
118118

119-
const handleDrop = async (droppedFiles: File[]) => {
119+
/** Returns true when parsing succeeded and the preview dialog was opened. */
120+
const handleDrop = async (droppedFiles: File[]): Promise<boolean> => {
120121
const file = droppedFiles[0];
121-
if (!file) return;
122+
if (!file) {
123+
setDropzoneState('error');
124+
setErrorMessage('No file was accepted. Please choose a .zone, .db, or .txt file.');
125+
return false;
126+
}
122127

123128
setFiles(droppedFiles);
124129
setDropzoneState('loading');
@@ -131,13 +136,13 @@ export function useDnsRecordImport({ projectId, dnsZoneId, onSuccess }: UseDnsRe
131136
if (result.errors.length > 0) {
132137
setDropzoneState('error');
133138
setErrorMessage(result.errors.join(', '));
134-
return;
139+
return false;
135140
}
136141

137142
if (result.records.length === 0) {
138143
setDropzoneState('error');
139144
setErrorMessage('No valid DNS records found in the file');
140-
return;
145+
return false;
141146
}
142147

143148
// Filter records by supported types
@@ -168,7 +173,7 @@ export function useDnsRecordImport({ projectId, dnsZoneId, onSuccess }: UseDnsRe
168173
if (supportedRecords.length === 0) {
169174
setDropzoneState('error');
170175
setErrorMessage('No supported DNS records found in the file');
171-
return;
176+
return false;
172177
}
173178

174179
// Deduplicate records within the batch (handles trailing dot normalization)
@@ -261,10 +266,12 @@ export function useDnsRecordImport({ projectId, dnsZoneId, onSuccess }: UseDnsRe
261266
resetDropzone();
262267
setDialogView('preview');
263268
setDialogOpen(true);
269+
return true;
264270
} catch (err) {
265271
const message = err instanceof Error ? err.message : 'Failed to read file';
266272
setDropzoneState('error');
267273
setErrorMessage(message);
274+
return false;
268275
}
269276
};
270277

bun.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"@conform-to/react": "^1.19.4",
3535
"@conform-to/zod": "^1.19.4",
3636
"@datum-cloud/activity-ui": "^0.5.1",
37-
"@datum-cloud/datum-ui": "^1.3.0",
37+
"@datum-cloud/datum-ui": "^1.3.2",
3838
"@epic-web/client-hints": "^1.3.9",
3939
"@gqlts/runtime": "^3.4.2",
4040
"@hono/prometheus": "^1.0.3",

0 commit comments

Comments
 (0)