Files
twenty/packages
Thomas Trompette 38e9d231bc fix: hide add-select-option prompt for users without data model permission (#23410)
Fixes #23341

## Problem

A user whose role lacks the `DATA_MODEL` permission flag still saw the
`Add "…" to options` prompt when typing a value that matched no option
in a multiselect. Clicking it did nothing.

`MultiSelectInput` renders `AddSelectOptionMenuItem` based purely on
whether the callback exists:

```tsx
{onAddSelectOption && searchFilter && filteredOptionsInDropDown.length === 0 && (
```

`MultiSelectFieldInput` always passed a callback, and did the permission
check *inside* it:

```tsx
const handleAddSelectOption = (optionName: string) => {
  if (!canAddSelectOption) {
    return;
  }
  addSelectOption(optionName);
};
```

So the guard suppressed the click but not the render, which is exactly
the reported symptom: the prompt is visible and inert.

## Fix

Gate at the prop instead of inside the handler, so the menu item is
never rendered when the action is unavailable:

```tsx
onAddSelectOption={canAddSelectOption ? addSelectOption : undefined}
```

The wrapper is now redundant and removed; `addSelectOption` already has
the matching `(optionName: string) => void` signature.

`SelectFieldInput` had the byte-identical bug (`SelectInput` gates on
`onAddSelectOption &&` the same way), so it gets the same change.

## Note on scope

`useCanAddSelectOption` requires `objectNamePlural` from the route in
addition to the permission flag:

```ts
const canAddSelectOption =
  userHasPermissionToEditDataModel &&
  isNonEmptyString(fieldName) &&
  isNonEmptyString(objectNamePlural);
```

Record *detail* pages (`/object/:objectNameSingular/:recordId`) have no
`objectNamePlural`, so the prompt was dead there for **every** user,
admins included. This change hides it in that case too, which is the
correct behavior since the click could never have worked.

## Testing

Verified manually against a local instance, toggling the patch in and
out on the same cell so before/after is directly comparable.

Company `Work Policy` (multiselect) in the Companies table view, typing
a string that matches no option:

| user | route | before | after |
|---|---|---|---|
| Member (no `DATA_MODEL`) | `/objects/companies` | prompt shown, click
does nothing | prompt hidden |
| Admin | `/objects/companies` | prompt shown, click works | prompt
shown, click works (navigates to
`/settings/objects/companies/workPolicy?newOption=…`) |
| Admin | `/object/company/:id` | prompt shown, click does nothing |
prompt hidden |

`nx lint:diff-with-main twenty-front` and `nx typecheck twenty-front`
both pass.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23410?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-28 11:33:12 +00:00
..