import type { ISetting, ISettingColor } from '@rocket.chat/core-typings'; import { Accordion, Box, Button, ButtonGroup } from '@rocket.chat/fuselage'; import { useStableCallback } from '@rocket.chat/fuselage-hooks'; import { Page, PageHeader, PageScrollableContentWithShadow, PageFooter } from '@rocket.chat/ui-client'; import type { TranslationKey } from '@rocket.chat/ui-contexts'; import { useToastMessageDispatch, useSettingsDispatch, useSettings } from '@rocket.chat/ui-contexts'; import type { ReactNode, MouseEvent, SubmitEvent } from 'react'; import { useMemo, memo } from 'react'; import { useTranslation } from 'react-i18next'; import type { EditableSetting } from '../../EditableSettingsContext'; import { useEditableSettingsDispatch, useEditableSettings } from '../../EditableSettingsContext'; export type SettingsGroupPageProps = { children: ReactNode; headerButtons?: ReactNode; onClickBack?: () => void; _id: string; i18nLabel: string; i18nDescription?: string; tabs?: ReactNode; isCustom?: boolean; }; const SettingsGroupPage = ({ children = undefined, headerButtons = undefined, onClickBack, _id, i18nLabel, i18nDescription = undefined, tabs = undefined, isCustom = false, }: SettingsGroupPageProps) => { const { t, i18n } = useTranslation(); const dispatch = useSettingsDispatch(); const dispatchToastMessage = useToastMessageDispatch(); const changedEditableSettings = useEditableSettings( useMemo( () => ({ group: _id, changed: true, }), [_id], ), ); const hasInvalidSetting = changedEditableSettings.some((setting) => setting.invalid); const isSaveDisabled = changedEditableSettings.length === 0 || hasInvalidSetting; const originalSettings = useSettings( useMemo( () => ({ _id: changedEditableSettings.map(({ _id }) => _id), }), [changedEditableSettings], ), ); const isColorSetting = (setting: ISetting): setting is ISettingColor => setting.type === 'color'; const save = useStableCallback(async () => { const changes = changedEditableSettings.map((setting) => { if (isColorSetting(setting)) { return { _id: setting._id, value: setting.value, editor: setting.editor, }; } return { _id: setting._id, value: setting.value, }; }); if (isSaveDisabled) { return; } try { await dispatch(changes, () => dispatchToastMessage({ type: 'success', message: t('Settings_updated') })); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } }); const dispatchToEditing = useEditableSettingsDispatch(); const cancel = useStableCallback(() => { const settingsToDispatch = changedEditableSettings .map(({ _id }) => originalSettings.find((setting) => setting._id === _id)) .map((setting) => { if (!setting) { return; } if (isColorSetting(setting)) { return { _id: setting._id, value: setting.value, editor: setting.editor, changed: false, }; } return { _id: setting._id, value: setting.value, changed: false, }; }) .filter(Boolean); dispatchToEditing(settingsToDispatch as Partial[]); }); const handleSubmit = (event: SubmitEvent): void => { event.preventDefault(); save(); }; const handleCancelClick = (event: MouseEvent): void => { event.preventDefault(); cancel(); }; const handleSaveClick = (event: MouseEvent): void => { event.preventDefault(); save(); }; if (!_id) { return {children}; } const isTranslationKey = (key: string): key is TranslationKey => (key as TranslationKey) !== undefined; return ( {headerButtons} {tabs} {isCustom ? ( children ) : ( {i18nDescription && isTranslationKey(i18nDescription) && i18n.exists(i18nDescription) && ( {t(i18nDescription)} )} {children} )} {changedEditableSettings.length > 0 && ( )} ); }; export default memo(SettingsGroupPage);