Skip to content

feat(locations): validate Create Storage Location form (ARTESCA-4665) - #1199

Draft
JeanMarcMilletScality wants to merge 1 commit into
development/4from
improvement/ARTESCA-4665-storage-location-form-validation
Draft

feat(locations): validate Create Storage Location form (ARTESCA-4665)#1199
JeanMarcMilletScality wants to merge 1 commit into
development/4from
improvement/ARTESCA-4665-storage-location-form-validation

Conversation

@JeanMarcMilletScality

@JeanMarcMilletScality JeanMarcMilletScality commented May 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes ARTESCA-4665 — the Create / Save Changes button on the Storage Location editor was enabled even when required fields were empty. The button is now disabled until the form is valid for the selected location type.

Validation is driven by a Joi schema (react-hook-form + joiResolver, matching the pattern already used in EndpointCreate, AccountCreate, and the ISV engine) keyed off locationType. Every storage type that has a form is covered: AWS, AWS Custom variants (ARTESCA, RING, Ceph, Atlas, Outscale Public/SNC, Orange OBS), GCP, Wasabi, DO Spaces, Oracle, Azure (with auth-type conditionals), Azure Archive (with queue + auth conditionals), Cold Locations (4 providers × polling/SQS queue), Hyperdrive V2, Sproxyd, Tape DMF, Tape Miria, CRR, and NFS.

Secret fields stay optional in edit mode so existing locations can be saved without re-entering credentials (the children already clear them on mount).

What's in this PR

  • src/react/locations/schemas.ts (new)buildLocationSchema(isEdit) returns a single Joi schema with Joi.alternatives().conditional switching the details validation by locationType. Helpers (reqStr, urlField, httpUrlField, editableSecret, nonEmptyListField) keep each per-type schema readable.
  • src/react/locations/LocationEditor.tsx — switched from useState + locationFormCheck to useForm + joiResolver + FormProvider. Top-level Location Name is validated inline (/^[a-z0-9-]+$/, max 63 chars) matching the existing tooltip rule. The Create button uses disabled={!isValid || loading || !isLocationExists(...)}. Component is split into outer (data fetching) + inner (useForm) so the resolver captures the correct editingExisting value once the fetch completes.
  • src/react/locations/locationFormCheck.ts (deleted) — its sparse per-type checks (NFS / Tape Miria / CRR only) are now part of the Joi schemas.
  • LocationEditor.test.tsx — added two tests:
    • Create button stays disabled until name + AWS S3 + accessKey/secretKey/bucketName are all filled.
    • Typing an uppercase name shows the inline error and keeps Create disabled.

Scope — what is not in this PR

This PR fixes the bug at the form level: the Create button can no longer submit an invalid form, regardless of type. It does not add inline "Field is required" errors inside the details panel for every individual field. That would require migrating each of the 14 LocationDetails*.tsx components from its current class / local-state shape to useFormContext so each FormGroup can read errors.details.<field>?.message. That refactor is ~3000 LOC of mechanical rewrites and is better suited to a follow-up PR.

What you still get for inline per-field errors today:

  • Location Name (this PR).
  • CRR and Tape Miria (their existing internal validators continue to render inline errors on blur).
  • ❌ The other 12 detail components disable the button but don't currently point at which field is missing.

How the bridge works without rewriting the children: each LocationDetails* keeps its existing props.onChange(details) callback. LocationEditor intercepts that callback and routes it to setValue('details', details, { shouldValidate: true }). The Joi schema then validates whatever lands in the form values — isValid flips correctly even though the children never touch react-hook-form directly.

Test plan

  • npm run check-types — clean
  • npx biome check src/react/locations/LocationEditor.tsx — clean (one pre-existing warning unchanged)
  • npm test -- --testPathPattern="src/react/locations" — 150 passing / 6 pre-existing skips / 0 new failures
  • Manual: open Storage Locations → Add New Storage Location, confirm Create is disabled on first paint
  • Manual: for each location type, confirm Create stays disabled until required fields are filled, then flips to enabled
  • Manual: enter an uppercase / spaced name, confirm the inline error appears and Create stays disabled
  • Manual: for Azure / Azure Archive / Cold Location, switch auth/queue sub-modes and verify conditional required fields drive enable/disable correctly
  • Manual: edit an existing location, confirm Save Changes is enabled when nothing changed and secret fields are blank

🤖 Generated with Claude Code

- add Joi schemas covering required fields for every location type
- migrate LocationEditor to react-hook-form + joiResolver
- validate Location Name inline ([a-z0-9-]+, max 63 chars)
- drop locationFormCheck.ts (replaced by the schemas)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bert-e

bert-e commented May 22, 2026

Copy link
Copy Markdown
Contributor

Hello jeanmarcmilletscality,

My role is to assist you with the merge of this
pull request. Please type @bert-e help to get information
on this process, or consult the user documentation.

Available options
name description privileged authored
/after_pull_request Wait for the given pull request id to be merged before continuing with the current one.
/bypass_author_approval Bypass the pull request author's approval
/bypass_build_status Bypass the build and test status
/bypass_commit_size Bypass the check on the size of the changeset TBA
/bypass_incompatible_branch Bypass the check on the source branch prefix
/bypass_jira_check Bypass the Jira issue check
/bypass_peer_approval Bypass the pull request peers' approval
/bypass_leader_approval Bypass the pull request leaders' approval
/approve Instruct Bert-E that the author has approved the pull request. ✍️
/create_pull_requests Allow the creation of integration pull requests.
/create_integration_branches Allow the creation of integration branches.
/no_octopus Prevent Wall-E from doing any octopus merge and use multiple consecutive merge instead
/unanimity Change review acceptance criteria from one reviewer at least to all reviewers
/wait Instruct Bert-E not to run until further notice.
Available commands
name description privileged
/help Print Bert-E's manual in the pull request.
/status Print Bert-E's current status in the pull request TBA
/clear Remove all comments from Bert-E from the history TBA
/retry Re-start a fresh build TBA
/build Re-start a fresh build TBA
/force_reset Delete integration branches & pull requests, and restart merge process from the beginning.
/reset Try to remove integration branches unless there are commits on them which do not appear on the source branch.

Status report is not available.

@bert-e

bert-e commented May 22, 2026

Copy link
Copy Markdown
Contributor

Request integration branches

Waiting for integration branch creation to be requested by the user.

To request integration branches, please comment on this pull request with the following command:

/create_integration_branches

Alternatively, the /approve and /create_pull_requests commands will automatically
create the integration branches.

@JeanMarcMilletScality
JeanMarcMilletScality changed the base branch from development/4.1 to development/4 May 22, 2026 09:01
@bert-e

bert-e commented May 22, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

@JeanMarcMilletScality
JeanMarcMilletScality marked this pull request as draft May 28, 2026 14:01
@bert-e

bert-e commented May 28, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

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