diff --git a/frontend/packages/console-shared/src/components/editor/BasicCodeEditor.tsx b/frontend/packages/console-shared/src/components/editor/BasicCodeEditor.tsx index b81e9b31db4..2b1a4758df1 100644 --- a/frontend/packages/console-shared/src/components/editor/BasicCodeEditor.tsx +++ b/frontend/packages/console-shared/src/components/editor/BasicCodeEditor.tsx @@ -1,4 +1,4 @@ -import * as React from 'react'; +import { FC, useContext } from 'react'; import { loader } from '@monaco-editor/react'; import { CodeEditor } from '@patternfly/react-code-editor'; import { css } from '@patternfly/react-styles'; @@ -20,9 +20,9 @@ loader.config({ monaco }); * Note that it is important that this is the only component that imports * monaco-editor, to avoid fetching files from a 3rd-party CDN. */ -export const BasicCodeEditor: React.FC = (props) => { +export const BasicCodeEditor: FC = (props) => { const { t } = useTranslation('console-shared'); - const theme = React.useContext(ThemeContext); + const theme = useContext(ThemeContext); return ( @@ -42,8 +42,8 @@ export const BasicCodeEditor: React.FC = (props) => { {...props} className={css('co-code-editor', props.className)} editorProps={{ - ...props?.editorProps, theme: `console-${theme}`, + ...props?.editorProps, beforeMount: (monacoInstance) => { defineThemes(monacoInstance?.editor); window.monaco = monacoInstance; // for e2e tests @@ -51,8 +51,8 @@ export const BasicCodeEditor: React.FC = (props) => { }, }} options={{ - ...props?.options, fontFamily: 'var(--pf-t--global--font--family--mono)', + ...props?.options, }} /> diff --git a/frontend/packages/console-shared/src/constants/common.ts b/frontend/packages/console-shared/src/constants/common.ts index 0cd24015eda..fc09f0d9cd6 100644 --- a/frontend/packages/console-shared/src/constants/common.ts +++ b/frontend/packages/console-shared/src/constants/common.ts @@ -46,6 +46,10 @@ export const COMMUNITY_PROVIDERS_WARNING_USERSETTINGS_KEY = `${USERSETTINGS_PREF export const PINNED_RESOURCES_LOCAL_STORAGE_KEY = `${STORAGE_PREFIX}/pinned-resources`; export const COLUMN_MANAGEMENT_LOCAL_STORAGE_KEY = `${STORAGE_PREFIX}/table-columns`; export const LOG_WRAP_LINES_USERSETTINGS_KEY = `${USERSETTINGS_PREFIX}.log.wrapLines`; +export const OVERRIDE_YAML_EDITOR_THEME_USER_SETTING_KEY = `${USERSETTINGS_PREFIX}.overrideYAMLEditorTheme`; +export const OVERRIDE_YAML_EDITOR_THEME_LOCAL_STORAGE_KEY = `${STORAGE_PREFIX}/overrideYAMLEditorTheme`; +export const CUSTOM_YAML_EDITOR_FONT_SIZE_USER_SETTING_KEY = `${USERSETTINGS_PREFIX}.customYAMLEditorFontSize`; +export const CUSTOM_YAML_EDITOR_FONT_SIZE_LOCAL_STORAGE_KEY = `${STORAGE_PREFIX}/customYAMLEditorFontSize`; export const SHOW_YAML_EDITOR_TOOLTIPS_USER_SETTING_KEY = `${USERSETTINGS_PREFIX}.showYAMLEditorTooltips`; export const SHOW_YAML_EDITOR_TOOLTIPS_LOCAL_STORAGE_KEY = `${STORAGE_PREFIX}/showYAMLEditorTooltips`; export const SHOW_YAML_EDITOR_STICKY_SCROLL_USER_SETTING_KEY = `${USERSETTINGS_PREFIX}.showYAMLEditorStickyScroll`; diff --git a/frontend/public/components/edit-yaml.tsx b/frontend/public/components/edit-yaml.tsx index 87fe8a7243c..97e81b402ab 100644 --- a/frontend/public/components/edit-yaml.tsx +++ b/frontend/public/components/edit-yaml.tsx @@ -9,18 +9,10 @@ import { ActionGroup, Alert, Button } from '@patternfly/react-core'; import { DownloadIcon } from '@patternfly/react-icons/dist/esm/icons/download-icon'; import { Trans, useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom-v5-compat'; -import { - FLAGS, - ALL_NAMESPACES_KEY, - SHOW_YAML_EDITOR_TOOLTIPS_USER_SETTING_KEY, - SHOW_YAML_EDITOR_TOOLTIPS_LOCAL_STORAGE_KEY, - SHOW_YAML_EDITOR_STICKY_SCROLL_USER_SETTING_KEY, - SHOW_YAML_EDITOR_STICKY_SCROLL_LOCAL_STORAGE_KEY, -} from '@console/shared/src/constants/common'; +import { FLAGS, ALL_NAMESPACES_KEY } from '@console/shared/src/constants/common'; import { getBadgeFromType } from '@console/shared/src/components/badges/badge-factory'; import { getResourceSidebarSamples } from '@console/shared/src/utils/sample-utils'; import { useTelemetry } from '@console/shared/src/hooks/useTelemetry'; -import { useUserSettingsCompatibility } from '@console/shared/src/hooks/useUserSettingsCompatibility'; import { useResourceConnectionHandler } from '@console/shared/src/hooks/useResourceConnectionHandler'; import PageBody from '@console/shared/src/components/layout/PageBody'; @@ -64,7 +56,7 @@ import { findOwner } from '../module/k8s/managed-by'; import { ClusterServiceVersionModel } from '@console/operator-lifecycle-manager/src/models'; import { definitionFor } from '../module/k8s/swagger'; import { ImportYAMLResults } from './import-yaml-results'; -import { EditYamlSettingsModal } from './modals/edit-yaml-settings-modal'; +import { EditYamlSettingsModal, useEditYamlSettings } from './modals/edit-yaml-settings-modal'; import { CodeEditorControl } from '@patternfly/react-code-editor'; import { CompressIcon } from '@patternfly/react-icons/dist/js/icons/compress-icon'; import { ExpandIcon } from '@patternfly/react-icons/dist/js/icons/expand-icon'; @@ -73,6 +65,7 @@ import { RootState } from '@console/internal/redux'; import { getActiveNamespace } from '@console/internal/reducers/ui'; import { useOverlay } from '@console/dynamic-plugin-sdk/src/app/modal-support/useOverlay'; import { ErrorModal } from './modals/error-modal'; +import type { CodeEditorProps } from '@console/dynamic-plugin-sdk/src/extensions/console-types'; const generateObjToLoad = ( templateExtensions: Parameters[0], @@ -189,19 +182,7 @@ const EditYAMLInner: React.FC = (props) => { ), ); - const [showTooltips] = useUserSettingsCompatibility( - SHOW_YAML_EDITOR_TOOLTIPS_USER_SETTING_KEY, - SHOW_YAML_EDITOR_TOOLTIPS_LOCAL_STORAGE_KEY, - true, - true, - ); - - const [stickyScrollEnabled] = useUserSettingsCompatibility( - SHOW_YAML_EDITOR_STICKY_SCROLL_USER_SETTING_KEY, - SHOW_YAML_EDITOR_STICKY_SCROLL_LOCAL_STORAGE_KEY, - true, - true, - ); + const { theme, fontSize, showTooltips, stickyScrollEnabled } = useEditYamlSettings(); const [callbackCommand, setCallbackCommand] = React.useState(''); const [showReplaceCodeModal, setShowReplaceCodeModal] = React.useState(false); @@ -803,7 +784,7 @@ const EditYAMLInner: React.FC = (props) => { } const readOnly = props.readOnly || notAllowed; - const options = { readOnly, scrollBeyondLastLine: false }; + const options: CodeEditorProps['options'] = { fontSize, readOnly, scrollBeyondLastLine: false }; const model = getModel(props.obj); const { samples, snippets } = model ? getResourceSidebarSamples(model, yamlSamplesList, t) @@ -876,9 +857,10 @@ const EditYAMLInner: React.FC = (props) => {
{showReplaceCodeModal && } void; - Icon?: React.ComponentType; + /** Title of the configuration option. We assume that titles are unique. */ + title: string; + /** + * Optional ID of the configuration option. Also used as a prefix for the following elements: + * - `${id}-title` for the element which contains the title + * - `${id}-description` for the element which contains the description + */ + id?: string; + /** + * Slot to render inside the configuration modal. Remember to add `aria-labelledby` and `aria-describedby` props + * to the control inside the slot, pointing to the title and description ids respectively. + */ + slot?: ReactNode; } -const ConfigModalItem: React.FCC = ({ +const ConfigModalItem: React.FunctionComponent = ({ + icon = , + description, title, + id = `ConfigModalItem-${title.replace(/\s+/g, '-').toLowerCase()}`, + slot, +}) => ( + + + + {icon} + + {title} + + + +
{description}
+
+ {slot} +
+); + +interface ConfigModalSwitchProps extends Omit { + /** Flag indicating whether the option is enabled or disabled. */ + isChecked?: SwitchProps['isChecked']; + /** onChange handler for the switch. */ + onChange?: SwitchProps['onChange']; + /** Labels for the enabled and disabled states of the switch. */ + labels?: { + enabled: string; + disabled: string; + }; +} + +const ConfigModalSwitch: React.FunctionComponent = ({ + icon = , description, - checked, - setChecked, - Icon = CogIcon, -}) => { + title, + id = `ConfigModalSwitch-${title.replace(/\s+/g, '-').toLowerCase()}`, + isChecked = false, + onChange, + labels = { enabled: undefined, disabled: undefined }, +}) => ( + + } + /> +); + +/* + * The following is not taken from the PatternFly example + */ +interface AppendToProps { + appendTo?: ComponentProps['appendTo']; +} + +type ThemeOption = 'default' | 'dark' | 'light'; + +const ThemeConfigItem: FC = () => { const { t } = useTranslation('public'); + const [theme, setTheme] = useUserSettingsCompatibility( + OVERRIDE_YAML_EDITOR_THEME_USER_SETTING_KEY, + OVERRIDE_YAML_EDITOR_THEME_LOCAL_STORAGE_KEY, + 'default', + true, + ); + + const options: SimpleSelectOption[] = useMemo( + () => [ + { + value: 'default', + description: t('Follow your user preference'), + content: t('Use theme setting'), + selected: theme === 'default', + }, + { + value: 'dark', + description: t('Always use dark mode'), + content: t('Dark'), + selected: theme === 'dark', + }, + { + value: 'light', + description: t('Always use light mode'), + content: t('Light'), + selected: theme === 'light', + }, + ], + [t, theme], + ); + return ( - - - - - - - - {title} - {description} - - - - - { - setChecked(c); + } + slot={ + setTheme(value)} + popperProps={{ appendTo: 'inline' }} /> - - + } + /> + ); +}; + +const FontSizeConfigItem = () => { + const { t } = useTranslation('public'); + + const [fontSize, setFontSize] = useUserSettingsCompatibility( + CUSTOM_YAML_EDITOR_FONT_SIZE_USER_SETTING_KEY, + CUSTOM_YAML_EDITOR_FONT_SIZE_LOCAL_STORAGE_KEY, + 14, + true, + ); + + return ( + } + slot={ + setFontSize((size) => Math.max(5, size - 1))} + onChange={(event) => setFontSize(Number((event.target as HTMLInputElement).value))} + onPlus={() => setFontSize((size) => size + 1)} + widthChars={2} + /> + } + /> ); }; @@ -102,76 +279,113 @@ const TooltipConfigItem = () => { SHOW_YAML_EDITOR_TOOLTIPS_USER_SETTING_KEY, SHOW_YAML_EDITOR_TOOLTIPS_LOCAL_STORAGE_KEY, true, + true, ); return ( - setShowTooltips(checked)} + isChecked={showTooltips} + icon={} /> ); }; const StickyScrollConfigItem = () => { const { t } = useTranslation('public'); - const [showStickyScroll, setShowStickyScroll] = useUserSettingsCompatibility( + const [stickyScrollEnabled, setStickyScrollEnabled] = useUserSettingsCompatibility( SHOW_YAML_EDITOR_STICKY_SCROLL_USER_SETTING_KEY, SHOW_YAML_EDITOR_STICKY_SCROLL_LOCAL_STORAGE_KEY, true, + true, ); return ( - setStickyScrollEnabled(checked)} + isChecked={stickyScrollEnabled} + icon={} /> ); }; const EDIT_YAML_SETTINGS_MODAL_ID = 'edit-yaml-settings-modal'; -interface EditYamlSettingsModalProps { - appendTo?: React.ComponentProps['appendTo']; -} - -export const EditYamlSettingsModal: React.FCC = ({ appendTo }) => { +/** + * A modal which controls certain settings of the YAML editor. Based off the + * [PatternFly code editor control] example. + * + * [PatternFly code editor control]: https://www.patternfly.org/components/code-editor#with-configuration-modal + */ +export const EditYamlSettingsModal: FC = ({ appendTo }) => { const { t } = useTranslation('public'); - const [isModalOpen, setIsModalOpen] = React.useState(false); + const [isModalOpen, setIsModalOpen] = useState(false); return ( <> setIsModalOpen(!isModalOpen)} + onClose={() => setIsModalOpen(false)} ouiaId={EDIT_YAML_SETTINGS_MODAL_ID} variant="small" appendTo={appendTo} - aria-labelledby={`${EDIT_YAML_SETTINGS_MODAL_ID}-title`} - aria-describedby={`${EDIT_YAML_SETTINGS_MODAL_ID}-body`} > + + } aria-label={t('Editor settings')} - tooltipProps={{ content: t('Editor settings') }} + aria-haspopup="dialog" + icon={} onClick={() => setIsModalOpen(true)} + tooltipProps={{ content: t('Editor settings') }} /> ); }; + +/** Get all the YAML editor settings from user settings and local storage */ +export const useEditYamlSettings = () => { + const [theme] = useUserSettingsCompatibility( + OVERRIDE_YAML_EDITOR_THEME_USER_SETTING_KEY, + OVERRIDE_YAML_EDITOR_THEME_LOCAL_STORAGE_KEY, + 'default', + true, + ); + const [fontSize] = useUserSettingsCompatibility( + CUSTOM_YAML_EDITOR_FONT_SIZE_USER_SETTING_KEY, + CUSTOM_YAML_EDITOR_FONT_SIZE_LOCAL_STORAGE_KEY, + 14, + true, + ); + const [showTooltips] = useUserSettingsCompatibility( + SHOW_YAML_EDITOR_TOOLTIPS_USER_SETTING_KEY, + SHOW_YAML_EDITOR_TOOLTIPS_LOCAL_STORAGE_KEY, + true, + true, + ); + const [stickyScrollEnabled] = useUserSettingsCompatibility( + SHOW_YAML_EDITOR_STICKY_SCROLL_USER_SETTING_KEY, + SHOW_YAML_EDITOR_STICKY_SCROLL_LOCAL_STORAGE_KEY, + true, + true, + ); + return { theme, fontSize, showTooltips, stickyScrollEnabled }; +}; diff --git a/frontend/public/components/modals/expand-pvc-modal.tsx b/frontend/public/components/modals/expand-pvc-modal.tsx index 1b88f00438a..0735da9afab 100644 --- a/frontend/public/components/modals/expand-pvc-modal.tsx +++ b/frontend/public/components/modals/expand-pvc-modal.tsx @@ -59,8 +59,8 @@ const ExpandPVCModal = ({ resource, kind, close, cancel }: ExpandPVCModalProps) Increase the capacity of PVC{' '} {{ resourceName: resource.metadata.name }}.{' '} - Note that capacity can't be less than the current PVC size. This can be a time-consuming - process. + Note that capacity must be at least the current PVC size. This expansion might take some + time to complete.

