@dashadmin/dash-admin 1.3.72 → 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,225 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { Box, IconButton, SxProps, Theme } from '@mui/material';
|
|
3
|
-
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
|
|
4
|
-
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
|
5
|
-
|
|
6
|
-
export interface IHorizontalScrollerProps {
|
|
7
|
-
children: React.ReactNode;
|
|
8
|
-
/** Pixels moved per arrow press. Default 240. */
|
|
9
|
-
step?: number;
|
|
10
|
-
/** Hide the arrows and rely on swipe/wheel alone. */
|
|
11
|
-
hideArrows?: boolean;
|
|
12
|
-
/** Width of the soft fade at each scrollable edge, in px. 0 disables it. */
|
|
13
|
-
fade?: number;
|
|
14
|
-
/** sx applied to the scrolling track (not the outer wrapper). */
|
|
15
|
-
trackSx?: SxProps<Theme>;
|
|
16
|
-
sx?: SxProps<Theme>;
|
|
17
|
-
className?: string;
|
|
18
|
-
ariaLabel?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* A horizontally scrollable strip with end-aware arrows, swipe and drag.
|
|
23
|
-
*
|
|
24
|
-
* Extracted from the pattern kt-tabs' CategorySelector already proved on the
|
|
25
|
-
* create-tab screen, so the dashboard shortcut strip behaves identically to the
|
|
26
|
-
* category carousel rather than inventing a second set of scrolling manners.
|
|
27
|
-
*
|
|
28
|
-
* Three input methods, deliberately, because they cover different users on the
|
|
29
|
-
* same screen: arrows for mouse users who expect affordances, touch drag for a
|
|
30
|
-
* tablet on the counter, and mouse drag for a trackpad. Native wheel/trackpad
|
|
31
|
-
* scrolling keeps working because the track is a real overflow container rather
|
|
32
|
-
* than a transform.
|
|
33
|
-
*
|
|
34
|
-
* The arrows disable at each end instead of disappearing: a control that
|
|
35
|
-
* vanishes shifts the layout under the pointer mid-interaction.
|
|
36
|
-
*/
|
|
37
|
-
export const HorizontalScroller: React.FC<IHorizontalScrollerProps> = ({
|
|
38
|
-
children,
|
|
39
|
-
step = 240,
|
|
40
|
-
hideArrows = false,
|
|
41
|
-
fade = 56,
|
|
42
|
-
trackSx,
|
|
43
|
-
sx,
|
|
44
|
-
className,
|
|
45
|
-
ariaLabel,
|
|
46
|
-
}) => {
|
|
47
|
-
const trackRef = useRef<HTMLDivElement>(null);
|
|
48
|
-
|
|
49
|
-
const [canScrollLeft, setCanScrollLeft] = useState(false);
|
|
50
|
-
const [canScrollRight, setCanScrollRight] = useState(false);
|
|
51
|
-
|
|
52
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
53
|
-
const dragStartX = useRef(0);
|
|
54
|
-
const scrollStartX = useRef(0);
|
|
55
|
-
|
|
56
|
-
const updateArrows = useCallback(() => {
|
|
57
|
-
const el = trackRef.current;
|
|
58
|
-
if (!el) return;
|
|
59
|
-
|
|
60
|
-
const { scrollLeft, scrollWidth, clientWidth } = el;
|
|
61
|
-
setCanScrollLeft(scrollLeft > 1);
|
|
62
|
-
// -1 for sub-pixel rounding: at the exact end these can differ by a
|
|
63
|
-
// fraction and leave the right arrow enabled forever.
|
|
64
|
-
setCanScrollRight(scrollLeft + clientWidth < scrollWidth - 1);
|
|
65
|
-
}, []);
|
|
66
|
-
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
const el = trackRef.current;
|
|
69
|
-
if (!el) return undefined;
|
|
70
|
-
|
|
71
|
-
el.addEventListener('scroll', updateArrows, { passive: true });
|
|
72
|
-
updateArrows();
|
|
73
|
-
|
|
74
|
-
// Content and container both change after mount — resources load, the
|
|
75
|
-
// panel is resized, the window changes. Without observing, the arrows
|
|
76
|
-
// report the state at first paint forever.
|
|
77
|
-
const observer = new ResizeObserver(updateArrows);
|
|
78
|
-
observer.observe(el);
|
|
79
|
-
Array.from(el.children).forEach((child) => observer.observe(child));
|
|
80
|
-
|
|
81
|
-
return () => {
|
|
82
|
-
el.removeEventListener('scroll', updateArrows);
|
|
83
|
-
observer.disconnect();
|
|
84
|
-
};
|
|
85
|
-
}, [updateArrows, children]);
|
|
86
|
-
|
|
87
|
-
const scrollBy = useCallback((direction: 'left' | 'right') => {
|
|
88
|
-
trackRef.current?.scrollBy({
|
|
89
|
-
left: direction === 'left' ? -step : step,
|
|
90
|
-
behavior: 'smooth',
|
|
91
|
-
});
|
|
92
|
-
}, [step]);
|
|
93
|
-
|
|
94
|
-
const onTouchStart = useCallback((e: React.TouchEvent) => {
|
|
95
|
-
dragStartX.current = e.touches[0].clientX;
|
|
96
|
-
scrollStartX.current = trackRef.current?.scrollLeft ?? 0;
|
|
97
|
-
}, []);
|
|
98
|
-
|
|
99
|
-
const onTouchMove = useCallback((e: React.TouchEvent) => {
|
|
100
|
-
const el = trackRef.current;
|
|
101
|
-
if (!el) return;
|
|
102
|
-
el.scrollLeft = scrollStartX.current + (dragStartX.current - e.touches[0].clientX);
|
|
103
|
-
}, []);
|
|
104
|
-
|
|
105
|
-
const onMouseDown = useCallback((e: React.MouseEvent) => {
|
|
106
|
-
setIsDragging(true);
|
|
107
|
-
dragStartX.current = e.clientX;
|
|
108
|
-
scrollStartX.current = trackRef.current?.scrollLeft ?? 0;
|
|
109
|
-
}, []);
|
|
110
|
-
|
|
111
|
-
const onMouseMove = useCallback((e: React.MouseEvent) => {
|
|
112
|
-
const el = trackRef.current;
|
|
113
|
-
if (!isDragging || !el) return;
|
|
114
|
-
// Without this, dragging across cards selects their labels instead.
|
|
115
|
-
e.preventDefault();
|
|
116
|
-
el.scrollLeft = scrollStartX.current + (dragStartX.current - e.clientX);
|
|
117
|
-
}, [isDragging]);
|
|
118
|
-
|
|
119
|
-
const endDrag = useCallback(() => {
|
|
120
|
-
setIsDragging(false);
|
|
121
|
-
updateArrows();
|
|
122
|
-
}, [updateArrows]);
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Arrows sit ON the strip rather than beside it.
|
|
126
|
-
*
|
|
127
|
-
* As flex siblings they stole ~80px of width from the track on every
|
|
128
|
-
* screen, including the ones with nothing to scroll. Overlaying them means
|
|
129
|
-
* the cards use the full width, and the arrow only appears where there is
|
|
130
|
-
* something in that direction — so it reads as an affordance rather than
|
|
131
|
-
* permanent chrome.
|
|
132
|
-
*/
|
|
133
|
-
const arrowSx = (side: 'left' | 'right', enabled: boolean) => ({
|
|
134
|
-
position: 'absolute' as const,
|
|
135
|
-
top: '50%',
|
|
136
|
-
transform: 'translateY(-50%)',
|
|
137
|
-
[side]: 4,
|
|
138
|
-
zIndex: 2,
|
|
139
|
-
// Hidden, not just dimmed, at the end of its travel — an overlay
|
|
140
|
-
// control that cannot do anything is only covering a card.
|
|
141
|
-
opacity: enabled ? 1 : 0,
|
|
142
|
-
pointerEvents: enabled ? ('auto' as const) : ('none' as const),
|
|
143
|
-
transition: 'opacity 0.2s ease',
|
|
144
|
-
bgcolor: 'background.paper',
|
|
145
|
-
boxShadow: 2,
|
|
146
|
-
'&:hover': { bgcolor: 'background.paper' },
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Fade the content itself at any edge that can still scroll.
|
|
151
|
-
*
|
|
152
|
-
* A mask rather than a gradient overlay: an overlay has to match whatever
|
|
153
|
-
* is behind the strip, and this sits on a themed gradient background where
|
|
154
|
-
* no single colour would. Masking makes the cards themselves go
|
|
155
|
-
* transparent, so it is correct on any backdrop and in either theme.
|
|
156
|
-
*/
|
|
157
|
-
const maskImage = fade > 0 && (canScrollLeft || canScrollRight)
|
|
158
|
-
? `linear-gradient(to right, ${
|
|
159
|
-
canScrollLeft ? `transparent 0, #000 ${fade}px` : '#000 0'
|
|
160
|
-
}, ${
|
|
161
|
-
canScrollRight ? `#000 calc(100% - ${fade}px), transparent 100%` : '#000 100%'
|
|
162
|
-
})`
|
|
163
|
-
: undefined;
|
|
164
|
-
|
|
165
|
-
return (
|
|
166
|
-
<Box className={className} sx={{ position: 'relative', minWidth: 0, ...sx }}>
|
|
167
|
-
{!hideArrows && (
|
|
168
|
-
<IconButton
|
|
169
|
-
size="small"
|
|
170
|
-
aria-label="scroll left"
|
|
171
|
-
disabled={!canScrollLeft}
|
|
172
|
-
onClick={() => scrollBy('left')}
|
|
173
|
-
sx={arrowSx('left', canScrollLeft)}
|
|
174
|
-
>
|
|
175
|
-
<ChevronLeftIcon />
|
|
176
|
-
</IconButton>
|
|
177
|
-
)}
|
|
178
|
-
|
|
179
|
-
<Box
|
|
180
|
-
ref={trackRef}
|
|
181
|
-
role="group"
|
|
182
|
-
aria-label={ariaLabel}
|
|
183
|
-
onTouchStart={onTouchStart}
|
|
184
|
-
onTouchMove={onTouchMove}
|
|
185
|
-
onTouchEnd={endDrag}
|
|
186
|
-
onMouseDown={onMouseDown}
|
|
187
|
-
onMouseMove={onMouseMove}
|
|
188
|
-
onMouseUp={endDrag}
|
|
189
|
-
onMouseLeave={endDrag}
|
|
190
|
-
sx={{
|
|
191
|
-
minWidth: 0,
|
|
192
|
-
overflowX: 'auto',
|
|
193
|
-
...(maskImage ? { maskImage, WebkitMaskImage: maskImage } : {}),
|
|
194
|
-
overflowY: 'hidden',
|
|
195
|
-
scrollBehavior: 'smooth',
|
|
196
|
-
WebkitOverflowScrolling: 'touch',
|
|
197
|
-
cursor: isDragging ? 'grabbing' : 'grab',
|
|
198
|
-
userSelect: isDragging ? 'none' : 'auto',
|
|
199
|
-
// Hidden: the fade and the arrows already say "there is
|
|
200
|
-
// more", and a bar under a masked edge looks like a
|
|
201
|
-
// rendering artefact.
|
|
202
|
-
scrollbarWidth: 'none',
|
|
203
|
-
'&::-webkit-scrollbar': { display: 'none' },
|
|
204
|
-
...trackSx,
|
|
205
|
-
}}
|
|
206
|
-
>
|
|
207
|
-
{children}
|
|
208
|
-
</Box>
|
|
209
|
-
|
|
210
|
-
{!hideArrows && (
|
|
211
|
-
<IconButton
|
|
212
|
-
size="small"
|
|
213
|
-
aria-label="scroll right"
|
|
214
|
-
disabled={!canScrollRight}
|
|
215
|
-
onClick={() => scrollBy('right')}
|
|
216
|
-
sx={arrowSx('right', canScrollRight)}
|
|
217
|
-
>
|
|
218
|
-
<ChevronRightIcon />
|
|
219
|
-
</IconButton>
|
|
220
|
-
)}
|
|
221
|
-
</Box>
|
|
222
|
-
);
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
export default HorizontalScroller;
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { MouseEvent, useState, useRef, useEffect } from 'react';
|
|
3
|
-
import { useLocaleState, useLocales } from 'react-admin';
|
|
4
|
-
import { Avatar, useMediaQuery, useTheme } from '@mui/material';
|
|
5
|
-
import LanguageIcon from '@mui/icons-material/Translate';
|
|
6
|
-
import ReactDOM from 'react-dom';
|
|
7
|
-
import { useWindowSize } from 'dash-utils';
|
|
8
|
-
const DefaultIcon = <LanguageIcon />;
|
|
9
|
-
|
|
10
|
-
export interface LanguageSwitcherButtonProps {
|
|
11
|
-
icon?: React.ReactNode;
|
|
12
|
-
languages?: { locale: string; name: string }[];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const LanguageSwitcher = (props: LanguageSwitcherButtonProps) => {
|
|
16
|
-
const { icon = DefaultIcon, languages: languagesProp } = props;
|
|
17
|
-
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
|
18
|
-
const languages = useLocales({ locales: languagesProp });
|
|
19
|
-
const [locale, setLocale] = useLocaleState();
|
|
20
|
-
|
|
21
|
-
const theme = useTheme();
|
|
22
|
-
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
|
|
23
|
-
const [webView, setWebView] = useState<boolean>(false);
|
|
24
|
-
const [open, setOpen] = useState(false);
|
|
25
|
-
const avatarRef = useRef<HTMLDivElement>(null);
|
|
26
|
-
const menuRef = useRef<HTMLDivElement>(null);
|
|
27
|
-
const [menuPosition, setMenuPosition] = useState({ top: 0, left: 0 });
|
|
28
|
-
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
29
|
-
|
|
30
|
-
const windowSize = useWindowSize();
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
if(document.body.classList.contains('webview')) {
|
|
33
|
-
setWebView(true)
|
|
34
|
-
} else {
|
|
35
|
-
setWebView(false)
|
|
36
|
-
}
|
|
37
|
-
}, []);
|
|
38
|
-
|
|
39
|
-
const getNameForLocale = (locale: string): string => {
|
|
40
|
-
const language = languages.find(language => language.locale === locale);
|
|
41
|
-
return language ? language.name : '';
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const changeLocale = (locale: string) => (): void => {
|
|
45
|
-
setLocale(locale);
|
|
46
|
-
setOpen(false);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const calculateMenuPosition = () => {
|
|
50
|
-
if (avatarRef.current && windowSize.width) {
|
|
51
|
-
const rect = avatarRef.current.getBoundingClientRect();
|
|
52
|
-
const menuWidth = 200; // minWidth from styles
|
|
53
|
-
|
|
54
|
-
let left = rect.left + window.scrollX;
|
|
55
|
-
|
|
56
|
-
// Ensure menu doesn't go off-screen using windowSize
|
|
57
|
-
if (left + menuWidth > windowSize.width) {
|
|
58
|
-
left = windowSize.width - menuWidth - 10; // 10px margin
|
|
59
|
-
}
|
|
60
|
-
if (left < 10) {
|
|
61
|
-
left = 10; // 10px margin
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
setMenuPosition({
|
|
65
|
-
top: rect.top + window.scrollY + 30,
|
|
66
|
-
left: left
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const handleLanguageMouseEnter = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
72
|
-
e.preventDefault();
|
|
73
|
-
|
|
74
|
-
// Clear any existing timeout
|
|
75
|
-
if (timeoutRef.current) {
|
|
76
|
-
clearTimeout(timeoutRef.current);
|
|
77
|
-
timeoutRef.current = null;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
setOpen(true);
|
|
81
|
-
calculateMenuPosition();
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const handleLanguageClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
85
|
-
e.preventDefault();
|
|
86
|
-
setOpen(prevOpen => !prevOpen);
|
|
87
|
-
calculateMenuPosition();
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const handleMouseLeave = () => {
|
|
91
|
-
if (!webView) {
|
|
92
|
-
// Add a small delay before closing to allow moving to menu
|
|
93
|
-
timeoutRef.current = setTimeout(() => {
|
|
94
|
-
setOpen(false);
|
|
95
|
-
}, 100);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const handleMenuMouseEnter = () => {
|
|
100
|
-
// Clear timeout when entering menu
|
|
101
|
-
if (timeoutRef.current) {
|
|
102
|
-
clearTimeout(timeoutRef.current);
|
|
103
|
-
timeoutRef.current = null;
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
const handleMenuMouseLeave = () => {
|
|
108
|
-
if (!webView) {
|
|
109
|
-
setOpen(false);
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
// Cleanup timeout on unmount
|
|
114
|
-
useEffect(() => {
|
|
115
|
-
return () => {
|
|
116
|
-
if (timeoutRef.current) {
|
|
117
|
-
clearTimeout(timeoutRef.current);
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
}, []);
|
|
121
|
-
|
|
122
|
-
// Recalculate position on screen resize
|
|
123
|
-
useEffect(() => {
|
|
124
|
-
const handleResize = () => {
|
|
125
|
-
if (open) {
|
|
126
|
-
calculateMenuPosition();
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
window.addEventListener('resize', handleResize);
|
|
131
|
-
return () => window.removeEventListener('resize', handleResize);
|
|
132
|
-
}, [open, isSmallScreen]);
|
|
133
|
-
|
|
134
|
-
return (
|
|
135
|
-
<>
|
|
136
|
-
<div
|
|
137
|
-
ref={avatarRef}
|
|
138
|
-
|
|
139
|
-
{... !webView ? {
|
|
140
|
-
onMouseEnter: handleLanguageMouseEnter,
|
|
141
|
-
onMouseLeave: handleMouseLeave
|
|
142
|
-
} : {
|
|
143
|
-
onClick: handleLanguageClick
|
|
144
|
-
}}
|
|
145
|
-
>
|
|
146
|
-
<Avatar
|
|
147
|
-
sizes='small'
|
|
148
|
-
sx={{ fontSize: '1rem' }}
|
|
149
|
-
style={{
|
|
150
|
-
width: '30px',
|
|
151
|
-
height: '30px',
|
|
152
|
-
minHeight: '30px'
|
|
153
|
-
}}
|
|
154
|
-
className='dash-icon-button-color dash-icon-button-bg'
|
|
155
|
-
>
|
|
156
|
-
{getNameForLocale(locale).substring(0, 2).toUpperCase()}
|
|
157
|
-
</Avatar>
|
|
158
|
-
</div>
|
|
159
|
-
|
|
160
|
-
{open && ReactDOM.createPortal(
|
|
161
|
-
<div
|
|
162
|
-
ref={menuRef}
|
|
163
|
-
className="dash-language-menu-portal"
|
|
164
|
-
onMouseEnter={!webView ? handleMenuMouseEnter : undefined}
|
|
165
|
-
onMouseLeave={!webView ? handleMenuMouseLeave : undefined}
|
|
166
|
-
>
|
|
167
|
-
<div
|
|
168
|
-
className={`dash-language-menu ${open ? 'show' : ''}`}
|
|
169
|
-
style={{
|
|
170
|
-
zIndex: 10000,
|
|
171
|
-
position: 'absolute',
|
|
172
|
-
top: menuPosition.top,
|
|
173
|
-
left: menuPosition.left,
|
|
174
|
-
}}
|
|
175
|
-
>
|
|
176
|
-
{languages.map(language => (
|
|
177
|
-
<div
|
|
178
|
-
key={language.locale}
|
|
179
|
-
className={`dash-language-menu-item ${language.locale === locale ? 'selected' : ''}`}
|
|
180
|
-
onClick={changeLocale(language.locale)}
|
|
181
|
-
style={{
|
|
182
|
-
padding: '8px 16px',
|
|
183
|
-
cursor: 'pointer',
|
|
184
|
-
backgroundColor: language.locale === locale ? 'rgba(0, 0, 0, 0.08)' : 'transparent',
|
|
185
|
-
minWidth: '150px'
|
|
186
|
-
}}
|
|
187
|
-
>
|
|
188
|
-
{language.name}
|
|
189
|
-
</div>
|
|
190
|
-
))}
|
|
191
|
-
</div>
|
|
192
|
-
</div>,
|
|
193
|
-
document.body
|
|
194
|
-
)}
|
|
195
|
-
</>
|
|
196
|
-
);
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
export default LanguageSwitcher;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { styled } from '@mui/material/styles';
|
|
2
|
-
import Tooltip, { TooltipProps, tooltipClasses } from '@mui/material/Tooltip';
|
|
3
|
-
|
|
4
|
-
const MUIHtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
|
|
5
|
-
<Tooltip {...props} classes={{ popper: className }} />
|
|
6
|
-
))(({ theme }) => ({
|
|
7
|
-
[`& .${tooltipClasses.tooltip}`]: {
|
|
8
|
-
backgroundColor: '#f5f5f9',
|
|
9
|
-
color: 'rgba(0, 0, 0, 0.87)',
|
|
10
|
-
maxWidth: 220,
|
|
11
|
-
fontSize: theme.typography.pxToRem(12),
|
|
12
|
-
border: '1px solid #dadde9',
|
|
13
|
-
},
|
|
14
|
-
}));
|
|
15
|
-
export default MUIHtmlTooltip;
|