Skip to content

feat(ui): add OrganizationProfileProfileSection#9068

Merged
alexcarpenter merged 1 commit into
mainfrom
feat/mosaic-org-profile-profile-section
Jul 9, 2026
Merged

feat(ui): add OrganizationProfileProfileSection#9068
alexcarpenter merged 1 commit into
mainfrom
feat/mosaic-org-profile-profile-section

Conversation

@alexcarpenter

@alexcarpenter alexcarpenter commented Jul 1, 2026

Copy link
Copy Markdown
Member

Description

Mosaic OrganizationProfile: name/slug edit section (machine + controller + view + wrapper), wired into General Panel.

  • Two machines, one controller: details (name/slug, commits on submit) + logo (avatar, commits on file pick).
  • No useEffect sync. Committed-vs-draft: org values injected read-only each render (committed*); edits held machine-owned (draft*, null=untouched); effective = draft ?? committed. Seeds late-loading org + refreshes post-save, never clobbers typing.
  • Details machine models modal lifecycle (closed/editing/saving + OPEN/CANCEL), mirroring delete section. Modal open driven by state; closes on save success, no effect.
  • View: "Edit profile" button → Dialog w/ Name + Slug (slug hidden when organizationSettings.slug.disabled) + Save/Cancel.
  • Gated on org:sys_profile:manage.
  • Panel view gains profile slot at top (profile → leave → delete, matching legacy order).
  • Swingset: story + MDX + registry + docModules wiring; added to General Panel story/composition.

Internal-only under /experimental Mosaic; no public API change.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Added a new organization profile section for editing the organization name, slug, and logo.
    • The general organization profile panel now includes this new profile section in the visible layout.
    • Added supporting storybook documentation so the new section appears in component examples.
  • Bug Fixes

    • Improved save behavior and validation for profile edits, including better handling of empty names, disabled slug settings, and error states.
    • Added coverage for logo upload/removal flows and permission-based visibility.

@changeset-bot

changeset-bot Bot commented Jul 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 97961dc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jul 9, 2026 7:05pm
swingset Ready Ready Preview, Comment Jul 9, 2026 7:05pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces an "Organization Profile Section" feature enabling users to edit an organization's name/slug and manage its logo. It adds two XState machines (details, logo), a controller hook orchestrating them via Clerk hooks, a view/component, integration into the general panel, tests, and Storybook/docs entries.

Changes

Organization Profile Section

