Files
twenty/packages/twenty-front/src/modules/side-panel/hooks/useOpenRichTextInSidePanel.ts
T
Charles Bochet 602db4ffea feat: enable Rich Text as a creatable field type (#18634)
## Summary

- Removes `RICH_TEXT` from the excluded/hidden field types in the
settings UI so users can create rich text fields on any object (not just
Note/Task)
- Creates a generic `RichTextFieldEditor` component that uses standard
`useUpdateOneRecord` for persistence, decoupled from the
Note/Task-specific `ActivityRichTextEditor`
- Updates the inline `RichTextFieldInput` and side panel to route to the
appropriate editor based on object type (activity editor for Note/Task,
generic editor for everything else)

## Details

### Tier 1 — Settings UI unlock
- Removed `RICH_TEXT` from `excludedFieldTypes` in
`SettingsObjectNewFieldSelect.tsx`
- Removed `RICH_TEXT` from `SettingsExcludedFieldType` type union
- Added `RICH_TEXT` to `previewableTypes` in
`SettingsDataModelFieldSettingsFormCard`

### Tier 2 — Generic inline editing
- New `RichTextFieldEditor` — a generic BlockNote editor that works for
any object using `useUpdateOneRecord` (no activity-specific coupling)
- `RichTextFieldInput` now branches: `ActivityRichTextEditor` for
Note/Task, `RichTextFieldEditor` for all other objects
- Generalized side panel state (`viewableRichTextComponentState`) from
`activityId`/`activityObjectNameSingular` to
`recordId`/`objectNameSingular`/`fieldName`
- `useOpenRichTextInSidePanel` now accepts an optional `fieldName`
parameter

### Tier 3 — Verification
- Search: only `markdown` subfield is indexed (correct behavior)
- Filters: `RichTextFilter` GraphQL input type already exists
- Import/export: `markdown` subfield is already marked `isImportable:
true`
2026-03-14 10:57:27 +01:00

36 lines
1.1 KiB
TypeScript

import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
import { viewableRichTextComponentState } from '@/side-panel/pages/rich-text-page/states/viewableRichTextComponentState';
import { t } from '@lingui/core/macro';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { SidePanelPages } from 'twenty-shared/types';
import { IconPencil } from 'twenty-ui/display';
export const useOpenRichTextInSidePanel = () => {
const { navigateSidePanelMenu, openSidePanelMenu } = useSidePanelMenu();
const store = useStore();
const openRichTextInSidePanel = useCallback(
(recordId: string, objectNameSingular: string, fieldName?: string) => {
store.set(viewableRichTextComponentState.atom, {
recordId,
objectNameSingular,
fieldName: fieldName ?? 'bodyV2',
});
openSidePanelMenu();
navigateSidePanelMenu({
page: SidePanelPages.EditRichText,
pageTitle: t`Rich Text`,
pageIcon: IconPencil,
});
},
[navigateSidePanelMenu, openSidePanelMenu, store],
);
return {
openRichTextInSidePanel,
};
};