@dashadmin/dash-admin 1.3.17 → 1.3.20
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/AppAsyncWrapper.js +1 -0
- package/dist/AppWrapper.js +1 -0
- package/dist/DASHAdmin.js +1 -0
- package/dist/DASHAdmin.tsx.old +456 -0
- package/dist/RoutingWrapper.js +1 -0
- package/dist/classes/DASHStorageClass.js +1 -0
- package/dist/components/Input/RichTextField.js +1 -0
- package/dist/components/Redirect.js +1 -0
- package/dist/components/avatar/Avatar.js +1 -0
- package/dist/components/avatar/SingleImageUploader.js +1 -0
- package/dist/components/currency/Format.js +1 -0
- package/dist/components/custom/Redirect.js +1 -0
- package/dist/components/error/Error.js +1 -0
- package/dist/components/geocoding/GeocodingField.js +1 -0
- package/dist/components/i18n/BridgedLocalesMenuButton.js +1 -0
- package/dist/components/i18n/LangSwitcher.js +1 -0
- package/dist/components/loader/GlobalLoader.js +1 -0
- package/dist/components/logs/LogFile.js +1 -0
- package/dist/components/logs/LogFileById.js +1 -0
- package/dist/components/logs/LogViewer.js +1 -0
- package/dist/components/menu/AppMenu.js +1 -0
- package/dist/components/menu/CustomMenuItemLink.js +1 -0
- package/dist/components/menu/DarkToggleMode.js +1 -0
- package/dist/components/menu/LanguageToggleMode.js +1 -0
- package/dist/components/misc/CustomImageInput.js +1 -0
- package/dist/components/misc/DASHGlobalErrorHandler.js +1 -0
- package/dist/components/misc/DarkModeSwitcher.js +1 -0
- package/dist/components/misc/LanguageSwitcher.js +1 -0
- package/dist/components/misc/MUIHtmlToolTip.js +1 -0
- package/dist/components/misc/MuiSimpleJsonTable.js +1 -0
- package/dist/components/misc/MultiLevelTable.js +1 -0
- package/dist/components/misc/NoResults.js +1 -0
- package/dist/components/misc/PDFViewer.js +1 -0
- package/dist/components/navigation/Breadcrumbs.js +1 -0
- package/dist/components/navigation/BreadcrumbsManager.js +1 -0
- package/dist/components/navigation/index.js +1 -0
- package/dist/components/panel/Error.js +1 -0
- package/dist/components/permission/AvailablePermissionsContext.js +1 -0
- package/dist/components/permission/PermissionsSelector.js +1 -0
- package/dist/components/permission/PermissionsSelectorList.js +1 -0
- package/dist/components/permission/tsx +0 -0
- package/dist/components/racustombuttons/CustomRAButton.js +1 -0
- package/dist/components/racustombuttons/QuickButton.js +1 -0
- package/dist/components/racustombuttons/QuickEditButton.js +1 -0
- package/dist/components/racustombuttons/QuickIconButton.js +1 -0
- package/dist/components/scrollbar/Scrollbar.js +1 -0
- package/dist/components/selects/MultiSelect.js +1 -0
- package/dist/components/selects/RASearchableSelect.js +1 -0
- package/dist/components/selects/RASearchableSelectChips.js +1 -0
- package/dist/components/selects/SearchableSelect.js +1 -0
- package/dist/components/subscription/BillingCycleSelectInput.js +1 -0
- package/dist/components/subscription/PlanAddonsSettings.js +1 -0
- package/dist/components/subscription/PlanAuditLog.js +1 -0
- package/dist/components/subscription/PlanFeaturesSettings.js +1 -0
- package/dist/components/subscription/PlanLimitsSettings.js +1 -0
- package/dist/components/subscription/PlanMetadataSettings.js +1 -0
- package/dist/components/subscription/PlanPricesSettings.js +1 -0
- package/dist/components/subscription/index.js +1 -0
- package/dist/components/svgelements/SvgLoading.js +1 -0
- package/dist/components/svgelements/SvgLogo.js +1 -0
- package/dist/components/svgelements/SvgLogoMin.js +1 -0
- package/dist/components/svgelements/SvgShipping.js +1 -0
- package/dist/components/tenant/AvailablePermissionsContext.js +0 -0
- package/dist/components/tenant/TenantAttributes.js +1 -0
- package/dist/components/tenant/TenantAttributesContext.js +1 -0
- package/dist/components/tenant/TenantSelector.js +1 -0
- package/dist/components/tenant/TenantSettings.js +1 -0
- package/dist/components/tenant/TenantSettingsContext.js +1 -0
- package/dist/components/tenant/TenantTheme.js +1 -0
- package/dist/components/user/AvatarComponent.js +1 -0
- package/dist/components/user/TenantAvatarComponent.js +1 -0
- package/dist/components/user/UserPreferences.js +1 -0
- package/dist/config/ACTIONS.js +1 -0
- package/dist/config/ConstantsService.js +1 -0
- package/dist/config/DASHAdminSystemConstants.js +1 -0
- package/dist/config/PARSERS.js +1 -0
- package/dist/contexts/DashQueryClientContext.js +1 -0
- package/dist/contexts/DashResourceContext.js +1 -0
- package/dist/contexts/I18nBridgeContext.js +1 -0
- package/dist/contexts/I18nBridgeSetter.js +1 -0
- package/dist/contexts/I18nReduxSync.js +1 -0
- package/dist/contexts/SubscriptionPlanFormatsProvider.js +1 -0
- package/dist/contexts/SystemRequestsCache.js +1 -0
- package/dist/contexts/auth/AuthContext.js +1 -0
- package/dist/contexts/auth/AuthContextLocalStorage.js +1 -0
- package/dist/contexts/auth/DASHAuthenticationService.js +1 -0
- package/dist/contexts/auth/WindowContext.js +1 -0
- package/dist/contexts/auth/index.js +1 -0
- package/dist/contexts/com/FCMContext.js +1 -0
- package/dist/contexts/com/LaravelEchoContext.js +1 -0
- package/dist/contexts/com/LaravelEchoMgr.js +1 -0
- package/dist/contexts/com/components/DefaultNotificationComponent.js +1 -0
- package/dist/contexts/com/components/NotificationAttributesTable.js +1 -0
- package/dist/contexts/com/components/NotificationRenderer.js +1 -0
- package/dist/contexts/com/components/NotificationsWidget.js +1 -0
- package/dist/contexts/com/components/notificationFormats.js +1 -0
- package/dist/contexts/com/useLaravelEcho.js +1 -0
- package/dist/contexts/dictionary/DictionaryContext.js +1 -0
- package/dist/declarations.d.ts +17 -0
- package/dist/default-theme/DASHAppProviders.js +1 -0
- package/dist/default-theme/DashThemeContext.js +1 -0
- package/dist/default-theme/DashThemeContext.tsx.fast +143 -0
- package/dist/default-theme/DashThemeContext.tsx.old +306 -0
- package/dist/default-theme/DashThemeHelperProvider.js +1 -0
- package/dist/default-theme/DomainAppLayout.js +1 -0
- package/dist/default-theme/DomainHeader.js +1 -0
- package/dist/default-theme/DomainTheme.js +1 -0
- package/dist/default-theme/FullLayoutMarkup.js +1 -0
- package/dist/default-theme/StaticLayout.js +1 -0
- package/dist/default-theme/index.js +1 -0
- package/dist/default-theme/menu/AppMaterialMenu.js +1 -0
- package/dist/default-theme/menu/AppMenuComponents/SubmenuPortal.js +1 -0
- package/dist/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItem.js +1 -0
- package/dist/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItems.js +1 -0
- package/dist/default-theme/menu/AppMenuComponents/expanded/CollapsableSidebarMenu.js +1 -0
- package/dist/default-theme/menu/AppMenuComponents/expanded/SidebarItem.js +1 -0
- package/dist/default-theme/menu/AppMenuComponents/getItem.js +1 -0
- package/dist/default-theme/menu/AppMenuComponents/interfaces.js +0 -0
- package/dist/default-theme/menu/AppMenuComponents/submenuConstants.js +1 -0
- package/dist/default-theme/menu/AppSidebarMaterial.js +1 -0
- package/dist/default-theme/menu/SidebarActions.js +1 -0
- package/dist/default-theme/updateDomCssVariables.js +1 -0
- package/dist/helpers/checkRole.js +1 -0
- package/dist/helpers/parseAxiosError.js +2 -0
- package/dist/hooks/audio/useAudio.js +1 -0
- package/dist/hooks/axios.js +1 -0
- package/dist/hooks/data/useDashboardStats.js +1 -0
- package/dist/hooks/data/usePackageByClientsStats.js +1 -0
- package/dist/hooks/data/usePackageByCommunesStats.js +1 -0
- package/dist/hooks/data/usePackageStats.js +1 -0
- package/dist/hooks/data/usePackageWithdrawDetails.js +1 -0
- package/dist/hooks/data/useStats.js +1 -0
- package/dist/hooks/isCurrentPath.js +1 -0
- package/dist/hooks/notifications/WSMessagesManager.js +1 -0
- package/dist/hooks/notifications/WSPusherManager.js +1 -0
- package/dist/hooks/useBreadcrumbs.js +1 -0
- package/dist/hooks/useClickOutside.js +1 -0
- package/dist/hooks/useFormPersistance.js +1 -0
- package/dist/hooks/useGlobalErrorMediator.js +1 -0
- package/dist/hooks/useGlobalLoaderMgr.js +1 -0
- package/dist/hooks/useHash.js +1 -0
- package/dist/hooks/useLocalStorage.js +1 -0
- package/dist/hooks/usePolyglotTranslation.js +1 -0
- package/dist/hooks/usePrevious.js +1 -0
- package/dist/hooks/usePrintSelected.js +1 -0
- package/dist/hooks/useVirtualHash.js +1 -0
- package/dist/hooks/window/useWindowSize.js +1 -0
- package/dist/interfaces/IAppResourceConfig.js +0 -0
- package/dist/interfaces/Log.js +0 -0
- package/dist/interfaces/Tenant.js +0 -0
- package/dist/interfaces/communication/IActions.js +0 -0
- package/dist/interfaces/communication/INotification.js +0 -0
- package/dist/interfaces/communication/IPayload.js +0 -0
- package/dist/interfaces/communication/IRequestAction.js +0 -0
- package/dist/interfaces/communication/IRequestPayload.js +0 -0
- package/dist/interfaces/communication/IResponseAction.js +0 -0
- package/dist/interfaces/misc/IAny.js +0 -0
- package/dist/interfaces/misc/IFlashMessage.js +0 -0
- package/dist/interfaces/navigation/IAppMenu.js +0 -0
- package/dist/interfaces/navigation/ICollapsableSidebarMenu.js +0 -0
- package/dist/interfaces/navigation/IMenuItem.js +0 -0
- package/dist/interfaces/notifications/IModel.js +0 -0
- package/dist/interfaces/notifications/IModelField.js +0 -0
- package/dist/interfaces/notifications/IUserNotification.js +0 -0
- package/dist/interfaces/notifications/IUserNotificationData.js +0 -0
- package/dist/interfaces/notifications/IUserNotificationPayload.js +0 -0
- package/dist/interfaces/user/IGetAuth.js +0 -0
- package/dist/interfaces/user/ITenantSettings.js +0 -0
- package/dist/interfaces/user/IUser.js +0 -0
- package/dist/interfaces/user/IUserSettings.js +0 -0
- package/dist/interfaces.js +1 -0
- package/dist/layout/AppLayout.js +1 -0
- package/dist/layout/ApplicationLayout.js +1 -0
- package/dist/layout/MotionWrapper.js +1 -0
- package/dist/layout/MotionWrapper.original.js +1 -0
- package/dist/layout/ResourceMenu.js +1 -0
- package/dist/layout/ResoureLayout.js +1 -0
- package/dist/layout/TransitionWrapper.js +24 -0
- package/dist/pages/ChangePassword.js +1 -0
- package/dist/pages/DASHLanding.js +1 -0
- package/dist/pages/DASHLightWeightLogin.js +1 -0
- package/dist/pages/DASHSimpleLogin.js +1 -0
- package/dist/pages/Login.js +1 -0
- package/dist/pages/Profile.js +1 -0
- package/dist/pages/RecoverPassword.js +1 -0
- package/dist/pages/SingleImageUploader.js +1 -0
- package/dist/pages/VerifyAccount.js +1 -0
- package/dist/providers/authProvider.js +1 -0
- package/dist/providers/dataProvider.js +1 -0
- package/dist/providers/i18n/en.js +1 -0
- package/dist/providers/i18n/es.js +1 -0
- package/dist/providers/i18n/languages.js +1 -0
- package/dist/providers/i18nProvider.js +1 -0
- package/dist/react-admin-dash/RADashComponent.js +1 -0
- package/dist/react-admin-dash/Resource.js +1 -0
- package/dist/resources/Brand/BrandResource.js +1 -0
- package/dist/resources/DASHResourceLoader.js +1 -0
- package/dist/resources/Log/LogResource.js +1 -0
- package/dist/resources/Tenant/ImpersonateTenantResource.js +1 -0
- package/dist/resources/Trash/TrashTemplate.js +1 -0
- package/dist/resources.js +1 -0
- package/dist/schemas/log.js +1 -0
- package/dist/schemas/notification.js +1 -0
- package/dist/schemas/permissions.js +1 -0
- package/dist/schemas/roles.js +1 -0
- package/dist/schemas/rolesDataGrid.js +1 -0
- package/dist/schemas/subscription/components/SubscriptionActions.js +1 -0
- package/dist/schemas/subscription/components/SubscriptionPaymentHistory.js +1 -0
- package/dist/schemas/subscription/components/SubscriptionPlanFeatures.js +1 -0
- package/dist/schemas/subscription/components/SubscriptionPlanPreview.js +1 -0
- package/dist/schemas/subscription/components/SubscriptionPlanStats.js +1 -0
- package/dist/schemas/subscription/components/SubscriptionStatusIndicator.js +1 -0
- package/dist/schemas/subscription/subscriptionPlanSchema.js +1 -0
- package/dist/schemas/subscription/subscriptionSchema.js +1 -0
- package/dist/schemas/subscriptionPlan.js +1 -0
- package/dist/schemas/tenant.js +1 -0
- package/dist/schemas/tenantUser.js +1 -0
- package/dist/schemas/tenant_superadmin.js +1 -0
- package/dist/schemas/user.js +1 -0
- package/dist/systemResources.js +1 -0
- package/dist/systemResources.old.js +1 -0
- package/dist/templates/ResourceTemplate.js +1 -0
- package/dist/templates/ResourceTemplate.tsx.memoized_experiment +350 -0
- package/dist/templates/ResourceTemplate.tsx.original +396 -0
- package/dist/templates/ResourceTemplateCreate.js +1 -0
- package/dist/templates/ResourceTemplateEdit.js +1 -0
- package/dist/templates/ResourceTemplateFull.js +1 -0
- package/dist/templates/ResourceTemplateList.js +1 -0
- package/dist/templates/ResourceTemplateOld.tsx.bkup +567 -0
- package/dist/templates/ResourceTemplateShow.js +1 -0
- package/dist/templates/TrashTemplate.js +1 -0
- package/dist/tenantResources.js +1 -0
- package/dist/test_portal_bubbles.js +1 -0
- package/dist/theme/AppHeader.js +1 -0
- package/dist/theme/AppLayoutSetting.js +1 -0
- package/dist/theme/AppLogo.js +1 -0
- package/dist/theme/AppSidebar.js +1 -0
- package/dist/theme/AppSidebarContent.js +1 -0
- package/dist/theme/AppSidebarLogo.js +1 -0
- package/dist/theme/components/PageTitle.js +1 -0
- package/dist/utils/cache/CacheInvalidatorContext.js +1 -0
- package/dist/utils/cache/CacheInvalidatorListenerComponent.js +1 -0
- package/dist/utils/cache/useCacheInvalidatorListener.js +1 -0
- package/dist/utils/convertFileToBase64.js +1 -0
- package/dist/utils/convertToFile.js +1 -0
- package/dist/utils/cookies.js +1 -0
- package/dist/utils/dashDefaultQueryClient.js +1 -0
- package/dist/utils/dataUrlToBlob.js +1 -0
- package/dist/utils/deepReplace.js +1 -0
- package/dist/utils/getProfileMenu.js +1 -0
- package/dist/utils/getTenantSettings.js +1 -0
- package/dist/utils/getType.js +1 -0
- package/dist/utils/getUserSettings.js +1 -0
- package/dist/utils/hasCode.js +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/injectTenantStyles.js +1 -0
- package/dist/utils/isComponent.js +1 -0
- package/dist/utils/navEvents.js +1 -0
- package/dist/utils/prototypes.js +1 -0
- package/dist/utils/regexp.js +1 -0
- package/dist/utils/resolveObjectPath.js +1 -0
- package/dist/utils/setNativeValue.js +1 -0
- package/dist/utils/slugify.js +1 -0
- package/dist/utils/validators/emailValidator.js +1 -0
- package/dist/utils/validators/requiredValidator.js +1 -0
- package/dist/utils/validators/rutValidator.js +1 -0
- package/dist/utils/validators.js +1 -0
- package/package.json +13 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var z=Object.defineProperty;var D=(r,i,e)=>i in r?z(r,i,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[i]=e;var b=(r,i,e)=>D(r,typeof i!="symbol"?i+"":i,e);import{jsx as Q}from"react/jsx-runtime";import{useDispatch as J,useSelector as M}from"react-redux";import g,{useCallback as l,useContext as K,useRef as m}from"react";import{DASH_REDUX_ACTIONS as h}from"@dashadmin/dash-admin-state";import{ACTION_UPDATE_AUTH as A}from"@dashadmin/dash-admin-state/src/redux/reducers/Auth";import q from"../../hooks/axios";import{getEnv as G}from"@dashadmin/dash-constants/src/DASHAdminSystemConstants";import{useDashThemeContext as $}from"../../../src/default-theme/DashThemeContext";import f from"../../theme/AppLayoutSetting";import B from"./DASHAuthenticationService";import{AuthPersistenceService as o,clearDeviceStoreAuth as W}from"@dashadmin/dash-auth";import{dashStorage as I}from"@dashadmin/dash-utils";class X{}b(X,"values");const S=g.createContext(null),vt=r=>{const{children:i}=r,e=M(t=>t.auth),u=J(),{axios:C}=q(),{recreateTheme:F}=$(),v=m(!1),T=m(""),V=m(""),E=m(""),k=m(""),Z=m(!1),[n,p]=g.useState(()=>{const t=o.getUser(),s=o.getToken(),a=o.getSystemValues(),c=JSON.parse(I.getItem("authenticated")||"false");return{authenticated:e.authenticated||c,user:e.user||t,auth:e.auth,token:e.user?.token||s,roles:e.user?.roles,systemValues:a}}),d=l(async()=>{console.log("Making GET request to:",G("APP_GETAUTH_ENDPOINT"));try{const{data:t}=await C.get(G("APP_GETAUTH_ENDPOINT"));return console.log("Received complete auth data:",t),o.saveAuth({auth:t.auth,systemValues:t.systemValues}),u(h.updateAuth(A,{user:t.user,authenticated:!0,auth:t.auth})),p(s=>({...s,systemValues:t.systemValues})),t}catch(t){throw console.error("Error fetching complete auth data:",t),o.markAsLoggedOut(),t}},[C,u]),tt=l(async()=>{const t=o.getToken(),s=o.getUser(),a=JSON.parse(I.getItem("authenticated")||"false");if(console.log("Initializing auth from token:",{hasToken:!!t,hasStoredUser:!!s,isAuthenticated:a,reduxAuthenticated:e.authenticated}),t&&!e.authenticated)try{console.log("Token found but not fully authenticated, fetching complete auth data..."),await d()}catch(c){console.error("Failed to initialize auth from token:",c),o.markAsLoggedOut()}else if(a&&s&&t&&!e.authenticated){console.log("Restoring auth session from localStorage");const c=o.getAuth();u(h.updateAuth(A,{user:s,authenticated:!0,auth:c?.auth||null}))}},[e.authenticated,u,d]),_=l(async t=>{if(!t||e.authenticated||v.current)return;const s=JSON.stringify(t);if(T.current!==s){v.current=!0,T.current=s,console.log("Handling react-admin identity:",t);try{u(h.updateAuth(A,{user:t.user||t,authenticated:t?.user?!0:!!t?.id,auth:t.auth})),await d()}catch{console.error("Failed to fetch complete auth data after identity load")}finally{v.current=!1}}},[e.authenticated,u,d]),U=async t=>{o.markAsLoggedOut(),await W(),B.setPendingRedirect(window.location.pathname),p({authenticated:!1,user:null,auth:null,token:null,roles:null,systemValues:null}),u(h.updateAuth(A,{user:null,authenticated:!1,auth:null})),j({authenticated:!1,user:null,auth:null,token:null,roles:null,systemValues:null}),document.body.classList.remove(f.LAYOUT_TYPE_FULL,f.LAYOUT_TYPE_BOXED,f.LAYOUT_TYPE_FRAMED,f.THEME_TYPE_DARK,f.THEME_TYPE_LIGHT),t&&t()},O=l(t=>{if(t&&(console.log("\u{1F504} AuthContext: Updating auth context with:",t),p(s=>{const a={...s,...t};return console.log("\u2705 AuthContext: Local context updated:",a),a}),(t.authenticated!==void 0||t.user||t.auth)&&t.authenticated!==!1)){console.log("\u{1F504} AuthContext: Dispatching to Redux state...");const s={user:t.user||e.user,authenticated:t.authenticated??e.authenticated,auth:t.auth||e.auth};console.log("\u{1F504} AuthContext: Redux payload:",s),u(h.updateAuth(A,s)),console.log("\u2705 AuthContext: Redux dispatch completed")}},[u,e.user,e.authenticated,e.auth]),R=l(t=>{console.log("Manual update values called with:",t),p(s=>({...s,...t}))},[]),w=l(()=>{try{if(n.roles==="guest")return Promise.resolve("guest");if(n.roles&&Array.isArray(n.roles)){const t={roles:n.roles.map(s=>typeof s=="string"?s:s.name)};return Promise.resolve(t)}if(e.user?.roles&&Array.isArray(e.user.roles)){const t={roles:e.user.roles.map(s=>typeof s=="string"?s:s.name)};return Promise.resolve(t)}return o.getPermissions()}catch(t){return console.error("Failed to get permissions from context:",t),Promise.resolve("null")}},[n.roles,e.user?.roles]),y=l(()=>n.systemValues||o.getSystemValues(),[n.systemValues]),P=l(t=>{const s=y();return s?s[t]:null},[y]),L=l(()=>P("point_of_sales"),[P]);g.useEffect(()=>{const t=s=>{console.log("Auth event received:",s.detail),O(s.detail)};return window.addEventListener("authEvent",t),()=>{window.removeEventListener("authEvent",t)}},[O]),g.useEffect(()=>{if(console.log("Redux auth state changed:",{authenticated:e.authenticated,user:!!e.user,auth:!!e.auth}),e.authenticated){let t=e?.auth?.tenantImages,s=e?.auth?.tenantSettings,a=n.systemValues;t||(t=o.getTenantImages()),s||(s=o.getTenantSettings()),a||(a=o.getSystemValues());const c=JSON.stringify(t);if(t&&V.current!==c){console.log("Updating panel settings with tenant images from auth context or persisted data"),V.current=c;const x={...t.horizontal_logo.original&&{horizontalLogo:t.horizontal_logo.original},...t.squared_logo.original&&{squaredLogo:t.squared_logo.original},...t.banner.original&&{loginBackground:t.banner.original}};u(h.setPanelSettings(x))}const H=JSON.stringify(s);s&&E.current!==H&&(console.log("Recreating MUI theme with tenant settings from auth context"),E.current=H,F(s),u(h.updateThemeSettings(s)));const N=JSON.stringify(a);if(a&&k.current!==N&&(console.log("Processing system values from auth context or persisted data"),k.current=N,console.log("Available system values:",Object.keys(a)),console.log("Point of Sales:",a.point_of_sales)),JSON.parse(I.getItem("authenticated")||"false")&&e.user?.tenant_id){const{DashIPCService:x}=window;x&&x.action("start-bg-service",{token:I.getItem("token"),channel:`private-tenant.${e.user.tenant_id}.system`})}}},[e.authenticated,n.systemValues]),g.useEffect(()=>{console.log("Auth context values changed:",{authenticated:n.authenticated,user:n.user?`${n.user.name} (${n.user.id})`:null,auth:n.auth,token:n.token?"present":"missing",systemValues:n.systemValues?Object.keys(n.systemValues):null})},[n]);const Y=g.useMemo(()=>{const t=n.user||e.user||o.getUser(),s=n.authenticated??e.authenticated??!1,a=n.token||e.user?.token||o.getToken();return{user:t,authenticated:s,auth:n.auth||e.auth,token:a,roles:n.roles||e.user?.roles,systemValues:n.systemValues||o.getSystemValues(),updateValues:R,logout:U,handleReactAdminIdentity:_,getPermissions:w,fetchAuth:d,getSystemValues:y,getSystemValue:P,getPointOfSales:L}},[n,e,R,U,_,w,d,y,P,L]);return Q(S.Provider,{value:Y,children:i})},Ct=S.Consumer,Tt=()=>K(S),j=r=>(console.log("Setting auth event:",r),window.dispatchEvent(new CustomEvent("authEvent",{detail:r})),r),Vt=()=>o.getPermissions();var Et=S;export{S as AuthContext,X as AuthContextClass,Ct as AuthContextConsumer,vt as AuthContextProvider,Et as default,Vt as getAuthPermissions,j as setAuthEvent,Tt as useAuthContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var d=Object.defineProperty;var A=(t,e,r)=>e in t?d(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var h=(t,e,r)=>A(t,typeof e!="symbol"?e+"":e,r);import{jsx as V}from"react/jsx-runtime";import P from"../../hooks/useLocalStorage";import I,{useContext as S,useState as f,useEffect as g}from"react";import{dashStorage as o}from"@dashadmin/dash-utils";class m{}h(m,"values");const n={authenticated:!1,user:null,auth:null,token:null,roles:null},a=I.createContext(null),U=t=>{const{children:e,values:r}=t,[x,u]=f(r||n),[i,c]=P("SerializedAuthContext",JSON.stringify(r||n));g(()=>{try{const s=typeof i=="string"?JSON.parse(i):i;u(s||n)}catch(s){console.error("Error parsing auth context from localStorage:",s),u(n)}},[]);const p=s=>{u(C=>{const l={...C,...s};return c(JSON.stringify(l)),l})};return V(a.Provider,{value:{...x,updateValues:p},children:e})},W=a.Consumer,b=()=>S(a),y=()=>{try{const t=o.getItem("SerializedAuthContext");return t?JSON.parse(t):n}catch(t){return console.error("Error getting auth context:",t),n}},R=t=>{try{const r={...y(),...t};return o.setItem("SerializedAuthContext",JSON.stringify(r)),r}catch(e){return console.error("Error updating auth context:",e),t}},q=t=>{try{return o.setItem("SerializedAuthContext",JSON.stringify(t)),o.setItem("roles",JSON.stringify(t.user.roles)),o.setItem("authenticated","true"),o.setItem("user",JSON.stringify(t.user)),t}catch(e){return console.error("Error setting auth context:",e),t}};var w=a;export{m as AuthContextClass,W as AuthContextConsumer,a as AuthContextLocalStorage,U as AuthContextProvider,w as default,y as getAuthContext,q as setAuthContext,R as updateAuthContext,b as useAuthContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var y=Object.defineProperty;var N=(m,t,e)=>t in m?y(m,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):m[t]=e;var p=(m,t,e)=>N(m,typeof t!="symbol"?t+"":t,e);import{createAxiosInstance as E}from"@dashadmin/dash-axios-hook";import{setCookie as _}from"../../utils/cookies";import{getEnv as g}from"../../config/DASHAdminSystemConstants";import{AuthPersistenceService as h,syncLocalStorageToDeviceStore as u,clearDeviceStoreAuth as v}from"@dashadmin/dash-auth";import{DASHAppConstants as T}from"@dashadmin/dash-constants";import{DASHAdminSystemConstants as R}from"@dashadmin/dash-constants";import{dashStorage as r}from"@dashadmin/dash-utils";import{DASH_REDUX_ACTIONS as S,dispatchToRedux as k}from"@dashadmin/dash-admin-state";import{ACTION_UPDATE_AUTH as I}from"@dashadmin/dash-admin-state/src/redux/reducers/Auth";class w{constructor(){p(this,"axiosInstance");p(this,"REDIRECT_STORAGE_KEY","redirectAfterLogin");p(this,"logoutFromStorage",async t=>{console.log("logoutFromStorage",t),h.markAsLoggedOut(),await v();const{DashIPCService:e}=window;e&&e.action("stop-bg-service")});p(this,"getInitialAuthState",()=>{try{const t=h.getAuth(),e=h.getUser(),s=h.getToken(),n=JSON.parse(r.getItem("authenticated")||"false");if(console.log("\u{1F50D} DASHLightApp: Initializing auth state with persisted data:",{hasPersistedAuth:!!t,hasStoredUser:!!e,hasStoredToken:!!s,isAuthenticated:n,storedUser:e?`${e.name||e.email} (${e.id})`:null,persistedAuthStructure:t?Object.keys(t):null}),n&&e&&s&&t){console.log("\u2705 DASHLightApp: Using persisted auth state");const a={authenticated:!0,user:e,auth:t.auth||null};return console.log("\u{1F50D} DASHLightApp: Constructed auth state:",{authenticated:a.authenticated,user:a.user?`${a.user.name||a.user.email} (${a.user.id})`:null,auth:a.auth?"present":null}),a}return s&&!n?(console.log("\u{1F504} DASHLightApp: Token found but not authenticated, will initialize later"),{authenticated:!1,user:null,auth:null}):(console.log("\u2139\uFE0F DASHLightApp: No valid persisted auth found, using default auth state"),{authenticated:!1,user:null,auth:null})}catch(t){return console.error("\u274C DASHLightApp: Error getting initial auth state:",t),{authenticated:!1,user:null,auth:null}}});this.axiosInstance=E()}reinitializeAxios(t){this.axiosInstance=E(t)}sanitizeRedirectUrl(t){if(!t)return"/";const e=/^\/[A-Za-z]:\/|^[A-Za-z]:\/|^file:\/\//i.test(t),s=window.location.protocol==="file:"||g("IS_ELECTRON")==="true"||g("IS_ELECTRON")===!0;if((e||t.includes("index.html"))&&t.includes("#")){const n=t.split("#");if(n.length>1&&n[1]){const a=n[1];return console.log("Detected file/electron path with hash, extracting route:",a),"#"+a}}return e?(console.log("Detected Windows file path in redirect, resetting to #/"),"#/"):t.includes("/resources/app/")||t.includes("/dist/index.html")||t.includes("Program Files")?(console.log("Detected Electron app path in redirect, resetting to #/"),"#/"):s&&t.startsWith("/")&&!t.startsWith("#")?(console.log("Detected Electron environment with standard path, adding hash prefix:",t),"#"+t):t}setPendingRedirect(t){if(!t||t==="/"||t==="#/"||t==="#"){console.log("Skipping pending redirect for root path:",t);return}const e=this.sanitizeRedirectUrl(t);if(e==="/"||e==="#/"||e==="#"){console.log("Skipping pending redirect for sanitized root path:",e);return}console.log("Setting pending redirect:",t,"\u2192",e),r.setItem(this.REDIRECT_STORAGE_KEY,e)}getPendingRedirect(){return r.getItem(this.REDIRECT_STORAGE_KEY)}clearPendingRedirect(){console.log("Clearing pending redirect"),r.removeItem(this.REDIRECT_STORAGE_KEY)}getRoleRedirect(t){const e=t?.roles;if(Array.isArray(e)&&e.length>0){for(const s of e)if(s.redirect)return console.log("Found role redirect:",s.name,"->",s.redirect),s.redirect}return null}determineRedirectUrl(t,e=!0){let s=null;if(t)return console.log("Using backend redirect:",t,"(persist:",e,")"),s=t,e?(this.setPendingRedirect(s),this.getPendingRedirect()):this.sanitizeRedirectUrl(s);const n=this.getPendingRedirect();return n?(console.log("Using localStorage redirect:",n),n):(s=g("APP_DEFAULT_REDIRECT"),e?(this.setPendingRedirect(s),this.getPendingRedirect()):this.sanitizeRedirectUrl(s))}async login(t){if(console.log("=== DASH AUTH SERVICE LOGIN START ==="),console.log("Credentials:",{username:t.username,password:"***",redirect:t.redirect,meta:t.meta}),!(t.username&&t.password))return console.log("\u274C Missing credentials"),Promise.resolve({success:!1,error:"Username and password are required"});try{console.log("Making login request to /login");const e=await this.axiosInstance.post("/login",{email:t.username,password:t.password,redirect:t.redirect,meta:t.meta});if(console.log("Login response status:",e.status),console.log("Login response data:",e.data),e.status>=200&&e.status<=299){console.log("\u2705 Login response successful");const s=e.data.redirectTo;console.log("\u{1F3AF} Backend redirectTo:",s);const n=new Date;if(new Date().setDate(n.getDate()+2),e.data&&e.data.token){console.log("Setting token in storage"),r.setItem("token",e.data.token);const c=e.data?.refresh_token||e.data?.refreshToken;c&&(console.log("Setting refresh token in storage"),r.setItem("refreshToken",c)),e.data?.meta&&(console.log("Setting app"),r.setItem("app",e.data.meta.app)),await u()}else console.warn("\u26A0\uFE0F No token in login response");try{console.log("Getting auth data from:",g("APP_GETAUTH_ENDPOINT"));const c=await this.axiosInstance.get(g("APP_GETAUTH_ENDPOINT"));console.log("Auth response status:",c.status),console.log("Auth response data:",c.data);const i=c.data;let o=s;if(!o){const A=this.getRoleRedirect(i.user),f=i.redirect||i.user?.redirect||A||null;console.log("Auth response redirect:",f,"(role redirect:",A,")"),f?o=f:t.redirect&&t.redirect!=="/login"?o=t.redirect:o=g("APP_DEFAULT_REDIRECT")||"/"}console.log("\u{1F3AF} Final redirect determined:",o),h.saveAuth(i);const l=i.auth?.tenantSettings?.primary_language_code||i.user?.preferences?.locale;l&&(localStorage.setItem("dash-user-locale",l),window.dispatchEvent(new CustomEvent("dash:locale-change",{detail:{locale:l}})),console.log("\u{1F310} DASHAuthService: Dispatched locale change event:",l)),r.setItem("authenticated","true"),r.setItem("user",JSON.stringify(i.user)),r.setItem("roles",i.user?.roles?JSON.stringify(i.user.roles):JSON.stringify(T.system.GUEST_ROLE)),JSON.parse(R.system.ENABLE_TENANT_IMPERSONATION.toString())&&i.user?.tenant_id&&(r.setItem("tenant_id",i.user?.tenant_id),r.setItem("user_id",i.user?.id));const d={authenticated:!0,user:i.user,auth:i.auth,token:e.data.token||r.getItem("token"),roles:i.user?.roles};return console.log("\u{1F504} DASHAuthenticationService: Dispatching to Redux:",d),k(S.updateAuth(I,{user:d.user,authenticated:d.authenticated,auth:d.auth})),await u(),console.log("\u2705 Login completed successfully"),Promise.resolve({success:!0,token:d.token,user:d.user,auth:d.auth,redirectAfterLogin:o})}catch(c){return await u(),console.error("\u274C Error getting auth data:",c),this.logoutFromStorage("login get auth error"),Promise.resolve({success:!1,error:"Failed to get user authentication data"})}}else return await u(),console.log("\u274C Login response status not successful:",e.status),this.logoutFromStorage("login status error logout"),Promise.reject({success:!1,error:`Login failed with status: ${e.status}`})}catch(e){return await u(),console.error("\u274C Login error:",e),console.error("Error details:",{message:e?.message,response:e?.response?.data,status:e?.response?.status}),this.logoutFromStorage("login error logout"),await u(),Promise.reject({success:!1,error:e?.response?.data?.message||e?.message||"Login failed"})}}async initializeFromToken(){const t=r.getItem("token");if(!t)return{success:!1,error:"No token found"};try{console.log("Initializing auth from existing token...");const{data:e}=await this.axiosInstance.get(g("APP_GETAUTH_ENDPOINT")),s=this.getRoleRedirect(e.user),n=e.redirect||e.user?.redirect||s||null;console.log("Backend redirect found during token initialization:",n,"(role redirect:",s,")"),h.saveAuth(e),r.setItem("authenticated","true"),r.setItem("user",JSON.stringify(e.user)),r.setItem("roles",e.user?.roles?JSON.stringify(e.user.roles):JSON.stringify(T.system.GUEST_ROLE)),JSON.parse(R.system.ENABLE_TENANT_IMPERSONATION.toString())&&e.user?.tenant_id&&(r.setItem("tenant_id",e.user?.tenant_id),_("tenant_id",e.user?.tenant_id),r.setItem("user_id",e.user?.id),_("user_id",e.user?.id));const a={authenticated:!0,user:e.user,auth:e.auth,token:t,roles:e.user?.roles};console.log("\u{1F504} DASHAuthenticationService: Dispatching token init to Redux:",a),k(S.updateAuth(I,{user:a.user,authenticated:a.authenticated,auth:a.auth})),console.log("Auth initialized successfully from existing token"),await u();const c=this.determineRedirectUrl(n,!1);return{success:!0,token:t,user:e.user,auth:e.auth,redirectAfterLogin:c}}catch(e){return console.error("Error initializing auth from token:",e),this.logoutFromStorage("initialize from token error"),await u(),{success:!1,error:"Failed to initialize authentication from token"}}}async refreshToken(t){try{console.log("[DASHAuthService] Attempting to refresh token...");const e=await this.axiosInstance.post("/auth/refresh",{refresh_token:t});if(e.status>=200&&e.status<=299){const s=e.data;return s.token&&(r.setItem("token",s.token),console.log("[DASHAuthService] Access token updated")),s.refresh_token&&(r.setItem("refreshToken",s.refresh_token),console.log("[DASHAuthService] Refresh token rotated")),await u(),console.log("[DASHAuthService] Token refresh successful"),{success:!0,token:s.token,refreshToken:s.refresh_token,user:s.user}}else return console.warn("[DASHAuthService] Token refresh returned non-success status:",e.status),{success:!1,error:"Token refresh failed"}}catch(e){return console.error("[DASHAuthService] Token refresh error:",e),e?.response?.status===401&&(console.log("[DASHAuthService] Refresh token is invalid or expired"),this.logoutFromStorage("refresh_token_expired")),{success:!1,error:e?.response?.data?.message||e?.message||"Network error occurred"}}}async checkAuth(){const t=JSON.parse(r.getItem("authenticated")||"false"),e=JSON.parse(r.getItem("user")||"null");return!!(t&&e?.id&&h.getAuth())}async getIdentity(){if(!r.getItem("token"))throw new Error("No token present");try{const{data:e}=await this.axiosInstance.get(g("APP_GETAUTH_ENDPOINT"));return r.setItem("roles",e.user?.roles?JSON.stringify(e.user.roles):JSON.stringify(T.system.GUEST_ROLE)),r.setItem("authenticated","true"),r.setItem("user",JSON.stringify(e.user)),JSON.parse(R.system.ENABLE_TENANT_IMPERSONATION.toString())&&e.user?.tenant_id&&(r.setItem("tenant_id",e.user?.tenant_id),r.setItem("user_id",e.user?.id)),await u(),e}catch(e){throw this.logoutFromStorage("get identity error logout"),e}}async shouldRefreshToken(){return r.getItem("token")?!!r.getItem("refreshToken"):!1}async handleTokenRefresh(){const t=r.getItem("refreshToken");if(!t)return!1;try{const e=await this.refreshToken(t);if(e.success)return r.setItem("token",e.token),e.refreshToken&&r.setItem("refreshToken",e.refreshToken),await u(),!0}catch(e){console.error("Token refresh failed:",e),this.logoutFromStorage("token refresh failed")}return!1}async shouldInitializeFromToken(t){if(t)return!0;const e=r.getItem("token"),s=JSON.parse(r.getItem("authenticated")||"false"),n=r.getItem("user");return!!(e&&(!s||!n))}async initializeApp(t){console.log("Initializing DASH app authentication...");const e=!0;if(await this.shouldInitializeFromToken(t))return console.log("Token found but not fully authenticated, initializing..."),await this.initializeFromToken();{const n=r.getItem("token"),a=JSON.parse(r.getItem("authenticated")||"false"),c=r.getItem("user");if(n&&a&&c)if(console.log("Already authenticated, checking if auth refresh needed"),e)try{console.log("Refreshing auth data for latest tenant/user information...");const i=await this.axiosInstance.get(g("APP_GETAUTH_ENDPOINT"));console.log("Fresh auth response:",i.data);const o=i.data,l=this.getRoleRedirect(o.user),d=o.redirect||o.user?.redirect||l||null;console.log("Backend redirect found during app initialization:",d,"(role redirect:",l,")"),h.saveAuth(o);const A=o.auth?.tenantSettings?.primary_language_code||o.user?.preferences?.locale;A&&(localStorage.setItem("dash-user-locale",A),window.dispatchEvent(new CustomEvent("dash:locale-change",{detail:{locale:A}})),console.log("\u{1F310} DASHAuthService: Dispatched locale change event (app init):",A)),r.setItem("user",JSON.stringify(o.user)),r.setItem("roles",o.user?.roles?JSON.stringify(o.user.roles):JSON.stringify(T.system.GUEST_ROLE)),JSON.parse(R.system.ENABLE_TENANT_IMPERSONATION.toString())&&o.user?.tenant_id&&(r.setItem("tenant_id",o.user?.tenant_id),r.setItem("user_id",o.user?.id));const f={authenticated:!0,user:o.user,auth:o.auth,token:n,roles:o.user?.roles};console.log("\u{1F504} DASHAuthenticationService: Dispatching fresh auth to Redux:",f),k(S.updateAuth(I,{user:f.user,authenticated:f.authenticated,auth:f.auth}));const D=this.determineRedirectUrl(d,!1);return console.log("Auth data refreshed successfully"),await u(),{success:!0,token:n,user:o.user,auth:o.auth,redirectAfterLogin:D}}catch(i){console.error("Error refreshing auth data:",i),console.log("Falling back to existing auth data");const o=JSON.parse(c),l=h.getAuth();console.log("\u{1F504} DASHAuthenticationService: Dispatching existing auth to Redux"),k(S.updateAuth(I,{user:o,authenticated:!0,auth:l?.auth||null}));const d=this.determineRedirectUrl(void 0,!1);return await u(),{success:!0,token:n,user:o,auth:l?.auth||null,redirectAfterLogin:d}}else{console.log("No auth refresh needed, using existing data");const i=JSON.parse(c),o=h.getAuth();console.log("\u{1F504} DASHAuthenticationService: Dispatching existing auth to Redux"),k(S.updateAuth(I,{user:i,authenticated:!0,auth:o?.auth||null}));const l=this.determineRedirectUrl(void 0,!1);return await u(),{success:!0,token:n,user:i,auth:o?.auth||null,redirectAfterLogin:l}}else return console.log("No valid authentication found"),await u(),{success:!1,error:"No valid authentication found"}}}async loginWithReactAdmin(t,e){debugger;return await(e||this.login)(t)}}var j=new w;export{j as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import t from"react";const o=t.createContext({isMobile:!1,width:0,height:0,mq:"all"});export{o as WindowContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./AuthContext";export*from"./WindowContext";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var M=Object.defineProperty;var k=(s,i,t)=>i in s?M(s,i,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[i]=t;var a=(s,i,t)=>k(s,typeof i!="symbol"?i+"":i,t);import{jsx as D}from"react/jsx-runtime";import F,{useEffect as O,useMemo as v,useRef as w}from"react";import{createAxiosInstance as L}from"@dashadmin/dash-axios-hook";import{useSelector as b}from"react-redux";import{getEnv as o}from"@dashadmin/dash-constants/src/DASHAdminSystemConstants";const _=()=>!!window?.Capacitor?.Plugins?.PushNotifications,p=()=>window?.Capacitor?.Plugins?.PushNotifications,f=()=>window?.Capacitor;class E{constructor(){a(this,"notifications",[]);a(this,"lastNotification",null);a(this,"axiosInstance",L());a(this,"permissionStatus","unknown");this.isSupported()||(this.permissionStatus="not_supported")}isSupported(){const i=f(),t=_(),d=i?.isNativePlatform?.()||!1;return console.log("\u{1F50D} FCM Support check:",{hasCapacitor:!!i,hasPlugin:t,isNativePlatform:d,platform:i?.getPlatform?.()||"web"}),t&&d}getPlatform(){return f()?.getPlatform?.()||"web"}async checkPermissions(){if(!this.isSupported())return console.log("\u{1F4F1} Push notifications not supported on this platform"),this.permissionStatus="not_supported",!1;try{const i=p();console.log("\u{1F50D} Checking push notification permissions...");const t=await i.checkPermissions();return console.log("\u{1F510} Permission status:",t),t.receive==="granted"?(this.permissionStatus="granted",!0):t.receive==="denied"?(this.permissionStatus="denied",!1):(this.permissionStatus="unknown",!1)}catch(i){return console.error("\u274C Error checking permissions:",i),this.permissionStatus="denied",!1}}async requestPermissions(){if(!this.isSupported())return console.log("\u{1F4F1} Push notifications not supported, skipping permission request"),!1;try{const i=p();console.log("\u{1F510} Requesting push notification permissions...");const t=await i.requestPermissions();return console.log("\u{1F510} Permission request result:",t),t.receive==="granted"?(this.permissionStatus="granted",console.log("\u2705 Push notification permissions granted"),!0):(this.permissionStatus="denied",console.log("\u274C Push notification permissions denied"),!1)}catch(i){return console.error("\u274C Error requesting permissions:",i),this.permissionStatus="denied",!1}}async initializePushNotifications(){if(console.log("\u{1F680} Initializing push notifications..."),!this.isSupported()){console.log("\u{1F4F1} Push notifications not supported on this platform, skipping initialization");return}try{if(!await this.checkPermissions()&&!await this.requestPermissions()){console.log("\u274C Cannot initialize push notifications without permissions");return}await this.registerNotifications(),await this.addListeners(),console.log("\u2705 Push notifications initialized successfully")}catch(i){throw console.error("\u274C Failed to initialize push notifications:",i),i}}async registerNotifications(){if(!this.isSupported())throw new Error("Push notifications not supported on this platform");try{const i=p();console.log("\u{1F4DD} Registering for push notifications..."),await i.register(),console.log("\u2705 Successfully registered for push notifications")}catch(i){throw console.error("\u274C Error registering for push notifications:",i),new Error(`Registration failed: ${i.message}`)}}async addListeners(){if(this.isSupported())try{const i=p();console.log("\u{1F442} Adding push notification listeners..."),await i.addListener("registration",t=>{console.log("\u{1F4DD} Registration token received:",t.value),this.sendTokenToBackend(t.value)}),await i.addListener("registrationError",t=>{console.error("\u274C Registration error:",t.error)}),await i.addListener("pushNotificationReceived",t=>{console.log("\u{1F4E8} Push notification received:",t),this.notifications.push(t),this.lastNotification=t}),await i.addListener("pushNotificationActionPerformed",t=>{console.log("\u{1F446} Push notification action performed:",t.actionId,t.inputValue)}),console.log("\u2705 Push notification listeners added successfully")}catch(i){throw console.error("\u274C Error adding listeners:",i),new Error(`Failed to add listeners: ${i.message}`)}}async sendTokenToBackend(i){try{console.log("\u{1F4E4} Sending FCM token to backend..."),await this.axiosInstance.post("/system/fcm/token",{fcm_token:i}),console.log("\u2705 FCM token sent to backend successfully")}catch(t){console.error("\u274C Error sending token to backend:",t)}}clear(){console.log("\u{1F9F9} Clearing notifications..."),this.notifications=[],this.lastNotification=null}cleanup(){console.log("\u{1F9F9} Cleaning up FCM service..."),this.clear()}getState(){return{notifications:this.notifications,lastNotification:this.lastNotification,clear:this.clear.bind(this),initializePushNotifications:this.initializePushNotifications.bind(this),permissionStatus:this.permissionStatus,isSupported:this.isSupported(),platform:this.getPlatform()}}getDebugInfo(){const i=f(),t=_();return{windowCapacitor:!!i,hasPushNotificationsPlugin:t,availablePlugins:i?.Plugins?Object.keys(i.Plugins):[],platform:this.getPlatform(),isNativePlatform:i?.isNativePlatform?.()||!1,isSupported:this.isSupported(),permissionStatus:this.permissionStatus,notificationsCount:this.notifications.length,hasLastNotification:!!this.lastNotification}}}const y=F.createContext({notifications:[],lastNotification:null,clear:()=>{},initializePushNotifications:async()=>{},permissionStatus:"unknown",isSupported:!1,platform:"web"}),T=({manager:s,children:i,...t})=>{const h=w(new E).current,{notifications:m,lastNotification:P,clear:S,initializePushNotifications:c,permissionStatus:I,isSupported:n,platform:l}=s?s():h.getState(),g=b(e=>e.auth),N=w(!1),r=v(()=>({APP_VERSION:o("APP_VERSION")||"1.0.0",BUILD_TIME:o("BUILD_TIME")||new Date().toISOString(),IS_ELECTRON:JSON.parse(o("IS_ELECTRON")||"false"),PLATFORM:o("PLATFORM")||"unknown",IS_WINDOWS:JSON.parse(o("IS_WINDOWS")||"false"),IS_MAC:JSON.parse(o("IS_MAC")||"false"),IS_LINUX:JSON.parse(o("IS_LINUX")||"false"),PLATFORM_TYPE:o("PLATFORM_TYPE")||"desktop",IS_ANDROID:JSON.parse(o("IS_ANDROID")||"false"),IS_IOS:JSON.parse(o("IS_IOS")||"false"),IS_CAPACITOR:JSON.parse(o("IS_CAPACITOR")||"false"),IS_MOBILE:JSON.parse(o("IS_MOBILE")||"false"),CAPACITOR_PLATFORM:o("CAPACITOR_PLATFORM")||"web",ANDROID_AVAILABLE:JSON.parse(o("ANDROID_AVAILABLE")||"false"),IOS_AVAILABLE:JSON.parse(o("IOS_AVAILABLE")||"false")}),[]),C=f();O(()=>{if(g.authenticated&&!N.current){const e=C?.getPlatform?.()||"web",u=C?.isNativePlatform?.()||!1;console.log("\u{1F510} User authenticated, checking if should initialize FCM...",{debug:!1,isSupported:n,platform:l,capacitorPlatform:e,isNativePlatform:u,envVars:{IS_ANDROID:r.IS_ANDROID,IS_IOS:r.IS_IOS,IS_CAPACITOR:r.IS_CAPACITOR,CAPACITOR_PLATFORM:r.CAPACITOR_PLATFORM}}),n?u||e==="android"||e==="ios"?(console.log("\u{1F4F1} Native platform detected: initializing FCM",{capacitorPlatform:e,isNativePlatform:u}),c().catch(A=>{console.error("\u274C FCM initialization failed:",A)})):console.log("\u{1F310} Web platform or unsupported: skipping FCM initialization",{capacitorPlatform:e,isNativePlatform:u}):console.log("\u274C FCM not supported on this platform")}N.current=g.authenticated},[g,!1,n,l,r,c]),O(()=>()=>{h.cleanup()},[h]);const R=v(()=>({notifications:m,lastNotification:P,clear:S,initializePushNotifications:c,permissionStatus:I,isSupported:n,platform:l}),[m,P,S,c,I,n,l]);return D(y.Provider,{value:R,children:i})};export{y as FCMContext,T as FCMProvider,E as FCMService,y as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as v}from"react/jsx-runtime";import c from"./LaravelEchoMgr";import n from"react";const a=n.createContext({events:[],lastEvent:null,clear:null}),i=({manager:e,children:t,...s})=>{const{events:o,lastEvent:r,clear:l}=e?e():c();return v(a.Provider,{value:{events:o,lastEvent:r,clear:l},children:t})};export{a as LaravelEchoContext,i as LaravelEchoProvider,a as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as v,jsxs as d}from"react/jsx-runtime";import{useContext as E,useEffect as l,useState as c}from"react";import{toast as p}from"react-toastify";import{NotificationComponent as u}from"./components/NotificationRenderer";import{AuthContext as m}from"../auth/AuthContext";import{NotificationWrapper as h}from"./components/NotificationsWidget";import f from"./useLaravelEcho";const I=e=>{p(d(h,{notification:e,children:[" ",v(u,{notification:e})," "]},0),{position:"top-right",autoClose:8e3,hideProgressBar:!1,closeOnClick:!0,pauseOnHover:!0,draggable:!0,progress:void 0})},N=e=>{p(d(h,{notification:e,children:[" ",v(u,{notification:e})," "]},0),{position:"top-right",autoClose:!1,hideProgressBar:!1,closeOnClick:!0,pauseOnHover:!0,draggable:!0,progress:void 0})},P=()=>{const[e,s]=c([]),[g,o]=c(null),t=E(m);console.log("\u{1F50D} LaravelEchoMgr: Initializing with authContext:",{hasUser:!!t?.user,userId:t?.user?.id,authenticated:t?.authenticated});const y=()=>{o(null)};l(()=>{console.log("Echo manager listener for private and public messages initialized")},[]),console.log("\u{1F50D} LaravelEchoMgr: Setting up public channel listener...");const i=f({type:"public",channel:"public",events:{public:a=>{console.log("\u{1F4E1} LaravelEchoMgr: Received public notification:",a),s([...e,a]),o(a),N(a)}},userId:null,enabled:!0});console.log("\u{1F50D} LaravelEchoMgr: Setting up private channel listener...");const n=f({type:"private",channel:`user.${t.user?.id}`,events:{notification:a=>{console.log("\u{1F4E1} LaravelEchoMgr: Received private notification:",a),I(a)}},userId:t.user?.id,enabled:!!t?.user?.id});return l(()=>{if(n?.lastEvent){console.log("\u{1F4E1} LaravelEchoMgr: Global event captured from private channel:",n.lastEvent);const a=n.lastEvent.data;a&&(o(a),s(r=>[...r,a]))}},[n?.lastEvent]),l(()=>{if(i?.lastEvent){console.log("\u{1F4E1} LaravelEchoMgr: Global event captured from public channel:",i.lastEvent);const a=i.lastEvent.data;a&&(o(a),s(r=>[...r,a]))}},[i?.lastEvent]),{events:e,lastEvent:g,clear:y}};var x=P;export{x as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Fragment as n,jsx as o}from"react/jsx-runtime";import i from"../../../components/misc/MuiSimpleJsonTable";const a=({notification:t,...e})=>o(n,{children:o(i,{tableData:t.notificationPayload,vertical:!0})});var p=a;export{p as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Fragment as d,jsx as n,jsxs as m}from"react/jsx-runtime";import c from"react";import f from"../../dictionary/DictionaryContext";const s=({tableData:o,ignore:i,include:l})=>{const r=c.useContext(f);i||(i=[]),l||(l=[]);let e=o?Object.keys(o):[];return l.length&&(e=e.filter(t=>l.includes(t))),i.length&&(e=e.filter(t=>!i.includes(t))),n("table",{className:"table",children:n("tbody",{children:n(()=>e&&e.length>0?e.map(t=>m("tr",{children:[n("td",{children:r.get(t)}),n("td",{children:typeof o[t]!="object"?r.get(o[t]):o[t]})]})):n(d,{}),{})})})};var g=s;export{g as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Fragment as f,jsx as a}from"react/jsx-runtime";import{useRecordContext as e}from"react-admin";import{formatNotification as n}from"./notificationFormats";const r=({notification:t})=>{let o=t;const i=n(o);return a(i.content,{notification:o})},c=({method:t,attribute:o})=>{const i=e();return a(r,{notification:i})},s=({method:t,attribute:o,resourceConfig:i})=>{switch(t){case"edit":case"create":return a(f,{children:"Not implemented"});case"view":case"list":return a(c,{attribute:o,method:t,resourceConfig:i})}};var A=s;export{r as NotificationComponent,A as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Fragment as F,jsx as t,jsxs as e}from"react/jsx-runtime";import m,{useContext as u,useEffect as v}from"react";import{useGetList as g}from"react-admin";import{NotificationComponent as y}from"./NotificationRenderer";import{Badge as I,Button as C,Popover as E}from"@mui/material";import{useNavigate as P}from"react-router";import{Link as b}from"react-router-dom";import{useStore as B}from"react-admin";import T from"@mui/icons-material/NotificationsActive";import x from"../LaravelEchoContext";import L from"../../dictionary/DictionaryContext";import k from"../../../components/scrollbar/Scrollbar";import{formatNotification as O}from"./notificationFormats";import{dashStorage as S}from"@dashadmin/dash-utils";const A=({notification:a,key:r,children:i})=>{const n=O(a);return e("li",{className:"dash-media",children:[e("div",{className:"dash-user-thumb dash-mr-3",children:[t(n.content,{notification:a}),t("span",{className:"dash-badge dash-badge-danger dash-text-white dash-rounded-circle"})]}),e("div",{className:"dash-media-body",children:[t("h5",{children:t(n.title,{notification:a})}),t("span",{children:t(n.content,{notification:a})}),i]})]},r)},D=()=>{const[a,r]=B("activeNotifications"),i=u(x);v(()=>{if(i.lastEvent&&S.getItem("lastEvent")!==JSON.stringify(i.lastEvent)){if(["ProductImportProgressNotification"].includes(i.lastEvent.notificationPayload.class))return;r((a||0)+1)}},[i.lastEvent]);const n=P(),{data:s}=g("notification",{pagination:{page:1,perPage:5},sort:null}),c=m.useContext(L),f=()=>t("ul",{className:"dash-sub-popover",children:t("li",{children:c.get("NO_AVAILABLE_NOTIFICATIONS")})}),p=()=>e(F,{children:[e("div",{className:"dash-popover-header",children:[t("h3",{className:"dash-mb-0",children:c.get("NOTIFICATIONS_WIDGET_TITLE")}),t(C,{onClick:()=>n("notification"),children:"Ver todas"})]}),t(k,{className:"dash-popover-scroll",children:t("ul",{className:"dash-sub-popover",children:s&&s.length?s.map((o,h)=>{const N={...o,notificationPayload:{...o.notificationPayload,notificationPayload:{...o.notificationPayload.notificationPayload,name:t(b,{target:"_blank",to:`/log/${o?.notificationPayload?.notificationPayload?.id}/show`,children:o?.notificationPayload?.notificationPayload?.name})}}};return t(A,{notification:o,children:t(y,{notification:N})},h)}):t(f,{})})})]}),[l,d]=m.useState(null);return e("div",{className:"dash-notify dash-header-entry",children:[t(E,{id:void 0,open:!!l,anchorEl:l,onClose:()=>{d(null)},anchorOrigin:{vertical:"bottom",horizontal:"left"},children:t(p,{})}),t(I,{onClick:o=>{d(o.currentTarget)},badgeContent:a,color:"primary",children:t(T,{color:"action"})})]})};var it=D;export{A as NotificationWrapper,D as NotificationsWidget,it as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Fragment as o,jsx as n}from"react/jsx-runtime";import f from"./DefaultNotificationComponent";function s(c,i,t,a){return{class:c.class,title:i||(e=>n(o,{children:"notification.title"})),icon:t||(e=>n(o,{children:"\u{1F514}"})),content:a||f}}var F=s;export{F as default,s as formatNotification};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var G=Object.defineProperty;var J=(r,e,g)=>e in r?G(r,e,{enumerable:!0,configurable:!0,writable:!0,value:g}):r[e]=g;var _=(r,e,g)=>J(r,typeof e!="symbol"?e+"":e,g);import{useState as C,useEffect as $,useContext as Y,useCallback as w,useRef as Q}from"react";import Z from"@rooks/use-previous";import ee from"laravel-echo";import ne from"pusher-js";import{ConstantsContext as te}from"../../config/ConstantsService";import{getEnv as p}from"@dashadmin/dash-constants/src/DASHAdminSystemConstants";import{useSelector as oe}from"react-redux";import{dashStorage as N}from"@dashadmin/dash-utils";window.Pusher=ne;const f=class f{constructor(){_(this,"clients");this.clients=new Map}static getInstance(){return f.instance||(f.instance=new f),f.instance}setClient(e,g){this.clients.set(e,g)}getClient(e){return this.clients.get(e)}removeClient(e){return this.clients.delete(e)}hasClient(e){return this.clients.has(e)}};_(f,"instance");let D=f;const H=D.getInstance(),ie=({type:r,channel:e,events:g,userId:s,socketId:re,pingInterval:z=3e4,debug:d=!0,enabled:L=!1})=>{const[c,T]=C(null),[n,I]=C(null),[M,K]=C(null),[y,P]=C(!1),v=Z(e),se=Y(te),l=Q(null),a=oe(t=>t.auth),[ce,R]=C(null);console.log("\u{1F50D} useLaravelEcho: Hook called with params:",{type:r,channel:e,userId:s,enabled:L,hasAuth:!!a?.user,authUserId:a?.user?.id,authenticated:a?.authenticated}),$(()=>{a.user?.id&&typeof a.user.id=="number"&&a.user.id!==s&&R(a.user.id),a?.authenticated===!1&&R(null)},[a]);const le=p("APP_ENV")==="production",i=(t,o)=>{d&&console.log(`%c\u{1F4E1} ${t}`,"color: #2196F3; font-weight: bold; font-size: 12px;",o||"")},A=(t,o)=>{d&&console.error(`%c\u{1F4E1} ${t}`,"color: #f44336; font-weight: bold; font-size: 12px;",o||"")},U=w(()=>{if(n&&n.connector&&n.connector.pusher)try{i("Sending custom ping event..."),n.connector.pusher.send_event("client-ping",{timestamp:new Date().toISOString()})}catch(t){A("Error pinging WebSocket connection:",t)}},[n,d]),x=w(()=>`${r}-${e||"global"}-${s||"public"}`,[r,s,e]),W=w(()=>{l.current&&(window.clearInterval(l.current),l.current=null),i("Disconnecting Laravel Echo client...",x()),n&&n.disconnect(),i("Setting Laravel Echo client to null..."),I(null),i("Setting Echo channel to null..."),T(null),i("Clearing current events..."),K(null),i("Setting connection status to false..."),P(!1),i("Removing client from Echo manager...")},[n]);$(()=>{if(!L){console.log("\u{1F50D} useLaravelEcho: Hook disabled, skipping WebSocket setup");return}if(!JSON.parse(p("APP_SOCKETS_ENABLED"))){console.log("\u{1F50D} useLaravelEcho: WebSockets disabled by APP_SOCKETS_ENABLED env var");return}const t=x();if(console.log("\u{1F50D} useLaravelEcho: Setting up WebSocket connection...",{clientId:t,type:r,channel:e,userId:s,enabled:L}),r==="private"&&!s){console.log("\u{1F50D} useLaravelEcho: Skipping private channel setup - no userId provided");return}if(r==="public"||r==="private"&&s){if(H.clients.has(t)){const m=H.getClient(t);console.log("\u{1F50D} useLaravelEcho: Using existing Echo client:",t),I(m);return}const o=s?N.getItem("token"):null,k=o?{headers:{Authorization:`Bearer ${o}`,Accept:"application/json","X-Requested-With":"XMLHttpRequest"}}:void 0;try{const m=p("APP_SOCKETS_HOST"),E=p("APP_SOCKETS_SCHEME")?.toLowerCase()==="https",X=m||window.location.hostname,O=p("APP_SOCKETS_PORT"),S={broadcaster:"pusher",key:p("APP_SOCKETS_KEY")||"dash",wsHost:X,...O&&O!==""?{wsPort:O}:{},secure:E,forceTLS:E,encrypted:E,useTLS:E,disableStats:!E,enabledTransports:E?["wss","ws"]:["ws"],disableCluster:!0,cluster:"mt1",logToConsole:d,activityTimeout:12e4,pongTimeout:3e4};if(console.log("\u{1F50D} useLaravelEcho: WebSocket config:",S),k){const h=p("APP_BACKEND_URL")||window.location.origin,b=p("APP_SOCKETS_AUTH_ENDPOINT")||"/api/ws/auth",j=h.endsWith("/")?h:`${h}/`,F=b.startsWith("/")?b.substring(1):b,B=`${j}${F}`;console.log("\u{1F50D} useLaravelEcho: Using auth endpoint:",B),S.authEndpoint=B,S.auth=k}console.log("\u{1F50D} useLaravelEcho: Initializing Echo client with config:",S);const u=new ee(S);u.connector&&u.connector.pusher&&(u.connector.pusher.bind_global((h,b)=>{i(`Global event received: ${h}`,b),K({event:h,data:b})}),u.connector.pusher.connection.bind("connected",()=>{i("Connected to Pusher!"),P(!0),N.setItem("socketConnectionState","true"),l.current&&window.clearInterval(l.current),l.current=window.setInterval(U,z)}),u.connector.pusher.connection.bind("disconnected",()=>{i("Disconnected from Pusher"),P(!1),l.current&&(window.clearInterval(l.current),l.current=null)}),u.connector.pusher.connection.bind("error",h=>{A("Pusher connection error:",h),P(!1)})),i("Setting Echo client",t),H.setClient(t,u),I(u)}catch(m){A("Error initializing Echo client:",m),W()}}return()=>{d&&(console.log("%c\u{1F4E1} Socket listener unmounted!","color: #ff6b6b; font-weight: bold;"),W())}},[s,L,e]),$(()=>{if(!n||!e||r==="private"&&!s)return;if(i(`Attempting to subscribe to ${r} channel: ${e}`),n.connector.channels[e.includes(".")?`private-${e}`:e]!==void 0){i("Skipping, already suscribed");return}if(c&&v&&e!==v&&(i(`Leaving previous channel: ${v}`),n.leaveChannel(v),T(null)),!c||e!==v)try{let o;r==="private"?(i(`Subscribing to private channel: ${e}`),o=n.private(e.replace("{userId}",s.toString()))):(i(`Subscribing to public channel: ${e}`),o=n.channel(e)),T(o),i("Channel subscription successful:",o)}catch(o){A(`Error subscribing to ${r} channel ${e}:`,o)}return()=>{n&&e&&n.leaveChannel(e)}},[n,e,r,s,v,d]),$(()=>{if(!n||!y)return;const t=()=>{document.visibilityState==="visible"&&n.connector&&n.connector.pusher&&n.connector.pusher.connection.state!=="connected"&&(i("Tab is visible again, reconnecting..."),n.connector.pusher.connect())},o=()=>{i("Browser is online, reconnecting..."),n.connector&&n.connector.pusher&&n.connector.pusher.connect()};return document.addEventListener("visibilitychange",t),window.addEventListener("online",o),()=>{document.removeEventListener("visibilitychange",t),window.removeEventListener("online",o)}},[n,y,d]);const q=w((t,o)=>{if(!c)return;console.log(`Adding listener for event: ${t}`);const k=t;c.listen(k,o)},[c]),V=w(t=>{if(!c)return;console.log(`Adding listener for event: ${t}`);const o=t;c.stopListening(o)},[c]);return{echoChannel:c,isConnected:y,lastEvent:M,ping:U,addListener:q,removeListener:V}};var Te=ie;export{Te as default,H as echoManager};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as s}from"react/jsx-runtime";import y from"react";function i(e,r){for(const[o,t]of Object.entries(r))typeof t=="object"&&t!==null?e=i(e,t):e=Array.isArray(e)?e.join(", ").replace(o,t):typeof e=="string"?e.replace(o,t):e;return e}const a=y.createContext({dictionary:null,replacements:null,get:e=>e}),l=({dictionary:e,replacements:r,children:o})=>s(a.Provider,{value:{dictionary:e,replacements:r,get:(t,c)=>{let n=t;return c&&r&&(n=i(n,r)),e[n]?e[n]:n}},children:o});export{a as DictionaryContext,l as DictionaryProvider,a as default};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
declare module '*.png';
|
|
2
|
+
declare module '*.jpg';
|
|
3
|
+
declare module '*.jpeg';
|
|
4
|
+
declare module '*.svg';
|
|
5
|
+
declare module '*.gif';
|
|
6
|
+
|
|
7
|
+
interface Window {
|
|
8
|
+
Pusher: any;
|
|
9
|
+
Echo: any;
|
|
10
|
+
io: any;
|
|
11
|
+
Laravel: any;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare var Vue: any;
|
|
15
|
+
declare var axios: any;
|
|
16
|
+
declare var jQuery: any;
|
|
17
|
+
declare var Turbo: any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as F}from"react/jsx-runtime";import*as c from"react";import{ToastContainer as l}from"react-toastify";import{DialogServiceProvider as P}from"@dashadmin/dash-dialog";import f from"@dashadmin/dash-modal";import{LaravelEchoProvider as v}from"../contexts/com/LaravelEchoContext";import{DASHAppConstants as h}from"@dashadmin/dash-constants";import{CacheInvalidatorContextProvider as C}from"../utils/cache/CacheInvalidatorContext";import u from"../utils/cache/CacheInvalidatorListenerComponent";import A from"../components/misc/DASHGlobalErrorHandler";import x from"../contexts/DashQueryClientContext";import{FCMProvider as y}from"../contexts/com/FCMContext";import D from"../hooks/notifications/WSMessagesManager";import{LocalizationProvider as T}from"@mui/x-date-pickers";import{AdapterDayjs as g}from"@mui/x-date-pickers/AdapterDayjs";import{AuthContextProvider as S}from"../contexts/auth";import{Provider as I}from"react-redux";import{DashThemeProvider as R}from"./DashThemeContext";import{ComponentRegistryProvider as M}from"@dashadmin/dash-auto-admin";import{I18nBridgeProvider as E,useI18nBridge as H}from"../contexts/I18nBridgeContext";const L=r=>{const{i18nProvider:o,locale:i}=H(),n=c.useCallback((t,d)=>{if(!o)return t;try{return o.translate(t,d)}catch{return t}},[o,i]),a=r.confirmText===void 0?n("dash.action.continue"):r.confirmText,m=r.cancelText===void 0?n("dash.action.cancel"):r.cancelText;return e(f,{...r,confirmText:a,cancelText:m})},U=({wsMessagesManager:r,dateAdapter:o,store:i,children:n,extendedThemeOptions:a,dashAutoAdminComponents:m,queryClient:t,queryPersister:d,CustomEchoProvider:s})=>{const p=e(E,{children:e(R,{extendedOptions:a,children:e(T,{dateAdapter:o||g,children:e(S,{children:e(x,{queryClient:t,persister:d,children:e(M,{customComponents:m||{},children:e(P,{component:L,componentProps:{sound:h.system.UI_SOUNDS},children:e(y,{children:e(s||v,{manager:r||D,children:F(C,{children:[e(u,{}),e(l,{style:{width:"520px"}}),e(A,{}),n]})})})})})})})})})});return i?e(I,{store:i,children:p}):p};var Pe=U;export{Pe as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as g,jsxs as I}from"react/jsx-runtime";import{createContext as E,useContext as M,useState as h,useEffect as d}from"react";import{appTheme as T,getAntTheme as f}from"@dashadmin/dash-styles";import{AuthPersistenceService as u}from"@dashadmin/dash-auth";import{updateDomCssVariables as S}from"@dashadmin/dash-utils";import k from"@mui/material/CssBaseline";import O from"antd/es/config-provider";import{createTheme as v,ThemeProvider as H}from"@mui/material";const l=E(null);function y(r){const s=r.breakpoints;return s&&!s.internal_mediaKeys&&s.keys&&s.up&&(s.internal_mediaKeys=s.keys.map(t=>s.up(t))),r}const W=()=>{const r=M(l);if(!r)throw new Error("useDashThemeContext must be used within a DashThemeProvider");return r},X=({extendedOptions:r,children:s})=>{const[t,C]=h(()=>document.documentElement.getAttribute("data-theme")||"dark"),[D,b]=h(()=>{const e=u.getTenantSettings();return T(r,{currentMode:t,colors:e?.colors,tenantSettings:e})}),[p,w]=h(()=>{const e=u.getTenantSettings();return y(v(T(r,{currentMode:t,colors:e?.colors,tenantSettings:e})))}),[P,x]=h(()=>{const e=u.getTenantSettings();return f({currentMode:t,colors:e?.colors,tenantSettings:e})}),a=()=>u.getTenantSettings()||null,c=(e,m)=>{const n=e||a(),o=m||document.documentElement.getAttribute("data-theme")||"dark";console.log("Recreating MUI theme with tenant settings:",n,"mode:",o);const i=T(r,{tenantSettings:n,colors:n?.colors,currentMode:o}),R=y(v(i));b(i),w(R),x(f({tenantSettings:n,colors:n?.colors,currentMode:o})),S(o,n?.colors,n?.values)};d(()=>{const e=new MutationObserver(m=>{m.forEach(n=>{if(n.type==="attributes"&&n.attributeName==="data-theme"){const o=document.documentElement.getAttribute("data-theme")||"dark";if(o!==t){console.log("Theme mode changed from",t,"to",o),C(o);const i=a();console.log("Updating theme with new mode:",o,"and settings:",i),S(o,i?.colors,i?.values)}}})});return e.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),()=>e.disconnect()},[t]),d(()=>{console.log("Current mode updated to:",t);const e=a();c(e,t)},[t]),d(()=>{const e=a();e&&(console.log("Recreating MUI theme on mount"),c(e,t))},[]),d(()=>{const e=m=>{if(m.type==="DASHTRefreshTheme"){const n=a();c(n,t)}};return window.addEventListener("DASHTRefreshTheme",e),()=>window.removeEventListener("DASHTRefreshTheme",e)},[]);const A={theme:p,themeOptions:D,recreateTheme:c,currentMode:t};return I(H,{noSsr:!0,disableTransitionOnChange:!0,theme:p,children:[g(k,{}),g(l.Provider,{value:A,children:g(O,{theme:P,children:s})})]})};var Y=l;export{X as DashThemeProvider,Y as default,W as useDashThemeContext};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import React, { createContext, useContext, useState, useEffect } from 'react';
|
|
2
|
+
//import { createTheme } from '@mui/material/styles';
|
|
3
|
+
import { appTheme } from 'dash-styles';
|
|
4
|
+
import { useColorScheme } from '@mui/material/styles';
|
|
5
|
+
import { AuthPersistenceService } from 'dash-auth';
|
|
6
|
+
import { useSelector } from 'react-redux';
|
|
7
|
+
import { IDASHAppState } from 'dash-admin-state';
|
|
8
|
+
import { updateDomCssVariables } from './updateDomCssVariables';
|
|
9
|
+
import { Theme,createTheme } from '@mui/material';
|
|
10
|
+
|
|
11
|
+
interface DashThemeContextType {
|
|
12
|
+
theme: Theme;
|
|
13
|
+
themeOptions: ReturnType<typeof appTheme>;
|
|
14
|
+
updateFullTheme: (settings?: any) => void;
|
|
15
|
+
recreateTheme: (tenantSettings?: any) => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Create context with null as default - we'll check for this in the hook
|
|
19
|
+
const DashThemeContext = createContext<DashThemeContextType | null>(null);
|
|
20
|
+
|
|
21
|
+
// Custom hook that ensures context is used within provider
|
|
22
|
+
export const useDashThemeContext = () => {
|
|
23
|
+
const context = useContext(DashThemeContext);
|
|
24
|
+
if (!context) {
|
|
25
|
+
throw new Error('useDashThemeContext must be used within a DashThemeProvider');
|
|
26
|
+
}
|
|
27
|
+
return context;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
interface DashThemeProviderProps {
|
|
31
|
+
children?: React.ReactNode;
|
|
32
|
+
extendedOptions?: any;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const DashThemeProvider: React.FC<DashThemeProviderProps> = ({ extendedOptions, children }) => {
|
|
36
|
+
const [themeOptions, setThemeOptions] = useState<ReturnType<typeof appTheme>>(() => appTheme(extendedOptions));
|
|
37
|
+
const [theme, setTheme] = useState<Theme>(() => createTheme(appTheme(extendedOptions)));
|
|
38
|
+
//const { auth, authenticated } = useAuthContext();
|
|
39
|
+
|
|
40
|
+
const { mode } = useColorScheme();
|
|
41
|
+
/*const dashThemeType = useSelector((state: IDASHAppState<any, any, any>) =>
|
|
42
|
+
state.settings.themeType
|
|
43
|
+
);*/
|
|
44
|
+
|
|
45
|
+
// Helper function to get tenant settings
|
|
46
|
+
const getTenantSettings = () => {
|
|
47
|
+
const persistedTenantSettings = AuthPersistenceService.getTenantSettings();
|
|
48
|
+
|
|
49
|
+
return persistedTenantSettings || null;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Function to recreate the entire MUI theme with tenant settings
|
|
53
|
+
const recreateTheme = (tenantSettings?: any) => {
|
|
54
|
+
const settings = tenantSettings || getTenantSettings();
|
|
55
|
+
|
|
56
|
+
console.log('Recreating MUI theme with tenant settings:', settings);
|
|
57
|
+
|
|
58
|
+
// Create new theme options with tenant settings
|
|
59
|
+
const newThemeOptions = appTheme(
|
|
60
|
+
extendedOptions,
|
|
61
|
+
{
|
|
62
|
+
tenantSettings: settings,
|
|
63
|
+
colors: settings?.colors,
|
|
64
|
+
}
|
|
65
|
+
// Add any other tenant-specific theme customizations here
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Create new MUI theme
|
|
69
|
+
const newTheme = createTheme(newThemeOptions);
|
|
70
|
+
|
|
71
|
+
// Update state
|
|
72
|
+
setThemeOptions(newThemeOptions);
|
|
73
|
+
setTheme(newTheme);
|
|
74
|
+
|
|
75
|
+
// Also update CSS variables
|
|
76
|
+
if (settings?.colors || settings?.values) {
|
|
77
|
+
const currentTheme = mode || document.documentElement.getAttribute('data-theme') || 'light';
|
|
78
|
+
updateDomCssVariables(currentTheme, settings?.colors, settings?.values);
|
|
79
|
+
//document.documentElement.setAttribute('data-theme', currentTheme);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Function to update CSS variables (keep existing functionality)
|
|
84
|
+
const updateFullTheme = (colors?: any) => {
|
|
85
|
+
const tenantSettings = getTenantSettings();
|
|
86
|
+
const colorsToUse = colors || tenantSettings?.colors || {};
|
|
87
|
+
const valuesToUse = tenantSettings?.values || {};
|
|
88
|
+
console.log('Updating custom CSS variables with colors:', colorsToUse);
|
|
89
|
+
|
|
90
|
+
const currentTheme = mode || document.documentElement.getAttribute('data-theme') || 'light';
|
|
91
|
+
updateDomCssVariables(currentTheme, colorsToUse, valuesToUse);
|
|
92
|
+
//document.documentElement.setAttribute('data-theme', currentTheme);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// Recreate theme when user authenticates or tenant settings change
|
|
96
|
+
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
//if(!auth || !authenticated) {
|
|
99
|
+
|
|
100
|
+
const tenantSettings = getTenantSettings();
|
|
101
|
+
if (tenantSettings) {
|
|
102
|
+
console.log("recreating mui theme on mount")
|
|
103
|
+
recreateTheme(tenantSettings);
|
|
104
|
+
}
|
|
105
|
+
// }
|
|
106
|
+
}, []);
|
|
107
|
+
|
|
108
|
+
// Handle theme mode changes
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
|
|
111
|
+
//if (authenticated) {
|
|
112
|
+
const tenantSettings = getTenantSettings();
|
|
113
|
+
if (tenantSettings) {
|
|
114
|
+
|
|
115
|
+
console.log("recreating mui theme on mode change")
|
|
116
|
+
recreateTheme(tenantSettings);
|
|
117
|
+
}
|
|
118
|
+
//}
|
|
119
|
+
}, [mode/*, dashThemeType*/]);
|
|
120
|
+
|
|
121
|
+
// Create the context value object
|
|
122
|
+
const contextValue: DashThemeContextType = {
|
|
123
|
+
theme,
|
|
124
|
+
themeOptions,
|
|
125
|
+
updateFullTheme,
|
|
126
|
+
recreateTheme
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
console.log("mui theme updated",themeOptions,theme);
|
|
131
|
+
}, [themeOptions]);
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<DashThemeContext.Provider value={contextValue}>
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
{children}
|
|
138
|
+
|
|
139
|
+
</DashThemeContext.Provider>
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export default DashThemeContext;
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import React, { createContext, useContext, useState, useEffect } from 'react';
|
|
2
|
+
import { Theme, createTheme } from '@mui/material/styles';
|
|
3
|
+
import { appTheme } from 'dash-styles';
|
|
4
|
+
import { useAuthContext } from 'dash-admin';
|
|
5
|
+
import { useSelector } from 'react-redux';
|
|
6
|
+
import { IDASHAppState, DASH_THEME_SETTINGS } from 'dash-admin-state';
|
|
7
|
+
import { AuthPersistenceService } from 'dash-auth';
|
|
8
|
+
interface DashThemeContextType {
|
|
9
|
+
theme: Theme;
|
|
10
|
+
themeOptions: ReturnType<typeof appTheme>; // Expose theme options
|
|
11
|
+
updateFullTheme: (settings?: any) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const defaultThemeOptions = appTheme();
|
|
15
|
+
const defaultTheme = createTheme(defaultThemeOptions);
|
|
16
|
+
|
|
17
|
+
const DashThemeContext = createContext<DashThemeContextType>({
|
|
18
|
+
theme: defaultTheme,
|
|
19
|
+
themeOptions: defaultThemeOptions,
|
|
20
|
+
updateFullTheme: () => { }
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
let themeStyleElement: HTMLStyleElement | null = null;
|
|
24
|
+
export const updateDomCssVariables = (theme: string, colors: { [x: string]: string }) => {
|
|
25
|
+
|
|
26
|
+
const themeSuffix = `--${theme}`;
|
|
27
|
+
|
|
28
|
+
if (!themeStyleElement) {
|
|
29
|
+
themeStyleElement = document.createElement('style');
|
|
30
|
+
themeStyleElement.id = 'dash-theme-variables';
|
|
31
|
+
document.head.appendChild(themeStyleElement);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
let styleString = '';
|
|
36
|
+
Object.entries(colors).forEach(([key, value]) => {
|
|
37
|
+
if (key.endsWith(themeSuffix)) {
|
|
38
|
+
const baseKey = key.slice(0, -themeSuffix.length);
|
|
39
|
+
styleString += `--${baseKey}: ${value}; `;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
themeStyleElement.textContent = `:root { ${styleString} }`;
|
|
44
|
+
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
export const useDashThemeContext = () => useContext(DashThemeContext);
|
|
49
|
+
|
|
50
|
+
interface DashThemeProviderProps {
|
|
51
|
+
children?: React.ReactNode;
|
|
52
|
+
extendedOptions?: any;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const DashThemeProvider: React.FC<DashThemeProviderProps> = ({ extendedOptions, children }) => {
|
|
56
|
+
const [themeOptions, setThemeOptions] = useState<ReturnType<typeof appTheme>>(() => appTheme(extendedOptions));
|
|
57
|
+
const [theme, setTheme] = useState<Theme>(() => createTheme(appTheme(extendedOptions)));
|
|
58
|
+
const [cssVariablesCache, setCssVariablesCache] = useState<Record<string, string> | null>(null);
|
|
59
|
+
const { auth, authenticated } = useAuthContext();
|
|
60
|
+
|
|
61
|
+
// Get theme type from Redux state
|
|
62
|
+
const themeType = useSelector((state: IDASHAppState<any, any, any>) =>
|
|
63
|
+
state.settings.themeType
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// Helper function to get tenant settings (prioritize persisted over auth)
|
|
67
|
+
const getTenantSettings = () => {
|
|
68
|
+
// First try to get persisted tenant settings
|
|
69
|
+
const persistedTenantSettings = AuthPersistenceService.getTenantSettings();
|
|
70
|
+
if (persistedTenantSettings) {
|
|
71
|
+
return persistedTenantSettings;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Fallback to auth tenant settings if no persisted data
|
|
75
|
+
return auth?.tenantSettings || null;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const getAllCssVariablesFromStyleSheets = (selector: string) => {
|
|
79
|
+
if (cssVariablesCache) {
|
|
80
|
+
return cssVariablesCache;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const cssVariables = {};
|
|
84
|
+
|
|
85
|
+
// Loop through all style sheets
|
|
86
|
+
for (let i = 0; i < document.styleSheets.length; i++) {
|
|
87
|
+
try {
|
|
88
|
+
const styleSheet = document.styleSheets[i];
|
|
89
|
+
// Skip if the stylesheet is from a different origin and can't be accessed
|
|
90
|
+
if (!styleSheet.cssRules) continue;
|
|
91
|
+
|
|
92
|
+
// Loop through all CSS rules in the stylesheet
|
|
93
|
+
for (let j = 0; j < styleSheet.cssRules.length; j++) {
|
|
94
|
+
const rule = styleSheet.cssRules[j];
|
|
95
|
+
|
|
96
|
+
// Check if it's a style rule (type 1)
|
|
97
|
+
|
|
98
|
+
/* @ts-ignore */
|
|
99
|
+
if (rule.selectorText === selector) {
|
|
100
|
+
|
|
101
|
+
/* @ts-ignore */
|
|
102
|
+
const style = rule.style;
|
|
103
|
+
|
|
104
|
+
// Loop through all style properties
|
|
105
|
+
for (let k = 0; k < style.length; k++) {
|
|
106
|
+
const prop = style[k];
|
|
107
|
+
if (prop.startsWith('--')) {
|
|
108
|
+
//console.log(prop,style.getPropertyValue(prop).trim());
|
|
109
|
+
cssVariables[prop] = style.getPropertyValue(prop).trim();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
} catch (e) {
|
|
116
|
+
// Skip cross-origin stylesheets that throw security errors
|
|
117
|
+
console.warn('Could not access stylesheet:', e);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
setCssVariablesCache(cssVariables);
|
|
122
|
+
return cssVariables;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// Function to update CSS variables based on tenant settings
|
|
126
|
+
const updateCSSVariablesCopy = (themeType: string, settingsColors: { [x: string]: string }) => {
|
|
127
|
+
|
|
128
|
+
const root = document.documentElement
|
|
129
|
+
|
|
130
|
+
const _cssVars = getAllCssVariablesFromStyleSheets(":root");
|
|
131
|
+
|
|
132
|
+
const cssVars = Object.keys(_cssVars).filter(prop => prop.endsWith(`--${themeType}`));
|
|
133
|
+
cssVars.forEach(varName => {
|
|
134
|
+
//console.log(varName);
|
|
135
|
+
const baseVarName = varName.replace(`--${themeType}`, '');
|
|
136
|
+
const value = _cssVars[varName];
|
|
137
|
+
if (value) {
|
|
138
|
+
//console.log("replaced",themeType,baseVarName,value)
|
|
139
|
+
root.style.setProperty(baseVarName, value);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
if (!settingsColors) return;
|
|
144
|
+
// Update CSS specific variables from backend config
|
|
145
|
+
|
|
146
|
+
// Update any CSS variables that match the incoming settings
|
|
147
|
+
Object.entries(settingsColors).forEach(([key, value]) => {
|
|
148
|
+
const cssVar = `--${key}`;
|
|
149
|
+
root.style.setProperty(cssVar, value);
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// TODO: this is too slow, setting properties one by one.
|
|
154
|
+
const updateCSSVariables2 = (currentTheme, colors: { [x: string]: string }) => {
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
const themeSuffix = `--${currentTheme}`;
|
|
158
|
+
|
|
159
|
+
Object.entries(colors).forEach(([key, value]) => {
|
|
160
|
+
if (key.endsWith(themeSuffix)) {
|
|
161
|
+
const baseKey = key.slice(0, -themeSuffix.length);
|
|
162
|
+
document.documentElement.style.setProperty(`--${baseKey}`, String(value));
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// TODO: this method is faster, but still slow.
|
|
171
|
+
|
|
172
|
+
const updateCSSVariables3 = (currentTheme, colors: { [x: string]: string }) => {
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
const themeSuffix = `--${currentTheme}`;
|
|
176
|
+
|
|
177
|
+
let styleString = '';
|
|
178
|
+
Object.entries(colors).forEach(([key, value]) => {
|
|
179
|
+
if (key.endsWith(themeSuffix)) {
|
|
180
|
+
const baseKey = key.slice(0, -themeSuffix.length);
|
|
181
|
+
styleString += `--${baseKey}: ${value}; `;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
document.documentElement.setAttribute('style', styleString);
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
const updateCSSVariables = (currentTheme: string, colors: { [x: string]: string }) => {
|
|
193
|
+
const startTime = performance.now();
|
|
194
|
+
const themeSuffix = `--${currentTheme}`;
|
|
195
|
+
|
|
196
|
+
// Create or get existing style element
|
|
197
|
+
if (!themeStyleElement) {
|
|
198
|
+
themeStyleElement = document.createElement('style');
|
|
199
|
+
themeStyleElement.id = 'dash-theme-variables';
|
|
200
|
+
document.head.appendChild(themeStyleElement);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Build CSS rule
|
|
204
|
+
/*const cssVariables: string[] = [];
|
|
205
|
+
Object.entries(colors).forEach(([key, value]) => {
|
|
206
|
+
if (key.endsWith(themeSuffix)) {
|
|
207
|
+
const baseKey = key.slice(0, -themeSuffix.length);
|
|
208
|
+
cssVariables.push(`--${baseKey}: ${value}`);
|
|
209
|
+
}
|
|
210
|
+
});*/
|
|
211
|
+
|
|
212
|
+
let styleString = '';
|
|
213
|
+
Object.entries(colors).forEach(([key, value]) => {
|
|
214
|
+
if (key.endsWith(themeSuffix)) {
|
|
215
|
+
const baseKey = key.slice(0, -themeSuffix.length);
|
|
216
|
+
styleString += `--${baseKey}: ${value}; `;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Update the style element content in one operation
|
|
221
|
+
themeStyleElement.textContent = `:root { ${styleString} }`;
|
|
222
|
+
|
|
223
|
+
//const endTime = performance.now();
|
|
224
|
+
//console.log(`updateCSSVariables execution time: ${endTime - startTime}ms`);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// Function to recreate theme after CSS variables are updated
|
|
228
|
+
const updateFullTheme = (colors?: any) => {
|
|
229
|
+
|
|
230
|
+
// Get tenant settings from persisted data or auth
|
|
231
|
+
const tenantSettings = getTenantSettings();
|
|
232
|
+
const colorsToUse = colors || tenantSettings?.colors || {};
|
|
233
|
+
|
|
234
|
+
console.log('Updating theme with colors:', colorsToUse);
|
|
235
|
+
//console.log('Using tenant settings from:', tenantSettings ? 'persisted/auth data' : 'none available');
|
|
236
|
+
|
|
237
|
+
updateCSSVariables(themeType, colorsToUse);
|
|
238
|
+
|
|
239
|
+
/*
|
|
240
|
+
DEPRECTATED AS USING CSS VARS FOR MODE SWITCHING
|
|
241
|
+
// Determine which theme function to use based on theme type
|
|
242
|
+
let themeFunction = () => appTheme(extendedOptions);
|
|
243
|
+
|
|
244
|
+
// Recreate theme options with updated CSS variables and theme type
|
|
245
|
+
const newThemeOptions = themeFunction();
|
|
246
|
+
setThemeOptions(newThemeOptions);
|
|
247
|
+
|
|
248
|
+
// Create actual theme from options
|
|
249
|
+
const newTheme = createTheme(newThemeOptions);
|
|
250
|
+
setTheme(newTheme);
|
|
251
|
+
*/
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// Listen for tenant settings changes (both from auth and persisted)
|
|
255
|
+
useEffect(() => {
|
|
256
|
+
const tenantSettings = getTenantSettings();
|
|
257
|
+
|
|
258
|
+
if (tenantSettings?.colors) {
|
|
259
|
+
console.log('Tenant settings detected, updating theme');
|
|
260
|
+
updateFullTheme(tenantSettings.colors);
|
|
261
|
+
} else if (authenticated && auth) {
|
|
262
|
+
// Fallback to auth tenant settings if available
|
|
263
|
+
updateFullTheme(auth?.tenantSettings?.colors);
|
|
264
|
+
} else {
|
|
265
|
+
// Apply theme even without tenant settings (for theme type changes)
|
|
266
|
+
updateFullTheme();
|
|
267
|
+
}
|
|
268
|
+
}, [auth, authenticated]); // Remove auth?.tenantSettings from dependency since we're using getTenantSettings()
|
|
269
|
+
|
|
270
|
+
// Add this useEffect in the DashThemeProvider component:
|
|
271
|
+
useEffect(() => {
|
|
272
|
+
const handleThemeUpdate = (event: CustomEvent) => {
|
|
273
|
+
console.log('Theme update event received:', event.detail);
|
|
274
|
+
updateFullTheme(event.detail.colors);
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
window.addEventListener('dash-theme-update', handleThemeUpdate as EventListener);
|
|
278
|
+
|
|
279
|
+
return () => {
|
|
280
|
+
window.removeEventListener('dash-theme-update', handleThemeUpdate as EventListener);
|
|
281
|
+
};
|
|
282
|
+
}, [updateFullTheme]);
|
|
283
|
+
// Listen for theme type changes
|
|
284
|
+
useEffect(() => {
|
|
285
|
+
|
|
286
|
+
const tenantSettings = getTenantSettings();
|
|
287
|
+
updateFullTheme(tenantSettings?.colors);
|
|
288
|
+
}, [themeType]);
|
|
289
|
+
|
|
290
|
+
// Initialize theme on mount with persisted settings
|
|
291
|
+
useEffect(() => {
|
|
292
|
+
const tenantSettings = getTenantSettings();
|
|
293
|
+
if (tenantSettings?.colors) {
|
|
294
|
+
console.log('Initializing theme with persisted tenant settings');
|
|
295
|
+
updateFullTheme(tenantSettings.colors);
|
|
296
|
+
}
|
|
297
|
+
}, []); // Run only on mount
|
|
298
|
+
|
|
299
|
+
return (
|
|
300
|
+
<DashThemeContext.Provider value={{ theme, themeOptions, updateFullTheme }}>
|
|
301
|
+
{children}
|
|
302
|
+
</DashThemeContext.Provider>
|
|
303
|
+
);
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
export default DashThemeContext;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as T}from"react/jsx-runtime";import{createContext as c,useContext as l,useEffect as a}from"react";import{AuthPersistenceService as p}from"@dashadmin/dash-auth";import{useColorScheme as u}from"@mui/material/styles";import{updateDomCssVariables as f}from"@dashadmin/dash-utils";import{dashStorage as s}from"@dashadmin/dash-utils";const m=()=>{const r=s.getItem("theme");return r==="light"||r==="dark"?r:"dark"},d=c({mode:m()}),k=()=>l(d),g=({children:r})=>{const{mode:e,setMode:n}=u(),i=e==="light"||e==="dark"?e:m(),h=()=>{const t=p.getTenantSettings();return t||null};return a(()=>{const t=s.getItem("theme");if(t&&(t==="light"||t==="dark")&&e!==t)n(t);else if(!t){const o="dark";s.setItem("theme",o),document.documentElement.setAttribute("data-theme",o),n(o)}},[]),a(()=>{if(e!=="light"&&e!=="dark")return;const t=new CustomEvent("dash-theme-mode-switched",{detail:{mode:e}});window.dispatchEvent(t);const o=h();(o?.colors||o?.values)&&(s.setItem("theme",e),document.documentElement.setAttribute("data-theme",e),f(e,o?.colors||{},o?.values||{}))},[e]),T(d.Provider,{value:{mode:i},children:r})};var S=g;export{g as DashThemeHelperProvider,S as default,k as useDashThemeHelperContext};
|