Skip to content

Comments

fix: auto-convert project name in settings & consolidate code#4436

Merged
stuartc merged 8 commits intomainfrom
fix/project-settings-name-conversion
Feb 24, 2026
Merged

fix: auto-convert project name in settings & consolidate code#4436
stuartc merged 8 commits intomainfrom
fix/project-settings-name-conversion

Conversation

@elias-ba
Copy link
Contributor

@elias-ba elias-ba commented Feb 18, 2026

Description

Fixes the project settings form to auto-convert project names to URL-safe format (lowercase, hyphens, digits), matching the behavior of the project creation form. Previously, entering a name like "DEP-burundi-datafi" in settings would fail validation since the form submitted the raw input directly.

This PR also consolidates all duplicate coerce_raw_name_to_safe_name functions into Project.form_changeset/2 and Project.form_with_users_changeset/2, using a virtual :raw_name schema field. This follows the pattern already established by Collection.form_changeset.

Along the way, a pre-existing bug was fixed in the dashboard creation modal where the save error path assigned to :project_changeset instead of :changeset, meaning validation errors from failed project creation were silently swallowed. Additionally, the @name assign is now initialized in update/2 (previously it only got set after the first validation event), and whitespace inside the name preview badge <span> tags was cleaned up to remove a trailing space.

Closes #4437

Validation steps

Project settings

  1. Edit the project name with uppercase/spaces (e.g. "My Cool Project")
  2. Verify the preview badge shows my-cool-project
  3. Save and confirm it persists the slug name
  4. Clear the name and verify a single "can't be blank" error (not duplicated)
  5. Change retention settings and verify the name does not break

Create New Project

  1. Type "Hello World!" and verify badge shows hello-world
  2. Clear the name and verify submit disables and a single error shows
  3. Submit and verify the project is created with the slug name

Create / Edit Sandboxes

  1. Create with "My Sandbox" and verify badge shows my-sandbox
  2. Create another with the same name and verify "Sandbox name already exists" error
  3. Edit a sandbox and rename it

Create / Edit Collections

  1. Create with spaces/uppercase and verify slug preview
  2. Edit an existing collection and verify name displays correctly

Create / Edit Projects (superuser interface)

  1. Edit name to uppercase and verify preview updates
  2. Save and verify slug persists

AI Usage

  • I have used Claude Code
  • I have used another model
  • I have not used AI

Pre-submission checklist

  • I have performed an AI review of my code (we recommend using /review with Claude Code)
  • I have implemented and tested all related authorization policies. (e.g., :owner, :admin, :editor, :viewer)
  • I have updated the changelog.
  • I have ticked a box in "AI usage" in this PR

@codecov
Copy link

codecov bot commented Feb 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.46%. Comparing base (dc5f4dd) to head (41385d3).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4436      +/-   ##
==========================================
+ Coverage   89.37%   89.46%   +0.08%     
==========================================
  Files         425      425              
  Lines       20194    20210      +16     
==========================================
+ Hits        18048    18080      +32     
+ Misses       2146     2130      -16     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@stuartc stuartc left a comment

Choose a reason for hiding this comment

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

Some issues, mostly around the validation not being tested - and errors not shown probably (raw_name doesn't have a schema so I can't see it getting errors?).

Also there is a smell around the copy pasting of coerce_raw_name_to_safe_name, not just in this PR, in other places. There are 5 different files with an almost copy paste of this kind of function. I first thought we should put the transform into the schema, but then thought that might cause rendering weirdness with the schema changing the input - Collection has a form_changeset function that handles the :raw_name and the model has that as a virtual field. Keeping the logic a model concern and not a view concern.

