From d25b032e16b327e3d202d18c0a54504a60857329 Mon Sep 17 00:00:00 2001 From: Malik Glossop Date: Thu, 4 Jun 2026 12:44:58 +0200 Subject: [PATCH] Merge pull request #33450 from overleaf/worktree-mg-writefull-spelling-tab Add writefull language suggestions section to Spelling and language tab GitOrigin-RevId: 6195683ca175a4c3da25a7ab334a605c67db04b8 --- server-ce/test/editor.spec.ts | 2 + services/web/config/settings.defaults.js | 1 + .../web/frontend/extracted-translations.json | 16 +++++ ...alSymbolsRoundedUnfilledPartialSlice.woff2 | Bin 10440 -> 10532 bytes .../material-symbols/unfilled-symbols.mjs | 1 + .../context/settings-modal-context.tsx | 43 ++++++++---- .../frontend/js/shared/components/select.tsx | 63 +++++++++++++++++- .../stylesheets/components/select.scss | 9 +++ services/web/locales/en.json | 17 +++++ .../components/shared/select.spec.tsx | 54 +++++++++++++++ .../settings-modal/settings-modal.test.tsx | 38 ++++++++++- 11 files changed, 226 insertions(+), 18 deletions(-) diff --git a/server-ce/test/editor.spec.ts b/server-ce/test/editor.spec.ts index 773121141f..1568b12f8d 100644 --- a/server-ce/test/editor.spec.ts +++ b/server-ce/test/editor.spec.ts @@ -44,6 +44,7 @@ describe('editor', function () { cy.log(`change project language to '${lng}'`) cy.findByRole('button', { name: 'Settings' }).click() cy.findByRole('dialog').within(() => { + cy.findByRole('tab', { name: 'Spelling and language' }).click() cy.findByLabelText('Spellcheck language').select(lng) }) cy.get('body').type('{esc}') @@ -76,6 +77,7 @@ describe('editor', function () { cy.log('remove word from dictionary') cy.findByRole('button', { name: 'Settings' }).click() cy.findByRole('dialog').within(() => { + cy.findByRole('tab', { name: 'Spelling and language' }).click() cy.findByLabelText('Dictionary').click() }) cy.findByTestId('dictionary-modal').within(() => { diff --git a/services/web/config/settings.defaults.js b/services/web/config/settings.defaults.js index 569d9babcd..83c5296497 100644 --- a/services/web/config/settings.defaults.js +++ b/services/web/config/settings.defaults.js @@ -1090,6 +1090,7 @@ module.exports = { integrationPanelComponents: [], referenceSearchSetting: [], settingsModalEditorTabSections: [], + settingsModalSpellcheckSections: [], errorLogsComponents: [], referenceIndices: [], railEntries: [], diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 7747d0724b..f0455fc789 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -133,6 +133,7 @@ "ai_feedback_the_suggestion_didnt_fix_the_error": "", "ai_feedback_the_suggestion_wasnt_the_best_fix_available": "", "ai_feedback_there_was_no_code_fix_suggested": "", + "ai_language_suggestions": "", "ai_shortcut_on_empty_lines": "", "ai_shortcut_on_text_selection": "", "alignment": "", @@ -216,6 +217,7 @@ "binary_history_error": "", "blank_project": "", "blocked_filename": "", + "blocked_language_suggestions": "", "blog": "", "bold": "", "booktabs": "", @@ -413,6 +415,8 @@ "currently_subscribed_to_plan": "", "custom": "", "custom_borders": "", + "custom_prompt": "", + "custom_prompt_example": "", "customer_stories": "", "customize_your_group_subscription": "", "customizing_figures": "", @@ -613,6 +617,9 @@ "enabling": "", "end_of_document": "", "end_time_utc": "", + "english__preference_for_ai_suggestion": "", + "english_american": "", + "english_british": "", "ensure_recover_account": "", "enter_any_size_including_units_or_valid_latex_command": "", "enter_emails_separated_by_commas": "", @@ -1042,6 +1049,13 @@ "labs_ongoing_experiments": "", "labs_settings": "", "language": "", + "language_model_gpt_any_language": "", + "language_model_gpt_any_language_description": "", + "language_model_gpt_custom_prompt": "", + "language_model_gpt_custom_prompt_description": "", + "language_model_writefull_english": "", + "language_model_writefull_english_description": "", + "language_suggestions": "", "last_active": "", "last_active_description": "", "last_edit": "", @@ -1205,6 +1219,7 @@ "missing_field_for_entry": "", "missing_fields_for_entry": "", "missing_payment_details": "", + "model": "", "money_back_guarantee": "", "month": "", "month_plural": "", @@ -1857,6 +1872,7 @@ "speech_input_not_available": "", "spellcheck": "", "spellcheck_language": "", + "spelling_and_language": "", "split_view": "", "sso": "", "sso_active": "", diff --git a/services/web/frontend/fonts/material-symbols/MaterialSymbolsRoundedUnfilledPartialSlice.woff2 b/services/web/frontend/fonts/material-symbols/MaterialSymbolsRoundedUnfilledPartialSlice.woff2 index 5ca6ba1da4ecf206da7345eedc48355058b6230d..dab440a52b27b68eb3f00e5d732bd75266cc6576 100644 GIT binary patch literal 10532 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�M4-VByA~_|&zs+-$Vi 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 mY-v8Cw!kU40tX-r2OEJ+Wkgmw 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

A82 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 m?.import?.default) .filter((h: unknown): h is SettingsSectionHook => typeof h === 'function') +const spellcheckExtraSectionHooks: SettingsSectionHook[] = + importOverleafModules('settingsModalSpellcheckSections') + .map((m: any) => m?.import?.default) + .filter((h: unknown): h is SettingsSectionHook => typeof h === 'function') + const useSlotSections = (hooks: SettingsSectionHook[]): SettingsSection[] => hooks.map(hook => hook()).filter((s): s is SettingsSection => s != null) @@ -78,6 +83,7 @@ export const SettingsModalProvider: FC = ({ const hasEditorTabs = useFeatureFlag('editor-tabs') const editorTabExtraSections = useSlotSections(editorTabExtraSectionHooks) + const spellcheckExtraSections = useSlotSections(spellcheckExtraSectionHooks) const allSettingsTabs: SettingsEntry[] = useMemo( () => [ @@ -125,20 +131,6 @@ export const SettingsModalProvider: FC = ({ }, ], }, - { - key: 'spellcheck', - title: t('spellcheck'), - settings: [ - { - key: 'spellCheckLanguage', - component: , - }, - { - key: 'dictionary-settings', - component: , - }, - ], - }, { key: 'tools', title: t('tools'), @@ -156,6 +148,28 @@ export const SettingsModalProvider: FC = ({ ...editorTabExtraSections, ], }, + { + key: 'spelling_and_language', + title: t('spelling_and_language'), + icon: 'spellcheck', + sections: [ + { + key: 'spellcheck', + title: t('spellcheck'), + settings: [ + { + key: 'spellCheckLanguage', + component: , + }, + { + key: 'dictionary-settings', + component: , + }, + ], + }, + ...spellcheckExtraSections, + ], + }, { key: 'compiler', title: t('compiler'), @@ -269,6 +283,7 @@ export const SettingsModalProvider: FC = ({ hasEmailNotifications, isOverleaf, editorTabExtraSections, + spellcheckExtraSections, ] ) diff --git a/services/web/frontend/js/shared/components/select.tsx b/services/web/frontend/js/shared/components/select.tsx index 3b5f36a77f..46e6f89ec3 100644 --- a/services/web/frontend/js/shared/components/select.tsx +++ b/services/web/frontend/js/shared/components/select.tsx @@ -5,6 +5,7 @@ import { useCallback, ReactNode, useState, + useId, } from 'react' import classNames from 'classnames' import { useSelect } from 'downshift' @@ -14,12 +15,47 @@ import FormControl from '@/shared/components/form/form-control' import MaterialIcon from '@/shared/components/material-icon' import { CaretUp, CaretDown, Check } from '@phosphor-icons/react' import { DropdownItem } from '@/shared/components/dropdown/dropdown-menu' +import OLOverlay from '@/shared/components/ol/ol-overlay' import OLSpinner from './ol/ol-spinner' import DSFormLabel from '@/shared/components/ds/ds-form-label' import DSFormGroup from '@/shared/components/ds/ds-form-group' import DSFormControl from '@/shared/components/ds/ds-form-control' import { DropdownItemProps } from '@/shared/components/types/dropdown-menu-props' +function SelectMenuPopover({ + show, + target, + onHide, + children, +}: { + show: boolean + target: HTMLElement | null + onHide: () => void + children: ReactNode +}) { + const id = useId() + return ( + + {({ ref, style }) => ( +

+ {children} +
+ )} + + ) +} + export type SelectProps = { // The items rendered as dropdown options. items: T[] @@ -63,6 +99,11 @@ export type SelectProps = { // CIAM-specific layout isCiam?: boolean size?: React.ComponentProps['size'] + // Renders the menu in a portal so it escapes overflow-clipping ancestors. + portal?: boolean + // Optional id for the toggle button element. When provided, enables association + // with an external