Fleet UI: Handle long fleet names across the Fleets UI#49216
Fleet UI: Handle long fleet names across the Fleets UI#49216RachelElysia wants to merge 7 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #49216 +/- ##
==========================================
+ Coverage 67.90% 67.91% +0.01%
==========================================
Files 3903 3905 +2
Lines 249343 249636 +293
Branches 13131 13130 -1
==========================================
+ Hits 169311 169543 +232
- Misses 64788 64821 +33
- Partials 15244 15272 +28
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@claude review |
|
AI review:
|
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
This PR addresses long fleet (team) names causing UI overflow and backend “Data too long” errors by enforcing consistent 255-character caps in the frontend and adding service-layer validation in the backend so callers receive a clear InvalidArgumentError.
Changes:
- Added a shared frontend
MAX_ENTITY_CHAR_LENGTH = 255constant and applied it broadly viaInputFieldmaxLengthcaps. - Hardened the Fleets UI for long names (table truncation, header flex/shrink behavior, modal wrapping, dropdown truncation) and fixed host label pill overflow.
- Added backend validation for team name length (
fleet.MaxTeamNameLength) inNewTeam,ModifyTeam, andApplyTeamSpecs, with expanded tests.
Reviewed changes
Copilot reviewed 38 out of 39 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| server/fleet/teams.go | Introduces MaxTeamNameLength = 255 to match DB column width. |
| ee/server/service/teams.go | Validates team name length (rune-based) in create/modify/spec-apply flows. |
| ee/server/service/teams_test.go | Adds test cases for max-length and multibyte names (currently contains a compile error; see comments). |
| frontend/utilities/constants.tsx | Adds shared MAX_ENTITY_CHAR_LENGTH = 255 constant for free-text DB-backed fields. |
| frontend/pages/admin/ManageFleetsPage/components/CreateFleetModal/CreateFleetModal.tsx | Caps fleet name input length via maxLength. |
| frontend/pages/admin/ManageFleetsPage/components/CreateFleetModal/CreateFleetModal.tests.tsx | Asserts fleet name input maxLength is 255. |
| frontend/pages/admin/ManageFleetsPage/components/RenameFleetModal/RenameFleetModal.tsx | Caps fleet name input length via maxLength. |
| frontend/pages/admin/ManageFleetsPage/components/RenameFleetModal/RenameFleetModal.tests.tsx | Asserts fleet name input maxLength is 255. |
| frontend/pages/admin/ManageFleetsPage/FleetTableConfig.tsx | Truncates long fleet names in the Fleets table with tooltip support. |
| frontend/pages/admin/ManageFleetsPage/TeamDetailsWrapper/_styles.scss | Ensures long fleet names truncate without wrapping header action buttons. |
| frontend/components/EnrollSecrets/EnrollSecretModal/_styles.scss | Ensures long fleet names wrap within the modal description area. |
| frontend/components/TeamsDropdown/TeamsDropdown.tsx | Adds truncation/overflow handling for long team names in the dropdown control/menu. |
| frontend/components/TeamsDropdown/_styles.scss | Makes the dropdown wrapper shrinkable in flex rows for truncation to work. |
| frontend/pages/hosts/details/cards/Labels/_styles.scss | Caps label pill button width to prevent overflow in host details. |
| frontend/pages/SoftwarePage/SoftwareLibrary/SelfServiceCategoriesPage/AddCategoryModal/AddCategoryModal.tsx | Replaces ad-hoc max length constant with shared MAX_ENTITY_CHAR_LENGTH. |
| frontend/pages/SoftwarePage/SoftwareLibrary/SelfServiceCategoriesPage/EditCategoryModal/EditCategoryModal.tsx | Same shared maxLength usage for editing category names. |
| frontend/pages/queries/edit/components/EditQueryForm/EditQueryForm.tsx | Uses shared MAX_ENTITY_CHAR_LENGTH for query name input. |
| frontend/pages/queries/edit/components/SaveNewQueryModal/SaveNewQueryModal.tsx | Uses shared MAX_ENTITY_CHAR_LENGTH for “save as new query” name input. |
| frontend/pages/policies/edit/components/PolicyForm/PolicyForm.tsx | Uses shared MAX_ENTITY_CHAR_LENGTH for policy name input. |
| frontend/pages/policies/edit/components/SaveNewPolicyModal/SaveNewPolicyModal.tsx | Uses shared MAX_ENTITY_CHAR_LENGTH for new policy name input. |
| frontend/pages/labels/NewLabelPage/NewLabelPage.tsx | Caps label name/description inputs via maxLength. |
| frontend/pages/labels/NewLabelPage/helpers.ts | Removes now-unreachable “too long” validations after DOM cap. |
| frontend/pages/labels/components/LabelForm/LabelForm.tsx | Caps label name/description inputs via maxLength. |
| frontend/pages/labels/components/LabelForm/helpers.ts | Removes now-unreachable “too long” validations after DOM cap. |
| frontend/pages/ManageControlsPage/Variables/components/AddCustomVariableModal/AddCustomVariableModal.tsx | Caps custom variable name input via maxLength. |
| frontend/pages/ManageControlsPage/Variables/components/AddCustomVariableModal/helpers.ts | Removes now-unreachable “too long” validation after DOM cap. |
| frontend/pages/ManageControlsPage/Variables/Variables.tests.tsx | Updates test to assert DOM maxLength instead of unreachable paste-based validation. |
| frontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/AddCertificateModal.tsx | Caps certificate name input via maxLength. |
| frontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/helpers.ts | Removes now-unreachable “too long” validation after DOM cap. |
| frontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/AddCertificateModal.tests.tsx | Updates test to assert DOM maxLength instead of unreachable paste-based validation. |
| frontend/pages/admin/ManageUsersPage/components/ApiUserForm/ApiUserForm.tsx | Caps API user “name” input via maxLength. |
| frontend/components/forms/packs/NewPackForm/NewPackForm.tsx | Caps pack name/description inputs via maxLength. |
| frontend/components/forms/packs/EditPackForm/EditPackForm.tsx | Caps pack name/description inputs via maxLength. |
| frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomESTForm/CustomESTForm.tsx | Caps CA variable/name-like field via maxLength. |
| frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomSCEPForm/CustomSCEPForm.tsx | Caps CA variable/name-like field via maxLength. |
| frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/DigicertForm.tsx | Caps CA variable/name-like field via maxLength. |
| frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/HydrantForm/HydrantForm.tsx | Caps CA variable/name-like field via maxLength. |
| frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/SmallstepForm/SmallstepForm.tsx | Caps CA variable/name-like field via maxLength. |
| changes/47290-long-fleet-name-ui | Excluded from diff by content policy (not reviewed). |
Files excluded by content exclusion policy (1)
- changes/47290-long-fleet-name-ui
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }, | ||
| { | ||
| name: "name at max length is accepted", | ||
| teamName: new(strings.Repeat("a", fleet.MaxTeamNameLength)), |
There was a problem hiding this comment.
False positive, I think — Go 1.26 supports new(expression), and .claude/rules/fleet-go-backend.md explicitly steers us toward new("value") / new(true) / new(42) over ptr.String(...). Tests compile and pass locally (go test -run TestNewTeamNameValidation ./ee/server/service/...).
I'm not a strong Go reviewer myself — can someone confirm new(strings.Repeat(...)) (function-call expression, not a literal) is fine per current convention, or should I swap to ptr.String(...) for readability?
| }, | ||
| { | ||
| name: "name over max length is rejected", | ||
| teamName: new(strings.Repeat("a", fleet.MaxTeamNameLength+1)), |
There was a problem hiding this comment.
False positive, I think — Go 1.26 supports new(expression), and .claude/rules/fleet-go-backend.md explicitly steers us toward new("value") / new(true) / new(42) over ptr.String(...). Tests compile and pass locally (go test -run TestNewTeamNameValidation ./ee/server/service/...).
I'm not a strong Go reviewer myself — can someone confirm new(strings.Repeat(...)) (function-call expression, not a literal) is fine per current convention, or should I swap to ptr.String(...) for readability?
| // Guards against regressing to byte-based length checks, which | ||
| // would reject multibyte names that fit within the character cap. | ||
| name: "multibyte name at max character length is accepted", | ||
| teamName: new(strings.Repeat("日", fleet.MaxTeamNameLength)), |
There was a problem hiding this comment.
False positive, I think — Go 1.26 supports new(expression), and .claude/rules/fleet-go-backend.md explicitly steers us toward new("value") / new(true) / new(42) over ptr.String(...). Tests compile and pass locally (go test -run TestNewTeamNameValidation ./ee/server/service/...).
I'm not a strong Go reviewer myself — can someone confirm new(strings.Repeat(...)) (function-call expression, not a literal) is fine per current convention, or should I swap to ptr.String(...) for readability?
| }, | ||
| { | ||
| name: "name at max length is accepted", | ||
| teamName: new(strings.Repeat("a", fleet.MaxTeamNameLength)), |
There was a problem hiding this comment.
False positive, I think — Go 1.26 supports new(expression), and .claude/rules/fleet-go-backend.md explicitly steers us toward new("value") / new(true) / new(42) over ptr.String(...). Tests compile and pass locally (go test -run TestNewTeamNameValidation ./ee/server/service/...).
I'm not a strong Go reviewer myself — can someone confirm new(strings.Repeat(...)) (function-call expression, not a literal) is fine per current convention, or should I swap to ptr.String(...) for readability?
| }, | ||
| { | ||
| name: "name over max length is rejected", | ||
| teamName: new(strings.Repeat("a", fleet.MaxTeamNameLength+1)), |
There was a problem hiding this comment.
False positive, I think — Go 1.26 supports new(expression), and .claude/rules/fleet-go-backend.md explicitly steers us toward new("value") / new(true) / new(42) over ptr.String(...). Tests compile and pass locally (go test -run TestNewTeamNameValidation ./ee/server/service/...).
I'm not a strong Go reviewer myself — can someone confirm new(strings.Repeat(...)) (function-call expression, not a literal) is fine per current convention, or should I swap to ptr.String(...) for readability?
| }, | ||
| { | ||
| name: "multibyte name at max character length is accepted", | ||
| teamName: new(strings.Repeat("日", fleet.MaxTeamNameLength)), |
There was a problem hiding this comment.
False positive, I think — Go 1.26 supports new(expression), and .claude/rules/fleet-go-backend.md explicitly steers us toward new("value") / new(true) / new(42) over ptr.String(...). Tests compile and pass locally (go test -run TestNewTeamNameValidation ./ee/server/service/...).
I'm not a strong Go reviewer myself — can someone confirm new(strings.Repeat(...)) (function-call expression, not a literal) is fine per current convention, or should I swap to ptr.String(...) for readability?
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThe change introduces shared 255-character frontend limits for user-supplied names and descriptions across multiple forms. Fleet creation and renaming inputs now enforce the limit, while backend team operations validate Unicode character counts and return formatted argument errors. Fleet table, team header, enrollment-secret modal, and host label styles now constrain or wrap long text. Label description validation is removed in favor of input length limits. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
frontend/pages/admin/ManageFleetsPage/TeamDetailsWrapper/_styles.scss (1)
22-27: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valuePrefer a dedicated class instead of a bare
h1selector.As noted in the PR comments summary, consider using a dedicated class (e.g.,
.team-details__title) instead of targeting the bareh1element for the truncation styles. This improves CSS maintainability and component encapsulation.🤖 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 `@frontend/pages/admin/ManageFleetsPage/TeamDetailsWrapper/_styles.scss` around lines 22 - 27, Replace the bare h1 selector in the team details styles with a dedicated title class such as team-details__title, and apply that class to the corresponding heading element. Preserve the existing truncation declarations while scoping them to the component-specific class.frontend/pages/labels/NewLabelPage/helpers.ts (1)
6-6: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove obsolete
descriptionvalidation state.With the removal of the
descriptionvalidation rules in this PR, thedescriptionvalidation state and its associated update logic are now unreachable. Removing these leftovers will clean up the components.
frontend/pages/labels/NewLabelPage/helpers.ts#L6-L6: Remove thedescriptionproperty fromINewLabelFormValidation.frontend/pages/labels/components/LabelForm/helpers.ts#L6-L6: Remove thedescriptionproperty fromILabelFormValidation.frontend/pages/labels/NewLabelPage/NewLabelPage.tsx#L273-L277: Remove this deadfieldName === "description"error-clearing block inonInputChange.frontend/pages/labels/components/LabelForm/LabelForm.tsx#L101-L105: Remove this deadfieldName === "description"error-clearing block inonFormChange.🤖 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 `@frontend/pages/labels/NewLabelPage/helpers.ts` at line 6, Remove the obsolete description property from INewLabelFormValidation in frontend/pages/labels/NewLabelPage/helpers.ts:6-6 and ILabelFormValidation in frontend/pages/labels/components/LabelForm/helpers.ts:6-6. Also remove the fieldName === "description" error-clearing blocks from onInputChange in frontend/pages/labels/NewLabelPage/NewLabelPage.tsx:273-277 and onFormChange in frontend/pages/labels/components/LabelForm/LabelForm.tsx:101-105.frontend/components/TeamsDropdown/TeamsDropdown.tsx (1)
243-243: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueName the TeamsDropdown menu width constant.
Move
500pxinto a named constant so this layout contract is easier to understand and tune consistently.🤖 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 `@frontend/components/TeamsDropdown/TeamsDropdown.tsx` at line 243, In TeamsDropdown, replace the inline "500px" value used for the menu maxWidth with a clearly named module-level constant, then reference that constant in the style configuration so the width contract can be tuned from one location.
🤖 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 `@frontend/components/TeamsDropdown/TeamsDropdown.tsx`:
- Line 243: In TeamsDropdown, replace the inline "500px" value used for the menu
maxWidth with a clearly named module-level constant, then reference that
constant in the style configuration so the width contract can be tuned from one
location.
In `@frontend/pages/admin/ManageFleetsPage/TeamDetailsWrapper/_styles.scss`:
- Around line 22-27: Replace the bare h1 selector in the team details styles
with a dedicated title class such as team-details__title, and apply that class
to the corresponding heading element. Preserve the existing truncation
declarations while scoping them to the component-specific class.
In `@frontend/pages/labels/NewLabelPage/helpers.ts`:
- Line 6: Remove the obsolete description property from INewLabelFormValidation
in frontend/pages/labels/NewLabelPage/helpers.ts:6-6 and ILabelFormValidation in
frontend/pages/labels/components/LabelForm/helpers.ts:6-6. Also remove the
fieldName === "description" error-clearing blocks from onInputChange in
frontend/pages/labels/NewLabelPage/NewLabelPage.tsx:273-277 and onFormChange in
frontend/pages/labels/components/LabelForm/LabelForm.tsx:101-105.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9e81c150-5cbe-46c8-9387-d2392104f9a7
📒 Files selected for processing (39)
changes/47290-long-fleet-name-uiee/server/service/teams.goee/server/service/teams_test.gofrontend/components/EnrollSecrets/EnrollSecretModal/_styles.scssfrontend/components/TeamsDropdown/TeamsDropdown.tsxfrontend/components/TeamsDropdown/_styles.scssfrontend/components/forms/packs/EditPackForm/EditPackForm.tsxfrontend/components/forms/packs/NewPackForm/NewPackForm.tsxfrontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/AddCertificateModal.tests.tsxfrontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/AddCertificateModal.tsxfrontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/helpers.tsfrontend/pages/ManageControlsPage/Variables/Variables.tests.tsxfrontend/pages/ManageControlsPage/Variables/components/AddCustomVariableModal/AddCustomVariableModal.tsxfrontend/pages/ManageControlsPage/Variables/components/AddCustomVariableModal/helpers.tsfrontend/pages/SoftwarePage/SoftwareLibrary/SelfServiceCategoriesPage/AddCategoryModal/AddCategoryModal.tsxfrontend/pages/SoftwarePage/SoftwareLibrary/SelfServiceCategoriesPage/EditCategoryModal/EditCategoryModal.tsxfrontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomESTForm/CustomESTForm.tsxfrontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomSCEPForm/CustomSCEPForm.tsxfrontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/DigicertForm.tsxfrontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/HydrantForm/HydrantForm.tsxfrontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/SmallstepForm/SmallstepForm.tsxfrontend/pages/admin/ManageFleetsPage/FleetTableConfig.tsxfrontend/pages/admin/ManageFleetsPage/TeamDetailsWrapper/_styles.scssfrontend/pages/admin/ManageFleetsPage/components/CreateFleetModal/CreateFleetModal.tests.tsxfrontend/pages/admin/ManageFleetsPage/components/CreateFleetModal/CreateFleetModal.tsxfrontend/pages/admin/ManageFleetsPage/components/RenameFleetModal/RenameFleetModal.tests.tsxfrontend/pages/admin/ManageFleetsPage/components/RenameFleetModal/RenameFleetModal.tsxfrontend/pages/admin/ManageUsersPage/components/ApiUserForm/ApiUserForm.tsxfrontend/pages/hosts/details/cards/Labels/_styles.scssfrontend/pages/labels/NewLabelPage/NewLabelPage.tsxfrontend/pages/labels/NewLabelPage/helpers.tsfrontend/pages/labels/components/LabelForm/LabelForm.tsxfrontend/pages/labels/components/LabelForm/helpers.tsfrontend/pages/policies/edit/components/PolicyForm/PolicyForm.tsxfrontend/pages/policies/edit/components/SaveNewPolicyModal/SaveNewPolicyModal.tsxfrontend/pages/queries/edit/components/EditQueryForm/EditQueryForm.tsxfrontend/pages/queries/edit/components/SaveNewQueryModal/SaveNewQueryModal.tsxfrontend/utilities/constants.tsxserver/fleet/teams.go
💤 Files with no reviewable changes (2)
- frontend/pages/ManageControlsPage/Variables/components/AddCustomVariableModal/helpers.ts
- frontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/helpers.ts
d89f53d to
866cf05
Compare
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
Copilot reviewed 36 out of 37 changed files in this pull request and generated no new comments.
Files excluded by content exclusion policy (1)
- changes/47290-long-fleet-name-ui
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
Copilot reviewed 36 out of 37 changed files in this pull request and generated 1 comment.
Files excluded by content exclusion policy (1)
- changes/47290-long-fleet-name-ui
| &__list-button { | ||
| max-width: 300px; | ||
| } |
Cap fleet name input at 255 chars in the Create/Rename modals, add matching service-layer validation on `NewTeam`, `ModifyTeam`, and `ApplyTeamSpecs` so API/GitOps callers get a friendly `InvalidArgumentError` instead of a raw "Data too long" MySQL error, and fix long-name overflow in the Fleets table, the fleet-detail page header, the manage enroll secrets modal, the TeamsDropdown trigger and menu options, and the host details Labels card. Introduce a shared `MAX_ENTITY_NAME_LENGTH = 255` constant, use it across 10 existing name-input files, and cap 16 additional user-supplied name and description inputs (API user, custom variable, certificate, label, pack, certificate authority forms) that were missing a maxLength.
- teams_test.go: use `new(...)` instead of the deprecated `ptr.String(...)` for the length-cap test cases (staticcheck SA1019). - AddCertificateModal.tests.tsx, Variables.tests.tsx: the existing tests pasted 256 chars and expected an inline "too long" validation message, but the new `maxLength: 255` cap blocks the 256th char at the DOM level so the error is now unreachable via user interaction. Swap for assertions that verify `input.maxLength === 255`.
…s the cap
With `inputOptions={{ maxLength: 255 }}` on the InputFields, the browser
blocks input past 255 chars, so the FE-side "notTooLong" / trimmedName-over-N
branches can't fire from user interaction and existing records can't hold
longer values either (the DB column is varchar(255) end-to-end).
Removed:
- `NAME_TOO_LONG_MSG` + `maxLength` validation in `AddCertificateModal/helpers.ts`.
- `notTooLong` name validator in `AddCustomVariableModal/helpers.ts`.
- `notTooLong` name + description validators in `NewLabelPage/helpers.ts` and `LabelForm/helpers.ts` (plus their now-unused local constants).
- `trimmedName.length > MAX_ENTITY_NAME_LENGTH` guard in `AddCategoryModal.tsx` and `EditCategoryModal.tsx`.
Unusual/shorter caps (e.g. varchar(64), custom business rules) still keep
their inline validators — silent truncation is only appropriate for the
common 255-char norm.
…name constant - Switch fleet-name length checks in ee/server/service/teams.go to utf8.RuneCountInString so multibyte names within the character cap are accepted (previously len() over-counted bytes and could reject valid names). - Drop the no-op description validator from both Label form helpers. - Rename MAX_ENTITY_NAME_LENGTH to MAX_ENTITY_CHAR_LENGTH and broaden the docstring to cover description fields too.
The `description` field on `ILabelFormValidation` / `INewLabelFormValidation`
and the corresponding `error={...description?.message}` InputField props were
left behind when the description length validators were pruned. Removed the
interface fields, the InputField error props, and the description branches
inside the state-merge callbacks so the type reflects reality.
Also tighten `LabelForm/helpers.ts` `IFormValidationKey` to the literal
`"name"` — `Extract<keyof ILabelFormData, "name">` compiles but reads oddly
for a single-key union.
0359cd9 to
26977cd
Compare
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
Copilot reviewed 36 out of 37 changed files in this pull request and generated no new comments.
Files excluded by content exclusion policy (1)
- changes/47290-long-fleet-name-ui
Script names come from the uploaded filename, not an InputField, so listing scripts sent readers looking for a form that doesn't exist.
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
Copilot reviewed 36 out of 37 changed files in this pull request and generated no new comments.
Files excluded by content exclusion policy (1)
- changes/47290-long-fleet-name-ui
RachelElysia
left a comment
There was a problem hiding this comment.
Nice PR — well-scoped for such a wide-reaching change. The backend validation + FE input caps + CSS overflow story hangs together cleanly, and the refactor from ad-hoc NAME_MAX_LENGTH = 255 locals to a shared MAX_ENTITY_CHAR_LENGTH is exactly the right consistency pass.
Should fix
None
Nice to have
1. Extract duplicated team-name validation to a helper — ee/server/service/teams.go:100-102, 191-193, 1336-1338
Three identical utf8.RuneCountInString(name) > fleet.MaxTeamNameLength blocks live in NewTeam, ModifyTeam, and ApplyTeamSpecs. A small validateTeamName helper would keep them in lockstep if the rule ever grows (e.g. disallowed characters, reserved names).
2. LabelForm/helpers.ts switch is now single-case — frontend/pages/labels/components/LabelForm/helpers.ts:60-65, 72-77
With only "name" left in IFormValidationKey, both switches degenerate to a single case — could be an if. Leaving as-is is also defensible for symmetry with NewLabelPage/helpers.ts; up to you.
3. Lost isEmpty semantic name in category modals — AddCategoryModal.tsx:29, EditCategoryModal.tsx:30
trimmedName.length === 0 is now inlined into isDisabled. Keeping a const isEmpty = ... above would read slightly nicer, but not worth churning.
Things I checked and are fine
- Trim happens before the length check in all three service methods.
utf8.RuneCountInStringmatches MySQLvarchar(255)inutf8mb4exactly — both count Unicode code points, so no drift. The new multibyte test locks that in against a byte-count regression.- Core
server/service/teams.goreturnsErrMissingLicensebefore any DB call, so the EE-only validation still covers Fleet Free entry points (no gap). NAME_TOO_LONG_MSGremoval — grep-confirmed no external consumers.- DOM
maxLength(UTF-16 units) is slightly stricter than the backend for astral-plane emoji names, but never looser — no truncation / data-loss surface. - Every FE
MAX_ENTITY_CHAR_LENGTHretrofit lines up with a realvarchar(255)column inschema.sql.mediumtextfields (policies/queries description) correctly stayed uncapped. - Changelog entry warranted (released bug, not
~unreleased).
…fires
.host-labels-card .button { max-width: 100% } (0,2,0) was overriding
.host-labels-card__list-button { max-width: 300px } (0,1,0), so long
label pills filled the full card width instead of capping at 300px.
Nest the selector to reach (0,3,0).
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
Copilot reviewed 36 out of 37 changed files in this pull request and generated no new comments.
Files excluded by content exclusion policy (1)
- changes/47290-long-fleet-name-ui
Issue
Closes #47290
Also implements the "Cap free-text
maxLengthto the backend column length" pattern established in #49041 (patterns.md thread).Description
Fleet name inputs had no
maxLengthcap and no service-layer length check, so a name >255 chars failed with a raw MySQLData too longerror, and several UI surfaces didn't handle long names gracefully. This PR fixes all four manifestations called out in the bug, plus a related label-overflow case on the host details page, and hardens adjacent name inputs across the app.Frontend fixes for #47290:
teams.name varchar(255)).LinkCellwithtooltipTruncate+className="w400"so long names truncate with an ellipsis and full-name tooltip instead of overflowing across the Hosts/Users columns..team-details__team-header): h1 getsoverflow: hidden; text-overflow: ellipsis; white-space: nowrap;,__team-detailsgetsmin-width: 0; flex: 1, and.action-buttonsgetsflex-shrink: 0+white-space: nowrapon buttons so Manage enroll secrets / Rename / Delete no longer wrap to a second line when the fleet name is long.__descriptiongetsoverflow-wrap: anywhere; min-width: 0so a long<b>{fleet name}</b>wraps within the modal instead of spilling out the right edge.Backend fixes for #47290:
fleet.MaxTeamNameLength = 255constant.NewTeam,ModifyTeam, andApplyTeamSpecsnow returnfleet.NewInvalidArgumentError("name", "may not exceed 255 characters")instead of surfacing a rawData too longMySQL error. Covers UI, API, and GitOps entry points.Broader consistency pass (per #49041 thread):
MAX_ENTITY_CHAR_LENGTH = 255constant infrontend/utilities/constants.tsx.NAME_MAX_LENGTH = 255/MAX_LABEL_NAME_LENGTH = 255locals to use it.InputFieldname/description inputs that were missing a cap (API user, custom variable, certificate, label name + description, pack name + description, and all 5 CA forms — CustomEST, CustomSCEP, Smallstep, Digicert, Hydrant).varchar(64), custom business rules) still keep their inline validators — silent truncation is only appropriate for the common 255-char norm.Bonus: fixed the long-label overflow on the host details Labels card by capping the pill button
max-widthat 300px.Screenrecording
Screen.Recording.2026-07-13.at.8.34.11.AM.mov
Screen.Recording.2026-07-13.at.8.38.26.AM.mov
Screen.Recording.2026-07-13.at.9.51.41.AM.mov
Latest - max width 300px long label:
Testing
Test coverage:
CreateFleetModal.tests.tsx,RenameFleetModal.tests.tsx— new case per file asserting the name input'smaxLength === 255.AddCertificateModal.tests.tsx,Variables.tests.tsx— the existing "shows too-long error when pasting 256 chars" tests are now unreachable via the DOM cap; converted tomaxLength === 255assertions.ee/server/service/teams_test.go—TestNewTeamNameValidation,TestModifyTeamNameValidation, andTestApplyTeamSpecsNameValidationeach get two new cases (accepts at the limit, rejects one over with the expected error message).Summary by CodeRabbit