@github-project-automation github-project-automation bot moved this from New Issues to In review in v2 Feb 20, 2026
@elias-ba elias-ba changed the title fix: auto-convert project name in settings form refactor: consolidate raw_name coercion into Project schema Feb 21, 2026
@elias-ba elias-ba changed the title refactor: consolidate raw_name coercion into Project schema refactor: consolidate raw_name coercion into project schema Feb 21, 2026
@elias-ba elias-ba changed the title refactor: consolidate raw_name coercion into project schema fix: auto-convert project name in settings & consolidate raw_name coercion Feb 21, 2026
@elias-ba elias-ba changed the title fix: auto-convert project name in settings & consolidate raw_name coercion fix: auto-convert project name in settings Feb 21, 2026
@elias-ba elias-ba changed the title fix: auto-convert project name in settings fix: auto-convert project name in settings & consolidate raw_name coercion Feb 21, 2026
@elias-ba elias-ba changed the title fix: auto-convert project name in settings & consolidate raw_name coercion fix: auto-convert project name in settings & consolidate code Feb 21, 2026
Copy link
Contributor Author

@elias-ba elias-ba left a comment

Choose a reason for hiding this comment

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

Thanks @stuartc, great catch on all fronts. I've reworked the PR following your suggestion to use the Collection pattern. Project now has a virtual :raw_name field and a form_changeset/2 that handles the derivation at the schema level, so all copies of coerce_raw_name_to_safe_name are gone. Errors on :name get copied back to :raw_name so they show up on the visible input. Also extracted a shared <.name_badge> component since the preview badge was duplicated across all the forms. I think this now looks way better, thanks a lot again. Would you mind having another look ?

@elias-ba elias-ba requested a review from stuartc February 21, 2026 23:53
Copy link
Collaborator

@theroinaochieng theroinaochieng left a comment

Choose a reason for hiding this comment

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

@elias-ba your validation steps for project settings say there should be a preview badge on the project settings page but there isn't.

All the rest of the validation steps pass :)

Image

@theroinaochieng theroinaochieng self-requested a review February 24, 2026 08:56
Copy link
Collaborator

@theroinaochieng theroinaochieng left a comment

Choose a reason for hiding this comment

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

@elias-ba please ignore my previous change request, I was on the wrong branch testing this. Looks great.

The project creation form auto-converts uppercase and spaces to the
lowercase-hyphens-digits format, but the settings form did not, causing
users to get a validation error when entering names like "DEP-burundi-datafi".

Aligns the settings form with the creation form by using a raw_name input
that gets converted via Helpers.url_safe_name/1 before saving.
The project name input was changed from `name` to `raw_name` for the
url-safe conversion feature, but two test assertions still referenced
the old field name.
Replace 5 duplicate `coerce_raw_name_to_safe_name` functions with
`Project.form_changeset/2` and `form_with_users_changeset/2` that use
a virtual `:raw_name` field to derive the URL-safe `:name` automatically.

- Add `Helpers.derive_name_param/1` so all save handlers derive the
  name server-side instead of relying on hidden-field timing
- Fix duplicate "can't be blank" error by moving `validate_required([:name])`
  out of shared `validate/1` into callers that cast `:name` directly
- Fix dashboard creation modal error path assigning to wrong key
  (`:project_changeset` → `:changeset`)
- Extract shared `<.name_badge>` component in Pills for the name
  preview badge used across all 5 forms
Add tests for previously untested code paths:
- settings cancel-retention-change handler resets form
- settings/dashboard/admin save error paths with copy_error
- sandbox edit save error path with copy_error
- fix broken changeset construction in sandbox edit stub
@elias-ba elias-ba force-pushed the fix/project-settings-name-conversion branch from eb71080 to acaeee0 Compare February 24, 2026 11:25
elias-ba and others added 2 commits February 24, 2026 11:37
Adds a test verifying that name-related changeset errors (e.g. duplicate
name) are shown inline on the form, while backend errors unrelated to
form fields still redirect with a flash message.
Add validate_required([:name]) after derive_name_from_raw_name() in
form_changeset/2 and form_with_users_changeset/2 so that raw_name
values like "!!!" that resolve to a blank slug produce "can't be blank"
consistently with the save-path changeset. Update name_badge component
to use :if attribute and {} interpolation per project HEEx conventions.
@stuartc stuartc merged commit 1ee2480 into main Feb 24, 2026
7 checks passed
@stuartc stuartc deleted the fix/project-settings-name-conversion branch February 24, 2026 13:38
@github-project-automation github-project-automation bot moved this from In review to Done in v2 Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

bug: project settings form does not auto-convert project name to url safe names

3 participants