@dashadmin/dash-admin 1.3.73 → 1.3.74-srcfree.1
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/dist/components/tenant/TenancyPlan.js +307 -0
- package/dist/systemResources.js +18 -2
- package/package.json +25 -22
- package/src/AppAsyncWrapper.tsx +0 -42
- package/src/AppWrapper.tsx +0 -45
- package/src/DASHAdmin.tsx +0 -502
- package/src/DASHAdmin.tsx.old +0 -456
- package/src/RoutingWrapper.tsx +0 -143
- package/src/classes/DASHStorageClass.tsx +0 -8
- package/src/components/Input/RichTextField.tsx +0 -27
- package/src/components/Redirect.tsx +0 -46
- package/src/components/avatar/Avatar.tsx +0 -71
- package/src/components/avatar/SingleImageUploader.tsx +0 -107
- package/src/components/currency/Format.tsx +0 -79
- package/src/components/custom/Redirect.tsx +0 -23
- package/src/components/error/Error.tsx +0 -168
- package/src/components/geocoding/GeocodingField.tsx +0 -167
- package/src/components/i18n/BridgedLocalesMenuButton.tsx +0 -160
- package/src/components/i18n/LangSwitcher.tsx +0 -204
- package/src/components/loader/GlobalLoader.tsx +0 -49
- package/src/components/logs/LogFile.tsx +0 -88
- package/src/components/logs/LogFileById.tsx +0 -68
- package/src/components/logs/LogViewer.tsx +0 -43
- package/src/components/menu/AppMenu.tsx +0 -22
- package/src/components/menu/CustomMenuItemLink.tsx +0 -61
- package/src/components/menu/DarkToggleMode.tsx +0 -65
- package/src/components/menu/LanguageToggleMode.tsx +0 -120
- package/src/components/misc/CustomImageInput.tsx +0 -62
- package/src/components/misc/DASHGlobalErrorHandler.tsx +0 -194
- package/src/components/misc/DarkModeSwitcher.tsx +0 -112
- package/src/components/misc/HorizontalScroller.tsx +0 -225
- package/src/components/misc/LanguageSwitcher.tsx +0 -199
- package/src/components/misc/MUIHtmlToolTip.tsx +0 -15
- package/src/components/misc/MuiSimpleJsonTable.tsx +0 -279
- package/src/components/misc/MultiLevelTable.tsx +0 -229
- package/src/components/misc/NoResults.tsx +0 -28
- package/src/components/misc/PDFViewer.tsx +0 -85
- package/src/components/navigation/Breadcrumbs.tsx +0 -220
- package/src/components/navigation/BreadcrumbsManager.tsx +0 -310
- package/src/components/navigation/index.tsx +0 -5
- package/src/components/panel/Error.tsx +0 -168
- package/src/components/permission/AvailablePermissionsContext.tsx +0 -173
- package/src/components/permission/PermissionsSelector.tsx +0 -834
- package/src/components/permission/PermissionsSelectorList.tsx +0 -473
- package/src/components/permission/tsx +0 -0
- package/src/components/racustombuttons/CustomRAButton.tsx +0 -87
- package/src/components/racustombuttons/QuickButton.tsx +0 -117
- package/src/components/racustombuttons/QuickEditButton.tsx +0 -115
- package/src/components/racustombuttons/QuickIconButton.tsx +0 -122
- package/src/components/scrollbar/Scrollbar.tsx +0 -31
- package/src/components/selects/MultiSelect.tsx +0 -53
- package/src/components/selects/RASearchableSelect.tsx +0 -282
- package/src/components/selects/RASearchableSelectChips.tsx +0 -308
- package/src/components/selects/SearchableSelect.tsx +0 -139
- package/src/components/serviceAccount/ApiKeyRevealDialog.tsx +0 -129
- package/src/components/serviceAccount/ServiceAccountStatusSwitch.tsx +0 -99
- package/src/components/subscription/BillingCycleSelectInput.tsx +0 -68
- package/src/components/subscription/PlanAddonsSettings.tsx +0 -563
- package/src/components/subscription/PlanAuditLog.tsx +0 -453
- package/src/components/subscription/PlanFeaturesSettings.tsx +0 -243
- package/src/components/subscription/PlanLimitsSettings.tsx +0 -230
- package/src/components/subscription/PlanMetadataSettings.tsx +0 -306
- package/src/components/subscription/PlanPricesSettings.tsx +0 -307
- package/src/components/subscription/index.ts +0 -7
- package/src/components/svgelements/SvgLoading.tsx +0 -229
- package/src/components/svgelements/SvgLogo.tsx +0 -53
- package/src/components/svgelements/SvgLogoMin.tsx +0 -64
- package/src/components/svgelements/SvgShipping.tsx +0 -673
- package/src/components/tenancy/GlobalTenantWrapper.tsx +0 -84
- package/src/components/tenancy/TenantSwitcher.tsx +0 -514
- package/src/components/tenant/AvailablePermissionsContext.tsx +0 -0
- package/src/components/tenant/SettingsSections.tsx +0 -151
- package/src/components/tenant/TenancySettings.tsx +0 -122
- package/src/components/tenant/TenantAttributes.tsx +0 -153
- package/src/components/tenant/TenantAttributesContext.tsx +0 -163
- package/src/components/tenant/TenantSelector.tsx +0 -142
- package/src/components/tenant/TenantSettings.tsx +0 -184
- package/src/components/tenant/TenantSettingsContext.tsx +0 -165
- package/src/components/tenant/TenantTheme.tsx +0 -172
- package/src/components/user/AvatarComponent.tsx +0 -317
- package/src/components/user/TenantAvatarComponent.tsx +0 -99
- package/src/components/user/UserPreferences.tsx +0 -677
- package/src/config/ACTIONS.tsx +0 -26
- package/src/config/ConstantsService.tsx +0 -44
- package/src/config/DASHAdminSystemConstants.tsx +0 -183
- package/src/config/PARSERS.tsx +0 -9
- package/src/contexts/DashQueryClientContext.tsx +0 -113
- package/src/contexts/DashResourceContext.tsx +0 -34
- package/src/contexts/I18nBridgeContext.tsx +0 -156
- package/src/contexts/I18nBridgeSetter.tsx +0 -39
- package/src/contexts/I18nReduxSync.tsx +0 -27
- package/src/contexts/SubscriptionPlanFormatsProvider.tsx +0 -217
- package/src/contexts/SystemRequestsCache.tsx +0 -215
- package/src/contexts/auth/AuthContext.tsx +0 -567
- package/src/contexts/auth/AuthContextLocalStorage.tsx +0 -140
- package/src/contexts/auth/DASHAuthenticationService.tsx +0 -915
- package/src/contexts/auth/WindowContext.tsx +0 -15
- package/src/contexts/auth/index.tsx +0 -3
- package/src/contexts/com/FCMContext.tsx +0 -415
- package/src/contexts/com/LaravelEchoContext.tsx +0 -41
- package/src/contexts/com/LaravelEchoMgr.tsx +0 -155
- package/src/contexts/com/components/DefaultNotificationComponent.tsx +0 -20
- package/src/contexts/com/components/EchoNotificationsCenter.tsx +0 -65
- package/src/contexts/com/components/NotificationAttributesTable.tsx +0 -54
- package/src/contexts/com/components/NotificationRenderer.tsx +0 -42
- package/src/contexts/com/components/NotificationsWidget.tsx +0 -182
- package/src/contexts/com/components/notificationFormats.tsx +0 -50
- package/src/contexts/com/useLaravelEcho.tsx +0 -432
- package/src/contexts/dictionary/DictionaryContext.tsx +0 -94
- package/src/declarations.d.ts +0 -17
- package/src/default-theme/DASHAppProviders.tsx +0 -117
- package/src/default-theme/DashThemeContext.tsx +0 -209
- package/src/default-theme/DashThemeContext.tsx.fast +0 -143
- package/src/default-theme/DashThemeContext.tsx.old +0 -306
- package/src/default-theme/DashThemeHelperProvider.tsx +0 -98
- package/src/default-theme/DomainAppLayout.tsx +0 -166
- package/src/default-theme/DomainHeader.tsx +0 -162
- package/src/default-theme/DomainTheme.tsx +0 -59
- package/src/default-theme/FullLayoutMarkup.tsx +0 -231
- package/src/default-theme/StaticLayout.tsx +0 -47
- package/src/default-theme/index.tsx +0 -11
- package/src/default-theme/menu/AppDashboardGrid.tsx +0 -279
- package/src/default-theme/menu/AppMaterialMenu.tsx +0 -546
- package/src/default-theme/menu/AppMenuComponents/SubmenuPortal.tsx +0 -61
- package/src/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItem.tsx +0 -264
- package/src/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItems.tsx +0 -31
- package/src/default-theme/menu/AppMenuComponents/expanded/CollapsableSidebarMenu.tsx +0 -293
- package/src/default-theme/menu/AppMenuComponents/expanded/SidebarItem.tsx +0 -92
- package/src/default-theme/menu/AppMenuComponents/getItem.tsx +0 -17
- package/src/default-theme/menu/AppMenuComponents/interfaces.tsx +0 -41
- package/src/default-theme/menu/AppMenuComponents/submenuConstants.ts +0 -90
- package/src/default-theme/menu/AppSidebarMaterial.tsx +0 -339
- package/src/default-theme/menu/SidebarActions.tsx +0 -84
- package/src/default-theme/updateDomCssVariables.tsx +0 -176
- package/src/helpers/checkRole.tsx +0 -66
- package/src/helpers/parseAxiosError.tsx +0 -41
- package/src/hooks/audio/useAudio.tsx +0 -39
- package/src/hooks/axios.tsx +0 -165
- package/src/hooks/data/useDashboardStats.tsx +0 -65
- package/src/hooks/data/usePackageByClientsStats.tsx +0 -44
- package/src/hooks/data/usePackageByCommunesStats.tsx +0 -44
- package/src/hooks/data/usePackageStats.tsx +0 -69
- package/src/hooks/data/usePackageWithdrawDetails.tsx +0 -61
- package/src/hooks/data/useStats.tsx +0 -86
- package/src/hooks/isCurrentPath.tsx +0 -22
- package/src/hooks/notifications/WSMessagesManager.tsx +0 -152
- package/src/hooks/notifications/WSPusherManager.tsx +0 -92
- package/src/hooks/useBreadcrumbs.tsx +0 -329
- package/src/hooks/useClickOutside.tsx +0 -57
- package/src/hooks/useFormPersistance.tsx +0 -150
- package/src/hooks/useGlobalErrorMediator.tsx +0 -43
- package/src/hooks/useGlobalLoaderMgr.tsx +0 -21
- package/src/hooks/useHash.tsx +0 -27
- package/src/hooks/useLocalStorage.tsx +0 -196
- package/src/hooks/usePolyglotTranslation.tsx +0 -62
- package/src/hooks/usePrevious.tsx +0 -9
- package/src/hooks/usePrintSelected.tsx +0 -37
- package/src/hooks/useVirtualHash.tsx +0 -33
- package/src/hooks/window/useWindowSize.tsx +0 -36
- package/src/index.tsx +0 -134
- package/src/interfaces/IAppResourceConfig.tsx +0 -20
- package/src/interfaces/Log.tsx +0 -16
- package/src/interfaces/Tenant.tsx +0 -25
- package/src/interfaces/communication/IActions.tsx +0 -5
- package/src/interfaces/communication/INotification.tsx +0 -21
- package/src/interfaces/communication/IPayload.tsx +0 -3
- package/src/interfaces/communication/IRequestAction.tsx +0 -10
- package/src/interfaces/communication/IRequestPayload.tsx +0 -7
- package/src/interfaces/communication/IResponseAction.tsx +0 -7
- package/src/interfaces/misc/IAny.tsx +0 -3
- package/src/interfaces/misc/IFlashMessage.tsx +0 -10
- package/src/interfaces/navigation/IAppMenu.ts +0 -14
- package/src/interfaces/navigation/ICollapsableSidebarMenu.ts +0 -12
- package/src/interfaces/navigation/IMenuItem.ts +0 -16
- package/src/interfaces/notifications/IModel.tsx +0 -6
- package/src/interfaces/notifications/IModelField.tsx +0 -8
- package/src/interfaces/notifications/IUserNotification.tsx +0 -12
- package/src/interfaces/notifications/IUserNotificationData.tsx +0 -13
- package/src/interfaces/notifications/IUserNotificationPayload.tsx +0 -8
- package/src/interfaces/user/IGetAuth.tsx +0 -92
- package/src/interfaces/user/ITenantSettings.tsx +0 -3
- package/src/interfaces/user/IUser.tsx +0 -60
- package/src/interfaces/user/IUserSettings.tsx +0 -43
- package/src/interfaces.tsx +0 -6
- package/src/layout/AppLayout.tsx +0 -112
- package/src/layout/ApplicationLayout.tsx +0 -197
- package/src/layout/MotionWrapper.original.tsx +0 -236
- package/src/layout/MotionWrapper.tsx +0 -236
- package/src/layout/ResourceMenu.tsx +0 -164
- package/src/layout/ResoureLayout.tsx +0 -105
- package/src/layout/TransitionWrapper.tsx +0 -125
- package/src/pages/ChangePassword.tsx +0 -179
- package/src/pages/DASHLanding.tsx +0 -22
- package/src/pages/DASHLightWeightLogin.tsx +0 -611
- package/src/pages/DASHSimpleLogin.tsx +0 -260
- package/src/pages/Login.tsx +0 -111
- package/src/pages/Profile.tsx +0 -357
- package/src/pages/RecoverPassword.tsx +0 -175
- package/src/pages/SingleImageUploader.tsx +0 -55
- package/src/pages/VerifyAccount.tsx +0 -128
- package/src/providers/authProvider.tsx +0 -217
- package/src/providers/dataProvider.tsx +0 -672
- package/src/providers/i18n/en.ts +0 -646
- package/src/providers/i18n/es.ts +0 -652
- package/src/providers/i18n/languages.tsx +0 -8
- package/src/providers/i18n/mergeTranslations.ts +0 -53
- package/src/providers/i18nProvider.tsx +0 -23
- package/src/react-admin-dash/RADashComponent.tsx +0 -240
- package/src/react-admin-dash/Resource.tsx +0 -77
- package/src/resources/Brand/BrandResource.tsx +0 -130
- package/src/resources/DASHResourceLoader.ts +0 -180
- package/src/resources/Log/LogResource.tsx +0 -73
- package/src/resources/Tenant/ImpersonateTenantResource.tsx +0 -113
- package/src/resources/Trash/TrashTemplate.tsx +0 -180
- package/src/resources/User/components/AvatarUploadField.tsx +0 -57
- package/src/resources/User/components/PasswordFields.tsx +0 -73
- package/src/resources/User/getProfileMenu.ts +0 -57
- package/src/resources/User/profileResource.tsx +0 -51
- package/src/resources/User/userLayout.tsx +0 -62
- package/src/resources/User/userResource.tsx +0 -111
- package/src/resources/User/userSchema.tsx +0 -213
- package/src/resources/User/usersFilters.tsx +0 -21
- package/src/resources.tsx +0 -280
- package/src/schemas/log.tsx +0 -45
- package/src/schemas/notification.tsx +0 -42
- package/src/schemas/permissions.tsx +0 -44
- package/src/schemas/roles.tsx +0 -48
- package/src/schemas/rolesDataGrid.tsx +0 -48
- package/src/schemas/subscription/components/SubscriptionActions.tsx +0 -153
- package/src/schemas/subscription/components/SubscriptionPaymentHistory.tsx +0 -127
- package/src/schemas/subscription/components/SubscriptionPlanFeatures.tsx +0 -162
- package/src/schemas/subscription/components/SubscriptionPlanPreview.tsx +0 -141
- package/src/schemas/subscription/components/SubscriptionPlanStats.tsx +0 -318
- package/src/schemas/subscription/components/SubscriptionStatusIndicator.tsx +0 -72
- package/src/schemas/subscription/subscriptionPlanSchema.tsx +0 -185
- package/src/schemas/subscription/subscriptionSchema.tsx +0 -152
- package/src/schemas/subscriptionPlan.ts +0 -422
- package/src/schemas/tenant.tsx +0 -129
- package/src/schemas/tenantUser.tsx +0 -96
- package/src/schemas/tenant_superadmin.tsx +0 -119
- package/src/schemas/user.tsx +0 -26
- package/src/systemResources.old.tsx +0 -928
- package/src/systemResources.tsx +0 -1369
- package/src/templates/ResourceTemplate.tsx +0 -240
- package/src/templates/ResourceTemplate.tsx.memoized_experiment +0 -350
- package/src/templates/ResourceTemplate.tsx.original +0 -396
- package/src/templates/ResourceTemplateCreate.tsx +0 -182
- package/src/templates/ResourceTemplateEdit.tsx +0 -176
- package/src/templates/ResourceTemplateFull.tsx +0 -581
- package/src/templates/ResourceTemplateList.tsx +0 -340
- package/src/templates/ResourceTemplateOld.tsx.bkup +0 -567
- package/src/templates/ResourceTemplateShow.tsx +0 -88
- package/src/templates/TrashTemplate.tsx +0 -179
- package/src/tenantResources.tsx +0 -223
- package/src/test_portal_bubbles.tsx +0 -40
- package/src/theme/AppHeader.tsx +0 -52
- package/src/theme/AppLayoutSetting.tsx +0 -33
- package/src/theme/AppLogo.tsx +0 -13
- package/src/theme/AppSidebar.tsx +0 -12
- package/src/theme/AppSidebarContent.tsx +0 -105
- package/src/theme/AppSidebarLogo.tsx +0 -48
- package/src/theme/components/PageTitle.tsx +0 -37
- package/src/utils/cache/CacheInvalidatorContext.tsx +0 -125
- package/src/utils/cache/CacheInvalidatorListenerComponent.tsx +0 -10
- package/src/utils/cache/useCacheInvalidatorListener.tsx +0 -27
- package/src/utils/convertFileToBase64.tsx +0 -9
- package/src/utils/convertToFile.tsx +0 -14
- package/src/utils/cookies.tsx +0 -33
- package/src/utils/dashDefaultQueryClient.tsx +0 -34
- package/src/utils/dataUrlToBlob.tsx +0 -30
- package/src/utils/deepReplace.tsx +0 -19
- package/src/utils/getProfileMenu.tsx +0 -41
- package/src/utils/getTenantSettings.tsx +0 -9
- package/src/utils/getType.tsx +0 -8
- package/src/utils/getUserSettings.tsx +0 -8
- package/src/utils/hasCode.tsx +0 -14
- package/src/utils/index.ts +0 -19
- package/src/utils/injectTenantStyles.ts +0 -28
- package/src/utils/isComponent.tsx +0 -45
- package/src/utils/navEvents.tsx +0 -91
- package/src/utils/prototypes.tsx +0 -5
- package/src/utils/regexp.tsx +0 -4
- package/src/utils/resolveObjectPath.tsx +0 -4
- package/src/utils/setNativeValue.tsx +0 -24
- package/src/utils/slugify.tsx +0 -11
- package/src/utils/validators/emailValidator.tsx +0 -6
- package/src/utils/validators/requiredValidator.tsx +0 -5
- package/src/utils/validators/rutValidator.tsx +0 -31
- package/src/utils/validators.tsx +0 -96
|
@@ -1,546 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
|
|
3
|
-
import { useSelector } from 'react-redux';
|
|
4
|
-
// Remove this import
|
|
5
|
-
// import { usePermissions } from 'react-admin';
|
|
6
|
-
|
|
7
|
-
import { List, IconButton, Box, useMediaQuery, useTheme } from '@mui/material';
|
|
8
|
-
import KeyboardDoubleArrowLeftIcon from '@mui/icons-material/KeyboardDoubleArrowLeft';
|
|
9
|
-
import KeyboardDoubleArrowRightIcon from '@mui/icons-material/KeyboardDoubleArrowRight';
|
|
10
|
-
import MenuOpenIcon from '@mui/icons-material/MenuOpen';
|
|
11
|
-
import { useEffect } from 'react';
|
|
12
|
-
import { IMenuItem, IAppMenu } from './AppMenuComponents/interfaces';
|
|
13
|
-
import SidebarItem from './AppMenuComponents/expanded/SidebarItem';
|
|
14
|
-
import SidebarItemCollapse from './AppMenuComponents/expanded/CollapsableSidebarMenu';
|
|
15
|
-
import CollapsedSidebarItems from './AppMenuComponents/collapsed/CollapsedSidebarItems';
|
|
16
|
-
import { IDashAutoAdminResourceConfig } from 'dash-auto-admin';
|
|
17
|
-
|
|
18
|
-
import { IDASHAppState, usePanelSettings } from 'dash-admin-state';
|
|
19
|
-
import checkRole from '../../helpers/checkRole';
|
|
20
|
-
import { slugify } from '../../utils/slugify';
|
|
21
|
-
// Direct imports to avoid circular barrel imports
|
|
22
|
-
import AvatarComponent from '../../components/user/AvatarComponent';
|
|
23
|
-
import TenantAvatarComponent from '../../components/user/TenantAvatarComponent';
|
|
24
|
-
|
|
25
|
-
import Scrollbar from '../../components/scrollbar/Scrollbar';
|
|
26
|
-
// Add this import
|
|
27
|
-
import { AuthPersistenceService } from 'dash-auth';
|
|
28
|
-
import { useAuthContext } from '../../contexts/auth/AuthContext';
|
|
29
|
-
import DarkToggleMode from '../../components/menu/DarkToggleMode';
|
|
30
|
-
// Use I18nBridgeContext exclusively
|
|
31
|
-
import { useI18nBridge } from '../../contexts/I18nBridgeContext';
|
|
32
|
-
import BridgedLocalesMenuButton from '../../components/i18n/BridgedLocalesMenuButton';
|
|
33
|
-
|
|
34
|
-
import { dashStorage } from 'dash-utils';
|
|
35
|
-
import SidebarActions from './SidebarActions';
|
|
36
|
-
import { useNavigate } from 'react-router';
|
|
37
|
-
|
|
38
|
-
// Update the interface to include new props
|
|
39
|
-
interface IAppMenuExtended extends IAppMenu {
|
|
40
|
-
logos?: {
|
|
41
|
-
horizontalLogo: React.ReactNode;
|
|
42
|
-
squaredLogo: React.ReactNode;
|
|
43
|
-
};
|
|
44
|
-
onToggleDrawer?: (e: React.MouseEvent) => void;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Group icons
|
|
48
|
-
const GenerateItems: React.FC<{ items: IMenuItem[]; navExpanded: boolean, navSize: "large" | "small", level: number, sidebarPosition?: "left" | "top" | "bottom" | "right", translate: (key: string, options?: any) => string }> = ({
|
|
49
|
-
items,
|
|
50
|
-
navExpanded,
|
|
51
|
-
navSize,
|
|
52
|
-
level,
|
|
53
|
-
sidebarPosition = "left",
|
|
54
|
-
translate
|
|
55
|
-
}) => {
|
|
56
|
-
const isHorizontal = sidebarPosition === "top" || sidebarPosition === "bottom";
|
|
57
|
-
|
|
58
|
-
return items &&
|
|
59
|
-
<>
|
|
60
|
-
{navExpanded && navSize === "large" ? (
|
|
61
|
-
<List
|
|
62
|
-
className={'sidebar-list'}
|
|
63
|
-
component='nav'
|
|
64
|
-
sx={isHorizontal ? {
|
|
65
|
-
display: 'flex',
|
|
66
|
-
flexDirection: 'row',
|
|
67
|
-
flexWrap: 'nowrap',
|
|
68
|
-
alignItems: 'center',
|
|
69
|
-
padding: 0,
|
|
70
|
-
margin: 0,
|
|
71
|
-
} : undefined}
|
|
72
|
-
>
|
|
73
|
-
{items.map((item, index) => {
|
|
74
|
-
return item.children && item.children.length ? (
|
|
75
|
-
<SidebarItemCollapse
|
|
76
|
-
navExpanded={navExpanded}
|
|
77
|
-
navSize={navSize}
|
|
78
|
-
item={item}
|
|
79
|
-
key={index}
|
|
80
|
-
level={level + 1}
|
|
81
|
-
sidebarPosition={sidebarPosition}
|
|
82
|
-
/>
|
|
83
|
-
) : (
|
|
84
|
-
|
|
85
|
-
<SidebarItem level={level} navExpanded={navExpanded} navSize={navSize} item={item} key={index} />
|
|
86
|
-
);
|
|
87
|
-
})}
|
|
88
|
-
</List>
|
|
89
|
-
) : (
|
|
90
|
-
<CollapsedSidebarItems level={level} items={items} navExpanded={navExpanded} navSize={navSize} sidebarPosition={sidebarPosition} />
|
|
91
|
-
)}
|
|
92
|
-
</>
|
|
93
|
-
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const AppMaterialMenu: React.FC<IAppMenuExtended> = props => {
|
|
98
|
-
|
|
99
|
-
const DEBUG = true;
|
|
100
|
-
const { menu, debug, navExpanded, navSize, logos, onToggleDrawer, sidebarPosition: propSidebarPosition } = props;
|
|
101
|
-
const navigate = useNavigate();
|
|
102
|
-
const theme = useTheme();
|
|
103
|
-
const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
|
104
|
-
const isMediumScreen = useMediaQuery(theme.breakpoints.down('md')); // For logo switching
|
|
105
|
-
|
|
106
|
-
// Get panel settings from Redux (includes dimensions, padding, but NOT sidebarPosition - that comes from prop)
|
|
107
|
-
const { sidebarLargeWidth, sidebarSmallWidth, sidebarHorizontalHeight, logoVerticalMaxWidth, logoVerticalMaxHeight, logoHorizontalMaxWidth, logoHorizontalMaxHeight } = usePanelSettings();
|
|
108
|
-
|
|
109
|
-
// Use sidebarPosition from prop (which is responsive from AppSidebarMaterial) with fallback to 'left'
|
|
110
|
-
const sidebarPosition = propSidebarPosition || 'left';
|
|
111
|
-
|
|
112
|
-
// Get i18n from Bridge context exclusively
|
|
113
|
-
const { i18nProvider, locale: currentLocale } = useI18nBridge();
|
|
114
|
-
|
|
115
|
-
// Use bridged translate
|
|
116
|
-
const translate = React.useCallback((key: string, options?: any) => {
|
|
117
|
-
// Safety check for non-string keys
|
|
118
|
-
if (typeof key !== 'string') {
|
|
119
|
-
return key;
|
|
120
|
-
}
|
|
121
|
-
// Use bridged provider
|
|
122
|
-
if (i18nProvider?.translate) {
|
|
123
|
-
try {
|
|
124
|
-
return i18nProvider.translate(key, options);
|
|
125
|
-
} catch (e) {
|
|
126
|
-
console.warn('Translation error:', e);
|
|
127
|
-
return key;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return key;
|
|
131
|
-
}, [i18nProvider]);
|
|
132
|
-
|
|
133
|
-
useEffect(() => {
|
|
134
|
-
DEBUG && console.log('🌐 AppMaterialMenu: Bridged i18nProvider:', i18nProvider);
|
|
135
|
-
DEBUG && console.log('🌐 AppMaterialMenu: currentLocale:', currentLocale);
|
|
136
|
-
|
|
137
|
-
// Enhanced debug: test translate with various keys
|
|
138
|
-
DEBUG && console.log('🧪 Translation test:', {
|
|
139
|
-
// Test react-admin built-in keys
|
|
140
|
-
'ra.action.delete': translate('ra.action.delete'),
|
|
141
|
-
'ra.action.save': translate('ra.action.save'),
|
|
142
|
-
// Test top-level custom keys
|
|
143
|
-
'kiosk.total': translate('kiosk.total'),
|
|
144
|
-
// Test nested resource keys
|
|
145
|
-
'resource.groups.products': translate('resource.groups.products'),
|
|
146
|
-
'resource.system.tenants.label': translate('resource.system.tenants.label'),
|
|
147
|
-
});
|
|
148
|
-
}, [i18nProvider, currentLocale, translate]);
|
|
149
|
-
|
|
150
|
-
//const resources = useResourceDefinitions()
|
|
151
|
-
|
|
152
|
-
// Replace usePermissions with useAuthContext - add null check
|
|
153
|
-
// const { permissions } = usePermissions();
|
|
154
|
-
const authContext = useAuthContext();
|
|
155
|
-
|
|
156
|
-
const [items, setItems] = React.useState<IMenuItem[]>(null);
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
// State for tenant logos
|
|
160
|
-
/* const [tenantLogos, setTenantLogos] = React.useState<{
|
|
161
|
-
horizontalLogo: string | null;
|
|
162
|
-
squaredLogo: string | null;
|
|
163
|
-
}>({
|
|
164
|
-
horizontalLogo: null,
|
|
165
|
-
squaredLogo: null
|
|
166
|
-
});*/
|
|
167
|
-
|
|
168
|
-
const resources = useSelector(
|
|
169
|
-
(
|
|
170
|
-
state: IDASHAppState<any, any, IDashAutoAdminResourceConfig>,
|
|
171
|
-
) => {
|
|
172
|
-
if (debug || menu) {
|
|
173
|
-
return menu;
|
|
174
|
-
}
|
|
175
|
-
return state.resources.items;
|
|
176
|
-
},
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
// Track resource changes for debugging
|
|
180
|
-
const prevResourcesRef = React.useRef<any[]>(null);
|
|
181
|
-
React.useEffect(() => {
|
|
182
|
-
const prevResources = prevResourcesRef.current;
|
|
183
|
-
const prevModels = Array.isArray(prevResources) ? prevResources.map((r: any) => r.model) : [];
|
|
184
|
-
const newModels = Array.isArray(resources) ? resources.map((r: any) => r.model) : [];
|
|
185
|
-
const added = newModels.filter(m => !prevModels.includes(m));
|
|
186
|
-
const removed = prevModels.filter(m => !newModels.includes(m));
|
|
187
|
-
console.log('📊 AppMaterialMenu: Resources from Redux', {
|
|
188
|
-
isSameRef: prevResources === resources,
|
|
189
|
-
prevCount: prevResources?.length || 0,
|
|
190
|
-
newCount: resources?.length || 0,
|
|
191
|
-
added: added.length > 0 ? added : 'none',
|
|
192
|
-
removed: removed.length > 0 ? removed : 'none',
|
|
193
|
-
allModels: newModels,
|
|
194
|
-
});
|
|
195
|
-
prevResourcesRef.current = resources;
|
|
196
|
-
}, [resources]);
|
|
197
|
-
|
|
198
|
-
const panelSettings = useSelector((state: any) => state.common.panelSettings);
|
|
199
|
-
const horizontalLogo = panelSettings?.horizontalLogo;
|
|
200
|
-
const squaredLogo = panelSettings?.squaredLogo;
|
|
201
|
-
|
|
202
|
-
const groupIcons = useSelector(
|
|
203
|
-
(state: IDASHAppState<any, any, IDashAutoAdminResourceConfig>) =>
|
|
204
|
-
state.settings.groupIcons
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
// Load tenant logos from AuthPersistenceService
|
|
208
|
-
/*useEffect(() => {
|
|
209
|
-
const tenantImages = AuthPersistenceService.getTenantImages();
|
|
210
|
-
DEBUG && console.log('AppMaterialMenu Loaded: loading tenant images:', tenantImages);
|
|
211
|
-
if (tenantImages) {
|
|
212
|
-
//console.log('AppMaterialMenu: Loading tenant logos:', tenantImages);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
setTenantLogos({
|
|
217
|
-
horizontalLogo: tenantImages.horizontal_logo?.original || null,
|
|
218
|
-
squaredLogo: tenantImages.squared_logo?.original || null
|
|
219
|
-
});
|
|
220
|
-
} else {
|
|
221
|
-
DEBUG && console.log('AppMaterialMenu: No tenant images found');
|
|
222
|
-
setTenantLogos({
|
|
223
|
-
horizontalLogo: null,
|
|
224
|
-
squaredLogo: null
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
//console.log('DASHTRefreshTheme');
|
|
231
|
-
window.dispatchEvent(new CustomEvent("DASHTRefreshTheme", {}));
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}, []);*/
|
|
237
|
-
|
|
238
|
-
useEffect(() => {
|
|
239
|
-
// Don't process resources if permissions haven't been loaded yet and not in debug mode
|
|
240
|
-
|
|
241
|
-
// Get user roles, defaulting to ["Public"] for unauthenticated users
|
|
242
|
-
const userRoles = authContext?.user?.roles
|
|
243
|
-
? authContext.user.roles.flatMap(role => role.name)
|
|
244
|
-
: ["Public"];
|
|
245
|
-
|
|
246
|
-
const groups = [
|
|
247
|
-
...new Set(
|
|
248
|
-
resources
|
|
249
|
-
.map((resource) => resource.group)
|
|
250
|
-
.filter((x) => x !== null && x !== undefined && x !== ''),
|
|
251
|
-
),
|
|
252
|
-
];
|
|
253
|
-
//group resources belonging to the group
|
|
254
|
-
const groupedResources = new Object();
|
|
255
|
-
groups.forEach((group) => {
|
|
256
|
-
groupedResources[group as string] = resources.filter((resource) => {
|
|
257
|
-
|
|
258
|
-
//console.log(resource.group + " | ", resource.label + " | ", permissions, resource.roles, checkRole(permissions, resource.roles));
|
|
259
|
-
/* @ts-ignore */
|
|
260
|
-
return (resource.group === group && checkRole(userRoles, resource.roles));
|
|
261
|
-
});
|
|
262
|
-
});
|
|
263
|
-
const _items: IMenuItem[] = [];
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
Object.keys(groupedResources).map((groupKey) => {
|
|
268
|
-
const group: IDashAutoAdminResourceConfig[] = groupedResources[groupKey];
|
|
269
|
-
if (!group.length) return;
|
|
270
|
-
const hidden = group[0] && group[0].hidden === true ? true : false;
|
|
271
|
-
if (hidden) return;
|
|
272
|
-
|
|
273
|
-
const _childrens = group
|
|
274
|
-
.filter((resource) => resource.hidden !== true);
|
|
275
|
-
|
|
276
|
-
// Generate paths relative to BrowserRouter basename (don't prepend currentAppPath)
|
|
277
|
-
// React Router's Link components will automatically prepend the basename
|
|
278
|
-
const _children = _childrens
|
|
279
|
-
.map((resource) => {
|
|
280
|
-
|
|
281
|
-
/* debugger;
|
|
282
|
-
const translation = translate(resource.label)
|
|
283
|
-
console.log( translation);
|
|
284
|
-
|
|
285
|
-
debugger;
|
|
286
|
-
*/
|
|
287
|
-
|
|
288
|
-
console.log('translating resource label:', resource.label, translate(resource.label));
|
|
289
|
-
|
|
290
|
-
// Add more debug info
|
|
291
|
-
// Use optional chaining carefully since i18nProvider might be null
|
|
292
|
-
const currentLocale = i18nProvider?.getLocale?.() || 'unknown';
|
|
293
|
-
const messages = i18nProvider?.getMessages?.(currentLocale) || {};
|
|
294
|
-
const hasKey = messages[resource.label] !== undefined;
|
|
295
|
-
|
|
296
|
-
console.log('🌐 Translation debug:', {
|
|
297
|
-
key: resource.label,
|
|
298
|
-
currentLocale,
|
|
299
|
-
hasKey,
|
|
300
|
-
translation: messages[resource.label],
|
|
301
|
-
allMessagesKeys: Object.keys(messages).filter(k => k.includes('resource.system')),
|
|
302
|
-
translateResult: translate(resource.label)
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
// For menuOnly resources, use redirect or path directly as the navigation target
|
|
306
|
-
// For regular resources, build the path from model + optional redirect
|
|
307
|
-
const buildMenuPath = () => {
|
|
308
|
-
if (resource.menuOnly) {
|
|
309
|
-
// menuOnly: use redirect, path, or fallback to model
|
|
310
|
-
return resource.redirect || resource.path || `/${resource.model}`;
|
|
311
|
-
}
|
|
312
|
-
// Regular resource: existing logic
|
|
313
|
-
if (resource?.redirect?.startsWith('/')) {
|
|
314
|
-
return resource.redirect;
|
|
315
|
-
}
|
|
316
|
-
if (resource?.redirect) {
|
|
317
|
-
return `/${resource.model}/${resource.redirect}`.replace(/\/+/g, '/');
|
|
318
|
-
}
|
|
319
|
-
return `/${resource.model}`.replace(/\/+/g, '/');
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
return {
|
|
323
|
-
label: translate(resource.label, { _: resource.label }),
|
|
324
|
-
key: resource.label,
|
|
325
|
-
to: buildMenuPath(),
|
|
326
|
-
icon: resource.icon,
|
|
327
|
-
group: slugify(group[0].group),
|
|
328
|
-
model: resource.model,
|
|
329
|
-
menuOnly: resource.menuOnly,
|
|
330
|
-
txtLabel: translate(resource.label, { _: resource.label }),
|
|
331
|
-
};
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
// Generate path relative to BrowserRouter basename (don't prepend currentAppPath)
|
|
335
|
-
// React Router's Link components will automatically prepend the basename
|
|
336
|
-
const _item: IMenuItem = {
|
|
337
|
-
label: translate(group[0].group, { _: group[0].group }),
|
|
338
|
-
key: slugify(group[0].group),
|
|
339
|
-
icon: group[0].icon || groupIcons[group[0].group],
|
|
340
|
-
group: slugify(group[0].group),
|
|
341
|
-
model: group[0].model,
|
|
342
|
-
to: group[0].redirect?.startsWith('/')
|
|
343
|
-
? group[0].redirect
|
|
344
|
-
: group[0].redirect
|
|
345
|
-
? `/${group[0].model}/${group[0].redirect}`.replace(/\/+/g, '/')
|
|
346
|
-
: `/${group[0].model}`.replace(/\/+/g, '/'),
|
|
347
|
-
txtLabel: translate(group[0].group, { _: group[0].group }),
|
|
348
|
-
...(_childrens && _childrens.length > 1 && { children: _children }) as any
|
|
349
|
-
};
|
|
350
|
-
|
|
351
|
-
_items.push(_item);
|
|
352
|
-
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
// Add ungrouped resources as top-level items
|
|
356
|
-
const ungroupedResources = resources.filter((resource) => {
|
|
357
|
-
const hasGroup = resource.group !== null && resource.group !== undefined && resource.group !== '';
|
|
358
|
-
return !hasGroup && checkRole(userRoles, resource.roles) && resource.hidden !== true;
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
ungroupedResources.forEach((resource) => {
|
|
362
|
-
const buildMenuPath = () => {
|
|
363
|
-
if (resource.menuOnly) {
|
|
364
|
-
return resource.redirect || resource.path || `/${resource.model}`;
|
|
365
|
-
}
|
|
366
|
-
if (resource?.redirect?.startsWith('/')) {
|
|
367
|
-
return resource.redirect;
|
|
368
|
-
}
|
|
369
|
-
if (resource?.redirect) {
|
|
370
|
-
return `/${resource.model}/${resource.redirect}`.replace(/\/+/g, '/');
|
|
371
|
-
}
|
|
372
|
-
return `/${resource.model}`.replace(/\/+/g, '/');
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
_items.push({
|
|
376
|
-
label: translate(resource.label, { _: resource.label }),
|
|
377
|
-
key: resource.label || resource.model,
|
|
378
|
-
to: buildMenuPath(),
|
|
379
|
-
icon: resource.icon,
|
|
380
|
-
group: null,
|
|
381
|
-
model: resource.model,
|
|
382
|
-
menuOnly: resource.menuOnly,
|
|
383
|
-
txtLabel: translate(resource.label, { _: resource.label }),
|
|
384
|
-
});
|
|
385
|
-
});
|
|
386
|
-
DEBUG && console.log("MENU ITEMS", _items);
|
|
387
|
-
setItems(_items);
|
|
388
|
-
}, [resources, debug, authContext?.user, translate, i18nProvider, currentLocale]); // Include translate, i18nProvider and currentLocale to rebuild menu when translations change
|
|
389
|
-
|
|
390
|
-
const isHorizontal = sidebarPosition === "top" || sidebarPosition === "bottom";
|
|
391
|
-
|
|
392
|
-
return <>
|
|
393
|
-
|
|
394
|
-
<Box className='sidebar-header'
|
|
395
|
-
|
|
396
|
-
sx={{
|
|
397
|
-
display: 'flex',
|
|
398
|
-
flexDirection: isHorizontal ? 'row' : (navExpanded && navSize === 'large' ? 'row' : 'column'),
|
|
399
|
-
alignItems: isHorizontal ? 'center' : undefined,
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
}>
|
|
403
|
-
|
|
404
|
-
<Box sx={{
|
|
405
|
-
paddingRight: '5px',
|
|
406
|
-
//borderRight: navExpanded && navSize === 'large' ? '1px solid rgba(0, 0, 0, 0.12)' : 'none',
|
|
407
|
-
display: 'flex',
|
|
408
|
-
flexDirection: 'column',
|
|
409
|
-
alignItems: 'center',
|
|
410
|
-
gap: 1
|
|
411
|
-
}}>
|
|
412
|
-
|
|
413
|
-
<Box
|
|
414
|
-
sx={{
|
|
415
|
-
display: 'flex',
|
|
416
|
-
alignItems: 'center',
|
|
417
|
-
//gap: 1,
|
|
418
|
-
flexDirection: 'column',
|
|
419
|
-
|
|
420
|
-
}}>
|
|
421
|
-
{/* Toggle icon - burger for mobile, arrows for desktop */}
|
|
422
|
-
{onToggleDrawer && (
|
|
423
|
-
<IconButton
|
|
424
|
-
className='dash-icon-button-color dash-icon-button-bg'
|
|
425
|
-
onClick={onToggleDrawer}
|
|
426
|
-
sx={{
|
|
427
|
-
m:1
|
|
428
|
-
}}
|
|
429
|
-
/*sx={{
|
|
430
|
-
m:1,
|
|
431
|
-
padding: '8px',
|
|
432
|
-
borderRadius: '8px',
|
|
433
|
-
backgroundColor: 'rgba(255,255,255,0.1)',
|
|
434
|
-
'&:hover': {
|
|
435
|
-
backgroundColor: 'rgba(255,255,255,0.2)',
|
|
436
|
-
}
|
|
437
|
-
}}*/
|
|
438
|
-
|
|
439
|
-
>
|
|
440
|
-
{navSize === 'small' ? (
|
|
441
|
-
<MenuOpenIcon sx={{ fontSize: 28, transform: 'scaleX(-1)' }} />
|
|
442
|
-
) : navExpanded ? (
|
|
443
|
-
<KeyboardDoubleArrowLeftIcon sx={{ fontSize: 28 }} />
|
|
444
|
-
) : (
|
|
445
|
-
<KeyboardDoubleArrowRightIcon sx={{ fontSize: 28 }} />
|
|
446
|
-
)}
|
|
447
|
-
</IconButton>
|
|
448
|
-
)}
|
|
449
|
-
{!(navExpanded && navSize === 'large') && !isSmallScreen && <TenantAvatarComponent
|
|
450
|
-
navExpanded={navExpanded}
|
|
451
|
-
navSize={navSize}
|
|
452
|
-
imageUrl={isMediumScreen || sidebarPosition === "left" || sidebarPosition === "right" ? squaredLogo : horizontalLogo}
|
|
453
|
-
maxWidth={isHorizontal ? logoHorizontalMaxWidth : logoVerticalMaxWidth}
|
|
454
|
-
maxHeight={isHorizontal ? logoHorizontalMaxHeight : logoVerticalMaxHeight}
|
|
455
|
-
sidebarSmallWidth={sidebarSmallWidth}
|
|
456
|
-
alt="Tenant Logo"
|
|
457
|
-
sidebarPosition={sidebarPosition}
|
|
458
|
-
onClick={() => navigate('/')}
|
|
459
|
-
/>}
|
|
460
|
-
</Box>
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
{(sidebarPosition === "left" || sidebarPosition === "right") && (
|
|
464
|
-
<SidebarActions sidebarPosition={sidebarPosition} navExpanded={navExpanded} />
|
|
465
|
-
)}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
</Box>
|
|
469
|
-
|
|
470
|
-
{navExpanded && navSize === 'large' && <Box
|
|
471
|
-
sx={{
|
|
472
|
-
display: 'flex',
|
|
473
|
-
alignItems: 'center',
|
|
474
|
-
|
|
475
|
-
flexDirection: 'column',
|
|
476
|
-
|
|
477
|
-
}}
|
|
478
|
-
|
|
479
|
-
>
|
|
480
|
-
|
|
481
|
-
<TenantAvatarComponent
|
|
482
|
-
navExpanded={navExpanded}
|
|
483
|
-
navSize={navSize}
|
|
484
|
-
|
|
485
|
-
imageUrl={isMediumScreen || sidebarPosition === "left" || sidebarPosition === "right" ? squaredLogo : horizontalLogo}
|
|
486
|
-
maxWidth={isHorizontal ? logoHorizontalMaxWidth : logoVerticalMaxWidth}
|
|
487
|
-
maxHeight={isHorizontal ? logoHorizontalMaxHeight : logoVerticalMaxHeight}
|
|
488
|
-
sidebarSmallWidth={sidebarSmallWidth}
|
|
489
|
-
alt="Tenant Logo"
|
|
490
|
-
sidebarPosition={sidebarPosition}
|
|
491
|
-
onClick={() => navigate('/')}
|
|
492
|
-
/>
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
</Box>}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
</Box>
|
|
500
|
-
|
|
501
|
-
{/* For horizontal mode (top/bottom), use a simple Box instead of Scrollbar
|
|
502
|
-
since react-custom-scrollbars creates nested divs that break flex layout */}
|
|
503
|
-
{(sidebarPosition === "top" || sidebarPosition === "bottom") ? (
|
|
504
|
-
<Box
|
|
505
|
-
className="dash-layout-sider-scrollbar horizontal-mode"
|
|
506
|
-
sx={{
|
|
507
|
-
display: 'flex',
|
|
508
|
-
flexDirection: 'row',
|
|
509
|
-
overflowX: 'auto',
|
|
510
|
-
overflowY: 'hidden',
|
|
511
|
-
flex: 1,
|
|
512
|
-
height: '100%',
|
|
513
|
-
alignItems: 'center',
|
|
514
|
-
}}
|
|
515
|
-
>
|
|
516
|
-
<GenerateItems items={items} navExpanded={navExpanded} navSize={navSize} level={0} sidebarPosition={sidebarPosition} translate={translate} />
|
|
517
|
-
</Box>
|
|
518
|
-
) : (
|
|
519
|
-
<Scrollbar
|
|
520
|
-
//autoHide={true}
|
|
521
|
-
//autoHideTimeout={1000}
|
|
522
|
-
//autoHideDuration={200}
|
|
523
|
-
className={'dash-layout-sider-scrollbar'}
|
|
524
|
-
>
|
|
525
|
-
<GenerateItems items={items} navExpanded={navExpanded} navSize={navSize} level={0} sidebarPosition={sidebarPosition} translate={translate} />
|
|
526
|
-
</Scrollbar>
|
|
527
|
-
)}
|
|
528
|
-
|
|
529
|
-
{(sidebarPosition === "top" || sidebarPosition === "bottom") && (
|
|
530
|
-
<SidebarActions sidebarPosition={sidebarPosition} navExpanded={navExpanded} />
|
|
531
|
-
)}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
</>
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
};
|
|
538
|
-
|
|
539
|
-
/*export default React.memo(
|
|
540
|
-
AppMaterialMenu,
|
|
541
|
-
(props, nextProps) =>
|
|
542
|
-
props === nextProps
|
|
543
|
-
) as typeof AppMaterialMenu;
|
|
544
|
-
*/
|
|
545
|
-
|
|
546
|
-
export default AppMaterialMenu;
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import React, { RefObject } from 'react';
|
|
2
|
-
import ReactDOM from 'react-dom';
|
|
3
|
-
import { SidebarPosition } from '../AppSidebarMaterial';
|
|
4
|
-
import { getSubmenuStyle, SUBMENU_SCROLL_THRESHOLD } from './submenuConstants';
|
|
5
|
-
|
|
6
|
-
export interface SubmenuPortalProps {
|
|
7
|
-
/** Whether the submenu is open */
|
|
8
|
-
open: boolean;
|
|
9
|
-
/** Reference to the parent menu item element for position calculation */
|
|
10
|
-
itemRef: RefObject<HTMLElement | null>;
|
|
11
|
-
/** Sidebar position affects where submenu opens relative to item */
|
|
12
|
-
sidebarPosition: SidebarPosition;
|
|
13
|
-
/** Submenu content to render */
|
|
14
|
-
children: React.ReactNode;
|
|
15
|
-
/** Mouse enter handler for hover behavior */
|
|
16
|
-
onMouseEnter?: () => void;
|
|
17
|
-
/** Mouse leave handler for hover behavior */
|
|
18
|
-
onMouseLeave?: () => void;
|
|
19
|
-
/** Number of children items (affects renderAtTop behavior) */
|
|
20
|
-
childrenCount?: number;
|
|
21
|
-
/** Additional CSS class */
|
|
22
|
-
className?: string;
|
|
23
|
-
/** Ref to the portaled root, so callers can include it in click-outside containment checks
|
|
24
|
-
* (the portal content is not a DOM descendant of itemRef, so itemRef alone isn't enough). */
|
|
25
|
-
contentRef?: RefObject<HTMLDivElement | null>;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Shared portal component for rendering submenus.
|
|
30
|
-
* Renders content in a portal attached to document.body with calculated position.
|
|
31
|
-
*/
|
|
32
|
-
const SubmenuPortal: React.FC<SubmenuPortalProps> = ({
|
|
33
|
-
open,
|
|
34
|
-
itemRef,
|
|
35
|
-
sidebarPosition,
|
|
36
|
-
children,
|
|
37
|
-
onMouseEnter,
|
|
38
|
-
onMouseLeave,
|
|
39
|
-
childrenCount = 0,
|
|
40
|
-
className = 'sidebar-submenu-portal',
|
|
41
|
-
contentRef,
|
|
42
|
-
}) => {
|
|
43
|
-
if (!open) return null;
|
|
44
|
-
|
|
45
|
-
const renderAtTop = childrenCount > SUBMENU_SCROLL_THRESHOLD;
|
|
46
|
-
|
|
47
|
-
return ReactDOM.createPortal(
|
|
48
|
-
<div
|
|
49
|
-
ref={contentRef}
|
|
50
|
-
className={className}
|
|
51
|
-
style={getSubmenuStyle(itemRef, sidebarPosition, renderAtTop)}
|
|
52
|
-
onMouseEnter={onMouseEnter}
|
|
53
|
-
onMouseLeave={onMouseLeave}
|
|
54
|
-
>
|
|
55
|
-
{children}
|
|
56
|
-
</div>,
|
|
57
|
-
document.body
|
|
58
|
-
);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export default SubmenuPortal;
|