feat(dashboard): deal a generated name into the create-box dialog#908
feat(dashboard): deal a generated name into the create-box dialog#908law-chain-hot wants to merge 4 commits into
Conversation
📝 WalkthroughWalkthroughDefault box-name generation is extracted into a new shared Nx library ( ChangesBox name generation and dashboard integration
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant CreateBoxDialog
participant useGeneratedBoxName
participant scrambleFrame
participant BoxAPI
User->>CreateBoxDialog: Open dialog
CreateBoxDialog->>useGeneratedBoxName: generate()
loop reveal animation
useGeneratedBoxName->>scrambleFrame: scrambleFrame(target, progress)
scrambleFrame-->>useGeneratedBoxName: partially revealed string
useGeneratedBoxName-->>CreateBoxDialog: display update
end
useGeneratedBoxName-->>CreateBoxDialog: onName(finalName)
User->>CreateBoxDialog: Click Create Box
CreateBoxDialog->>BoxAPI: create box(name)
alt 409 conflict
BoxAPI-->>CreateBoxDialog: 409 error
CreateBoxDialog->>useGeneratedBoxName: generate()
else success
BoxAPI-->>CreateBoxDialog: created
end
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 24fadaec3f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| setIsGenerating(false) | ||
| }, []) | ||
|
|
||
| useEffect(() => clearTimer, []) |
There was a problem hiding this comment.
Reset generation when StrictMode clears the timer
When this hook mounts while the dialog is already open, React.StrictMode (the dashboard root is wrapped at apps/dashboard/src/main.tsx:34) runs the effect cleanup immediately after the first setup. This cleanup clears the only interval created by generate() without setting isGenerating back to false; the replayed open effect then hits the wasOpenRef guard in CreateBoxDialog.tsx:249 and does not start a replacement timer, so the field stays read-only and the Create button remains disabled indefinitely for mounted-open dialogs/tests.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
🧹 Nitpick comments (4)
apps/libs/box-name/project.json (1)
1-7: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd the standard Nx target(s) here.
targets: {}meansapps/libs/box-namewon’t participate inrun-manyforbuild/lint, unlike sibling libs such asapi-clientandanalytics-api-client.🤖 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 `@apps/libs/box-name/project.json` around lines 1 - 7, The box-name project is missing the standard Nx targets, so it will be skipped by workspace commands like run-many for build and lint. Update the project.json for the box-name library to match sibling libraries such as api-client and analytics-api-client by adding the usual build/lint target entries under targets instead of leaving it empty.apps/dashboard/src/components/Box/CreateBoxDialog.tsx (2)
351-378: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMinor: refresh button isn't disabled during submit.
disabled={isGenerating}on the refresh button doesn't account forsubmitting; a user could trigger a new name generation while a create request is in flight. Doesn't corrupt the in-flight request (name is already captured in the mutation call), but produces a confusing UI state.🤖 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 `@apps/dashboard/src/components/Box/CreateBoxDialog.tsx` around lines 351 - 378, The refresh/suggest-name button in CreateBoxDialog can still be clicked while a box submit is in flight, which creates a confusing UI state. Update the button’s disabled logic in CreateBoxDialog so it is disabled whenever either isGenerating or submitting is true, and keep the existing generate() behavior otherwise.
308-315: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAuto-regenerating on 409 also replaces user-typed names, not just client-suggested ones.
If a user manually edits the field to a specific name and it collides (409), the current logic silently swaps in a random new name rather than prompting the user to pick a different one for their intentionally-chosen name. Consider only auto-regenerating when the colliding name matches the last client-generated suggestion, and otherwise ask the user to edit the name themselves.
🤖 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 `@apps/dashboard/src/components/Box/CreateBoxDialog.tsx` around lines 308 - 315, The 409 handling in CreateBoxDialog should not always replace the current name with a new generated one. Update the create-box error path in the submit flow so auto-regeneration only happens when the submitted name matches the last client-generated suggestion; otherwise, show a message asking the user to choose another name and leave their manual edit intact. Use the existing generate() logic and the 409 branch around handleApiError as the place to add the check, keyed off the current field value versus the last generated name.apps/dashboard/src/components/Box/useGeneratedBoxName.ts (1)
22-54: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
clearTimerreferenced inuseCallback/useEffectwithout being a stable dependency.Functionally safe (it only touches the stable
timerref), butreact-hooks/exhaustive-depswill likely flagclearTimeras a missing dependency ingenerate,reset, and the unmount effect, which can fail CI lint checks.♻️ Wrap `clearTimer` in `useCallback` to satisfy lint and make the contract explicit
- const clearTimer = () => { + const clearTimer = useCallback(() => { if (timer.current) clearInterval(timer.current) timer.current = undefined - } + }, []) const generate = useCallback(() => { clearTimer() ... - }, []) + }, [clearTimer]) const reset = useCallback(() => { clearTimer() setDisplay('') setIsGenerating(false) - }, []) + }, [clearTimer]) - useEffect(() => clearTimer, []) + useEffect(() => clearTimer, [clearTimer])🤖 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 `@apps/dashboard/src/components/Box/useGeneratedBoxName.ts` around lines 22 - 54, The `clearTimer` helper in `useGeneratedBoxName` is being used inside `generate`, `reset`, and the cleanup `useEffect` without being a stable dependency, which will trigger the hooks lint rule. Wrap `clearTimer` in `useCallback` (with only the `timer` ref as its dependency, if any) and then include it in the dependency arrays for `generate`, `reset`, and the unmount effect so the contract is explicit and lint-safe.
🤖 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.
Nitpick comments:
In `@apps/dashboard/src/components/Box/CreateBoxDialog.tsx`:
- Around line 351-378: The refresh/suggest-name button in CreateBoxDialog can
still be clicked while a box submit is in flight, which creates a confusing UI
state. Update the button’s disabled logic in CreateBoxDialog so it is disabled
whenever either isGenerating or submitting is true, and keep the existing
generate() behavior otherwise.
- Around line 308-315: The 409 handling in CreateBoxDialog should not always
replace the current name with a new generated one. Update the create-box error
path in the submit flow so auto-regeneration only happens when the submitted
name matches the last client-generated suggestion; otherwise, show a message
asking the user to choose another name and leave their manual edit intact. Use
the existing generate() logic and the 409 branch around handleApiError as the
place to add the check, keyed off the current field value versus the last
generated name.
In `@apps/dashboard/src/components/Box/useGeneratedBoxName.ts`:
- Around line 22-54: The `clearTimer` helper in `useGeneratedBoxName` is being
used inside `generate`, `reset`, and the cleanup `useEffect` without being a
stable dependency, which will trigger the hooks lint rule. Wrap `clearTimer` in
`useCallback` (with only the `timer` ref as its dependency, if any) and then
include it in the dependency arrays for `generate`, `reset`, and the unmount
effect so the contract is explicit and lint-safe.
In `@apps/libs/box-name/project.json`:
- Around line 1-7: The box-name project is missing the standard Nx targets, so
it will be skipped by workspace commands like run-many for build and lint.
Update the project.json for the box-name library to match sibling libraries such
as api-client and analytics-api-client by adding the usual build/lint target
entries under targets instead of leaving it empty.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b5b96323-7bae-4d28-9251-172c23b92128
📒 Files selected for processing (11)
apps/api/Dockerfileapps/api/src/box/utils/box-name-generator.tsapps/dashboard/src/components/Box/CreateBoxDialog.tsxapps/dashboard/src/components/Box/useGeneratedBoxName.tsapps/dashboard/src/lib/scramble.test.tsapps/dashboard/src/lib/scramble.tsapps/dashboard/tsconfig.app.jsonapps/libs/box-name/package.jsonapps/libs/box-name/project.jsonapps/libs/box-name/src/index.tsapps/tsconfig.base.json
| @@ -0,0 +1,49 @@ | |||
| /* | |||
| * Copyright 2025 Daytona Platforms Inc. | |||
What
Opening the Create-Box dialog now deals the user a generated name (e.g.
cozy-otter): it lands in the editable name field via a shortscramble/decode animation, and a refresh button deals another one. The old
static
my-new-boxplaceholder only remains as the empty-field hint.How
@boxlite-ai/box-name(apps/libs/box-name) — the singlesource of truth for the adjective/animal word lists and
generateBoxName().apps/apikeeps only the persistence-side collision fallback(
persistWithGeneratedBoxName) and imports the generator from the lib.endpoints, no word-list duplication.
useGeneratedBoxNamehook +scramble.tsdrive the reveal animation.Collision handling
Client-generated names can collide with the per-org unique-name constraint
(the server's
-boxIdfallback only applies to empty-name creates), so thedialog catches a create
409, toasts, and automatically deals a fresh name;the next click succeeds. Clearing the field still submits no name and the
server auto-names as before.
Test
apps/dashboard/src/lib/scramble.test.ts— reveal-frame contract (3 tests).apps/api/src/box/utils/box-name-generator.spec.ts(existing, 5 tests) nowexercises the shared lib through the re-export.
Summary by CodeRabbit
New Features
Bug Fixes
Tests