@admin-layout/tailwind-design-pro 12.0.16-alpha.7 → 12.0.16-alpha.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/lib/cdm-locales/en/menu.json +2 -1
- package/lib/cdm-locales/es/menu.json +2 -1
- package/lib/cdm-locales/index.d.ts +2 -0
- package/lib/cdm-locales/index.d.ts.map +1 -0
- package/lib/cdm-locales/index.ts +1 -0
- package/lib/components/LanguageMenu/LanguageMenu.js.map +1 -1
- package/lib/components/Layout/BasicLayout/index.d.ts +2 -1
- package/lib/components/Layout/BasicLayout/index.d.ts.map +1 -1
- package/lib/components/Layout/BasicLayout/index.js +134 -44
- package/lib/components/Layout/BasicLayout/index.js.map +1 -1
- package/lib/components/Layout/BasicLayout/utils.d.ts +2 -0
- package/lib/components/Layout/BasicLayout/utils.d.ts.map +1 -1
- package/lib/components/Layout/BasicLayout/utils.js +16 -13
- package/lib/components/Layout/BasicLayout/utils.js.map +1 -1
- package/lib/components/Layout/GlobalFooter/Account.d.ts +4 -0
- package/lib/components/Layout/GlobalFooter/Account.d.ts.map +1 -0
- package/lib/components/Layout/GlobalFooter/BottomMenuDropdown.d.ts.map +1 -1
- package/lib/components/Layout/GlobalFooter/BottomMenuDropdown.js +7 -12
- package/lib/components/Layout/GlobalFooter/BottomMenuDropdown.js.map +1 -1
- package/lib/components/Layout/GlobalHeader/Header.d.ts.map +1 -1
- package/lib/components/Layout/GlobalHeader/Header.js +31 -8
- package/lib/components/Layout/GlobalHeader/Header.js.map +1 -1
- package/lib/components/Layout/GlobalHeader/MainHeader.d.ts +0 -2
- package/lib/components/Layout/GlobalHeader/MainHeader.d.ts.map +1 -1
- package/lib/components/Layout/GlobalHeader/MainHeader.js +54 -85
- package/lib/components/Layout/GlobalHeader/MainHeader.js.map +1 -1
- package/lib/components/Layout/GlobalHeader/OrganizationDropdown.js +1 -1
- package/lib/components/Layout/GlobalHeader/OrganizationDropdown.js.map +1 -1
- package/lib/components/Layout/GlobalHeader/RightContent.d.ts +1 -0
- package/lib/components/Layout/GlobalHeader/RightContent.d.ts.map +1 -1
- package/lib/components/Layout/GlobalHeader/RightContent.js +73 -6
- package/lib/components/Layout/GlobalHeader/RightContent.js.map +1 -1
- package/lib/components/Layout/GlobalHeader/RightMenu.d.ts.map +1 -1
- package/lib/components/Layout/GlobalHeader/RightMenu.js +2 -4
- package/lib/components/Layout/GlobalHeader/RightMenu.js.map +1 -1
- package/lib/components/Layout/GlobalHeader/SearchBar.js.map +1 -1
- package/lib/components/Layout/GlobalHeader/index.d.ts +0 -1
- package/lib/components/Layout/GlobalHeader/index.d.ts.map +1 -1
- package/lib/components/Layout/ProTailwindLayout.d.ts +2 -2
- package/lib/components/Layout/ProTailwindLayout.d.ts.map +1 -1
- package/lib/components/Layout/ProTailwindLayout.js +69 -7
- package/lib/components/Layout/ProTailwindLayout.js.map +1 -1
- package/lib/components/Layout/Sidebar/BottomMenu.d.ts +4 -0
- package/lib/components/Layout/Sidebar/BottomMenu.d.ts.map +1 -0
- package/lib/components/Layout/Sidebar/BottomMenu.js +330 -0
- package/lib/components/Layout/Sidebar/BottomMenu.js.map +1 -0
- package/lib/components/Layout/Sidebar/Divider.js.map +1 -1
- package/lib/components/Layout/Sidebar/DynamicIcon.js.map +1 -1
- package/lib/components/Layout/Sidebar/MainSidebar.d.ts +5 -0
- package/lib/components/Layout/Sidebar/MainSidebar.d.ts.map +1 -0
- package/lib/components/Layout/Sidebar/{Sidebar.js → MainSidebar.js} +94 -34
- package/lib/components/Layout/Sidebar/MainSidebar.js.map +1 -0
- package/lib/components/Layout/Sidebar/MainSidebarMenu.d.ts +4 -0
- package/lib/components/Layout/Sidebar/MainSidebarMenu.d.ts.map +1 -0
- package/lib/components/Layout/Sidebar/MainSidebarMenu.js +291 -0
- package/lib/components/Layout/Sidebar/MainSidebarMenu.js.map +1 -0
- package/lib/components/Layout/Sidebar/PerplexSidebar.d.ts +5 -0
- package/lib/components/Layout/Sidebar/PerplexSidebar.d.ts.map +1 -0
- package/lib/components/Layout/Sidebar/PerplexSidebar.js +277 -0
- package/lib/components/Layout/Sidebar/PerplexSidebar.js.map +1 -0
- package/lib/components/Layout/Sidebar/PerplexSidebarMenu.d.ts +4 -0
- package/lib/components/Layout/Sidebar/PerplexSidebarMenu.d.ts.map +1 -0
- package/lib/components/Layout/Sidebar/PerplexSidebarMenu.js +330 -0
- package/lib/components/Layout/Sidebar/PerplexSidebarMenu.js.map +1 -0
- package/lib/components/Layout/TailwindLayout.d.ts.map +1 -1
- package/lib/components/Layout/TailwindLayout.js +37 -10
- package/lib/components/Layout/TailwindLayout.js.map +1 -1
- package/lib/components/Layout/getPageTitle.js.map +1 -1
- package/lib/components/Layout/slot-fill/AdditionalSettings.js.map +1 -1
- package/lib/components/Layout/slot-fill/Footer.js.map +1 -1
- package/lib/components/Layout/slot-fill/HeaderSearchBar.js.map +1 -1
- package/lib/components/Layout/slot-fill/HeaderSearchButton.js.map +1 -1
- package/lib/components/Layout/slot-fill/Logo.d.ts +4 -0
- package/lib/components/Layout/slot-fill/Logo.d.ts.map +1 -0
- package/lib/components/Layout/slot-fill/Logo.js +7 -0
- package/lib/components/Layout/slot-fill/Logo.js.map +1 -0
- package/lib/components/Layout/slot-fill/RightContent.js.map +1 -1
- package/lib/components/Layout/slot-fill/SideMenuLogo.d.ts +4 -0
- package/lib/components/Layout/slot-fill/SideMenuLogo.d.ts.map +1 -0
- package/lib/components/Layout/slot-fill/SideMenuLogo.js +7 -0
- package/lib/components/Layout/slot-fill/SideMenuLogo.js.map +1 -0
- package/lib/components/Layout/slot-fill/index.d.ts +2 -0
- package/lib/components/Layout/slot-fill/index.d.ts.map +1 -1
- package/lib/components/Layout/util.js +1 -1
- package/lib/components/Layout/util.js.map +1 -1
- package/lib/components/SettingDrawer/CheckBoxTheme.d.ts.map +1 -1
- package/lib/components/SettingDrawer/CheckBoxTheme.js +13 -3
- package/lib/components/SettingDrawer/CheckBoxTheme.js.map +1 -1
- package/lib/components/SettingDrawer/InvitationSettings.d.ts.map +1 -1
- package/lib/components/SettingDrawer/InvitationSettings.js +10 -6
- package/lib/components/SettingDrawer/InvitationSettings.js.map +1 -1
- package/lib/components/SettingDrawer/LayoutChange.d.ts.map +1 -1
- package/lib/components/SettingDrawer/LayoutChange.js +23 -16
- package/lib/components/SettingDrawer/LayoutChange.js.map +1 -1
- package/lib/components/SettingDrawer/MenuVisibilitySettings.d.ts +20 -0
- package/lib/components/SettingDrawer/MenuVisibilitySettings.d.ts.map +1 -0
- package/lib/components/SettingDrawer/MenuVisibilitySettings.js +120 -0
- package/lib/components/SettingDrawer/MenuVisibilitySettings.js.map +1 -0
- package/lib/components/SettingDrawer/NavigationsModes.d.ts +1 -1
- package/lib/components/SettingDrawer/NavigationsModes.d.ts.map +1 -1
- package/lib/components/SettingDrawer/NavigationsModes.js +90 -39
- package/lib/components/SettingDrawer/NavigationsModes.js.map +1 -1
- package/lib/components/SettingDrawer/RegionalSettings.d.ts.map +1 -1
- package/lib/components/SettingDrawer/RegionalSettings.js +54 -177
- package/lib/components/SettingDrawer/RegionalSettings.js.map +1 -1
- package/lib/components/SettingDrawer/SettingDrawer.d.ts.map +1 -1
- package/lib/components/SettingDrawer/SettingDrawer.js +404 -66
- package/lib/components/SettingDrawer/SettingDrawer.js.map +1 -1
- package/lib/components/SettingDrawer/Switch/index.js.map +1 -1
- package/lib/components/SettingDrawer/ThemeColor.d.ts.map +1 -1
- package/lib/components/SettingDrawer/ThemeColor.js +15 -3
- package/lib/components/SettingDrawer/ThemeColor.js.map +1 -1
- package/lib/components/SettingDrawer/types.d.ts +12 -0
- package/lib/components/SettingDrawer/types.d.ts.map +1 -1
- package/lib/components/UpdateSettingsResource/UpdateSettingsResource.server.d.ts +10 -5
- package/lib/components/UpdateSettingsResource/UpdateSettingsResource.server.d.ts.map +1 -1
- package/lib/components/UpdateSettingsResource/UpdateSettingsResource.server.js +97 -4
- package/lib/components/UpdateSettingsResource/UpdateSettingsResource.server.js.map +1 -1
- package/lib/components/index.js +1 -1
- package/lib/components/typings.d.ts +20 -1
- package/lib/components/typings.d.ts.map +1 -1
- package/lib/compute.d.ts.map +1 -1
- package/lib/compute.js +10 -2
- package/lib/compute.js.map +1 -1
- package/lib/config/constants.js.map +1 -1
- package/lib/config/env-config.d.ts +3 -0
- package/lib/config/env-config.d.ts.map +1 -1
- package/lib/config/env-config.js +10 -0
- package/lib/config/env-config.js.map +1 -1
- package/lib/helpers/DynamicIcon.js.map +1 -1
- package/lib/hooks/useMediaQuery.js.map +1 -1
- package/lib/hooks/useScrollThreshold.js.map +1 -1
- package/lib/hooks/useTailwindTheme.js +82 -0
- package/lib/hooks/useTailwindTheme.js.map +1 -0
- package/lib/icons.d.ts +2 -0
- package/lib/icons.d.ts.map +1 -1
- package/lib/icons.js +4 -2
- package/lib/icons.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/machines/selectors.d.ts +118 -0
- package/lib/machines/selectors.d.ts.map +1 -0
- package/lib/machines/settingsMachine.d.ts +25 -2
- package/lib/machines/settingsMachine.d.ts.map +1 -1
- package/lib/machines/settingsMachine.js +174 -163
- package/lib/machines/settingsMachine.js.map +1 -1
- package/lib/machines/settingsMachine.test.d.ts +2 -0
- package/lib/machines/settingsMachine.test.d.ts.map +1 -0
- package/lib/machines/types.d.ts +106 -9
- package/lib/machines/types.d.ts.map +1 -1
- package/lib/machines/types.js.map +1 -1
- package/lib/module.js.map +1 -1
- package/lib/redux/searchReducer.js.map +1 -1
- package/lib/routes.json +9 -1
- package/lib/tailwindConfig.js.map +1 -1
- package/lib/utils/__tests__/configOverrides.test.d.ts +2 -0
- package/lib/utils/__tests__/configOverrides.test.d.ts.map +1 -0
- package/lib/utils/configOverrides.d.ts +213 -0
- package/lib/utils/configOverrides.d.ts.map +1 -0
- package/lib/utils/configOverrides.js +91 -0
- package/lib/utils/configOverrides.js.map +1 -0
- package/lib/utils/isBrowser/index.js.map +1 -1
- package/lib/utils/settingsUtils.d.ts +20 -0
- package/lib/utils/settingsUtils.d.ts.map +1 -0
- package/lib/utils/settingsUtils.js +74 -0
- package/lib/utils/settingsUtils.js.map +1 -0
- package/lib/utils/utils/index.js.map +1 -1
- package/package.json +6 -6
- package/lib/components/Layout/GlobalHeader/Logo.d.ts +0 -4
- package/lib/components/Layout/GlobalHeader/Logo.d.ts.map +0 -1
- package/lib/components/Layout/GlobalHeader/Logo.js +0 -141
- package/lib/components/Layout/GlobalHeader/Logo.js.map +0 -1
- package/lib/components/Layout/Sidebar/Sidebar.d.ts +0 -5
- package/lib/components/Layout/Sidebar/Sidebar.d.ts.map +0 -1
- package/lib/components/Layout/Sidebar/Sidebar.js.map +0 -1
- package/lib/components/Layout/Sidebar/SidebarMenu.d.ts +0 -4
- package/lib/components/Layout/Sidebar/SidebarMenu.d.ts.map +0 -1
- package/lib/components/Layout/Sidebar/SidebarMenu.js +0 -176
- package/lib/components/Layout/Sidebar/SidebarMenu.js.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {jsx,Fragment,jsxs}from'react/jsx-runtime';import {useState,useRef,useEffect}from'react';import {
|
|
2
|
-
const updateTheme = (dark, color, publicPath = '/theme') => {
|
|
1
|
+
import {jsx,Fragment,jsxs}from'react/jsx-runtime';import {useSelector}from'@xstate/react';import clsx from'clsx';import {parse}from'qs';import*as React from'react';import {useState,useRef,useEffect}from'react';import {useTranslation}from'react-i18next';import'@react-icons/all-files/fa/FaMoon.js';import'@react-icons/all-files/fa/FaSun.js';import {useMediaQuery}from'../../hooks/useMediaQuery.js';import {icons}from'../../icons.js';import isBrowser from'../../utils/isBrowser/index.js';import {getDefaultApplyToAllRoutes,getSettingValue}from'../../utils/settingsUtils.js';import'@common-stack/components-pro';import {AdditionalSettingsSlot}from'../Layout/slot-fill/AdditionalSettings.js';import'reflect-metadata';import'@admin-layout/client/lib/constants/layout.js';import CheckBoxTheme from'./CheckBoxTheme.js';import InvitationSettings from'./InvitationSettings.js';import LayoutChange from'./LayoutChange.js';import MenuVisibilitySettings from'./MenuVisibilitySettings.js';import NavigationModes from'./NavigationsModes.js';import RegionalSettings from'./RegionalSettings.js';import ThemeColor from'./ThemeColor.js';import {ThemeSelector}from'./ThemeSelector.js';import {WebFontsSelector}from'./WebFontsSelector.js';import {useWriteSettingsMutation,useResetApplicationUiSettingsMutation}from'common/lib/generated/generated.js';import {ConfigCollectionName,ConfigFragmentName}from'common/lib/generated/generated-models.js';import {generateCdecodeUri,DEFAULT_CONTRIBUTION_TENANT_ID}from'@adminide-stack/core';import {config}from'../../config/env-config.js';const updateTheme = (dark, color, publicPath = '/theme') => {
|
|
3
2
|
// ssr
|
|
4
3
|
if (typeof window === 'undefined' || !window.umi_plugin_ant_themeVar) {
|
|
5
4
|
return;
|
|
@@ -42,7 +41,7 @@ const updateTheme = (dark, color, publicPath = '/theme') => {
|
|
|
42
41
|
}
|
|
43
42
|
// localStorage.setItem('site-theme', dark ? 'dark' : 'light');
|
|
44
43
|
};
|
|
45
|
-
const initState = (settings, onSettingChange, publicPath) => {
|
|
44
|
+
const initState = (settings, onSettingChange, publicPath, oldSetting) => {
|
|
46
45
|
if (!isBrowser()) {
|
|
47
46
|
return;
|
|
48
47
|
}
|
|
@@ -51,21 +50,25 @@ const initState = (settings, onSettingChange, publicPath) => {
|
|
|
51
50
|
const params = parse(window.location.search.replace('?', ''));
|
|
52
51
|
const replaceSetting = {};
|
|
53
52
|
Object.keys(params).forEach(key => {
|
|
54
|
-
if (
|
|
53
|
+
if (settings[key] !== undefined || settings[key] === undefined) {
|
|
55
54
|
replaceSetting[key] = params[key];
|
|
56
55
|
if (key.includes('Render')) {
|
|
57
56
|
replaceSetting[key] = params[key] === 'false' ? false : undefined;
|
|
58
57
|
}
|
|
59
58
|
}
|
|
60
59
|
});
|
|
61
|
-
|
|
60
|
+
// Only call onSettingChange if we have actual URL parameters to apply
|
|
61
|
+
if (onSettingChange && Object.keys(replaceSetting).length > 0) {
|
|
62
|
+
console.log('✅ initState: Calling onSettingChange with URL params:', replaceSetting);
|
|
62
63
|
onSettingChange({
|
|
63
64
|
...settings,
|
|
64
65
|
...replaceSetting
|
|
65
66
|
});
|
|
67
|
+
} else {
|
|
68
|
+
console.log('⏭️ initState: Skipping onSettingChange - no valid URL params to apply');
|
|
66
69
|
}
|
|
67
70
|
// Set the topic in the URL and load it once.
|
|
68
|
-
if (oldSetting
|
|
71
|
+
if (oldSetting?.navTheme !== params.navTheme && params.navTheme) {
|
|
69
72
|
updateTheme(settings.navTheme === 'realDark', params.primaryColor, publicPath);
|
|
70
73
|
loadedStyle = true;
|
|
71
74
|
}
|
|
@@ -74,21 +77,37 @@ const initState = (settings, onSettingChange, publicPath) => {
|
|
|
74
77
|
return;
|
|
75
78
|
}
|
|
76
79
|
// If there is no topic in the URL, and no load in the URL is loaded.
|
|
77
|
-
if (
|
|
80
|
+
if (oldSetting?.navTheme !== settings.navTheme && settings.navTheme) {
|
|
78
81
|
updateTheme(settings.navTheme === 'realDark', settings.primaryColor, publicPath);
|
|
79
82
|
}
|
|
80
83
|
};
|
|
81
|
-
const getThemeList = (settings, location) => {
|
|
84
|
+
const getThemeList = (settings, location, routePattern) => {
|
|
82
85
|
const {
|
|
83
86
|
t
|
|
84
87
|
} = useTranslation('settings');
|
|
85
88
|
const {
|
|
86
89
|
isMobile
|
|
87
90
|
} = useMediaQuery();
|
|
88
|
-
const currentRoute = location?.pathname || '/';
|
|
89
|
-
const routeSettings = settings?.routeSettings?.[currentRoute] || settings?.routeSettings?.['/'] || settings;
|
|
91
|
+
const currentRoute = routePattern || location?.pathname || '/';
|
|
90
92
|
const deviceType = isMobile ? 'mobile' : 'desktop';
|
|
91
|
-
|
|
93
|
+
// Helper function to get value from settings with route/device override support
|
|
94
|
+
const getUILayoutValue = path => {
|
|
95
|
+
const routeDeviceKey = `[${currentRoute}][${deviceType}]`;
|
|
96
|
+
const uiOverride = settings?.uiSettings?.[routeDeviceKey];
|
|
97
|
+
if (uiOverride) {
|
|
98
|
+
const value = path.split('.').reduce((obj, key) => obj?.[key], uiOverride);
|
|
99
|
+
if (value !== undefined) return value;
|
|
100
|
+
}
|
|
101
|
+
return path.split('.').reduce((obj, key) => obj?.[key], settings);
|
|
102
|
+
};
|
|
103
|
+
const deviceLayout = {
|
|
104
|
+
navigationMode: getUILayoutValue('navigationMode'),
|
|
105
|
+
sideMenuType: getUILayoutValue('sideMenuType'),
|
|
106
|
+
contentWidth: getUILayoutValue('contentWidth'),
|
|
107
|
+
fixedHeader: getUILayoutValue('fixedHeader'),
|
|
108
|
+
fixedSidebar: getUILayoutValue('fixedSidebar'),
|
|
109
|
+
splitMenus: getUILayoutValue('splitMenus')
|
|
110
|
+
};
|
|
92
111
|
let list = [];
|
|
93
112
|
const defaultList = [
|
|
94
113
|
//@sri following are needed otherwise we need make above plugin to work
|
|
@@ -264,7 +283,6 @@ const fontOptions = [{
|
|
|
264
283
|
}];
|
|
265
284
|
const SettingDrawer = props => {
|
|
266
285
|
const {
|
|
267
|
-
settings,
|
|
268
286
|
onSettingChange,
|
|
269
287
|
hideLoading,
|
|
270
288
|
hideColors,
|
|
@@ -275,8 +293,12 @@ const SettingDrawer = props => {
|
|
|
275
293
|
colorList,
|
|
276
294
|
navTheme,
|
|
277
295
|
pathname,
|
|
278
|
-
location
|
|
296
|
+
location,
|
|
297
|
+
fullMenuData,
|
|
298
|
+
routePattern
|
|
279
299
|
} = props;
|
|
300
|
+
// Don't use useLayoutSettings() - it pulls from Redux which may be stale
|
|
301
|
+
// Use settingState from XState actor instead (line 393)
|
|
280
302
|
const {
|
|
281
303
|
CloseIcon,
|
|
282
304
|
Settings5FillIcon,
|
|
@@ -289,41 +311,122 @@ const SettingDrawer = props => {
|
|
|
289
311
|
} = useMediaQuery();
|
|
290
312
|
const [copied, setCopied] = useState(false);
|
|
291
313
|
const [copiedModified, setCopiedModified] = useState(false);
|
|
314
|
+
const [activeDeviceTab, setActiveDeviceTab] = useState(isMobile ? 'mobile' : 'desktop');
|
|
315
|
+
const [applyToAllRoutes, setApplyToAllRoutes] = useState(false);
|
|
292
316
|
const {
|
|
293
317
|
t
|
|
294
318
|
} = useTranslation('settings');
|
|
295
|
-
|
|
319
|
+
// Track if we've already initialized to prevent loops
|
|
320
|
+
const hasInitializedRef = useRef(false);
|
|
321
|
+
const resource = generateCdecodeUri(DEFAULT_CONTRIBUTION_TENANT_ID, {
|
|
322
|
+
resourceType: ConfigCollectionName.Applications,
|
|
323
|
+
resourceId: config.APPLICATION_ID,
|
|
324
|
+
idField: 'appId'
|
|
325
|
+
}, {}, ConfigFragmentName.UiSettings);
|
|
326
|
+
const [writeSettingsMutation, {
|
|
327
|
+
client
|
|
328
|
+
}] = useWriteSettingsMutation();
|
|
329
|
+
const [resetApplicationSettings] = useResetApplicationUiSettingsMutation();
|
|
296
330
|
const btnRef = useRef();
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
|
|
302
|
-
//
|
|
303
|
-
const
|
|
331
|
+
// REVOLUTIONARY APPROACH: Use stable selectors instead of raw context access
|
|
332
|
+
// This completely eliminates the infinite loop problem because:
|
|
333
|
+
// 1. selectPublicSettings only returns context.public (no internal state)
|
|
334
|
+
// 2. useSelector memoizes the result - only re-renders if PUBLIC settings actually change
|
|
335
|
+
// 3. configModel reference changes are isolated in context.internal, never seen here
|
|
336
|
+
// 4. No filtering logic needed - separation is built into the machine
|
|
337
|
+
const settingState = useSelector(actor, state => state.context.public);
|
|
338
|
+
const changedSettings = useSelector(actor, state => state.context.internal.changedSettings);
|
|
339
|
+
useSelector(actor, state => state.context.internal.deviceType);
|
|
340
|
+
// Track previous settings to detect meaningful changes
|
|
341
|
+
const prevSettingsRef = useRef();
|
|
342
|
+
useEffect(() => {
|
|
343
|
+
const prevSettings = prevSettingsRef.current;
|
|
344
|
+
const currentSettings = settingState;
|
|
345
|
+
if (prevSettings) {
|
|
346
|
+
const prevString = JSON.stringify(prevSettings);
|
|
347
|
+
const currentString = JSON.stringify(currentSettings);
|
|
348
|
+
const hasChanged = prevString !== currentString;
|
|
349
|
+
console.log('⚡ SettingDrawer - PUBLIC settings update:', {
|
|
350
|
+
hasChanged,
|
|
351
|
+
prevKeys: prevSettings ? Object.keys(prevSettings).length : 0,
|
|
352
|
+
currentKeys: currentSettings ? Object.keys(currentSettings).length : 0
|
|
353
|
+
});
|
|
354
|
+
if (hasChanged) {
|
|
355
|
+
console.log('🔍 What changed in PUBLIC settings:', {
|
|
356
|
+
changedKeys: Object.keys(currentSettings).filter(key => {
|
|
357
|
+
const prevValue = JSON.stringify(prevSettings[key]);
|
|
358
|
+
const currentValue = JSON.stringify(currentSettings[key]);
|
|
359
|
+
return prevValue !== currentValue;
|
|
360
|
+
})
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
prevSettingsRef.current = JSON.parse(JSON.stringify(currentSettings));
|
|
365
|
+
}, [settingState]);
|
|
366
|
+
const currentRoute = routePattern || location?.pathname || '/';
|
|
367
|
+
// Use activeDeviceTab instead of isMobile for device type
|
|
368
|
+
const deviceType = activeDeviceTab;
|
|
369
|
+
// Calculate the default value for applyToAllRoutes based on what overrides exist
|
|
370
|
+
const defaultApplyToAllRoutes = React.useMemo(() => {
|
|
371
|
+
return getDefaultApplyToAllRoutes(settingState, currentRoute, deviceType);
|
|
372
|
+
}, [settingState, currentRoute, deviceType]);
|
|
373
|
+
// Update applyToAllRoutes when route or device changes
|
|
374
|
+
useEffect(() => {
|
|
375
|
+
setApplyToAllRoutes(defaultApplyToAllRoutes);
|
|
376
|
+
}, [defaultApplyToAllRoutes]);
|
|
377
|
+
// Pass settingState directly - child components will use getSettingValue internally
|
|
378
|
+
// with the applyToAllRoutes prop to get the correct scoped values
|
|
379
|
+
const settingsForComponents = settingState;
|
|
380
|
+
// Helper to get theme value with overrides applied
|
|
381
|
+
const getThemeValue = () => getSettingValue(settingState, 'theme', applyToAllRoutes, currentRoute, deviceType, 'default');
|
|
382
|
+
// Helper to get font family value with overrides applied
|
|
383
|
+
const getFontFamilyValue = () => getSettingValue(settingState, 'fontFamily', applyToAllRoutes, currentRoute, deviceType, 'Poppins, sans-serif');
|
|
384
|
+
const themeList = getThemeList(settingState, location, routePattern);
|
|
304
385
|
/**
|
|
305
386
|
* Modify settings
|
|
306
387
|
* @param key
|
|
307
388
|
* @param value
|
|
308
389
|
*/
|
|
309
390
|
const handleSettingChange = (key, value) => {
|
|
310
|
-
//
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}
|
|
391
|
+
// Menu visibility and applyToAllRoutes are always global
|
|
392
|
+
const isGlobalSetting = key === 'hiddenMenuKeys' || key === 'hiddenMenuCategories' || key === 'applyToAllRoutes';
|
|
393
|
+
// If this is a global setting, save as global
|
|
394
|
+
if (isGlobalSetting) {
|
|
395
|
+
console.log('🌐 Sending GLOBAL setting to actor:', {
|
|
396
|
+
key,
|
|
397
|
+
value
|
|
318
398
|
});
|
|
319
|
-
} else {
|
|
320
399
|
actor.send({
|
|
321
|
-
type: '
|
|
400
|
+
type: 'UISETTING_UPDATE',
|
|
322
401
|
value: {
|
|
323
402
|
[key]: value
|
|
324
403
|
}
|
|
325
404
|
});
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
// Extract the setting name from the key
|
|
408
|
+
// Key is just "settingName" (no uilayout wrapper)
|
|
409
|
+
const settingName = key;
|
|
410
|
+
// Build the correct bracket pattern based on applyToAllRoutes
|
|
411
|
+
let fullKey;
|
|
412
|
+
if (applyToAllRoutes) {
|
|
413
|
+
// Apply to all routes: [device].settingName
|
|
414
|
+
fullKey = `[${deviceType}].${settingName}`;
|
|
415
|
+
} else {
|
|
416
|
+
// Route-specific: [route][device].settingName
|
|
417
|
+
fullKey = `[${currentRoute}][${deviceType}].${settingName}`;
|
|
326
418
|
}
|
|
419
|
+
console.log('📤 Sending SCOPED setting to actor:', {
|
|
420
|
+
fullKey,
|
|
421
|
+
value,
|
|
422
|
+
eventType: 'UISETTING_UPDATE'
|
|
423
|
+
});
|
|
424
|
+
actor.send({
|
|
425
|
+
type: 'UISETTING_UPDATE',
|
|
426
|
+
value: {
|
|
427
|
+
[fullKey]: value
|
|
428
|
+
}
|
|
429
|
+
});
|
|
327
430
|
};
|
|
328
431
|
const handleCopySettings = async () => {
|
|
329
432
|
if (!isBrowser()) return;
|
|
@@ -339,38 +442,152 @@ const SettingDrawer = props => {
|
|
|
339
442
|
const handleCopyModifiedSettings = async () => {
|
|
340
443
|
if (!isBrowser()) return;
|
|
341
444
|
try {
|
|
342
|
-
const
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
445
|
+
const settingsCookie = document.cookie.split(';').find(cookie => cookie.startsWith(' settings='));
|
|
446
|
+
const settingsValue = settingsCookie.split('=')[1];
|
|
447
|
+
const decodedComponent = decodeURIComponent(settingsValue);
|
|
448
|
+
const parsedSettings = JSON.parse(atob(decodedComponent));
|
|
449
|
+
console.log('Settings in cookies : ', parsedSettings);
|
|
450
|
+
navigator.clipboard.writeText(JSON.stringify(parsedSettings, null, 2));
|
|
347
451
|
} catch (err) {
|
|
348
452
|
console.error('Failed to copy modified settings:', err);
|
|
349
453
|
}
|
|
350
454
|
};
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if
|
|
361
|
-
|
|
455
|
+
const handleSaveSettings = async () => {
|
|
456
|
+
if (!isBrowser()) return;
|
|
457
|
+
try {
|
|
458
|
+
// Transform changedSettings to wrap in uilayout structure for backend
|
|
459
|
+
const wrappedSettings = {};
|
|
460
|
+
Object.keys(changedSettings || {}).forEach(key => {
|
|
461
|
+
const value = changedSettings[key];
|
|
462
|
+
// Skip route paths
|
|
463
|
+
if (key.startsWith('/')) return;
|
|
464
|
+
// Check if it's a bracket key like [device].settingName or [route][device].settingName
|
|
465
|
+
if (key.startsWith('[')) {
|
|
466
|
+
// Extract bracket pattern and setting name
|
|
467
|
+
// e.g., "[desktop].theme" or "[/route][desktop].navTheme"
|
|
468
|
+
const match = key.match(/^(\[.+?\](?:\[.+?\])?)\.(.+)$/);
|
|
469
|
+
if (match) {
|
|
470
|
+
const bracketKey = match[1]; // e.g., "[desktop]" or "[/route][desktop]"
|
|
471
|
+
const settingName = match[2]; // e.g., "theme"
|
|
472
|
+
// Wrap in uilayout structure: [desktop].uilayout.theme
|
|
473
|
+
const wrappedKey = `${bracketKey}.uilayout.${settingName}`;
|
|
474
|
+
wrappedSettings[wrappedKey] = value;
|
|
475
|
+
} else {
|
|
476
|
+
// If pattern doesn't match, keep as is
|
|
477
|
+
wrappedSettings[key] = value;
|
|
478
|
+
}
|
|
479
|
+
} else {
|
|
480
|
+
// Non-bracket keys (like hiddenMenuKeys) - keep as is
|
|
481
|
+
wrappedSettings[key] = value;
|
|
362
482
|
}
|
|
483
|
+
});
|
|
484
|
+
// Prepare mutation variables
|
|
485
|
+
const variables = {
|
|
486
|
+
editingUri: resource,
|
|
487
|
+
settings: wrappedSettings
|
|
488
|
+
};
|
|
489
|
+
const response = await writeSettingsMutation({
|
|
490
|
+
variables
|
|
491
|
+
});
|
|
492
|
+
if (response.data) {
|
|
493
|
+
console.log('Settings saved successfully');
|
|
494
|
+
// Reset XState changedSettings (this will disable save button)
|
|
495
|
+
actor.send({
|
|
496
|
+
type: 'UISETTING_RESET_CHANGED_SETTINGS'
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
} catch (err) {
|
|
500
|
+
console.error('Failed to save settings:', err);
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
const handleResetSettings = async () => {
|
|
504
|
+
if (!isBrowser()) return;
|
|
505
|
+
const confirmed = window.confirm('Are you sure you want to reset all settings? This will delete all customizations from database and cookies, then reload the page.');
|
|
506
|
+
if (!confirmed) return;
|
|
507
|
+
try {
|
|
508
|
+
console.log('🔥 Resetting all settings...');
|
|
509
|
+
// Step 1: Delete uiSettings from database using the resetApplicationSettings mutation
|
|
510
|
+
try {
|
|
511
|
+
await resetApplicationSettings({
|
|
512
|
+
variables: {
|
|
513
|
+
appId: config.APPLICATION_ID
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
console.log('✅ Database uiSettings deleted');
|
|
517
|
+
} catch (dbErr) {
|
|
518
|
+
console.error('⚠️ Failed to delete database uiSettings:', dbErr);
|
|
519
|
+
// Continue anyway to clear cookies
|
|
520
|
+
}
|
|
521
|
+
// Step 2: Clear cookies by sending DELETE request
|
|
522
|
+
try {
|
|
523
|
+
const response = await fetch('/resources/settings', {
|
|
524
|
+
method: 'DELETE',
|
|
525
|
+
headers: {
|
|
526
|
+
'Content-Type': 'application/json'
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
const result = await response.json();
|
|
530
|
+
console.log('✅ Settings cookies cleared');
|
|
531
|
+
} catch (cookieErr) {
|
|
532
|
+
console.error('⚠️ Failed to clear cookies:', cookieErr);
|
|
533
|
+
}
|
|
534
|
+
// Step 3: Reset XState machine
|
|
535
|
+
actor.send({
|
|
536
|
+
type: 'UISETTING_RESET_CHANGED_SETTINGS'
|
|
537
|
+
});
|
|
538
|
+
} catch (err) {
|
|
539
|
+
console.error('❌ Error resetting settings:', err);
|
|
540
|
+
alert('Failed to reset settings. Please try again.');
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
useEffect(() => {
|
|
544
|
+
// REVOLUTIONARY: No filtering needed! settingState already contains ONLY public settings
|
|
545
|
+
// The XState machine now has a separated structure:
|
|
546
|
+
// - context.public = user-facing settings (what we're using)
|
|
547
|
+
// - context.internal = machine state (never exposed)
|
|
548
|
+
//
|
|
549
|
+
// This completely eliminates the loop problem at the architectural level.
|
|
550
|
+
if (isBrowser()) {
|
|
551
|
+
const hasUrlParams = !!window.location.search;
|
|
552
|
+
console.log('🔄 SettingDrawer useEffect - PUBLIC settings:', {
|
|
553
|
+
hasUrlParams,
|
|
554
|
+
hasInitialized: hasInitializedRef.current,
|
|
555
|
+
settingsKeys: settingState ? Object.keys(settingState).length : 0
|
|
556
|
+
});
|
|
557
|
+
// Only call initState on first mount OR if there are URL params
|
|
558
|
+
const shouldInit = !hasInitializedRef.current || hasUrlParams;
|
|
559
|
+
if (shouldInit) {
|
|
560
|
+
console.log('🔥 Calling initState:', {
|
|
561
|
+
reason: !hasInitializedRef.current ? 'first mount' : 'has URL params'
|
|
562
|
+
});
|
|
563
|
+
initState(settingState, onSettingChange, props.publicPath, undefined);
|
|
564
|
+
hasInitializedRef.current = true;
|
|
565
|
+
} else {
|
|
566
|
+
console.log('⏭️ Skipping initState - already initialized and no URL params');
|
|
363
567
|
}
|
|
364
568
|
}
|
|
365
|
-
}, [
|
|
569
|
+
}, [settingState, props.publicPath]); // settingState only changes when PUBLIC settings change
|
|
570
|
+
// Update activeDeviceTab when isMobile changes
|
|
571
|
+
useEffect(() => {
|
|
572
|
+
setActiveDeviceTab(isMobile ? 'mobile' : 'desktop');
|
|
573
|
+
}, [isMobile]);
|
|
574
|
+
// Update machine when device tab changes
|
|
575
|
+
useEffect(() => {
|
|
576
|
+
if (actor) {
|
|
577
|
+
actor.send({
|
|
578
|
+
type: 'UISETTING_UPDATE_DEVICE_TYPE',
|
|
579
|
+
deviceType: activeDeviceTab
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
}, [activeDeviceTab, actor]);
|
|
366
583
|
const currentPathname = isBrowser() ? window.location.pathname : pathname || '';
|
|
367
584
|
return jsx(Fragment, {
|
|
368
|
-
children:
|
|
585
|
+
children: settingState?.showSettingPanel && jsxs(Fragment, {
|
|
369
586
|
children: [jsx("button", {
|
|
370
587
|
ref: btnRef,
|
|
371
588
|
onClick: () => setShow(!show),
|
|
372
589
|
style: {
|
|
373
|
-
backgroundColor:
|
|
590
|
+
backgroundColor: settingState?.primaryColor,
|
|
374
591
|
display: 'flex',
|
|
375
592
|
alignItems: 'center',
|
|
376
593
|
justifyContent: 'center'
|
|
@@ -399,6 +616,107 @@ const SettingDrawer = props => {
|
|
|
399
616
|
fontSize: '36px'
|
|
400
617
|
})
|
|
401
618
|
})]
|
|
619
|
+
}), jsxs("div", {
|
|
620
|
+
className: "mt-8 pb-8 border-b border-black dark:border-[#2a2b2a]",
|
|
621
|
+
children: [jsx(MenuVisibilitySettings, {
|
|
622
|
+
fullMenuData: fullMenuData,
|
|
623
|
+
settings: settingState,
|
|
624
|
+
changeSetting: handleSettingChange
|
|
625
|
+
}), jsxs("div", {
|
|
626
|
+
className: "flex items-center justify-between",
|
|
627
|
+
children: [jsxs("div", {
|
|
628
|
+
children: [jsx("p", {
|
|
629
|
+
className: "text-sm text-black dark:text-white font-medium",
|
|
630
|
+
children: "Apply to All Routes"
|
|
631
|
+
}), jsx("p", {
|
|
632
|
+
className: "text-xs text-gray-600 dark:text-gray-400",
|
|
633
|
+
children: "When enabled, route-specific settings will apply to all routes instead of just the current route"
|
|
634
|
+
})]
|
|
635
|
+
}), jsxs("label", {
|
|
636
|
+
className: "relative inline-flex items-center cursor-pointer",
|
|
637
|
+
children: [jsx("input", {
|
|
638
|
+
type: "checkbox",
|
|
639
|
+
className: "sr-only peer",
|
|
640
|
+
checked: applyToAllRoutes,
|
|
641
|
+
onChange: e => setApplyToAllRoutes(e.target.checked)
|
|
642
|
+
}), jsx("div", {
|
|
643
|
+
className: "w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"
|
|
644
|
+
})]
|
|
645
|
+
})]
|
|
646
|
+
}), jsx("div", {
|
|
647
|
+
className: "mt-4",
|
|
648
|
+
children: jsxs("div", {
|
|
649
|
+
className: "flex mb-4",
|
|
650
|
+
children: [jsx("button", {
|
|
651
|
+
className: `flex-1 py-2 px-4 text-sm font-medium transition-colors duration-200 rounded-l-lg border border-r-0 border-gray-300 ${activeDeviceTab === 'desktop' ? 'bg-blue-500 text-white border-blue-500' : 'bg-white text-gray-700 hover:bg-gray-50 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700'}`,
|
|
652
|
+
onClick: () => setActiveDeviceTab('desktop'),
|
|
653
|
+
children: jsxs("span", {
|
|
654
|
+
className: "flex items-center justify-center",
|
|
655
|
+
children: [jsxs("svg", {
|
|
656
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
657
|
+
width: "16",
|
|
658
|
+
height: "16",
|
|
659
|
+
viewBox: "0 0 24 24",
|
|
660
|
+
fill: "none",
|
|
661
|
+
stroke: "currentColor",
|
|
662
|
+
strokeWidth: "2",
|
|
663
|
+
strokeLinecap: "round",
|
|
664
|
+
strokeLinejoin: "round",
|
|
665
|
+
className: "mr-1",
|
|
666
|
+
children: [jsx("rect", {
|
|
667
|
+
x: "2",
|
|
668
|
+
y: "3",
|
|
669
|
+
width: "20",
|
|
670
|
+
height: "14",
|
|
671
|
+
rx: "2",
|
|
672
|
+
ry: "2"
|
|
673
|
+
}), jsx("line", {
|
|
674
|
+
x1: "8",
|
|
675
|
+
y1: "21",
|
|
676
|
+
x2: "16",
|
|
677
|
+
y2: "21"
|
|
678
|
+
}), jsx("line", {
|
|
679
|
+
x1: "12",
|
|
680
|
+
y1: "17",
|
|
681
|
+
x2: "12",
|
|
682
|
+
y2: "21"
|
|
683
|
+
})]
|
|
684
|
+
}), t('desktop_tab')]
|
|
685
|
+
})
|
|
686
|
+
}), jsx("button", {
|
|
687
|
+
className: `flex-1 py-2 px-4 text-sm font-medium transition-colors duration-200 rounded-r-lg border border-gray-300 ${activeDeviceTab === 'mobile' ? 'bg-blue-500 text-white border-blue-500' : 'bg-white text-gray-700 hover:bg-gray-50 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700'}`,
|
|
688
|
+
onClick: () => setActiveDeviceTab('mobile'),
|
|
689
|
+
children: jsxs("span", {
|
|
690
|
+
className: "flex items-center justify-center",
|
|
691
|
+
children: [jsxs("svg", {
|
|
692
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
693
|
+
width: "16",
|
|
694
|
+
height: "16",
|
|
695
|
+
viewBox: "0 0 24 24",
|
|
696
|
+
fill: "none",
|
|
697
|
+
stroke: "currentColor",
|
|
698
|
+
strokeWidth: "2",
|
|
699
|
+
strokeLinecap: "round",
|
|
700
|
+
strokeLinejoin: "round",
|
|
701
|
+
className: "mr-1",
|
|
702
|
+
children: [jsx("rect", {
|
|
703
|
+
x: "5",
|
|
704
|
+
y: "2",
|
|
705
|
+
width: "14",
|
|
706
|
+
height: "20",
|
|
707
|
+
rx: "2",
|
|
708
|
+
ry: "2"
|
|
709
|
+
}), jsx("line", {
|
|
710
|
+
x1: "12",
|
|
711
|
+
y1: "18",
|
|
712
|
+
x2: "12",
|
|
713
|
+
y2: "18"
|
|
714
|
+
})]
|
|
715
|
+
}), t('mobile_tab')]
|
|
716
|
+
})
|
|
717
|
+
})]
|
|
718
|
+
})
|
|
719
|
+
})]
|
|
402
720
|
}), jsxs("div", {
|
|
403
721
|
className: "mt-8 pb-8 border-b border-black dark:border-[#2a2b2a]",
|
|
404
722
|
children: [jsx("p", {
|
|
@@ -408,7 +726,9 @@ const SettingDrawer = props => {
|
|
|
408
726
|
children: jsx(CheckBoxTheme, {
|
|
409
727
|
list: themeList.themeList,
|
|
410
728
|
changeSetting: handleSettingChange,
|
|
411
|
-
settings:
|
|
729
|
+
settings: settingsForComponents,
|
|
730
|
+
location: location,
|
|
731
|
+
applyToAllRoutes: applyToAllRoutes,
|
|
412
732
|
...props
|
|
413
733
|
})
|
|
414
734
|
}), jsxs("div", {
|
|
@@ -417,7 +737,7 @@ const SettingDrawer = props => {
|
|
|
417
737
|
className: "text-black dark:text-white",
|
|
418
738
|
children: t('Select Theme')
|
|
419
739
|
}), jsx(ThemeSelector, {
|
|
420
|
-
value:
|
|
740
|
+
value: getThemeValue(),
|
|
421
741
|
onChange: value => handleSettingChange('theme', value),
|
|
422
742
|
options: themeOptions
|
|
423
743
|
})]
|
|
@@ -429,7 +749,10 @@ const SettingDrawer = props => {
|
|
|
429
749
|
}), jsx(ThemeColor, {
|
|
430
750
|
color: colorList || themeList.colorList[navTheme === 'realDark' ? 'dark' : 'light'],
|
|
431
751
|
changeSetting: handleSettingChange,
|
|
432
|
-
settings:
|
|
752
|
+
settings: settingsForComponents,
|
|
753
|
+
location: location,
|
|
754
|
+
routePattern: routePattern,
|
|
755
|
+
applyToAllRoutes: applyToAllRoutes
|
|
433
756
|
})]
|
|
434
757
|
}), jsxs("div", {
|
|
435
758
|
className: "mt-8",
|
|
@@ -437,7 +760,7 @@ const SettingDrawer = props => {
|
|
|
437
760
|
className: "text-black dark:text-white",
|
|
438
761
|
children: t('Font Family')
|
|
439
762
|
}), jsx(WebFontsSelector, {
|
|
440
|
-
value:
|
|
763
|
+
value: getFontFamilyValue(),
|
|
441
764
|
onChange: value => handleSettingChange('fontFamily', value),
|
|
442
765
|
options: fontOptions
|
|
443
766
|
})]
|
|
@@ -445,38 +768,40 @@ const SettingDrawer = props => {
|
|
|
445
768
|
}), jsxs("div", {
|
|
446
769
|
className: "mt-8 pb-8 border-b border-black dark:border-[#2a2b2a]",
|
|
447
770
|
children: [jsx(NavigationModes, {
|
|
448
|
-
settings:
|
|
771
|
+
settings: settingsForComponents,
|
|
449
772
|
changeSetting: handleSettingChange,
|
|
773
|
+
applyToAllRoutes: applyToAllRoutes,
|
|
450
774
|
...props
|
|
451
775
|
}), jsx("div", {
|
|
452
776
|
className: "mt-8",
|
|
453
777
|
children: jsx(LayoutChange, {
|
|
454
|
-
settings:
|
|
778
|
+
settings: settingsForComponents,
|
|
455
779
|
changeSetting: handleSettingChange,
|
|
780
|
+
applyToAllRoutes: applyToAllRoutes,
|
|
456
781
|
...props
|
|
457
782
|
})
|
|
458
783
|
}), jsx("div", {
|
|
459
784
|
className: "mt-8",
|
|
460
785
|
children: jsx(InvitationSettings, {
|
|
461
|
-
settings:
|
|
786
|
+
settings: settingsForComponents,
|
|
462
787
|
changeSetting: handleSettingChange,
|
|
463
|
-
location: location
|
|
788
|
+
location: location,
|
|
789
|
+
routePattern: routePattern,
|
|
790
|
+
applyToAllRoutes: applyToAllRoutes
|
|
464
791
|
})
|
|
465
792
|
})]
|
|
466
|
-
}),
|
|
793
|
+
}), jsx("div", {
|
|
467
794
|
className: "mt-8 pb-8 border-b border-black dark:border-[#2a2b2a]",
|
|
468
|
-
children:
|
|
469
|
-
|
|
470
|
-
children: t('regional_rettings')
|
|
471
|
-
}), jsx(RegionalSettings, {
|
|
472
|
-
settings: settingState,
|
|
795
|
+
children: jsx(RegionalSettings, {
|
|
796
|
+
settings: settingsForComponents,
|
|
473
797
|
changeSetting: handleSettingChange,
|
|
798
|
+
applyToAllRoutes: applyToAllRoutes,
|
|
474
799
|
...props
|
|
475
|
-
})
|
|
800
|
+
})
|
|
476
801
|
}), jsx("div", {
|
|
477
802
|
className: "mt-8 pb-8 border-b border-black dark:border-[#2a2b2a]",
|
|
478
803
|
children: jsx(AdditionalSettingsSlot, {
|
|
479
|
-
settings:
|
|
804
|
+
settings: settingsForComponents,
|
|
480
805
|
onSettingsChange: handleSettingChange,
|
|
481
806
|
pathname: currentPathname
|
|
482
807
|
})
|
|
@@ -488,6 +813,13 @@ const SettingDrawer = props => {
|
|
|
488
813
|
}), jsxs("div", {
|
|
489
814
|
className: "flex flex-wrap gap-2 mt-2",
|
|
490
815
|
children: [jsx("button", {
|
|
816
|
+
disabled: !changedSettings || Object.keys(changedSettings).length === 0,
|
|
817
|
+
className: clsx('flex-1 min-w-[140px] sm:flex-none sm:w-auto px-4 py-2 rounded-lg border text-sm font-medium shadow-sm transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2', !changedSettings || Object.keys(changedSettings).length === 0 ? 'border-gray-300 text-gray-500 bg-gray-50 cursor-not-allowed dark:border-gray-600 dark:text-gray-400 dark:bg-gray-800' : 'border-yellow-300 text-yellow-700 bg-yellow-50 hover:bg-yellow-100 active:bg-yellow-200 dark:border-yellow-600 dark:text-yellow-200 dark:bg-yellow-900/50 dark:hover:bg-yellow-900'),
|
|
818
|
+
onClick: handleSaveSettings,
|
|
819
|
+
children: jsx("span", {
|
|
820
|
+
children: !changedSettings || Object.keys(changedSettings).length === 0 ? 'No Changes' : 'Save Settings'
|
|
821
|
+
})
|
|
822
|
+
}), jsx("button", {
|
|
491
823
|
className: clsx('flex-1 min-w-[140px] sm:flex-none sm:w-auto px-4 py-2 rounded-lg border text-sm font-medium shadow-sm transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2', copied ? 'border-green-300 text-green-700 bg-green-50 dark:border-green-600 dark:text-green-200 dark:bg-green-900' : 'border-yellow-300 text-yellow-700 bg-yellow-50 hover:bg-yellow-100 active:bg-yellow-200 dark:border-yellow-600 dark:text-yellow-200 dark:bg-yellow-900/50 dark:hover:bg-yellow-900'),
|
|
492
824
|
onClick: handleCopySettings,
|
|
493
825
|
children: copied ? jsxs(Fragment, {
|
|
@@ -519,6 +851,12 @@ const SettingDrawer = props => {
|
|
|
519
851
|
children: "Copy Modified Settings"
|
|
520
852
|
})]
|
|
521
853
|
})
|
|
854
|
+
}), jsx("button", {
|
|
855
|
+
className: "flex-1 min-w-[140px] sm:flex-none sm:w-auto px-4 py-2 rounded-lg border border-red-300 text-red-700 bg-red-50 hover:bg-red-100 active:bg-red-200 dark:border-red-600 dark:text-red-200 dark:bg-red-900/50 dark:hover:bg-red-900 text-sm font-medium shadow-sm transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500",
|
|
856
|
+
onClick: handleResetSettings,
|
|
857
|
+
children: jsx("span", {
|
|
858
|
+
children: "\uD83D\uDD04 Reset All Settings"
|
|
859
|
+
})
|
|
522
860
|
})]
|
|
523
861
|
})]
|
|
524
862
|
})]
|