diff --git a/frontend/public/components/monitoring/receiver-forms/slack-receiver-form.tsx b/frontend/public/components/monitoring/receiver-forms/slack-receiver-form.tsx index 06be2391c79..2b5bf8bb8af 100644 --- a/frontend/public/components/monitoring/receiver-forms/slack-receiver-form.tsx +++ b/frontend/public/components/monitoring/receiver-forms/slack-receiver-form.tsx @@ -253,7 +253,7 @@ export const Form: React.FC = ({ globals, formValues, dispatchFormCha - {t('public~The title of the Slack message.')} + {t('public~Slack message title')} @@ -270,9 +270,7 @@ export const Form: React.FC = ({ globals, formValues, dispatchFormCha /> - - {t('public~The text of the Slack message.')} - + {t('public~Slack message text')} diff --git a/frontend/public/locales/en/public.json b/frontend/public/locales/en/public.json index 27f43a8a28e..6e6fe7eb1cf 100644 --- a/frontend/public/locales/en/public.json +++ b/frontend/public/locales/en/public.json @@ -910,16 +910,28 @@ "Enter the name of the {{label}} to delete": "Enter the name of the {{label}} to delete", "Delete PersistentVolumeClaim": "Delete PersistentVolumeClaim", "Are you sure you want to delete <2>{{pvcName}} PersistentVolumeClaim?": "Are you sure you want to delete <2>{{pvcName}} PersistentVolumeClaim?", - "On": "On", - "Off": "Off", + "Follow your user preference": "Follow your user preference", + "Use theme setting": "Use theme setting", + "Always use dark mode": "Always use dark mode", + "Dark": "Dark", + "Always use light mode": "Always use light mode", + "Light": "Light", + "Theme": "Theme", + "Select the code editor color theme": "Select the code editor color theme", + "Font size": "Font size", + "Adjust the font size of the code editor": "Adjust the font size of the code editor", + "Enter a font size": "Enter a font size", + "Decrease font size": "Decrease font size", + "Increase font size": "Increase font size", "Tooltips": "Tooltips", - "Show tooltips for Resource and Field names and definitions.": "Show tooltips for Resource and Field names and definitions.", + "Show tooltips for Resource names, Field names, and definitions": "Show tooltips for Resource names, Field names, and definitions", "Sticky scroll": "Sticky scroll", - "Stick scopes to the top of the editor so they are always visible.": "Stick scopes to the top of the editor so they are always visible.", + "Pin scopes to the top of the editor so they are always visible": "Pin scopes to the top of the editor so they are always visible", "Editor settings": "Editor settings", + "Changes apply immediately": "Changes apply immediately", "OK": "OK", "Expand {{kind}}": "Expand {{kind}}", - "Increase the capacity of PVC <2>{{resourceName}}. Note that capacity can't be less than the current PVC size. This can be a time-consuming process.": "Increase the capacity of PVC <2>{{resourceName}}. Note that capacity can't be less than the current PVC size. This can be a time-consuming process.", + "Increase the capacity of PVC <2>{{resourceName}}. Note that capacity must be at least the current PVC size. This expansion might take some time to complete.": "Increase the capacity of PVC <2>{{resourceName}}. Note that capacity must be at least the current PVC size. This expansion might take some time to complete.", "Total size": "Total size", "requestSize": "requestSize", "Expand": "Expand", @@ -1057,9 +1069,9 @@ "Link names": "Link names", "Find and link channel names and usernames.": "Find and link channel names and usernames.", "Title": "Title", - "The title of the Slack message.": "The title of the Slack message.", + "Slack message title": "Slack message title", "Text": "Text", - "The text of the Slack message.": "The text of the Slack message.", + "Slack message text": "Slack message text", "The endpoint to send HTTP POST requests to.": "The endpoint to send HTTP POST requests to.", "Me": "Me", "System": "System",