Skip to content

feat(dashboard): deal a generated name into the create-box dialog#908

Open
law-chain-hot wants to merge 4 commits into
mainfrom
claude/wonderful-varahamihira-c27579
Open

feat(dashboard): deal a generated name into the create-box dialog#908
law-chain-hot wants to merge 4 commits into
mainfrom
claude/wonderful-varahamihira-c27579

Conversation

@law-chain-hot

@law-chain-hot law-chain-hot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

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 short
scramble/decode animation, and a refresh button deals another one. The old
static my-new-box placeholder only remains as the empty-field hint.

How

  • New shared lib @boxlite-ai/box-name (apps/libs/box-name) — the single
    source of truth for the adjective/animal word lists and generateBoxName().
    • apps/api keeps only the persistence-side collision fallback
      (persistWithGeneratedBoxName) and imports the generator from the lib.
    • The dashboard generates names locally from the same lib — no new server
      endpoints
      , no word-list duplication.
  • useGeneratedBoxName hook + scramble.ts drive the reveal animation.

Collision handling

Client-generated names can collide with the per-org unique-name constraint
(the server's -boxId fallback only applies to empty-name creates), so the
dialog 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) now
    exercises the shared lib through the re-export.

Summary by CodeRabbit

  • New Features

    • Added smarter box-name suggestions when creating a box, with a refresh option for new name ideas.
    • Introduced a shared name generator used across the app for consistent box names.
    • Added animated name scrambling/reveal behavior in the dashboard.
  • Bug Fixes

    • Improved handling of name conflicts by automatically suggesting a new name instead of showing an immediate failure.
    • Prevented box creation while a new name is still being generated.
  • Tests

    • Added coverage for the name-scrambling behavior.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Default box-name generation is extracted into a new shared Nx library (@boxlite-ai/box-name), which the API now imports instead of using an inline implementation. The dashboard adds a scramble-reveal text animation utility and a hook that suggests generated names in the CreateBoxDialog, along with 409-conflict regeneration handling and build/path configuration updates.

Changes

Box name generation and dashboard integration

Layer / File(s) Summary
Shared box-name library package
apps/libs/box-name/src/index.ts, apps/libs/box-name/package.json, apps/libs/box-name/project.json, apps/tsconfig.base.json, apps/dashboard/tsconfig.app.json, apps/api/Dockerfile
New Nx library exports BOX_NAME_ADJECTIVES, BOX_NAME_ANIMALS, and generateBoxName(); package manifests, path aliases, and Dockerfile COPY step wire the library into consumers.
API consumes shared library
apps/api/src/box/utils/box-name-generator.ts
The API's box-name generator now imports and re-exports generateBoxName from the shared library instead of its own word lists/RNG logic.
Scramble-reveal animation utility
apps/dashboard/src/lib/scramble.ts, apps/dashboard/src/lib/scramble.test.ts
New scrambleFrame(target, progress) reveals characters left-to-right based on progress, filling the remainder with randomized glyphs; covered by unit tests.
useGeneratedBoxName hook
apps/dashboard/src/components/Box/useGeneratedBoxName.ts
New hook animates a generated name reveal via interval-driven scrambling, exposing display, isGenerating, generate, and reset.
CreateBoxDialog integration
apps/dashboard/src/components/Box/CreateBoxDialog.tsx
Dialog triggers name generation on open, resets on close, shows a read-only animated name with a refresh button, regenerates on HTTP 409 conflicts, and disables submission while generating.

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
Loading

Possibly related PRs

  • boxlite-ai/boxlite#730: Both PRs modify apps/api/Dockerfile to change how workspace library files are copied into the Docker build stages.
  • boxlite-ai/boxlite#853: Both PRs revolve around the API's default box-name generation logic in box-name-generator.ts.

Suggested reviewers: DorianZheng, G4614

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main dashboard change: generating and animating a box name in the create dialog.
Description check ✅ Passed The description covers the summary, implementation details, collision handling, and tests, though it doesn't use the exact template headings.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/wonderful-varahamihira-c27579

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@law-chain-hot law-chain-hot changed the title feat(dashboard): show a generated name as the create-box placeholder feat(dashboard): deal a generated name into the create-box dialog Jul 3, 2026
@law-chain-hot
law-chain-hot marked this pull request as ready for review July 7, 2026 14:34
@law-chain-hot
law-chain-hot requested a review from a team as a code owner July 7, 2026 14:34

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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, [])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
apps/libs/box-name/project.json (1)

1-7: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the standard Nx target(s) here. targets: {} means apps/libs/box-name won’t participate in run-many for build/lint, unlike sibling libs such as api-client and analytics-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 value

Minor: refresh button isn't disabled during submit.

disabled={isGenerating} on the refresh button doesn't account for submitting; 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 win

Auto-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

clearTimer referenced in useCallback/useEffect without being a stable dependency.

Functionally safe (it only touches the stable timer ref), but react-hooks/exhaustive-deps will likely flag clearTimer as a missing dependency in generate, 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

📥 Commits

Reviewing files that changed from the base of the PR and between 19b21c7 and 24fadae.

📒 Files selected for processing (11)
  • apps/api/Dockerfile
  • apps/api/src/box/utils/box-name-generator.ts
  • apps/dashboard/src/components/Box/CreateBoxDialog.tsx
  • apps/dashboard/src/components/Box/useGeneratedBoxName.ts
  • apps/dashboard/src/lib/scramble.test.ts
  • apps/dashboard/src/lib/scramble.ts
  • apps/dashboard/tsconfig.app.json
  • apps/libs/box-name/package.json
  • apps/libs/box-name/project.json
  • apps/libs/box-name/src/index.ts
  • apps/tsconfig.base.json

@@ -0,0 +1,49 @@
/*
* Copyright 2025 Daytona Platforms Inc.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong license

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants