diff --git a/app/settings/server/functions/settings.js b/app/settings/server/functions/settings.js index d1cb239ae81..7a7ae4a47c1 100644 --- a/app/settings/server/functions/settings.js +++ b/app/settings/server/functions/settings.js @@ -64,10 +64,7 @@ const overrideSetting = (_id, value, options) => { * @param {Object} setting */ -settings.add = function(_id, value, options = {}) { - if (options == null) { - options = {}; - } +settings.add = function(_id, value, { editor, ...options } = {}) { if (!_id || value == null) { return false; } @@ -112,9 +109,9 @@ settings.add = function(_id, value, options = {}) { createdAt: new Date(), }, }; - if (options.editor != null) { - updateOperations.$setOnInsert.editor = options.editor; - delete options.editor; + if (editor != null) { + updateOperations.$setOnInsert.editor = editor; + updateOperations.$setOnInsert.packageEditor = editor; } if (options.value == null) { if (options.force === true) { diff --git a/app/theme/server/server.js b/app/theme/server/server.js index 3430baed66f..9cde1fc6753 100644 --- a/app/theme/server/server.js +++ b/app/theme/server/server.js @@ -106,6 +106,7 @@ export const theme = new class { this.variables[name] = { type, value, + editor, }; if (persist) { const config = { diff --git a/client/components/admin/settings/Setting.js b/client/components/admin/settings/Setting.js index e8d171e5816..cbbc3b66a0f 100644 --- a/client/components/admin/settings/Setting.js +++ b/client/components/admin/settings/Setting.js @@ -67,11 +67,13 @@ export function Setting({ settingId, sectionChanged }) { const { value: contextValue, editor: contextEditor, + packageEditor, update, reset, ...setting } = useSetting(settingId); + const t = useTranslation(); const [value, setValue] = useState(contextValue); @@ -116,7 +118,7 @@ export function Setting({ settingId, sectionChanged }) { const label = (i18nLabel && t(i18nLabel)) || (_id || t(_id)); const hint = useMemo(() => t.has(i18nDescription) && {t(i18nDescription)}, [i18nDescription]); const callout = useMemo(() => alert && {t(alert)}, [alert]); - const hasResetButton = !disableReset && !readonly && type !== 'asset' && JSON.stringify(value) !== JSON.stringify(packageValue) && !disabled; + const hasResetButton = !disableReset && !readonly && type !== 'asset' && (JSON.stringify(packageEditor) !== JSON.stringify(editor) || JSON.stringify(value) !== JSON.stringify(packageValue)) && !disabled; return { const persistedSettings = filterSettings(state.persistedSettings); const changes = settings.map((setting) => { - const { _id, value, packageValue, editor } = persistedSettings.find(({ _id }) => _id === setting._id); + const { _id, value, packageValue, packageEditor } = persistedSettings.find(({ _id }) => _id === setting._id); return { _id, value: packageValue, - editor, - changed: packageValue !== value, + editor: packageEditor, + changed: JSON.stringify(packageValue) !== JSON.stringify(value), }; }); @@ -348,29 +348,29 @@ export const useSection = (groupId, sectionName) => { export const useSettingActions = (persistedSetting) => { const { hydrate } = useContext(SettingsContext); - const update = useDebouncedCallback(({ value = persistedSetting.value, editor = persistedSetting.editor }) => { + const update = useDebouncedCallback(({ value, editor }) => { const changes = [{ _id: persistedSetting._id, - value, - editor, - changed: (value !== persistedSetting.value) || (editor !== persistedSetting.editor), + ...value !== undefined && { value }, + ...editor !== undefined && { editor }, + changed: JSON.stringify(persistedSetting.value) !== JSON.stringify(value) || JSON.stringify(editor) !== JSON.stringify(persistedSetting.editor), }]; hydrate(changes); - }, 70, [hydrate, persistedSetting]); + }, 100, [hydrate, persistedSetting]); const reset = useDebouncedCallback(() => { - const { _id, value, packageValue, editor } = persistedSetting; + const { _id, value, packageValue, packageEditor, editor } = persistedSetting; const changes = [{ _id, value: packageValue, - editor, - changed: JSON.stringify(packageValue) !== JSON.stringify(value), + editor: packageEditor, + changed: JSON.stringify(packageValue) !== JSON.stringify(value) || JSON.stringify(packageEditor) !== JSON.stringify(editor), }]; hydrate(changes); - }, 70, [hydrate, persistedSetting]); + }, 100, [hydrate, persistedSetting]); return { update, reset }; }; diff --git a/client/components/admin/settings/inputs/ColorSettingInput.js b/client/components/admin/settings/inputs/ColorSettingInput.js index cb8fe5f7043..410d20ada91 100644 --- a/client/components/admin/settings/inputs/ColorSettingInput.js +++ b/client/components/admin/settings/inputs/ColorSettingInput.js @@ -4,10 +4,10 @@ import { Flex, InputBox, Margins, - SelectInput, TextInput, + Select, } from '@rocket.chat/fuselage'; -import React from 'react'; +import React, { useCallback } from 'react'; import { useTranslation } from '../../../../contexts/TranslationContext'; import { ResetSettingButton } from '../ResetSettingButton'; @@ -17,7 +17,7 @@ export function ColorSettingInput({ label, value, editor, - allowedTypes, + allowedTypes = [], placeholder, readonly, autocomplete, @@ -29,14 +29,13 @@ export function ColorSettingInput({ }) { const t = useTranslation(); - const handleChange = (event) => { + const handleChange = useCallback((event) => { onChangeValue && onChangeValue(event.currentTarget.value); - }; + }, []); - const handleEditorTypeChange = (event) => { - const editor = event.currentTarget.value.trim(); - onChangeEditor && onChangeEditor(editor); - }; + const handleEditorTypeChange = useCallback((value) => { + onChangeEditor && onChangeEditor(value); + }, []); return <> @@ -71,7 +70,7 @@ export function ColorSettingInput({ onChange={handleChange} />} - - {allowedTypes && allowedTypes.map((allowedType) => - {t(allowedType)}, - )} - + options={allowedTypes.map((type) => [ + type, + t(type), + ])} + /> diff --git a/private/server/dynamic-css.js b/private/server/dynamic-css.js index ff871155d63..2a17c4c073a 100644 --- a/private/server/dynamic-css.js +++ b/private/server/dynamic-css.js @@ -138,6 +138,8 @@ var DynamicCss = {}; + window.DynamicCss = DynamicCss; + DynamicCss.test = function () { return window.CSS && window.CSS.supports && window.CSS.supports('(--foo: red)'); }; diff --git a/server/startup/migrations/index.js b/server/startup/migrations/index.js index 6c9b0f4d36d..a16c0c71d5b 100644 --- a/server/startup/migrations/index.js +++ b/server/startup/migrations/index.js @@ -172,4 +172,5 @@ import './v171'; import './v172'; import './v173'; import './v174'; +import './v175'; import './xrun'; diff --git a/server/startup/migrations/v175.js b/server/startup/migrations/v175.js new file mode 100644 index 00000000000..ff10fc83003 --- /dev/null +++ b/server/startup/migrations/v175.js @@ -0,0 +1,18 @@ +import { Migrations } from '../../../app/migrations/server'; +import { theme } from '../../../app/theme/server/server'; +import { Settings } from '../../../app/models'; + +Migrations.add({ + version: 175, + up() { + Object.entries(theme.variables) + .filter(([, value]) => value.type === 'color') + .forEach(([key, { editor }]) => { + Settings.update({ _id: `theme-color-${ key }` }, { + $set: { + packageEditor: editor, + }, + }); + }); + }, +});