Layer / File(s) Summary
Profile details state machine
packages/ui/src/mosaic/organization/organization-profile-profile-section-details.machine.ts
Adds context/event types and an XState machine handling open/editing/saving/cancel transitions for name and slug, invoking updateOrganization conditionally with slug.
Profile logo state machine
packages/ui/src/mosaic/organization/organization-profile-profile-section-logo.machine.ts
Adds context/event types and a machine for upload/remove logo actions invoking setLogo asynchronously.
Controller hook orchestration
packages/ui/src/mosaic/organization/organization-profile-profile-section.controller.tsx
Adds useOrganizationProfileProfileSectionController, wiring Clerk org/session state and Mosaic environment into both machines, computing loading/hidden/ready status, canSubmit, and canRemove.
Profile section component and view
packages/ui/src/mosaic/organization/organization-profile-profile-section.tsx, .../organization-profile-profile-section.view.tsx
Adds OrganizationProfileProfileSection and its view rendering committed values plus an edit dialog with Name/Slug inputs, error display, and Cancel/Save actions.
Integration into general panel and namespace
.../organization-profile-general-panel-view.tsx, .../organization-profile-general-panel.tsx, .../organization-profile.tsx
Adds profile prop to the general panel view, wires the new section into the panel, and exposes ProfileSection on the OrganizationProfile namespace.
Machine and controller tests
packages/ui/src/mosaic/organization/__tests__/*
Adds Vitest suites covering details machine submit/cancel/error flows, logo machine upload/remove/error flows, and controller loading/hidden/editing/slug/logo-removal behaviors.
Storybook stories and docs
.changeset/org-profile-profile-section.md, packages/swingset/src/components/DocsViewer.tsx, packages/swingset/src/lib/registry.ts, packages/swingset/src/stories/organization-profile-*
Adds a changeset, registers new story/docs entries, and updates the general panel story/mdx to include the new profile section demo.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant OrganizationProfileProfileSectionView
  participant DetailsMachine
  participant Controller
  participant ClerkOrganization

  OrganizationProfileProfileSectionView->>DetailsMachine: send TYPE_NAME/TYPE_SLUG
  OrganizationProfileProfileSectionView->>DetailsMachine: send SUBMIT
  DetailsMachine->>Controller: invoke updateOrganization(name, slug)
  Controller->>ClerkOrganization: organization.update(...)
  ClerkOrganization-->>Controller: resolve/reject
  Controller-->>DetailsMachine: onDone/onError
  DetailsMachine-->>OrganizationProfileProfileSectionView: closed / editing with error
Loading

Suggested reviewers: wobsoriano

Poem

A rabbit hops through org and slug,
Draft to committed, snug as a bug 🐰
Dialogs open, saves take flight,
Logos swapped from day to night,
Tests all pass, the burrow's tight! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change by naming the new OrganizationProfileProfileSection feature.
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

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

@pkg-pr-new

pkg-pr-new Bot commented Jul 9, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9068

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9068

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9068

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9068

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9068

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9068

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9068

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9068

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9068

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9068

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9068

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9068

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9068

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9068

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9068

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9068

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9068

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9068

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9068

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9068

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9068

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9068

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9068

commit: 97961dc

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-07-09T19:06:39.353Z

Summary

Metric Count
Packages analyzed 19
Packages with changes 0
🔴 Breaking changes 0
🟡 Non-breaking changes 0
🟢 Additions 0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 97961dc.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/ui/src/mosaic/organization/__tests__/organization-profile-profile-section-details.machine.test.ts (1)

40-46: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a test for slug-only edits.

Coverage exercises name-only changes and the slug-disabled path, but not the case where only the slug diverges while the name is unchanged (dataChanged's slug branch, Line 36 in the machine). Worth adding given canSave currently has no dedicated guard for a blank slug either (see companion comment on the machine file).

🤖 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
`@packages/ui/src/mosaic/organization/__tests__/organization-profile-profile-section-details.machine.test.ts`
around lines 40 - 46, Add a machine test in
organization-profile-profile-section-details.machine.test for the slug-only edit
case: keep the name unchanged, send a slug update, and assert SUBMIT is allowed
so the dataChanged slug branch is covered. Use the existing start() helper and
the same actor.can({ type: 'SUBMIT' }) pattern, and place it alongside the
current name-divergence coverage to mirror the machine behavior in
dataChanged/canSave.
packages/ui/src/mosaic/organization/__tests__/organization-profile-profile-section.controller.test.tsx (1)

106-133: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding coverage for save failures and late-loading organization data.

Current tests don't cover organization.update/setLogo rejecting (to verify error propagation into snapshot.context.error), nor the scenario where organization becomes available only after the initial render — which is the specific case the PR description says the machine design is meant to handle correctly. Given the stale-closure risk flagged in the controller file, a regression test here would materially increase confidence. As per coding guidelines, tests should "Verify proper error handling and edge cases."

🤖 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
`@packages/ui/src/mosaic/organization/__tests__/organization-profile-profile-section.controller.test.tsx`
around lines 106 - 133, Add regression coverage in the organization profile
controller tests for the missing edge cases: verify that failures from
organization.update and setLogo flow into snapshot.context.error, and add a case
where organization is undefined on initial render but becomes available later.
Use Harness, update, and setLogo to drive the save path and assert the error
state and late-bound organization handling, matching the stale-closure scenario
the controller is meant to support.

Source: Coding guidelines

🤖 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.

Inline comments:
In
`@packages/ui/src/mosaic/organization/organization-profile-profile-section.view.tsx`:
- Around line 152-158: The Cancel button in
organization-profile-profile-section.view.tsx is inside the form but has no
explicit button type, so it defaults to submit and can accidentally trigger
handleSubmit alongside the CANCEL action. Update the Button used for Cancel in
the organization profile section to use a non-submit type (matching the intent
of the existing trigger and Save buttons), while keeping the onClick send({
type: 'CANCEL' }) behavior intact. Verify the fix in the component that renders
the form around handleSubmit and canSubmit so Cancel only discards changes and
never submits.

---

Nitpick comments:
In
`@packages/ui/src/mosaic/organization/__tests__/organization-profile-profile-section-details.machine.test.ts`:
- Around line 40-46: Add a machine test in
organization-profile-profile-section-details.machine.test for the slug-only edit
case: keep the name unchanged, send a slug update, and assert SUBMIT is allowed
so the dataChanged slug branch is covered. Use the existing start() helper and
the same actor.can({ type: 'SUBMIT' }) pattern, and place it alongside the
current name-divergence coverage to mirror the machine behavior in
dataChanged/canSave.

In
`@packages/ui/src/mosaic/organization/__tests__/organization-profile-profile-section.controller.test.tsx`:
- Around line 106-133: Add regression coverage in the organization profile
controller tests for the missing edge cases: verify that failures from
organization.update and setLogo flow into snapshot.context.error, and add a case
where organization is undefined on initial render but becomes available later.
Use Harness, update, and setLogo to drive the save path and assert the error
state and late-bound organization handling, matching the stale-closure scenario
the controller is meant to support.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: dc1682bd-645e-4779-82a0-4f33b7081759

📥 Commits

Reviewing files that changed from the base of the PR and between 961ae31 and 97961dc.

📒 Files selected for processing (18)
  • .changeset/org-profile-profile-section.md
  • packages/swingset/src/components/DocsViewer.tsx
  • packages/swingset/src/lib/registry.ts
  • packages/swingset/src/stories/organization-profile-general-panel.mdx
  • packages/swingset/src/stories/organization-profile-general-panel.stories.tsx
  • packages/swingset/src/stories/organization-profile-profile-section.mdx
  • packages/swingset/src/stories/organization-profile-profile-section.stories.tsx
  • packages/ui/src/mosaic/organization/__tests__/organization-profile-profile-section-details.machine.test.ts
  • packages/ui/src/mosaic/organization/__tests__/organization-profile-profile-section-logo.machine.test.ts
  • packages/ui/src/mosaic/organization/__tests__/organization-profile-profile-section.controller.test.tsx
  • packages/ui/src/mosaic/organization/organization-profile-general-panel-view.tsx
  • packages/ui/src/mosaic/organization/organization-profile-general-panel.tsx
  • packages/ui/src/mosaic/organization/organization-profile-profile-section-details.machine.ts
  • packages/ui/src/mosaic/organization/organization-profile-profile-section-logo.machine.ts
  • packages/ui/src/mosaic/organization/organization-profile-profile-section.controller.tsx
  • packages/ui/src/mosaic/organization/organization-profile-profile-section.tsx
  • packages/ui/src/mosaic/organization/organization-profile-profile-section.view.tsx
  • packages/ui/src/mosaic/organization/organization-profile.tsx

@alexcarpenter alexcarpenter merged commit 80a2b4d into main Jul 9, 2026
53 checks passed
@alexcarpenter alexcarpenter deleted the feat/mosaic-org-profile-profile-section branch July 9, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants