diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index dbcb9262bc..50809a721c 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -134,6 +134,7 @@ "anyone_with_link_can_edit": "", "anyone_with_link_can_view": "", "app_on_x": "", + "appearance": "", "apply_suggestion": "", "archive": "", "archive_projects": "", @@ -159,6 +160,7 @@ "autocompile_disabled_reason": "", "autocomplete": "", "autocomplete_references": "", + "automatically_inserts_closing_brackets_and_parentheses": "", "available_with_group_professional": "", "back": "", "back_to_configuration": "", @@ -235,6 +237,7 @@ "change_the_ownership_of_your_personal_projects": "", "change_to_group_plan": "", "change_to_this_plan": "", + "changes_the_color_scheme_of_the_code_editor": "", "changing_the_position_of_your_figure": "", "changing_the_position_of_your_table": "", "chat": "", @@ -317,6 +320,7 @@ "continue_to": "", "continue_using_free_features": "", "continue_with_free_plan": "", + "controls_the_theme_of_the_application_interface": "", "copied": "", "copy": "", "copy_code": "", @@ -469,7 +473,6 @@ "editor_limit_exceeded_in_this_project": "", "editor_only": "", "editor_only_hide_pdf": "", - "editor_settings": "", "editor_theme": "", "educational_disclaimer": "", "educational_disclaimer_heading": "", @@ -494,6 +497,8 @@ "enable_stop_on_first_error_under_recompile_dropdown_menu": "", "enable_stop_on_first_error_under_recompile_dropdown_menu_v2": "", "enabled": "", + "enables_a_real_time_equation_preview_in_the_editor": "", + "enables_real_time_syntax_checking_in_the_editor": "", "enabling": "", "end_of_document": "", "enter_6_digit_code": "", @@ -592,7 +597,6 @@ "full_width": "", "future_payments": "", "general": "", - "general_settings": "", "generate_token": "", "generic_if_problem_continues_contact_us": "", "generic_linked_file_compile_error": "", @@ -806,8 +810,6 @@ "integrations": "", "integrations_like_github": "", "interested_in_cheaper_personal_plan": "", - "interface": "", - "interface_settings": "", "invalid_confirmation_code": "", "invalid_email": "", "invalid_file_name": "", @@ -1165,7 +1167,6 @@ "pdf_only_hide_editor": "", "pdf_preview_error": "", "pdf_rendering_error": "", - "pdf_settings": "", "pdf_unavailable_for_download": "", "pdf_viewer": "", "pdf_viewer_error": "", @@ -1627,6 +1628,7 @@ "suggested": "", "suggested_fix_for_error_in_path": "", "suggestion_applied": "", + "suggests_code_completions_while_typing": "", "support_for_your_browser_is_ending_soon": "", "supports_up_to_x_users": "", "sure_you_want_to_cancel_plan_change": "", @@ -1790,6 +1792,7 @@ "toolbar_toggle_symbol_palette": "", "toolbar_undo": "", "toolbar_undo_redo_actions": "", + "tools": "", "tooltip_hide_filetree": "", "tooltip_hide_panel": "", "tooltip_hide_pdf": "", diff --git a/services/web/frontend/fonts/material-symbols/MaterialSymbolsRoundedUnfilledPartialSlice.woff2 b/services/web/frontend/fonts/material-symbols/MaterialSymbolsRoundedUnfilledPartialSlice.woff2 index a7c79e29a9..ade3a5b5df 100644 Binary files a/services/web/frontend/fonts/material-symbols/MaterialSymbolsRoundedUnfilledPartialSlice.woff2 and b/services/web/frontend/fonts/material-symbols/MaterialSymbolsRoundedUnfilledPartialSlice.woff2 differ diff --git a/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs b/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs index 9c4a941859..57bef6ea11 100644 --- a/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs +++ b/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs @@ -5,6 +5,7 @@ export default /** @type {const} */ ([ 'book_5', + 'brush', 'code', 'create_new_folder', 'description', diff --git a/services/web/frontend/js/features/ide-redesign/components/settings/appearance-settings/appearance-settings.tsx b/services/web/frontend/js/features/ide-redesign/components/settings/appearance-settings/appearance-settings.tsx new file mode 100644 index 0000000000..2ab843049e --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/settings/appearance-settings/appearance-settings.tsx @@ -0,0 +1,10 @@ +import SettingsSection from '../settings-section' +import OverallThemeSetting from '../appearance-settings/overall-theme-setting' + +export default function AppearanceSettings() { + return ( + + + + ) +} diff --git a/services/web/frontend/js/features/ide-redesign/components/settings/appearance-settings/overall-theme-setting.tsx b/services/web/frontend/js/features/ide-redesign/components/settings/appearance-settings/overall-theme-setting.tsx new file mode 100644 index 0000000000..6249da1ceb --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/settings/appearance-settings/overall-theme-setting.tsx @@ -0,0 +1,45 @@ +import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context' +import DropdownSetting from '../dropdown-setting' +import getMeta from '@/utils/meta' +import { useMemo } from 'react' +import type { Option } from '../dropdown-setting' +import { useTranslation } from 'react-i18next' +import { OverallThemeMeta } from '../../../../../../../types/project-settings' +import { isIEEEBranded } from '@/utils/is-ieee-branded' +import { useLayoutContext } from '@/shared/context/layout-context' +import { OverallTheme } from '@/shared/utils/styles' + +export default function OverallThemeSetting() { + const { t } = useTranslation() + const overallThemes = getMeta('ol-overallThemes') as + | OverallThemeMeta[] + | undefined + + const { loadingStyleSheet } = useLayoutContext() + const { overallTheme, setOverallTheme } = useProjectSettingsContext() + + const options: Array> = useMemo( + () => + overallThemes?.map(({ name, val }) => ({ + value: val, + label: name, + })) ?? [], + [overallThemes] + ) + + if (!overallThemes || isIEEEBranded()) { + return null + } + + return ( + + ) +} diff --git a/services/web/frontend/js/features/ide-redesign/components/settings/dropdown-setting.tsx b/services/web/frontend/js/features/ide-redesign/components/settings/dropdown-setting.tsx new file mode 100644 index 0000000000..f999809a88 --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/settings/dropdown-setting.tsx @@ -0,0 +1,90 @@ +import OLFormSelect from '@/features/ui/components/ol/ol-form-select' +import { ChangeEventHandler, useCallback } from 'react' +import Setting from './setting' +import classNames from 'classnames' +import { Spinner } from 'react-bootstrap-5' + +type PossibleValue = string | number + +export type Option = { + value: T + label: string + ariaHidden?: 'true' | 'false' + disabled?: boolean +} + +export type Optgroup = { + label: string + options: Array> +} + +type SettingsMenuSelectProps = { + id: string + label: string + description: string + options: Array> + onChange: (val: T) => void + value?: T + disabled?: boolean + width?: 'default' | 'wide' + loading?: boolean +} + +export default function DropdownSetting({ + id, + label, + description, + options, + onChange, + value, + disabled = false, + width = 'default', + loading = false, +}: SettingsMenuSelectProps) { + const handleChange: ChangeEventHandler = useCallback( + event => { + const selectedValue = event.target.value + let onChangeValue: PossibleValue = selectedValue + if (typeof value === 'number') { + onChangeValue = parseInt(selectedValue, 10) + } + onChange(onChangeValue as T) + }, + [onChange, value] + ) + + return ( + + {loading ? ( + + ) +} diff --git a/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/auto-close-brackets-setting.tsx b/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/auto-close-brackets-setting.tsx new file mode 100644 index 0000000000..893e011070 --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/auto-close-brackets-setting.tsx @@ -0,0 +1,19 @@ +import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context' +import ToggleSetting from '../toggle-setting' +import { useTranslation } from 'react-i18next' + +export default function AutoCloseBracketsSetting() { + const { autoPairDelimiters, setAutoPairDelimiters } = + useProjectSettingsContext() + const { t } = useTranslation() + + return ( + + ) +} diff --git a/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/auto-complete-setting.tsx b/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/auto-complete-setting.tsx new file mode 100644 index 0000000000..bf15beca96 --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/auto-complete-setting.tsx @@ -0,0 +1,18 @@ +import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context' +import ToggleSetting from '../toggle-setting' +import { useTranslation } from 'react-i18next' + +export default function AutoCompleteSetting() { + const { autoComplete, setAutoComplete } = useProjectSettingsContext() + const { t } = useTranslation() + + return ( + + ) +} diff --git a/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/code-check-setting.tsx b/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/code-check-setting.tsx new file mode 100644 index 0000000000..2f2a22ee0c --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/code-check-setting.tsx @@ -0,0 +1,18 @@ +import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context' +import ToggleSetting from '../toggle-setting' +import { useTranslation } from 'react-i18next' + +export default function CodeCheckSetting() { + const { syntaxValidation, setSyntaxValidation } = useProjectSettingsContext() + const { t } = useTranslation() + + return ( + + ) +} diff --git a/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/editor-settings.tsx b/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/editor-settings.tsx new file mode 100644 index 0000000000..a61c19ccc3 --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/editor-settings.tsx @@ -0,0 +1,25 @@ +import EditorThemeSetting from './editor-theme-setting' +import AutoCompleteSetting from './auto-complete-setting' +import CodeCheckSetting from './code-check-setting' +import AutoCloseBracketsSetting from './auto-close-brackets-setting' +import SettingsSection from '../settings-section' +import MathPreviewSetting from './math-preview-setting' +import { useTranslation } from 'react-i18next' + +export default function EditorSettings() { + const { t } = useTranslation() + + return ( + <> + + + + + + + + + + + ) +} diff --git a/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/editor-theme-setting.tsx b/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/editor-theme-setting.tsx new file mode 100644 index 0000000000..d904257021 --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/editor-theme-setting.tsx @@ -0,0 +1,46 @@ +import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context' +import DropdownSetting from '../dropdown-setting' +import getMeta from '@/utils/meta' +import { useMemo } from 'react' +import type { Option } from '../dropdown-setting' +import { useTranslation } from 'react-i18next' + +export default function EditorThemeSetting() { + const editorThemes = getMeta('ol-editorThemes') + const legacyEditorThemes = getMeta('ol-legacyEditorThemes') + const { editorTheme, setEditorTheme } = useProjectSettingsContext() + const { t } = useTranslation() + + const options = useMemo(() => { + const editorThemeOptions: Array