@stackcraftmx/calcita 0.0.0-stage → 0.23.0
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/LICENSE +110 -0
- package/README.md +611 -2
- package/cli/askQuestions.js +63 -0
- package/cli/calcita.js +150 -0
- package/cli/makeComponent.js +50 -0
- package/cli/makeForm.js +68 -0
- package/cli/makeModule.js +78 -0
- package/cli/makePage.js +62 -0
- package/cli/names.js +64 -0
- package/cli/newProject.js +103 -0
- package/cli/packageVersions.js +38 -0
- package/cli/projectAnswers.js +145 -0
- package/cli/projectConfig.js +38 -0
- package/cli/projectFiles.js +126 -0
- package/cli/screenLabels.js +41 -0
- package/cli/templateFiles.js +186 -0
- package/cli/templates/component/core/__ComponentName__.jsx.tpl +23 -0
- package/cli/templates/component/module/__ComponentName__.jsx.tpl +21 -0
- package/cli/templates/form/formik/__FormName__.jsx.tpl +50 -0
- package/cli/templates/form/hookForm/__FormName__.jsx.tpl +53 -0
- package/cli/templates/form/shared/__formName__Schema.js.tpl +20 -0
- package/cli/templates/form/shared/__formName__Texts.js.tpl +6 -0
- package/cli/templates/module/__Name__Page.jsx.tpl +75 -0
- package/cli/templates/module/__name__Api.js.tpl +39 -0
- package/cli/templates/module/__name__Texts.js.tpl +27 -0
- package/cli/templates/module/menu.js.tpl +21 -0
- package/cli/templates/module/routes.js.tpl +7 -0
- package/cli/templates/moduleServer/__name__Server.js.tpl +68 -0
- package/cli/templates/page/__PageName__Page.jsx.tpl +22 -0
- package/cli/templates/page/__pageName__PageTexts.js.tpl +23 -0
- package/cli/templates/project/README.md.tpl +55 -0
- package/cli/templates/project/dot-gitignore.tpl +11 -0
- package/cli/templates/project/index.html.tpl +20 -0
- package/cli/templates/project/jsconfig.json.tpl +16 -0
- package/cli/templates/project/pnpm-workspace.yaml.tpl +5 -0
- package/cli/templates/project/public/favicon.svg +1 -0
- package/cli/templates/project/public/icons/apple-touch-icon.png +0 -0
- package/cli/templates/project/public/icons/icon-192.png +0 -0
- package/cli/templates/project/public/icons/icon-512-maskable.png +0 -0
- package/cli/templates/project/public/icons/icon-512.png +0 -0
- package/cli/templates/project/public/manifest.webmanifest.tpl +17 -0
- package/cli/templates/project/src/app/AppProviders.jsx.tpl +102 -0
- package/cli/templates/project/src/app/AppShell.jsx.tpl +87 -0
- package/cli/templates/project/src/app/appRouter.jsx.tpl +49 -0
- package/cli/templates/project/src/app/appSettings.js.tpl +13 -0
- package/cli/templates/project/src/app/appTexts.js.tpl +15 -0
- package/cli/templates/project/src/app/combineTexts.js.tpl +31 -0
- package/cli/templates/project/src/app/i18n.js.tpl +19 -0
- package/cli/templates/project/src/app/shellTexts.js.tpl +16 -0
- package/cli/templates/project/src/core/AppLogo.jsx.tpl +12 -0
- package/cli/templates/project/src/core/accountConnector.js.tpl +36 -0
- package/cli/templates/project/src/core/apiClient.js.tpl +15 -0
- package/cli/templates/project/src/core/appPaths.js.tpl +11 -0
- package/cli/templates/project/src/core/index.js.tpl +8 -0
- package/cli/templates/project/src/fakeServer/networkDelay.js.tpl +40 -0
- package/cli/templates/project/src/fakeServer/serverText.js.tpl +20 -0
- package/cli/templates/project/src/main.jsx.tpl +24 -0
- package/cli/templates/project/src/modules/auth/ForgotPasswordPage.jsx.tpl +14 -0
- package/cli/templates/project/src/modules/auth/ResetPasswordPage.jsx.tpl +15 -0
- package/cli/templates/project/src/modules/auth/SignInPage.jsx.tpl +29 -0
- package/cli/templates/project/src/modules/auth/authTexts.js.tpl +6 -0
- package/cli/templates/project/src/modules/auth/routes.js.tpl +11 -0
- package/cli/templates/project/src/modules/home/HomePage.jsx.tpl +38 -0
- package/cli/templates/project/src/modules/home/homeTexts.js.tpl +29 -0
- package/cli/templates/project/src/modules/home/menu.js.tpl +17 -0
- package/cli/templates/project/src/modules/home/routes.js.tpl +4 -0
- package/cli/templates/project/src/modules/profile/ProfilePage.jsx.tpl +13 -0
- package/cli/templates/project/src/modules/profile/routes.js.tpl +6 -0
- package/cli/templates/project/vite.config.js.tpl +27 -0
- package/dist/DataTable/AuditTrailDialog.js +40 -0
- package/dist/DataTable/AuditTrailDialog.js.map +1 -0
- package/dist/DataTable/AuditTrailTable.js +87 -0
- package/dist/DataTable/AuditTrailTable.js.map +1 -0
- package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js +71 -0
- package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js.map +1 -0
- package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js +50 -0
- package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js.map +1 -0
- package/dist/DataTable/ColumnFilters/SortableFilterHeader.js +54 -0
- package/dist/DataTable/ColumnFilters/SortableFilterHeader.js.map +1 -0
- package/dist/DataTable/ColumnFilters/TextColumnFilter.js +24 -0
- package/dist/DataTable/ColumnFilters/TextColumnFilter.js.map +1 -0
- package/dist/DataTable/EmptyState.js +22 -0
- package/dist/DataTable/EmptyState.js.map +1 -0
- package/dist/DataTable/FilterChips.js +39 -0
- package/dist/DataTable/FilterChips.js.map +1 -0
- package/dist/DataTable/GoToPage.js +62 -0
- package/dist/DataTable/GoToPage.js.map +1 -0
- package/dist/DataTable/ServerTable.js +407 -0
- package/dist/DataTable/ServerTable.js.map +1 -0
- package/dist/DataTable/buildChipConfig.js +27 -0
- package/dist/DataTable/buildChipConfig.js.map +1 -0
- package/dist/DataTable/columns.js +122 -0
- package/dist/DataTable/columns.js.map +1 -0
- package/dist/DataTable/filterContext.js +15 -0
- package/dist/DataTable/filterContext.js.map +1 -0
- package/dist/DataTable/serverTableParams.js +19 -0
- package/dist/DataTable/serverTableParams.js.map +1 -0
- package/dist/DataTable/tableMachine.js +87 -0
- package/dist/DataTable/tableMachine.js.map +1 -0
- package/dist/DataTable/useDebouncedFilter.js +29 -0
- package/dist/DataTable/useDebouncedFilter.js.map +1 -0
- package/dist/DataTable/useTableState.js +132 -0
- package/dist/DataTable/useTableState.js.map +1 -0
- package/dist/access/Can.js +9 -0
- package/dist/access/Can.js.map +1 -0
- package/dist/access/PermissionMatrix.js +83 -0
- package/dist/access/PermissionMatrix.js.map +1 -0
- package/dist/access/RequireAccess.js +14 -0
- package/dist/access/RequireAccess.js.map +1 -0
- package/dist/access/accessRules.js +49 -0
- package/dist/access/accessRules.js.map +1 -0
- package/dist/access/permissionGroups.js +43 -0
- package/dist/access/permissionGroups.js.map +1 -0
- package/dist/access/useCan.js +12 -0
- package/dist/access/useCan.js.map +1 -0
- package/dist/account/AccountProvider.js +58 -0
- package/dist/account/AccountProvider.js.map +1 -0
- package/dist/account/AccountSecuritySection.js +81 -0
- package/dist/account/AccountSecuritySection.js.map +1 -0
- package/dist/account/DemoTotpCodeButton.js +26 -0
- package/dist/account/DemoTotpCodeButton.js.map +1 -0
- package/dist/account/ForgotPasswordScreen.js +26 -0
- package/dist/account/ForgotPasswordScreen.js.map +1 -0
- package/dist/account/ProfileScreen.js +108 -0
- package/dist/account/ProfileScreen.js.map +1 -0
- package/dist/account/ResetPasswordScreen.js +57 -0
- package/dist/account/ResetPasswordScreen.js.map +1 -0
- package/dist/account/SignInScreen.js +101 -0
- package/dist/account/SignInScreen.js.map +1 -0
- package/dist/account/accountConnector.js +31 -0
- package/dist/account/accountConnector.js.map +1 -0
- package/dist/account/demo/createDemoAccountConnector.js +368 -0
- package/dist/account/demo/createDemoAccountConnector.js.map +1 -0
- package/dist/account/demo/totp.js +61 -0
- package/dist/account/demo/totp.js.map +1 -0
- package/dist/account/restAccountConnector.js +117 -0
- package/dist/account/restAccountConnector.js.map +1 -0
- package/dist/account-demo.js +12 -0
- package/dist/account-demo.js.map +1 -0
- package/dist/account.js +25 -0
- package/dist/account.js.map +1 -0
- package/dist/adapters/i18next.js +7 -0
- package/dist/adapters/i18next.js.map +1 -0
- package/dist/adapters/nextNavigation.js +36 -0
- package/dist/adapters/nextNavigation.js.map +1 -0
- package/dist/adapters/reactRouter.js +7 -0
- package/dist/adapters/reactRouter.js.map +1 -0
- package/dist/adapters/reactRouterRoutes.js +48 -0
- package/dist/adapters/reactRouterRoutes.js.map +1 -0
- package/dist/api/ApiError.js +58 -0
- package/dist/api/ApiError.js.map +1 -0
- package/dist/api/createApiClient.js +226 -0
- package/dist/api/createApiClient.js.map +1 -0
- package/dist/api/staleChunks.js +47 -0
- package/dist/api/staleChunks.js.map +1 -0
- package/dist/appShell/AccountMenu.js +86 -0
- package/dist/appShell/AccountMenu.js.map +1 -0
- package/dist/appShell/AppLayout.js +493 -0
- package/dist/appShell/AppLayout.js.map +1 -0
- package/dist/appShell/AppearanceSettings.js +93 -0
- package/dist/appShell/AppearanceSettings.js.map +1 -0
- package/dist/appShell/AuthLayout.js +44 -0
- package/dist/appShell/AuthLayout.js.map +1 -0
- package/dist/appShell/BarActionButton.js +31 -0
- package/dist/appShell/BarActionButton.js.map +1 -0
- package/dist/appShell/BarActions.js +94 -0
- package/dist/appShell/BarActions.js.map +1 -0
- package/dist/appShell/BarCapsule.js +35 -0
- package/dist/appShell/BarCapsule.js.map +1 -0
- package/dist/appShell/HeaderTools.js +53 -0
- package/dist/appShell/HeaderTools.js.map +1 -0
- package/dist/appShell/MobileTabBar.js +346 -0
- package/dist/appShell/MobileTabBar.js.map +1 -0
- package/dist/appShell/SettingsMenu.js +41 -0
- package/dist/appShell/SettingsMenu.js.map +1 -0
- package/dist/appShell/SideMenu.js +217 -0
- package/dist/appShell/SideMenu.js.map +1 -0
- package/dist/appShell/SideMenuEntry.js +140 -0
- package/dist/appShell/SideMenuEntry.js.map +1 -0
- package/dist/appShell/SubmenuActionsMenu.js +71 -0
- package/dist/appShell/SubmenuActionsMenu.js.map +1 -0
- package/dist/appShell/TabBarEditor.js +55 -0
- package/dist/appShell/TabBarEditor.js.map +1 -0
- package/dist/appShell/TopMenu.js +80 -0
- package/dist/appShell/TopMenu.js.map +1 -0
- package/dist/appShell/appMenuContext.js +11 -0
- package/dist/appShell/appMenuContext.js.map +1 -0
- package/dist/appShell/barActionsSlot.js +26 -0
- package/dist/appShell/barActionsSlot.js.map +1 -0
- package/dist/appShell/barMenuPlacement.js +33 -0
- package/dist/appShell/barMenuPlacement.js.map +1 -0
- package/dist/appShell/menuItemText.js +33 -0
- package/dist/appShell/menuItemText.js.map +1 -0
- package/dist/appShell/pageTitle.js +45 -0
- package/dist/appShell/pageTitle.js.map +1 -0
- package/dist/appShell/shellSizes.js +38 -0
- package/dist/appShell/shellSizes.js.map +1 -0
- package/dist/appShell/tabBarRule.js +12 -0
- package/dist/appShell/tabBarRule.js.map +1 -0
- package/dist/appShell/tabBarScroll.js +23 -0
- package/dist/appShell/tabBarScroll.js.map +1 -0
- package/dist/appShell/useDrawerCollapsed.js +29 -0
- package/dist/appShell/useDrawerCollapsed.js.map +1 -0
- package/dist/appShell/useFittingActionCount.js +45 -0
- package/dist/appShell/useFittingActionCount.js.map +1 -0
- package/dist/appShell/usePinnedMobileTabs.js +32 -0
- package/dist/appShell/usePinnedMobileTabs.js.map +1 -0
- package/dist/appShell/useTabBarMinimized.js +33 -0
- package/dist/appShell/useTabBarMinimized.js.map +1 -0
- package/dist/auth/PasswordChecklist.js +44 -0
- package/dist/auth/PasswordChecklist.js.map +1 -0
- package/dist/auth/passwordRules.js +43 -0
- package/dist/auth/passwordRules.js.map +1 -0
- package/dist/calendar/EventCalendar.js +138 -0
- package/dist/calendar/EventCalendar.js.map +1 -0
- package/dist/calendar.js +6 -0
- package/dist/calendar.js.map +1 -0
- package/dist/charts.js +7 -0
- package/dist/charts.js.map +1 -0
- package/dist/date-pickers.js +8 -0
- package/dist/date-pickers.js.map +1 -0
- package/dist/datePickers/DateInput.js +75 -0
- package/dist/datePickers/DateInput.js.map +1 -0
- package/dist/datePickers/FormDateField.js +12 -0
- package/dist/datePickers/FormDateField.js.map +1 -0
- package/dist/dates.js +25 -0
- package/dist/dates.js.map +1 -0
- package/dist/dictionaries/dictionaries.js +48 -0
- package/dist/dictionaries/dictionaries.js.map +1 -0
- package/dist/downloads/DownloadManager.js +201 -0
- package/dist/downloads/DownloadManager.js.map +1 -0
- package/dist/downloads/downloadQueue.js +54 -0
- package/dist/downloads/downloadQueue.js.map +1 -0
- package/dist/downloads/downloadsMachine.js +77 -0
- package/dist/downloads/downloadsMachine.js.map +1 -0
- package/dist/excel/reportWorkbook.js +299 -0
- package/dist/excel/reportWorkbook.js.map +1 -0
- package/dist/excel.js +13 -0
- package/dist/excel.js.map +1 -0
- package/dist/feedback/ConfirmDialog.js +72 -0
- package/dist/feedback/ConfirmDialog.js.map +1 -0
- package/dist/feedback/ModalWaiting.js +23 -0
- package/dist/feedback/ModalWaiting.js.map +1 -0
- package/dist/feedback/NewBuildNotice.js +79 -0
- package/dist/feedback/NewBuildNotice.js.map +1 -0
- package/dist/feedback/StaleBuildBoundary.js +36 -0
- package/dist/feedback/StaleBuildBoundary.js.map +1 -0
- package/dist/feedback/Toaster.js +20 -0
- package/dist/feedback/Toaster.js.map +1 -0
- package/dist/feedback/confirmActionMachine.js +67 -0
- package/dist/feedback/confirmActionMachine.js.map +1 -0
- package/dist/feedback/toast.js +88 -0
- package/dist/feedback/toast.js.map +1 -0
- package/dist/feedback/useConfirmAction.js +40 -0
- package/dist/feedback/useConfirmAction.js.map +1 -0
- package/dist/filepond/FileDropzone.js +254 -0
- package/dist/filepond/FileDropzone.js.map +1 -0
- package/dist/filepond/pondServer.js +48 -0
- package/dist/filepond/pondServer.js.map +1 -0
- package/dist/filepond.js +10 -0
- package/dist/filepond.js.map +1 -0
- package/dist/files.js +43 -0
- package/dist/files.js.map +1 -0
- package/dist/formatting.js +177 -0
- package/dist/formatting.js.map +1 -0
- package/dist/forms/FormCatalogField.js +12 -0
- package/dist/forms/FormCatalogField.js.map +1 -0
- package/dist/forms/FormColorField.js +12 -0
- package/dist/forms/FormColorField.js.map +1 -0
- package/dist/forms/FormNumberField.js +12 -0
- package/dist/forms/FormNumberField.js.map +1 -0
- package/dist/forms/FormProblemAlert.js +15 -0
- package/dist/forms/FormProblemAlert.js.map +1 -0
- package/dist/forms/FormSelectField.js +12 -0
- package/dist/forms/FormSelectField.js.map +1 -0
- package/dist/forms/FormServerProblem.js +23 -0
- package/dist/forms/FormServerProblem.js.map +1 -0
- package/dist/forms/FormTextField.js +12 -0
- package/dist/forms/FormTextField.js.map +1 -0
- package/dist/forms/FormWizard.js +90 -0
- package/dist/forms/FormWizard.js.map +1 -0
- package/dist/forms/SubmitButton.js +14 -0
- package/dist/forms/SubmitButton.js.map +1 -0
- package/dist/forms/applyServerProblem.js +15 -0
- package/dist/forms/applyServerProblem.js.map +1 -0
- package/dist/forms/auth/ChangePasswordForm.js +46 -0
- package/dist/forms/auth/ChangePasswordForm.js.map +1 -0
- package/dist/forms/auth/ForgotPasswordForm.js +50 -0
- package/dist/forms/auth/ForgotPasswordForm.js.map +1 -0
- package/dist/forms/auth/SignInForm.js +48 -0
- package/dist/forms/auth/SignInForm.js.map +1 -0
- package/dist/forms/security/SecondStepForm.js +122 -0
- package/dist/forms/security/SecondStepForm.js.map +1 -0
- package/dist/forms/security/TwoStepVerificationCard.js +336 -0
- package/dist/forms/security/TwoStepVerificationCard.js.map +1 -0
- package/dist/forms/security/securityRules.js +28 -0
- package/dist/forms/security/securityRules.js.map +1 -0
- package/dist/forms/serverProblemFields.js +25 -0
- package/dist/forms/serverProblemFields.js.map +1 -0
- package/dist/forms/useFormikField.js +16 -0
- package/dist/forms/useFormikField.js.map +1 -0
- package/dist/forms/validation.js +55 -0
- package/dist/forms/validation.js.map +1 -0
- package/dist/forms/validationMessages.js +16 -0
- package/dist/forms/validationMessages.js.map +1 -0
- package/dist/forms.js +57 -0
- package/dist/forms.js.map +1 -0
- package/dist/hookForm/FormCatalogField.js +12 -0
- package/dist/hookForm/FormCatalogField.js.map +1 -0
- package/dist/hookForm/FormColorField.js +12 -0
- package/dist/hookForm/FormColorField.js.map +1 -0
- package/dist/hookForm/FormNumberField.js +12 -0
- package/dist/hookForm/FormNumberField.js.map +1 -0
- package/dist/hookForm/FormProblemAlert.js +17 -0
- package/dist/hookForm/FormProblemAlert.js.map +1 -0
- package/dist/hookForm/FormSelectField.js +12 -0
- package/dist/hookForm/FormSelectField.js.map +1 -0
- package/dist/hookForm/FormTextField.js +12 -0
- package/dist/hookForm/FormTextField.js.map +1 -0
- package/dist/hookForm/SubmitButton.js +15 -0
- package/dist/hookForm/SubmitButton.js.map +1 -0
- package/dist/hookForm/applyServerProblem.js +21 -0
- package/dist/hookForm/applyServerProblem.js.map +1 -0
- package/dist/hookForm/useHookFormField.js +19 -0
- package/dist/hookForm/useHookFormField.js.map +1 -0
- package/dist/i18next.js +5 -0
- package/dist/i18next.js.map +1 -0
- package/dist/identifiers.js +8 -0
- package/dist/identifiers.js.map +1 -0
- package/dist/inbox/InboxLayout.js +68 -0
- package/dist/inbox/InboxLayout.js.map +1 -0
- package/dist/inbox/MessageList.js +64 -0
- package/dist/inbox/MessageList.js.map +1 -0
- package/dist/inbox/MessageView.js +53 -0
- package/dist/inbox/MessageView.js.map +1 -0
- package/dist/inbox/inboxDates.js +8 -0
- package/dist/inbox/inboxDates.js.map +1 -0
- package/dist/index.js +383 -0
- package/dist/index.js.map +1 -0
- package/dist/inputs/CatalogInput.js +62 -0
- package/dist/inputs/CatalogInput.js.map +1 -0
- package/dist/inputs/ColorInput.js +108 -0
- package/dist/inputs/ColorInput.js.map +1 -0
- package/dist/inputs/FieldFrame.js +20 -0
- package/dist/inputs/FieldFrame.js.map +1 -0
- package/dist/inputs/FormSection.js +105 -0
- package/dist/inputs/FormSection.js.map +1 -0
- package/dist/inputs/NumberInput.js +69 -0
- package/dist/inputs/NumberInput.js.map +1 -0
- package/dist/inputs/SelectInput.js +66 -0
- package/dist/inputs/SelectInput.js.map +1 -0
- package/dist/inputs/TextInput.js +97 -0
- package/dist/inputs/TextInput.js.map +1 -0
- package/dist/inputs/colorContrast.js +46 -0
- package/dist/inputs/colorContrast.js.map +1 -0
- package/dist/inputs/formLayoutContext.js +9 -0
- package/dist/inputs/formLayoutContext.js.map +1 -0
- package/dist/inputs/numberText.js +48 -0
- package/dist/inputs/numberText.js.map +1 -0
- package/dist/kanban/KanbanBoard.js +113 -0
- package/dist/kanban/KanbanBoard.js.map +1 -0
- package/dist/kanban/kanbanMoves.js +29 -0
- package/dist/kanban/kanbanMoves.js.map +1 -0
- package/dist/kanban.js +9 -0
- package/dist/kanban.js.map +1 -0
- package/dist/laravel/csrfRetry.js +18 -0
- package/dist/laravel/csrfRetry.js.map +1 -0
- package/dist/laravel.js +6 -0
- package/dist/laravel.js.map +1 -0
- package/dist/lastListUrl.js +35 -0
- package/dist/lastListUrl.js.map +1 -0
- package/dist/locales/en.js +714 -0
- package/dist/locales/en.js.map +1 -0
- package/dist/locales/es.js +714 -0
- package/dist/locales/es.js.map +1 -0
- package/dist/maps/MapView.js +96 -0
- package/dist/maps/MapView.js.map +1 -0
- package/dist/maps/mapMarkers.js +19 -0
- package/dist/maps/mapMarkers.js.map +1 -0
- package/dist/maps.js +10 -0
- package/dist/maps.js.map +1 -0
- package/dist/money/money.js +380 -0
- package/dist/money/money.js.map +1 -0
- package/dist/money.js +6 -0
- package/dist/money.js.map +1 -0
- package/dist/navigation/appMenu.js +93 -0
- package/dist/navigation/appMenu.js.map +1 -0
- package/dist/navigation/useMenuBadges.js +45 -0
- package/dist/navigation/useMenuBadges.js.map +1 -0
- package/dist/navigation.js +30 -0
- package/dist/navigation.js.map +1 -0
- package/dist/navigationTrail.js +82 -0
- package/dist/navigationTrail.js.map +1 -0
- package/dist/next.js +5 -0
- package/dist/next.js.map +1 -0
- package/dist/observability/buildWatch.js +19 -0
- package/dist/observability/buildWatch.js.map +1 -0
- package/dist/observability/logger.js +43 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/observability/publishedBuild.js +39 -0
- package/dist/observability/publishedBuild.js.map +1 -0
- package/dist/observability/usePublishedBuildWatch.js +76 -0
- package/dist/observability/usePublishedBuildWatch.js.map +1 -0
- package/dist/passkeys.js +7 -0
- package/dist/passkeys.js.map +1 -0
- package/dist/periodRanges.js +33 -0
- package/dist/periodRanges.js.map +1 -0
- package/dist/problems.js +51 -0
- package/dist/problems.js.map +1 -0
- package/dist/pwa/InstallAppSetting.js +33 -0
- package/dist/pwa/InstallAppSetting.js.map +1 -0
- package/dist/pwa/InstallInstructionsDialog.js +35 -0
- package/dist/pwa/InstallInstructionsDialog.js.map +1 -0
- package/dist/pwa/InstallPromptBanner.js +64 -0
- package/dist/pwa/InstallPromptBanner.js.map +1 -0
- package/dist/pwa/installInstructions.js +60 -0
- package/dist/pwa/installInstructions.js.map +1 -0
- package/dist/pwa/useInstallPrompt.js +70 -0
- package/dist/pwa/useInstallPrompt.js.map +1 -0
- package/dist/react-hook-form.js +30 -0
- package/dist/react-hook-form.js.map +1 -0
- package/dist/react-router.js +10 -0
- package/dist/react-router.js.map +1 -0
- package/dist/security/ActivityLog.js +79 -0
- package/dist/security/ActivityLog.js.map +1 -0
- package/dist/security/RecoveryCodesDialog.js +84 -0
- package/dist/security/RecoveryCodesDialog.js.map +1 -0
- package/dist/security/SessionsCard.js +81 -0
- package/dist/security/SessionsCard.js.map +1 -0
- package/dist/security/passkeys.js +39 -0
- package/dist/security/passkeys.js.map +1 -0
- package/dist/table.js +35 -0
- package/dist/table.js.map +1 -0
- package/dist/theme/androidDevice.js +16 -0
- package/dist/theme/androidDevice.js.map +1 -0
- package/dist/theme/appleTracking.js +34 -0
- package/dist/theme/appleTracking.js.map +1 -0
- package/dist/theme/components/MuiAppBar.js +27 -0
- package/dist/theme/components/MuiAppBar.js.map +1 -0
- package/dist/theme/components/MuiBackdrop.js +13 -0
- package/dist/theme/components/MuiBackdrop.js.map +1 -0
- package/dist/theme/components/MuiButton.js +25 -0
- package/dist/theme/components/MuiButton.js.map +1 -0
- package/dist/theme/components/MuiButtonBase.js +16 -0
- package/dist/theme/components/MuiButtonBase.js.map +1 -0
- package/dist/theme/components/MuiChip.js +30 -0
- package/dist/theme/components/MuiChip.js.map +1 -0
- package/dist/theme/components/MuiDataGrid.js +30 -0
- package/dist/theme/components/MuiDataGrid.js.map +1 -0
- package/dist/theme/components/MuiDrawer.js +18 -0
- package/dist/theme/components/MuiDrawer.js.map +1 -0
- package/dist/theme/components/MuiMenuItem.js +17 -0
- package/dist/theme/components/MuiMenuItem.js.map +1 -0
- package/dist/theme/components/MuiTypography.js +22 -0
- package/dist/theme/components/MuiTypography.js.map +1 -0
- package/dist/theme/components/glassComponents.js +885 -0
- package/dist/theme/components/glassComponents.js.map +1 -0
- package/dist/theme/components/minimalComponents.js +146 -0
- package/dist/theme/components/minimalComponents.js.map +1 -0
- package/dist/theme/components/paletteOf.js +7 -0
- package/dist/theme/components/paletteOf.js.map +1 -0
- package/dist/theme/createToolkitTheme.js +100 -0
- package/dist/theme/createToolkitTheme.js.map +1 -0
- package/dist/theme/glassSurface.js +328 -0
- package/dist/theme/glassSurface.js.map +1 -0
- package/dist/theme/glassToasterStyles.js +50 -0
- package/dist/theme/glassToasterStyles.js.map +1 -0
- package/dist/theme/mergeComponents.js +42 -0
- package/dist/theme/mergeComponents.js.map +1 -0
- package/dist/theme/stackcraftPalette.js +59 -0
- package/dist/theme/stackcraftPalette.js.map +1 -0
- package/dist/theme/toolkitComponents.js +26 -0
- package/dist/theme/toolkitComponents.js.map +1 -0
- package/dist/timeline.js +8 -0
- package/dist/timeline.js.map +1 -0
- package/dist/toolkit/ToolkitProvider.js +49 -0
- package/dist/toolkit/ToolkitProvider.js.map +1 -0
- package/dist/toolkit/browserNavigation.js +34 -0
- package/dist/toolkit/browserNavigation.js.map +1 -0
- package/dist/toolkit/toolkitContext.js +19 -0
- package/dist/toolkit/toolkitContext.js.map +1 -0
- package/dist/toolkit/toolkitSettings.js +87 -0
- package/dist/toolkit/toolkitSettings.js.map +1 -0
- package/dist/toolkit/useToolkitTranslation.js +18 -0
- package/dist/toolkit/useToolkitTranslation.js.map +1 -0
- package/dist/types/DataTable/AuditTrailDialog.d.ts +32 -0
- package/dist/types/DataTable/AuditTrailTable.d.ts +28 -0
- package/dist/types/DataTable/ColumnFilters/HeaderFilterPopover.d.ts +8 -0
- package/dist/types/DataTable/ColumnFilters/MultiSelectColumnFilter.d.ts +16 -0
- package/dist/types/DataTable/ColumnFilters/SortableFilterHeader.d.ts +26 -0
- package/dist/types/DataTable/ColumnFilters/TextColumnFilter.d.ts +8 -0
- package/dist/types/DataTable/ColumnFilters/index.d.ts +4 -0
- package/dist/types/DataTable/EmptyState.d.ts +8 -0
- package/dist/types/DataTable/FilterChips.d.ts +15 -0
- package/dist/types/DataTable/GoToPage.d.ts +8 -0
- package/dist/types/DataTable/ServerTable.d.ts +110 -0
- package/dist/types/DataTable/buildChipConfig.d.ts +22 -0
- package/dist/types/DataTable/columns.d.ts +93 -0
- package/dist/types/DataTable/filterContext.d.ts +13 -0
- package/dist/types/DataTable/index.d.ts +13 -0
- package/dist/types/DataTable/serverTableParams.d.ts +16 -0
- package/dist/types/DataTable/tableMachine.d.ts +41 -0
- package/dist/types/DataTable/useDebouncedFilter.d.ts +8 -0
- package/dist/types/DataTable/useTableState.d.ts +93 -0
- package/dist/types/access/Can.d.ts +11 -0
- package/dist/types/access/PermissionMatrix.d.ts +21 -0
- package/dist/types/access/RequireAccess.d.ts +11 -0
- package/dist/types/access/accessRules.d.ts +24 -0
- package/dist/types/access/permissionGroups.d.ts +56 -0
- package/dist/types/access/useCan.d.ts +11 -0
- package/dist/types/account/AccountProvider.d.ts +27 -0
- package/dist/types/account/AccountSecuritySection.d.ts +7 -0
- package/dist/types/account/DemoTotpCodeButton.d.ts +6 -0
- package/dist/types/account/ForgotPasswordScreen.d.ts +15 -0
- package/dist/types/account/ProfileScreen.d.ts +13 -0
- package/dist/types/account/ResetPasswordScreen.d.ts +19 -0
- package/dist/types/account/SignInScreen.d.ts +25 -0
- package/dist/types/account/accountConnector.d.ts +263 -0
- package/dist/types/account/demo/createDemoAccountConnector.d.ts +30 -0
- package/dist/types/account/demo/totp.d.ts +45 -0
- package/dist/types/account/restAccountConnector.d.ts +49 -0
- package/dist/types/account-demo.d.ts +2 -0
- package/dist/types/account.d.ts +16 -0
- package/dist/types/adapters/i18next.d.ts +11 -0
- package/dist/types/adapters/nextNavigation.d.ts +33 -0
- package/dist/types/adapters/reactRouter.d.ts +6 -0
- package/dist/types/adapters/reactRouterRoutes.d.ts +30 -0
- package/dist/types/api/ApiError.d.ts +42 -0
- package/dist/types/api/createApiClient.d.ts +146 -0
- package/dist/types/api/staleChunks.d.ts +15 -0
- package/dist/types/appShell/AccountMenu.d.ts +28 -0
- package/dist/types/appShell/AppLayout.d.ts +66 -0
- package/dist/types/appShell/AppearanceSettings.d.ts +34 -0
- package/dist/types/appShell/AuthLayout.d.ts +21 -0
- package/dist/types/appShell/BarActionButton.d.ts +15 -0
- package/dist/types/appShell/BarActions.d.ts +18 -0
- package/dist/types/appShell/BarCapsule.d.ts +12 -0
- package/dist/types/appShell/HeaderTools.d.ts +27 -0
- package/dist/types/appShell/MobileTabBar.d.ts +17 -0
- package/dist/types/appShell/SettingsMenu.d.ts +13 -0
- package/dist/types/appShell/SideMenu.d.ts +31 -0
- package/dist/types/appShell/SideMenuEntry.d.ts +17 -0
- package/dist/types/appShell/SubmenuActionsMenu.d.ts +24 -0
- package/dist/types/appShell/TabBarEditor.d.ts +13 -0
- package/dist/types/appShell/TopMenu.d.ts +7 -0
- package/dist/types/appShell/appMenuContext.d.ts +9 -0
- package/dist/types/appShell/barActionsSlot.d.ts +35 -0
- package/dist/types/appShell/barMenuPlacement.d.ts +9 -0
- package/dist/types/appShell/menuItemText.d.ts +55 -0
- package/dist/types/appShell/pageTitle.d.ts +26 -0
- package/dist/types/appShell/shellSizes.d.ts +45 -0
- package/dist/types/appShell/tabBarRule.d.ts +5 -0
- package/dist/types/appShell/tabBarScroll.d.ts +26 -0
- package/dist/types/appShell/useDrawerCollapsed.d.ts +8 -0
- package/dist/types/appShell/useFittingActionCount.d.ts +7 -0
- package/dist/types/appShell/usePinnedMobileTabs.d.ts +7 -0
- package/dist/types/appShell/useTabBarMinimized.d.ts +8 -0
- package/dist/types/auth/PasswordChecklist.d.ts +11 -0
- package/dist/types/auth/passwordRules.d.ts +34 -0
- package/dist/types/calendar/EventCalendar.d.ts +46 -0
- package/dist/types/calendar.d.ts +1 -0
- package/dist/types/charts.d.ts +2 -0
- package/dist/types/date-pickers.d.ts +2 -0
- package/dist/types/datePickers/DateInput.d.ts +39 -0
- package/dist/types/datePickers/FormDateField.d.ts +7 -0
- package/dist/types/dates.d.ts +18 -0
- package/dist/types/dictionaries/dictionaries.d.ts +54 -0
- package/dist/types/downloads/DownloadManager.d.ts +1 -0
- package/dist/types/downloads/downloadQueue.d.ts +45 -0
- package/dist/types/downloads/downloadsMachine.d.ts +10 -0
- package/dist/types/downloads/index.d.ts +3 -0
- package/dist/types/excel/reportWorkbook.d.ts +157 -0
- package/dist/types/excel.d.ts +1 -0
- package/dist/types/feedback/ConfirmDialog.d.ts +29 -0
- package/dist/types/feedback/ModalWaiting.d.ts +8 -0
- package/dist/types/feedback/NewBuildNotice.d.ts +18 -0
- package/dist/types/feedback/StaleBuildBoundary.d.ts +21 -0
- package/dist/types/feedback/Toaster.d.ts +1 -0
- package/dist/types/feedback/confirmActionMachine.d.ts +19 -0
- package/dist/types/feedback/index.d.ts +8 -0
- package/dist/types/feedback/toast.d.ts +100 -0
- package/dist/types/feedback/useConfirmAction.d.ts +33 -0
- package/dist/types/filepond/FileDropzone.d.ts +59 -0
- package/dist/types/filepond/pondServer.d.ts +17 -0
- package/dist/types/filepond.d.ts +3 -0
- package/dist/types/files.d.ts +29 -0
- package/dist/types/formatting.d.ts +106 -0
- package/dist/types/forms/FormCatalogField.d.ts +6 -0
- package/dist/types/forms/FormColorField.d.ts +6 -0
- package/dist/types/forms/FormNumberField.d.ts +6 -0
- package/dist/types/forms/FormProblemAlert.d.ts +6 -0
- package/dist/types/forms/FormSelectField.d.ts +6 -0
- package/dist/types/forms/FormServerProblem.d.ts +8 -0
- package/dist/types/forms/FormTextField.d.ts +6 -0
- package/dist/types/forms/FormWizard.d.ts +20 -0
- package/dist/types/forms/SubmitButton.d.ts +9 -0
- package/dist/types/forms/applyServerProblem.d.ts +9 -0
- package/dist/types/forms/auth/ChangePasswordForm.d.ts +15 -0
- package/dist/types/forms/auth/ForgotPasswordForm.d.ts +12 -0
- package/dist/types/forms/auth/SignInForm.d.ts +18 -0
- package/dist/types/forms/index.d.ts +19 -0
- package/dist/types/forms/security/SecondStepForm.d.ts +28 -0
- package/dist/types/forms/security/TwoStepVerificationCard.d.ts +81 -0
- package/dist/types/forms/security/securityRules.d.ts +24 -0
- package/dist/types/forms/serverProblemFields.d.ts +19 -0
- package/dist/types/forms/useFormikField.d.ts +11 -0
- package/dist/types/forms/validation.d.ts +251 -0
- package/dist/types/forms/validationMessages.d.ts +12 -0
- package/dist/types/forms.d.ts +2 -0
- package/dist/types/hookForm/FormCatalogField.d.ts +8 -0
- package/dist/types/hookForm/FormColorField.d.ts +8 -0
- package/dist/types/hookForm/FormNumberField.d.ts +8 -0
- package/dist/types/hookForm/FormProblemAlert.d.ts +7 -0
- package/dist/types/hookForm/FormSelectField.d.ts +8 -0
- package/dist/types/hookForm/FormTextField.d.ts +8 -0
- package/dist/types/hookForm/SubmitButton.d.ts +21 -0
- package/dist/types/hookForm/applyServerProblem.d.ts +10 -0
- package/dist/types/hookForm/useHookFormField.d.ts +13 -0
- package/dist/types/i18next.d.ts +1 -0
- package/dist/types/identifiers.d.ts +2 -0
- package/dist/types/inbox/InboxLayout.d.ts +26 -0
- package/dist/types/inbox/MessageList.d.ts +27 -0
- package/dist/types/inbox/MessageView.d.ts +23 -0
- package/dist/types/inbox/inboxDates.d.ts +6 -0
- package/dist/types/index.d.ts +84 -0
- package/dist/types/inputs/CatalogInput.d.ts +41 -0
- package/dist/types/inputs/ColorInput.d.ts +28 -0
- package/dist/types/inputs/FieldFrame.d.ts +14 -0
- package/dist/types/inputs/FormSection.d.ts +29 -0
- package/dist/types/inputs/NumberInput.d.ts +36 -0
- package/dist/types/inputs/SelectInput.d.ts +34 -0
- package/dist/types/inputs/TextInput.d.ts +60 -0
- package/dist/types/inputs/colorContrast.d.ts +18 -0
- package/dist/types/inputs/formLayoutContext.d.ts +3 -0
- package/dist/types/inputs/numberText.d.ts +25 -0
- package/dist/types/kanban/KanbanBoard.d.ts +33 -0
- package/dist/types/kanban/kanbanMoves.d.ts +38 -0
- package/dist/types/kanban.d.ts +2 -0
- package/dist/types/laravel/csrfRetry.d.ts +21 -0
- package/dist/types/laravel.d.ts +1 -0
- package/dist/types/lastListUrl.d.ts +20 -0
- package/dist/types/locales/en.d.ts +711 -0
- package/dist/types/locales/es.d.ts +711 -0
- package/dist/types/maps/MapView.d.ts +32 -0
- package/dist/types/maps/mapMarkers.d.ts +23 -0
- package/dist/types/maps.d.ts +2 -0
- package/dist/types/money/money.d.ts +203 -0
- package/dist/types/money.d.ts +1 -0
- package/dist/types/navigation/appMenu.d.ts +92 -0
- package/dist/types/navigation/useMenuBadges.d.ts +16 -0
- package/dist/types/navigation.d.ts +22 -0
- package/dist/types/navigationTrail.d.ts +49 -0
- package/dist/types/next.d.ts +1 -0
- package/dist/types/observability/buildWatch.d.ts +28 -0
- package/dist/types/observability/logger.d.ts +19 -0
- package/dist/types/observability/publishedBuild.d.ts +35 -0
- package/dist/types/observability/usePublishedBuildWatch.d.ts +16 -0
- package/dist/types/passkeys.d.ts +1 -0
- package/dist/types/periodRanges.d.ts +32 -0
- package/dist/types/problems.d.ts +31 -0
- package/dist/types/pwa/InstallAppSetting.d.ts +1 -0
- package/dist/types/pwa/InstallInstructionsDialog.d.ts +18 -0
- package/dist/types/pwa/InstallPromptBanner.d.ts +7 -0
- package/dist/types/pwa/installInstructions.d.ts +52 -0
- package/dist/types/pwa/useInstallPrompt.d.ts +12 -0
- package/dist/types/react-hook-form.d.ts +11 -0
- package/dist/types/react-router.d.ts +2 -0
- package/dist/types/security/ActivityLog.d.ts +31 -0
- package/dist/types/security/RecoveryCodesDialog.d.ts +11 -0
- package/dist/types/security/SessionsCard.d.ts +22 -0
- package/dist/types/security/passkeys.d.ts +18 -0
- package/dist/types/table.d.ts +1 -0
- package/dist/types/theme/androidDevice.d.ts +11 -0
- package/dist/types/theme/appleTracking.d.ts +17 -0
- package/dist/types/theme/components/MuiAppBar.d.ts +13 -0
- package/dist/types/theme/components/MuiBackdrop.d.ts +11 -0
- package/dist/types/theme/components/MuiButton.d.ts +27 -0
- package/dist/types/theme/components/MuiButtonBase.d.ts +14 -0
- package/dist/types/theme/components/MuiChip.d.ts +29 -0
- package/dist/types/theme/components/MuiDataGrid.d.ts +45 -0
- package/dist/types/theme/components/MuiDrawer.d.ts +13 -0
- package/dist/types/theme/components/MuiMenuItem.d.ts +17 -0
- package/dist/types/theme/components/MuiTypography.d.ts +20 -0
- package/dist/types/theme/components/glassComponents.d.ts +8 -0
- package/dist/types/theme/components/minimalComponents.d.ts +22 -0
- package/dist/types/theme/components/paletteOf.d.ts +5 -0
- package/dist/types/theme/createToolkitTheme.d.ts +48 -0
- package/dist/types/theme/glassSurface.d.ts +247 -0
- package/dist/types/theme/glassToasterStyles.d.ts +7 -0
- package/dist/types/theme/mergeComponents.d.ts +15 -0
- package/dist/types/theme/stackcraftPalette.d.ts +142 -0
- package/dist/types/theme/toolkitComponents.d.ts +4 -0
- package/dist/types/timeline.d.ts +2 -0
- package/dist/types/toolkit/ToolkitProvider.d.ts +31 -0
- package/dist/types/toolkit/browserNavigation.d.ts +32 -0
- package/dist/types/toolkit/toolkitContext.d.ts +28 -0
- package/dist/types/toolkit/toolkitSettings.d.ts +68 -0
- package/dist/types/toolkit/useToolkitTranslation.d.ts +10 -0
- package/dist/types/ui/actions/CopyButton.d.ts +13 -0
- package/dist/types/ui/actions/DownloadMenu.d.ts +50 -0
- package/dist/types/ui/actions/SecretField.d.ts +13 -0
- package/dist/types/ui/filters/DateRangeFilter.d.ts +16 -0
- package/dist/types/ui/filters/PeriodRangeSelector.d.ts +28 -0
- package/dist/types/ui/filters/QuickFilters.d.ts +21 -0
- package/dist/types/ui/filters/SegmentedControl.d.ts +44 -0
- package/dist/types/ui/index.d.ts +33 -0
- package/dist/types/ui/labels/DictionaryText.d.ts +7 -0
- package/dist/types/ui/labels/StatusChip.d.ts +21 -0
- package/dist/types/ui/labels/Tag.d.ts +19 -0
- package/dist/types/ui/layout/CollapsibleSection.d.ts +15 -0
- package/dist/types/ui/layout/ContentDialog.d.ts +13 -0
- package/dist/types/ui/layout/DefinitionList.d.ts +15 -0
- package/dist/types/ui/layout/DetailHeader.d.ts +15 -0
- package/dist/types/ui/layout/ErrorPage.d.ts +22 -0
- package/dist/types/ui/layout/FullPageLoader.d.ts +1 -0
- package/dist/types/ui/layout/GlassLensFilter.d.ts +1 -0
- package/dist/types/ui/layout/GlassPanel.d.ts +11 -0
- package/dist/types/ui/layout/PageHeader.d.ts +15 -0
- package/dist/types/ui/layout/PageHeading.d.ts +18 -0
- package/dist/types/ui/layout/ProfileHeader.d.ts +17 -0
- package/dist/types/ui/layout/ScrollableRow.d.ts +33 -0
- package/dist/types/ui/layout/SectionCard.d.ts +11 -0
- package/dist/types/ui/layout/appBarHeight.d.ts +13 -0
- package/dist/types/ui/metrics/BarList.d.ts +19 -0
- package/dist/types/ui/metrics/CalendarHeatmap.d.ts +28 -0
- package/dist/types/ui/metrics/ChartTooltip.d.ts +5 -0
- package/dist/types/ui/metrics/ColumnChart.d.ts +35 -0
- package/dist/types/ui/metrics/MetricCard.d.ts +31 -0
- package/dist/types/ui/metrics/TableToggle.d.ts +7 -0
- package/dist/types/ui/metrics/barListLabels.d.ts +17 -0
- package/dist/types/ui/metrics/heatmapScale.d.ts +45 -0
- package/dist/types/ui/navigation/BackButton.d.ts +11 -0
- package/dist/types/ui/navigation/ColorSchemeToggle.d.ts +7 -0
- package/dist/types/ui/navigation/DocumentTitle.d.ts +6 -0
- package/dist/types/ui/navigation/FontSizeToggle.d.ts +6 -0
- package/dist/types/ui/navigation/LanguageToggle.d.ts +8 -0
- package/dist/types/ui/navigation/PageBreadcrumbs.d.ts +9 -0
- package/dist/types/ui/navigation/colorMode.d.ts +18 -0
- package/dist/types/ui/navigation/fontSizeLevels.d.ts +25 -0
- package/dist/types/ui/navigation/useFontSize.d.ts +10 -0
- package/dist/types/ui/timeline/GroupedTimeline.d.ts +38 -0
- package/dist/types/ui/timeline/timelineDot.d.ts +19 -0
- package/dist/types/upload/FileDropzone.d.ts +34 -0
- package/dist/types/upload/fileRules.d.ts +51 -0
- package/dist/types/upload/uploadMachine.d.ts +23 -0
- package/dist/types/upload/uploadWithProgress.d.ts +16 -0
- package/dist/ui/actions/CopyButton.js +28 -0
- package/dist/ui/actions/CopyButton.js.map +1 -0
- package/dist/ui/actions/DownloadMenu.js +163 -0
- package/dist/ui/actions/DownloadMenu.js.map +1 -0
- package/dist/ui/actions/SecretField.js +57 -0
- package/dist/ui/actions/SecretField.js.map +1 -0
- package/dist/ui/filters/DateRangeFilter.js +86 -0
- package/dist/ui/filters/DateRangeFilter.js.map +1 -0
- package/dist/ui/filters/PeriodRangeSelector.js +56 -0
- package/dist/ui/filters/PeriodRangeSelector.js.map +1 -0
- package/dist/ui/filters/QuickFilters.js +91 -0
- package/dist/ui/filters/QuickFilters.js.map +1 -0
- package/dist/ui/filters/SegmentedControl.js +80 -0
- package/dist/ui/filters/SegmentedControl.js.map +1 -0
- package/dist/ui/labels/DictionaryText.js +11 -0
- package/dist/ui/labels/DictionaryText.js.map +1 -0
- package/dist/ui/labels/StatusChip.js +52 -0
- package/dist/ui/labels/StatusChip.js.map +1 -0
- package/dist/ui/labels/Tag.js +26 -0
- package/dist/ui/labels/Tag.js.map +1 -0
- package/dist/ui/layout/CollapsibleSection.js +48 -0
- package/dist/ui/layout/CollapsibleSection.js.map +1 -0
- package/dist/ui/layout/ContentDialog.js +97 -0
- package/dist/ui/layout/ContentDialog.js.map +1 -0
- package/dist/ui/layout/DefinitionList.js +30 -0
- package/dist/ui/layout/DefinitionList.js.map +1 -0
- package/dist/ui/layout/DetailHeader.js +27 -0
- package/dist/ui/layout/DetailHeader.js.map +1 -0
- package/dist/ui/layout/ErrorPage.js +40 -0
- package/dist/ui/layout/ErrorPage.js.map +1 -0
- package/dist/ui/layout/FullPageLoader.js +13 -0
- package/dist/ui/layout/FullPageLoader.js.map +1 -0
- package/dist/ui/layout/GlassLensFilter.js +53 -0
- package/dist/ui/layout/GlassLensFilter.js.map +1 -0
- package/dist/ui/layout/GlassPanel.js +18 -0
- package/dist/ui/layout/GlassPanel.js.map +1 -0
- package/dist/ui/layout/PageHeader.js +23 -0
- package/dist/ui/layout/PageHeader.js.map +1 -0
- package/dist/ui/layout/PageHeading.js +51 -0
- package/dist/ui/layout/PageHeading.js.map +1 -0
- package/dist/ui/layout/ProfileHeader.js +64 -0
- package/dist/ui/layout/ProfileHeader.js.map +1 -0
- package/dist/ui/layout/ScrollableRow.js +156 -0
- package/dist/ui/layout/ScrollableRow.js.map +1 -0
- package/dist/ui/layout/SectionCard.js +18 -0
- package/dist/ui/layout/SectionCard.js.map +1 -0
- package/dist/ui/layout/appBarHeight.js +42 -0
- package/dist/ui/layout/appBarHeight.js.map +1 -0
- package/dist/ui/metrics/BarList.js +89 -0
- package/dist/ui/metrics/BarList.js.map +1 -0
- package/dist/ui/metrics/CalendarHeatmap.js +131 -0
- package/dist/ui/metrics/CalendarHeatmap.js.map +1 -0
- package/dist/ui/metrics/ChartTooltip.js +16 -0
- package/dist/ui/metrics/ChartTooltip.js.map +1 -0
- package/dist/ui/metrics/ColumnChart.js +110 -0
- package/dist/ui/metrics/ColumnChart.js.map +1 -0
- package/dist/ui/metrics/MetricCard.js +64 -0
- package/dist/ui/metrics/MetricCard.js.map +1 -0
- package/dist/ui/metrics/TableToggle.js +13 -0
- package/dist/ui/metrics/TableToggle.js.map +1 -0
- package/dist/ui/metrics/barListLabels.js +9 -0
- package/dist/ui/metrics/barListLabels.js.map +1 -0
- package/dist/ui/metrics/heatmapScale.js +67 -0
- package/dist/ui/metrics/heatmapScale.js.map +1 -0
- package/dist/ui/navigation/BackButton.js +28 -0
- package/dist/ui/navigation/BackButton.js.map +1 -0
- package/dist/ui/navigation/ColorSchemeToggle.js +37 -0
- package/dist/ui/navigation/ColorSchemeToggle.js.map +1 -0
- package/dist/ui/navigation/DocumentTitle.js +11 -0
- package/dist/ui/navigation/DocumentTitle.js.map +1 -0
- package/dist/ui/navigation/FontSizeToggle.js +40 -0
- package/dist/ui/navigation/FontSizeToggle.js.map +1 -0
- package/dist/ui/navigation/LanguageToggle.js +27 -0
- package/dist/ui/navigation/LanguageToggle.js.map +1 -0
- package/dist/ui/navigation/PageBreadcrumbs.js +51 -0
- package/dist/ui/navigation/PageBreadcrumbs.js.map +1 -0
- package/dist/ui/navigation/colorMode.js +13 -0
- package/dist/ui/navigation/colorMode.js.map +1 -0
- package/dist/ui/navigation/fontSizeLevels.js +24 -0
- package/dist/ui/navigation/fontSizeLevels.js.map +1 -0
- package/dist/ui/navigation/useFontSize.js +44 -0
- package/dist/ui/navigation/useFontSize.js.map +1 -0
- package/dist/ui/timeline/GroupedTimeline.js +104 -0
- package/dist/ui/timeline/GroupedTimeline.js.map +1 -0
- package/dist/ui/timeline/timelineDot.js +20 -0
- package/dist/ui/timeline/timelineDot.js.map +1 -0
- package/dist/upload/FileDropzone.js +143 -0
- package/dist/upload/FileDropzone.js.map +1 -0
- package/dist/upload/fileRules.js +62 -0
- package/dist/upload/fileRules.js.map +1 -0
- package/dist/upload/uploadMachine.js +73 -0
- package/dist/upload/uploadMachine.js.map +1 -0
- package/dist/upload/uploadWithProgress.js +45 -0
- package/dist/upload/uploadWithProgress.js.map +1 -0
- package/package.json +303 -5
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
function allowOnlyUnrestricted(access) {
|
|
2
|
+
return !access;
|
|
3
|
+
}
|
|
4
|
+
function createAccessChecker({ abilities = [], roles = [], policies = {}, context = {} } = {}) {
|
|
5
|
+
const abilitySet = new Set(abilities);
|
|
6
|
+
const roleSet = new Set(roles);
|
|
7
|
+
const passesPolicy = (policyName) => {
|
|
8
|
+
const policy = policies[policyName];
|
|
9
|
+
if (typeof policy !== "function") {
|
|
10
|
+
throw new Error(`La política «${policyName}» no está definida en createAccessChecker({policies})`);
|
|
11
|
+
}
|
|
12
|
+
return Boolean(policy(context));
|
|
13
|
+
};
|
|
14
|
+
return (access) => {
|
|
15
|
+
if (!access) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
if (access.ability && !abilitySet.has(access.ability)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if (access.anyOf && !access.anyOf.some((ability) => abilitySet.has(ability))) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
if (access.allOf && !access.allOf.every((ability) => abilitySet.has(ability))) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
if (access.role && !roleSet.has(access.role)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (access.anyRole && !access.anyRole.some((role) => roleSet.has(role))) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
if (access.policy && !passesPolicy(access.policy)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
if (access.policies && !access.policies.every(passesPolicy)) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (access.check && !access.check(context)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
allowOnlyUnrestricted,
|
|
47
|
+
createAccessChecker
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=accessRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessRules.js","sources":["../../src/access/accessRules.js"],"sourcesContent":["// Quién puede ver qué: el menú, las rutas y los botones preguntan lo mismo con la misma regla («access»).\n//\n// El framework NO sabe de roles ni de permisos: cada proyecto declara sus reglas como le acomode y le da a ToolkitProvider\n// una función canAccess(access) → boolean. Para no programarla cada vez, createAccessChecker la arma con las formas de\n// siempre, y se pueden combinar (todas las que vengan tienen que cumplirse):\n//\n// RBAC por permisos (las `abilities` que manda la sesión):\n// {ability: 'orders.view'} ese permiso\n// {anyOf: ['orders.view', 'orders.admin']} alguno de esos\n// {allOf: ['orders.view', 'reports.view']} todos\n// RBAC por roles:\n// {role: 'admin'} · {anyRole: ['admin', 'supervisor']}\n// ABAC (atributos: dueño del registro, organización, horario…):\n// {policy: 'ownsRecord'} · {policies: ['ownsRecord', 'sameOrganization']} políticas con nombre, que el proyecto\n// define una vez en createAccessChecker\n// {check: (context) => context.user.id === record.ownerId} la regla escrita ahí mismo\n//\n// Sin access (undefined) lo ve cualquiera con sesión. Sin sesión o sin la lista, nada: falla CERRADO.\n//\n// OJO: esto solo decide lo que se PINTA. Lo que cada quien puede hacer lo vuelve a decidir el backend en cada petición;\n// cambiar esto en el navegador no abre nada.\n//\n// Funciones puras, sin React: function (regla de la casa). Se prueban con node --test (accessRules.test.js).\n\n/**\n * El canAccess de un proyecto que no usa permisos: sin access lo ve cualquiera; con access, nadie (falla cerrado, para\n * que una regla escrita y sin conectar se note en lugar de abrir todo).\n *\n * @param {object|undefined|null} access\n * @returns {boolean}\n */\nexport function allowOnlyUnrestricted(access) {\n return !access;\n}\n\n/**\n * Arma el canAccess(access) del proyecto con sus permisos, sus roles y sus políticas.\n *\n * @param {object} [options]\n * @param {string[]} [options.abilities] los permisos de la sesión (p. ej. los `abilities` que manda el backend)\n * @param {string[]} [options.roles] los roles de la sesión\n * @param {Record<string, (context: any) => boolean>} [options.policies] las políticas con nombre (ABAC); reciben el context\n * @param {object} [options.context] lo que reciben las políticas y los check (la persona, su organización…)\n * @returns {(access: object|undefined|null) => boolean}\n */\nexport function createAccessChecker({abilities = [], roles = [], policies = {}, context = {}} = {}) {\n const abilitySet = new Set(abilities);\n const roleSet = new Set(roles);\n\n const passesPolicy = (policyName) => {\n const policy = policies[policyName];\n // una política que nadie definió es un error de configuración: truena en vez de abrir o cerrar en silencio\n if (typeof policy !== 'function') {\n throw new Error(`La política «${policyName}» no está definida en createAccessChecker({policies})`);\n }\n return Boolean(policy(context));\n };\n\n return (access) => {\n if (!access) {\n return true;\n }\n if (access.ability && !abilitySet.has(access.ability)) {\n return false;\n }\n if (access.anyOf && !access.anyOf.some((ability) => abilitySet.has(ability))) {\n return false;\n }\n if (access.allOf && !access.allOf.every((ability) => abilitySet.has(ability))) {\n return false;\n }\n if (access.role && !roleSet.has(access.role)) {\n return false;\n }\n if (access.anyRole && !access.anyRole.some((role) => roleSet.has(role))) {\n return false;\n }\n if (access.policy && !passesPolicy(access.policy)) {\n return false;\n }\n if (access.policies && !access.policies.every(passesPolicy)) {\n return false;\n }\n if (access.check && !access.check(context)) {\n return false;\n }\n return true;\n };\n}\n"],"names":[],"mappings":"AA+BO,SAAS,sBAAsB,QAAQ;AAC1C,SAAO,CAAC;AACZ;AAYO,SAAS,oBAAoB,EAAC,YAAY,CAAA,GAAI,QAAQ,CAAA,GAAI,WAAW,IAAI,UAAU,CAAA,EAAE,IAAI,CAAA,GAAI;AAChG,QAAM,aAAa,IAAI,IAAI,SAAS;AACpC,QAAM,UAAU,IAAI,IAAI,KAAK;AAE7B,QAAM,eAAe,CAAC,eAAe;AACjC,UAAM,SAAS,SAAS,UAAU;AAElC,QAAI,OAAO,WAAW,YAAY;AAC9B,YAAM,IAAI,MAAM,gBAAgB,UAAU,uDAAuD;AAAA,IACrG;AACA,WAAO,QAAQ,OAAO,OAAO,CAAC;AAAA,EAClC;AAEA,SAAO,CAAC,WAAW;AACf,QAAI,CAAC,QAAQ;AACT,aAAO;AAAA,IACX;AACA,QAAI,OAAO,WAAW,CAAC,WAAW,IAAI,OAAO,OAAO,GAAG;AACnD,aAAO;AAAA,IACX;AACA,QAAI,OAAO,SAAS,CAAC,OAAO,MAAM,KAAK,CAAC,YAAY,WAAW,IAAI,OAAO,CAAC,GAAG;AAC1E,aAAO;AAAA,IACX;AACA,QAAI,OAAO,SAAS,CAAC,OAAO,MAAM,MAAM,CAAC,YAAY,WAAW,IAAI,OAAO,CAAC,GAAG;AAC3E,aAAO;AAAA,IACX;AACA,QAAI,OAAO,QAAQ,CAAC,QAAQ,IAAI,OAAO,IAAI,GAAG;AAC1C,aAAO;AAAA,IACX;AACA,QAAI,OAAO,WAAW,CAAC,OAAO,QAAQ,KAAK,CAAC,SAAS,QAAQ,IAAI,IAAI,CAAC,GAAG;AACrE,aAAO;AAAA,IACX;AACA,QAAI,OAAO,UAAU,CAAC,aAAa,OAAO,MAAM,GAAG;AAC/C,aAAO;AAAA,IACX;AACA,QAAI,OAAO,YAAY,CAAC,OAAO,SAAS,MAAM,YAAY,GAAG;AACzD,aAAO;AAAA,IACX;AACA,QAAI,OAAO,SAAS,CAAC,OAAO,MAAM,OAAO,GAAG;AACxC,aAAO;AAAA,IACX;AACA,WAAO;AAAA,EACX;AACJ;"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const LAST_ORDER = 1e3;
|
|
2
|
+
function composePermissionGroups(menuModules, t) {
|
|
3
|
+
const modules = Array.isArray(menuModules) ? menuModules : Object.values(menuModules);
|
|
4
|
+
return modules.filter((menuModule) => Array.isArray(menuModule.permissions) && menuModule.permissions.length > 0).sort((first, second) => (first.order ?? LAST_ORDER) - (second.order ?? LAST_ORDER)).map((menuModule) => {
|
|
5
|
+
const menuItem = menuModule.buildMenuItem?.({}) ?? {};
|
|
6
|
+
return {
|
|
7
|
+
key: menuItem.to ?? menuModule.permissions[0].key,
|
|
8
|
+
label: menuItem.label ?? t(menuItem.labelKey),
|
|
9
|
+
permissions: menuModule.permissions.map((permission) => ({
|
|
10
|
+
key: permission.key,
|
|
11
|
+
label: permission.label ?? t(permission.labelKey),
|
|
12
|
+
description: permission.description ?? (permission.descriptionKey ? t(permission.descriptionKey) : void 0)
|
|
13
|
+
}))
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function groupStateOf(group, granted) {
|
|
18
|
+
const grantedSet = new Set(granted);
|
|
19
|
+
const grantedCount = group.permissions.filter((permission) => grantedSet.has(permission.key)).length;
|
|
20
|
+
const total = group.permissions.length;
|
|
21
|
+
return { grantedCount, total, isAll: total > 0 && grantedCount === total, isSome: grantedCount > 0 && grantedCount < total };
|
|
22
|
+
}
|
|
23
|
+
function withPermission(granted, permissionKey, shouldGrant) {
|
|
24
|
+
if (shouldGrant) {
|
|
25
|
+
return granted.includes(permissionKey) ? [...granted] : [...granted, permissionKey];
|
|
26
|
+
}
|
|
27
|
+
return granted.filter((key) => key !== permissionKey);
|
|
28
|
+
}
|
|
29
|
+
function withPermissionGroup(granted, group, shouldGrant) {
|
|
30
|
+
const groupKeys = new Set(group.permissions.map((permission) => permission.key));
|
|
31
|
+
if (shouldGrant) {
|
|
32
|
+
const missing = group.permissions.map((permission) => permission.key).filter((key) => !granted.includes(key));
|
|
33
|
+
return [...granted, ...missing];
|
|
34
|
+
}
|
|
35
|
+
return granted.filter((key) => !groupKeys.has(key));
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
composePermissionGroups,
|
|
39
|
+
groupStateOf,
|
|
40
|
+
withPermission,
|
|
41
|
+
withPermissionGroup
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=permissionGroups.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissionGroups.js","sources":["../../src/access/permissionGroups.js"],"sourcesContent":["// La lógica de la pantalla de perfiles y permisos (PermissionMatrix), sin React: cuántos permisos de un grupo tiene un\n// perfil, y prender o apagar un permiso o un grupo entero.\n//\n// Los permisos son los mismos textos que piden los menu.js y las rutas (access: {ability: 'orders.view'}). Cada módulo\n// declara los suyos en su menu.js y composePermissionGroups los junta (un grupo por módulo, en el orden del menú): la\n// pantalla de perfiles no tiene lista central que editar. Guardar la lista de permisos del perfil es cosa del backend.\n//\n// // modules/orders/menu.js\n// export const permissions = [\n// {key: 'orders.view', labelKey: 'orders:permissions.view', descriptionKey: 'orders:permissions.viewDescription'},\n// {key: 'orders.cancel', labelKey: 'orders:permissions.cancel'},\n// ];\n//\n// Funciones puras, sin React: function (regla de la casa). Se prueban con node --test (permissionGroups.test.js).\n\n// la posición de un módulo que no dice su order: al final (la misma regla que composeMenu)\nconst LAST_ORDER = 1000;\n\n/**\n * Los grupos de permisos que declaran los módulos en su menu.js (`export const permissions`), uno por módulo y en el orden\n * del menú, con el nombre de su entrada del menú como título del grupo.\n *\n * @param {Record<string, any>|any[]} menuModules lo que regresa import.meta.glob(..., {eager: true}) o una lista\n * @param {(key: string, values?: object) => string} t el traductor (para las llaves labelKey y descriptionKey)\n * @returns {Array<{key: string, label: string, permissions: Array<{key: string, label: string, description?: string}>}>}\n */\nexport function composePermissionGroups(menuModules, t) {\n const modules = Array.isArray(menuModules) ? menuModules : Object.values(menuModules);\n return modules\n .filter((menuModule) => Array.isArray(menuModule.permissions) && menuModule.permissions.length > 0)\n .sort((first, second) => (first.order ?? LAST_ORDER) - (second.order ?? LAST_ORDER))\n .map((menuModule) => {\n const menuItem = menuModule.buildMenuItem?.({}) ?? {};\n return {\n key: menuItem.to ?? menuModule.permissions[0].key,\n label: menuItem.label ?? t(menuItem.labelKey),\n permissions: menuModule.permissions.map((permission) => ({\n key: permission.key,\n label: permission.label ?? t(permission.labelKey),\n description: permission.description ?? (permission.descriptionKey ? t(permission.descriptionKey) : undefined),\n })),\n };\n });\n}\n\n/**\n * Cuántos permisos del grupo están dados.\n *\n * @param {{permissions: Array<{key: string}>}} group\n * @param {string[]} granted los permisos del perfil\n * @returns {{grantedCount: number, total: number, isAll: boolean, isSome: boolean}}\n */\nexport function groupStateOf(group, granted) {\n const grantedSet = new Set(granted);\n const grantedCount = group.permissions.filter((permission) => grantedSet.has(permission.key)).length;\n const total = group.permissions.length;\n return {grantedCount, total, isAll: total > 0 && grantedCount === total, isSome: grantedCount > 0 && grantedCount < total};\n}\n\n/**\n * Prende o apaga un permiso. Lo demás se queda en su orden; uno nuevo va al final.\n *\n * @param {string[]} granted\n * @param {string} permissionKey\n * @param {boolean} shouldGrant\n * @returns {string[]} la lista nueva (no cambia la de entrada)\n */\nexport function withPermission(granted, permissionKey, shouldGrant) {\n if (shouldGrant) {\n return granted.includes(permissionKey) ? [...granted] : [...granted, permissionKey];\n }\n return granted.filter((key) => key !== permissionKey);\n}\n\n/**\n * Prende o apaga todos los permisos de un grupo. Los que ya estaban se quedan en su lugar; los que faltan van al final.\n *\n * @param {string[]} granted\n * @param {{permissions: Array<{key: string}>}} group\n * @param {boolean} shouldGrant\n * @returns {string[]}\n */\nexport function withPermissionGroup(granted, group, shouldGrant) {\n const groupKeys = new Set(group.permissions.map((permission) => permission.key));\n if (shouldGrant) {\n const missing = group.permissions.map((permission) => permission.key).filter((key) => !granted.includes(key));\n return [...granted, ...missing];\n }\n return granted.filter((key) => !groupKeys.has(key));\n}\n"],"names":[],"mappings":"AAgBA,MAAM,aAAa;AAUZ,SAAS,wBAAwB,aAAa,GAAG;AACpD,QAAM,UAAU,MAAM,QAAQ,WAAW,IAAI,cAAc,OAAO,OAAO,WAAW;AACpF,SAAO,QACF,OAAO,CAAC,eAAe,MAAM,QAAQ,WAAW,WAAW,KAAK,WAAW,YAAY,SAAS,CAAC,EACjG,KAAK,CAAC,OAAO,YAAY,MAAM,SAAS,eAAe,OAAO,SAAS,WAAW,EAClF,IAAI,CAAC,eAAe;AACjB,UAAM,WAAW,WAAW,gBAAgB,CAAA,CAAE,KAAK,CAAA;AACnD,WAAO;AAAA,MACH,KAAK,SAAS,MAAM,WAAW,YAAY,CAAC,EAAE;AAAA,MAC9C,OAAO,SAAS,SAAS,EAAE,SAAS,QAAQ;AAAA,MAC5C,aAAa,WAAW,YAAY,IAAI,CAAC,gBAAgB;AAAA,QACrD,KAAK,WAAW;AAAA,QAChB,OAAO,WAAW,SAAS,EAAE,WAAW,QAAQ;AAAA,QAChD,aAAa,WAAW,gBAAgB,WAAW,iBAAiB,EAAE,WAAW,cAAc,IAAI;AAAA,MACvH,EAAkB;AAAA,IAClB;AAAA,EACQ,CAAC;AACT;AASO,SAAS,aAAa,OAAO,SAAS;AACzC,QAAM,aAAa,IAAI,IAAI,OAAO;AAClC,QAAM,eAAe,MAAM,YAAY,OAAO,CAAC,eAAe,WAAW,IAAI,WAAW,GAAG,CAAC,EAAE;AAC9F,QAAM,QAAQ,MAAM,YAAY;AAChC,SAAO,EAAC,cAAc,OAAO,OAAO,QAAQ,KAAK,iBAAiB,OAAO,QAAQ,eAAe,KAAK,eAAe,MAAK;AAC7H;AAUO,SAAS,eAAe,SAAS,eAAe,aAAa;AAChE,MAAI,aAAa;AACb,WAAO,QAAQ,SAAS,aAAa,IAAI,CAAC,GAAG,OAAO,IAAI,CAAC,GAAG,SAAS,aAAa;AAAA,EACtF;AACA,SAAO,QAAQ,OAAO,CAAC,QAAQ,QAAQ,aAAa;AACxD;AAUO,SAAS,oBAAoB,SAAS,OAAO,aAAa;AAC7D,QAAM,YAAY,IAAI,IAAI,MAAM,YAAY,IAAI,CAAC,eAAe,WAAW,GAAG,CAAC;AAC/E,MAAI,aAAa;AACb,UAAM,UAAU,MAAM,YAAY,IAAI,CAAC,eAAe,WAAW,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,SAAS,GAAG,CAAC;AAC5G,WAAO,CAAC,GAAG,SAAS,GAAG,OAAO;AAAA,EAClC;AACA,SAAO,QAAQ,OAAO,CAAC,QAAQ,CAAC,UAAU,IAAI,GAAG,CAAC;AACtD;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useToolkitSettings } from "../toolkit/toolkitContext.js";
|
|
2
|
+
function useCan(access) {
|
|
3
|
+
return useToolkitSettings().canAccess(access);
|
|
4
|
+
}
|
|
5
|
+
function useAccessChecker() {
|
|
6
|
+
return useToolkitSettings().canAccess;
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
useAccessChecker,
|
|
10
|
+
useCan
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=useCan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCan.js","sources":["../../src/access/useCan.js"],"sourcesContent":["// ¿Esta sesión puede ver esto? Con la regla que el proyecto le dio a ToolkitProvider (canAccess).\n//\n// const canCancel = useCan({ability: 'orders.cancel'});\n// {canCancel && <Button>Cancelar pedido</Button>}\n//\n// Hook genérico del paquete: function (regla de la casa).\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\n\n/**\n * @param {object|undefined|null} access la regla (accessRules.js); sin ella, sí\n * @returns {boolean}\n */\nexport function useCan(access) {\n return useToolkitSettings().canAccess(access);\n}\n\n/**\n * La regla del proyecto, para preguntar por varias cosas a la vez (p. ej. armar el menú).\n *\n * @returns {(access: object|undefined|null) => boolean}\n */\nexport function useAccessChecker() {\n return useToolkitSettings().canAccess;\n}\n"],"names":[],"mappings":";AAYO,SAAS,OAAO,QAAQ;AAC3B,SAAO,mBAAkB,EAAG,UAAU,MAAM;AAChD;AAOO,SAAS,mBAAmB;AAC/B,SAAO,mBAAkB,EAAG;AAChC;"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useState, useCallback, useRef, useEffect, useMemo, useContext } from "react";
|
|
4
|
+
import { missingConnectorFunctionsOf } from "./accountConnector.js";
|
|
5
|
+
import { createAccessChecker } from "../access/accessRules.js";
|
|
6
|
+
import ErrorPage, { ERROR_PAGE_KIND } from "../ui/layout/ErrorPage.js";
|
|
7
|
+
import FullPageLoader from "../ui/layout/FullPageLoader.js";
|
|
8
|
+
const AccountContext = createContext(null);
|
|
9
|
+
const NOT_LOADED = void 0;
|
|
10
|
+
function AccountProvider({ connector, refreshKey, initialSession = NOT_LOADED, children }) {
|
|
11
|
+
const missingFunctions = missingConnectorFunctionsOf(connector);
|
|
12
|
+
if (missingFunctions.length > 0) {
|
|
13
|
+
throw new Error(`Al conector de la cuenta le faltan estas funciones: ${missingFunctions.join(", ")}`);
|
|
14
|
+
}
|
|
15
|
+
const [session, setSession] = useState(initialSession);
|
|
16
|
+
const [loadError, setLoadError] = useState(null);
|
|
17
|
+
const refreshSession = useCallback(async () => {
|
|
18
|
+
try {
|
|
19
|
+
setSession(await connector.loadSession());
|
|
20
|
+
setLoadError(null);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
setLoadError(error);
|
|
23
|
+
}
|
|
24
|
+
}, [connector]);
|
|
25
|
+
const signOut = useCallback(async () => {
|
|
26
|
+
await connector.signOut();
|
|
27
|
+
setSession(null);
|
|
28
|
+
}, [connector]);
|
|
29
|
+
const skipsFirstLoad = useRef(initialSession !== NOT_LOADED);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (skipsFirstLoad.current) {
|
|
32
|
+
skipsFirstLoad.current = false;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
refreshSession();
|
|
36
|
+
}, [refreshSession, refreshKey]);
|
|
37
|
+
const canAccess = useMemo(() => createAccessChecker({ abilities: session?.abilities ?? [], roles: session?.roles ?? [] }), [session]);
|
|
38
|
+
const value = useMemo(() => ({ connector, session: session ?? null, refreshSession, signOut }), [connector, session, refreshSession, signOut]);
|
|
39
|
+
if (loadError && session === NOT_LOADED) {
|
|
40
|
+
return /* @__PURE__ */ jsx(ErrorPage, { kind: ERROR_PAGE_KIND.serverError, text: loadError.message, onRetry: refreshSession });
|
|
41
|
+
}
|
|
42
|
+
if (session === NOT_LOADED) {
|
|
43
|
+
return /* @__PURE__ */ jsx(FullPageLoader, {});
|
|
44
|
+
}
|
|
45
|
+
return /* @__PURE__ */ jsx(AccountContext.Provider, { value, children: children(canAccess) });
|
|
46
|
+
}
|
|
47
|
+
function useAccount() {
|
|
48
|
+
const account = useContext(AccountContext);
|
|
49
|
+
if (!account) {
|
|
50
|
+
throw new Error("useAccount necesita estar dentro de <AccountProvider>");
|
|
51
|
+
}
|
|
52
|
+
return account;
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
AccountProvider as default,
|
|
56
|
+
useAccount
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=AccountProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccountProvider.js","sources":["../../src/account/AccountProvider.jsx"],"sourcesContent":["// La cuenta al alcance de toda la app: carga la sesión al abrir (connector.loadSession) y la reparte. Las pantallas de la\n// cuenta y la barra la leen con useAccount; el menú, las rutas y los botones preguntan sus permisos con la regla que sale de\n// aquí (createAccessChecker), que se le pasa a ToolkitProvider:\n//\n// <AccountProvider connector={accountConnector}>\n// {(canAccess) => <ToolkitProvider canAccess={canAccess} …>…</ToolkitProvider>}\n// </AccountProvider>\n//\n// Mientras llega la primera respuesta se ve la pantalla de carga (sin ella, el menú se pintaría vacío un instante); si el\n// servidor no contesta, la página de error con «Intentar de nuevo», no la de entrar (no es que no haya sesión).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {createContext, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';\n\nimport {missingConnectorFunctionsOf} from '@/account/accountConnector.js';\nimport {createAccessChecker} from '@/access/accessRules.js';\nimport ErrorPage, {ERROR_PAGE_KIND} from '@/ui/layout/ErrorPage.jsx';\nimport FullPageLoader from '@/ui/layout/FullPageLoader.jsx';\n\nconst AccountContext = createContext(null);\n// lo que se sabe antes de la primera respuesta: ni dentro ni fuera\nconst NOT_LOADED = undefined;\n\n/**\n * @param {object} props\n * @param {import('@/account/accountConnector.js').AccountConnector} props.connector las llamadas al backend\n * @param {unknown} [props.refreshKey] al cambiar, la sesión se vuelve a leer (p. ej. el idioma, si el backend manda los\n * nombres de los perfiles traducidos)\n * @param {import('@/account/accountConnector.js').AccountSession|null} [props.initialSession] la sesión que ya se conoce\n * (p. ej. la que leyó el servidor al pintar): se usa sin esperar la primera respuesta\n * @param {(canAccess: (access: object|null|undefined) => boolean) => import('react').ReactNode} props.children recibe la\n * regla de permisos de la sesión\n */\nexport default function AccountProvider({connector, refreshKey, initialSession = NOT_LOADED, children}) {\n // guard clause: un conector incompleto es un error de quien lo escribió; se avisa al arrancar y no al picar un botón\n const missingFunctions = missingConnectorFunctionsOf(connector);\n if (missingFunctions.length > 0) {\n throw new Error(`Al conector de la cuenta le faltan estas funciones: ${missingFunctions.join(', ')}`);\n }\n\n const [session, setSession] = useState(initialSession);\n const [loadError, setLoadError] = useState(null);\n\n const refreshSession = useCallback(async () => {\n try {\n setSession(await connector.loadSession());\n setLoadError(null);\n } catch (error) {\n setLoadError(error);\n }\n }, [connector]);\n\n const signOut = useCallback(async () => {\n await connector.signOut();\n setSession(null);\n }, [connector]);\n\n // con la sesión ya conocida no se pide al abrir; sí cuando cambia refreshKey\n const skipsFirstLoad = useRef(initialSession !== NOT_LOADED);\n useEffect(() => {\n if (skipsFirstLoad.current) {\n skipsFirstLoad.current = false;\n return;\n }\n refreshSession();\n }, [refreshSession, refreshKey]);\n\n const canAccess = useMemo(() => createAccessChecker({abilities: session?.abilities ?? [], roles: session?.roles ?? []}), [session]);\n const value = useMemo(() => ({connector, session: session ?? null, refreshSession, signOut}), [connector, session, refreshSession, signOut]);\n\n if (loadError && session === NOT_LOADED) {\n return <ErrorPage kind={ERROR_PAGE_KIND.serverError} text={loadError.message} onRetry={refreshSession} />;\n }\n if (session === NOT_LOADED) {\n return <FullPageLoader />;\n }\n return <AccountContext.Provider value={value}>{children(canAccess)}</AccountContext.Provider>;\n}\n\n/**\n * La cuenta: {session, refreshSession, signOut, connector}. session es null si nadie está dentro.\n *\n * @returns {{session: import('@/account/accountConnector.js').AccountSession|null, refreshSession: () => Promise<void>, signOut: () => Promise<void>, connector: import('@/account/accountConnector.js').AccountConnector}}\n */\nexport function useAccount() {\n const account = useContext(AccountContext);\n if (!account) {\n throw new Error('useAccount necesita estar dentro de <AccountProvider>');\n }\n return account;\n}\n"],"names":[],"mappings":";;;;;;;AAmBA,MAAM,iBAAiB,cAAc,IAAI;AAEzC,MAAM,aAAa;AAYnB,SAAwB,gBAAgB,EAAC,WAAW,YAAY,iBAAiB,YAAY,YAAW;AAEpG,QAAM,mBAAmB,4BAA4B,SAAS;AAC9D,MAAI,iBAAiB,SAAS,GAAG;AAC7B,UAAM,IAAI,MAAM,uDAAuD,iBAAiB,KAAK,IAAI,CAAC,EAAE;AAAA,EACxG;AAEA,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,cAAc;AACrD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,IAAI;AAE/C,QAAM,iBAAiB,YAAY,YAAY;AAC3C,QAAI;AACA,iBAAW,MAAM,UAAU,aAAa;AACxC,mBAAa,IAAI;AAAA,IACrB,SAAS,OAAO;AACZ,mBAAa,KAAK;AAAA,IACtB;AAAA,EACJ,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,UAAU,YAAY,YAAY;AACpC,UAAM,UAAU,QAAA;AAChB,eAAW,IAAI;AAAA,EACnB,GAAG,CAAC,SAAS,CAAC;AAGd,QAAM,iBAAiB,OAAO,mBAAmB,UAAU;AAC3D,YAAU,MAAM;AACZ,QAAI,eAAe,SAAS;AACxB,qBAAe,UAAU;AACzB;AAAA,IACJ;AACA,mBAAA;AAAA,EACJ,GAAG,CAAC,gBAAgB,UAAU,CAAC;AAE/B,QAAM,YAAY,QAAQ,MAAM,oBAAoB,EAAC,WAAW,SAAS,aAAa,CAAA,GAAI,OAAO,SAAS,SAAS,CAAA,EAAC,CAAE,GAAG,CAAC,OAAO,CAAC;AAClI,QAAM,QAAQ,QAAQ,OAAO,EAAC,WAAW,SAAS,WAAW,MAAM,gBAAgB,QAAA,IAAW,CAAC,WAAW,SAAS,gBAAgB,OAAO,CAAC;AAE3I,MAAI,aAAa,YAAY,YAAY;AACrC,WAAO,oBAAC,aAAU,MAAM,gBAAgB,aAAa,MAAM,UAAU,SAAS,SAAS,eAAA,CAAgB;AAAA,EAC3G;AACA,MAAI,YAAY,YAAY;AACxB,+BAAQ,gBAAA,EAAe;AAAA,EAC3B;AACA,6BAAQ,eAAe,UAAf,EAAwB,OAAe,UAAA,SAAS,SAAS,GAAE;AACvE;AAOO,SAAS,aAAa;AACzB,QAAM,UAAU,WAAW,cAAc;AACzC,MAAI,CAAC,SAAS;AACV,UAAM,IAAI,MAAM,uDAAuD;AAAA,EAC3E;AACA,SAAO;AACX;"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback, useEffect, useMemo } from "react";
|
|
4
|
+
import Alert from "@mui/material/Alert";
|
|
5
|
+
import Skeleton from "@mui/material/Skeleton";
|
|
6
|
+
import Stack from "@mui/material/Stack";
|
|
7
|
+
import Typography from "@mui/material/Typography";
|
|
8
|
+
import { useAccount } from "./AccountProvider.js";
|
|
9
|
+
import DemoTotpCodeButton from "./DemoTotpCodeButton.js";
|
|
10
|
+
import ChangePasswordForm from "../forms/auth/ChangePasswordForm.js";
|
|
11
|
+
import TwoStepVerificationCard from "../forms/security/TwoStepVerificationCard.js";
|
|
12
|
+
import ActivityLog from "../security/ActivityLog.js";
|
|
13
|
+
import { createPasskey, passkeysSupported } from "../security/passkeys.js";
|
|
14
|
+
import SessionsCard from "../security/SessionsCard.js";
|
|
15
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
16
|
+
import SectionCard from "../ui/layout/SectionCard.js";
|
|
17
|
+
const FORM_MAX_WIDTH = 520;
|
|
18
|
+
const LOADING_HEIGHT_PIXELS = 220;
|
|
19
|
+
function AccountSecuritySection({ showPasswordChange = true }) {
|
|
20
|
+
const { t } = useToolkitTranslation("account");
|
|
21
|
+
const { connector, session } = useAccount();
|
|
22
|
+
const [security, setSecurity] = useState(null);
|
|
23
|
+
const [sessions, setSessions] = useState(null);
|
|
24
|
+
const [events, setEvents] = useState(null);
|
|
25
|
+
const [loadError, setLoadError] = useState(null);
|
|
26
|
+
const isDemo = typeof connector.demoTotpCode === "function";
|
|
27
|
+
const refreshActivity = useCallback(() => connector.listActivity().then(setEvents).catch((error) => setLoadError(error.message)), [connector]);
|
|
28
|
+
const refreshSessions = useCallback(() => connector.listSessions().then(setSessions).catch((error) => setLoadError(error.message)), [connector]);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
connector.loadSecurity().then(setSecurity).catch((error) => setLoadError(error.message));
|
|
31
|
+
refreshSessions();
|
|
32
|
+
refreshActivity();
|
|
33
|
+
}, [connector, refreshActivity, refreshSessions]);
|
|
34
|
+
const actions = useMemo(() => ({
|
|
35
|
+
addPasskey: async (name) => connector.savePasskey({ name, credential: await createPasskey(await connector.passkeyRegistrationOptions()) }),
|
|
36
|
+
removePasskey: (passkey, password) => connector.removePasskey({ passkeyId: passkey.id, password }),
|
|
37
|
+
startTotp: async () => ({
|
|
38
|
+
...await connector.startTotp(),
|
|
39
|
+
// en la demostración, el atajo del código abajo del campo
|
|
40
|
+
extra: isDemo ? /* @__PURE__ */ jsx(DemoTotpCodeButton, { loadCode: connector.demoTotpCode }) : void 0
|
|
41
|
+
}),
|
|
42
|
+
confirmTotp: (code) => connector.confirmTotp(code),
|
|
43
|
+
disableTotp: (password) => connector.disableTotp(password),
|
|
44
|
+
regenerateRecoveryCodes: (password) => connector.regenerateRecoveryCodes(password)
|
|
45
|
+
}), [connector, isDemo]);
|
|
46
|
+
const changeSecurity = (nextSecurity) => {
|
|
47
|
+
setSecurity(nextSecurity);
|
|
48
|
+
refreshActivity();
|
|
49
|
+
};
|
|
50
|
+
return /* @__PURE__ */ jsxs(Stack, { spacing: 3, children: [
|
|
51
|
+
loadError && /* @__PURE__ */ jsx(Alert, { severity: "error", children: loadError }),
|
|
52
|
+
showPasswordChange && /* @__PURE__ */ jsxs(SectionCard, { title: t("profile.password.title"), children: [
|
|
53
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mb: 2 }, children: t("profile.password.text") }),
|
|
54
|
+
/* @__PURE__ */ jsx(Stack, { sx: { maxWidth: FORM_MAX_WIDTH }, children: /* @__PURE__ */ jsx(ChangePasswordForm, { onSubmit: async (values) => {
|
|
55
|
+
await connector.changePassword(values);
|
|
56
|
+
refreshActivity();
|
|
57
|
+
} }) })
|
|
58
|
+
] }),
|
|
59
|
+
security ? /* @__PURE__ */ jsx(
|
|
60
|
+
TwoStepVerificationCard,
|
|
61
|
+
{
|
|
62
|
+
security,
|
|
63
|
+
onSecurityChange: changeSecurity,
|
|
64
|
+
actions,
|
|
65
|
+
canUsePasskeys: passkeysSupported(),
|
|
66
|
+
account: session?.user.email,
|
|
67
|
+
passkeyNotice: isDemo ? t("demo.passkeyNote") : void 0
|
|
68
|
+
}
|
|
69
|
+
) : /* @__PURE__ */ jsx(Skeleton, { variant: "rounded", height: LOADING_HEIGHT_PIXELS }),
|
|
70
|
+
isDemo && /* @__PURE__ */ jsx(Alert, { severity: "info", children: t("demo.securityNote") }),
|
|
71
|
+
/* @__PURE__ */ jsx(SessionsCard, { sessions, onCloseOthers: connector.closeOtherSessions, onClosed: () => {
|
|
72
|
+
refreshSessions();
|
|
73
|
+
refreshActivity();
|
|
74
|
+
} }),
|
|
75
|
+
/* @__PURE__ */ jsx(ActivityLog, { events })
|
|
76
|
+
] });
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
AccountSecuritySection as default
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=AccountSecuritySection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccountSecuritySection.js","sources":["../../src/account/AccountSecuritySection.jsx"],"sourcesContent":["// La seguridad de la cuenta, completa: cambiar la contraseña (ChangePasswordForm), la verificación en dos pasos\n// (TwoStepVerificationCard: llaves de acceso, app autenticadora y códigos de recuperación), las sesiones abiertas\n// (SessionsCard) y la bitácora (ActivityLog). Todo lo del servidor sale del conector de la cuenta.\n//\n// Las llaves de acceso se crean aquí con el navegador (createPasskey) y la respuesta va al servidor (savePasskey). La\n// bitácora se vuelve a pedir después de cada cambio: así se ve aparecer lo que se acaba de hacer.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useCallback, useEffect, useMemo, useState} from 'react';\nimport Alert from '@mui/material/Alert';\nimport Skeleton from '@mui/material/Skeleton';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {useAccount} from '@/account/AccountProvider.jsx';\nimport DemoTotpCodeButton from '@/account/DemoTotpCodeButton.jsx';\nimport ChangePasswordForm from '@/forms/auth/ChangePasswordForm.jsx';\nimport TwoStepVerificationCard from '@/forms/security/TwoStepVerificationCard.jsx';\nimport ActivityLog from '@/security/ActivityLog.jsx';\nimport {createPasskey, passkeysSupported} from '@/security/passkeys.js';\nimport SessionsCard from '@/security/SessionsCard.jsx';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport SectionCard from '@/ui/layout/SectionCard.jsx';\n\n// lo ancho del formulario de la contraseña: un renglón cómodo\nconst FORM_MAX_WIDTH = 520;\nconst LOADING_HEIGHT_PIXELS = 220;\n\n/**\n * @param {object} props\n * @param {boolean} [props.showPasswordChange] por omisión sí\n */\nexport default function AccountSecuritySection({showPasswordChange = true}) {\n const {t} = useToolkitTranslation('account');\n const {connector, session} = useAccount();\n const [security, setSecurity] = useState(null);\n const [sessions, setSessions] = useState(null);\n const [events, setEvents] = useState(null);\n const [loadError, setLoadError] = useState(null);\n const isDemo = typeof connector.demoTotpCode === 'function';\n\n const refreshActivity = useCallback(() => connector.listActivity().then(setEvents).catch((error) => setLoadError(error.message)), [connector]);\n const refreshSessions = useCallback(() => connector.listSessions().then(setSessions).catch((error) => setLoadError(error.message)), [connector]);\n\n useEffect(() => {\n connector.loadSecurity().then(setSecurity).catch((error) => setLoadError(error.message));\n refreshSessions();\n refreshActivity();\n }, [connector, refreshActivity, refreshSessions]);\n\n // lo que hace la tarjeta de dos pasos en cada caso, con el conector\n const actions = useMemo(() => ({\n addPasskey: async (name) => connector.savePasskey({name, credential: await createPasskey(await connector.passkeyRegistrationOptions())}),\n removePasskey: (passkey, password) => connector.removePasskey({passkeyId: passkey.id, password}),\n startTotp: async () => ({\n ...await connector.startTotp(),\n // en la demostración, el atajo del código abajo del campo\n extra: isDemo ? <DemoTotpCodeButton loadCode={connector.demoTotpCode} /> : undefined,\n }),\n confirmTotp: (code) => connector.confirmTotp(code),\n disableTotp: (password) => connector.disableTotp(password),\n regenerateRecoveryCodes: (password) => connector.regenerateRecoveryCodes(password),\n }), [connector, isDemo]);\n\n const changeSecurity = (nextSecurity) => {\n setSecurity(nextSecurity);\n refreshActivity();\n };\n\n return (\n <Stack spacing={3}>\n {loadError && <Alert severity=\"error\">{loadError}</Alert>}\n {showPasswordChange && (\n <SectionCard title={t('profile.password.title')}>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{mb: 2}}>{t('profile.password.text')}</Typography>\n <Stack sx={{maxWidth: FORM_MAX_WIDTH}}>\n <ChangePasswordForm onSubmit={async (values) => {\n await connector.changePassword(values);\n refreshActivity();\n }} />\n </Stack>\n </SectionCard>\n )}\n {security\n ? <TwoStepVerificationCard security={security} onSecurityChange={changeSecurity} actions={actions}\n canUsePasskeys={passkeysSupported()} account={session?.user.email}\n // en la demostración la llave es de verdad pero el servidor se olvida al recargar:\n // se avisa antes de crearla para que nadie se quede con una llave huérfana\n passkeyNotice={isDemo ? t('demo.passkeyNote') : undefined} />\n : <Skeleton variant=\"rounded\" height={LOADING_HEIGHT_PIXELS} />}\n {isDemo && <Alert severity=\"info\">{t('demo.securityNote')}</Alert>}\n <SessionsCard sessions={sessions} onCloseOthers={connector.closeOtherSessions} onClosed={() => {\n refreshSessions();\n refreshActivity();\n }} />\n <ActivityLog events={events} />\n </Stack>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useFormikContext } from "formik";
|
|
4
|
+
import Button from "@mui/material/Button";
|
|
5
|
+
import Stack from "@mui/material/Stack";
|
|
6
|
+
import Typography from "@mui/material/Typography";
|
|
7
|
+
import ScienceOutlinedIcon from "@mui/icons-material/ScienceOutlined";
|
|
8
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
9
|
+
function DemoTotpCodeButton({ loadCode }) {
|
|
10
|
+
const { t } = useToolkitTranslation("account");
|
|
11
|
+
const { setFieldValue } = useFormikContext();
|
|
12
|
+
const fillCode = async () => {
|
|
13
|
+
const code = await loadCode();
|
|
14
|
+
if (code) {
|
|
15
|
+
setFieldValue("code", code);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
return /* @__PURE__ */ jsxs(Stack, { spacing: 0.5, sx: { alignItems: "center" }, children: [
|
|
19
|
+
/* @__PURE__ */ jsx(Button, { size: "small", startIcon: /* @__PURE__ */ jsx(ScienceOutlinedIcon, {}), onClick: fillCode, children: t("demo.totpCode") }),
|
|
20
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", sx: { textAlign: "center" }, children: t("demo.totpCodeHelp") })
|
|
21
|
+
] });
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
DemoTotpCodeButton as default
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=DemoTotpCodeButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DemoTotpCodeButton.js","sources":["../../src/account/DemoTotpCodeButton.jsx"],"sourcesContent":["// El atajo de la DEMOSTRACIÓN para la app autenticadora: llena el campo «code» del formulario con el código que enseñaría\n// la app ahorita. Para quien prueba sin la app en su teléfono (y para las pruebas automáticas, que no escanean QR). Solo\n// sale cuando el conector trae demoTotpCode: con un backend de verdad no existe (el código solo lo conoce la app).\n//\n// Va dentro del formulario de formik (abajo del segundo paso o en el diálogo de activar la app).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useFormikContext} from 'formik';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport ScienceOutlinedIcon from '@mui/icons-material/ScienceOutlined';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\n\n/**\n * @param {{loadCode: () => Promise<string|null>}} props\n */\nexport default function DemoTotpCodeButton({loadCode}) {\n const {t} = useToolkitTranslation('account');\n const {setFieldValue} = useFormikContext();\n\n const fillCode = async () => {\n const code = await loadCode();\n if (code) {\n setFieldValue('code', code);\n }\n };\n\n return (\n <Stack spacing={0.5} sx={{alignItems: 'center'}}>\n <Button size=\"small\" startIcon={<ScienceOutlinedIcon />} onClick={fillCode}>{t('demo.totpCode')}</Button>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{textAlign: 'center'}}>{t('demo.totpCodeHelp')}</Typography>\n </Stack>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAkBA,SAAwB,mBAAmB,EAAC,YAAW;AACnD,QAAM,EAAC,EAAA,IAAK,sBAAsB,SAAS;AAC3C,QAAM,EAAC,cAAA,IAAiB,iBAAA;AAExB,QAAM,WAAW,YAAY;AACzB,UAAM,OAAO,MAAM,SAAA;AACnB,QAAI,MAAM;AACN,oBAAc,QAAQ,IAAI;AAAA,IAC9B;AAAA,EACJ;AAEA,SACI,qBAAC,SAAM,SAAS,KAAK,IAAI,EAAC,YAAY,YAClC,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAO,MAAK,SAAQ,WAAW,oBAAC,qBAAA,CAAA,CAAoB,GAAI,SAAS,UAAW,UAAA,EAAE,eAAe,GAAE;AAAA,IAChG,oBAAC,YAAA,EAAW,SAAQ,WAAU,OAAM,kBAAiB,IAAI,EAAC,WAAW,SAAA,GAAY,UAAA,EAAE,mBAAmB,EAAA,CAAE;AAAA,EAAA,GAC5G;AAER;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useAccount } from "./AccountProvider.js";
|
|
4
|
+
import { AuthLayout } from "../appShell/AuthLayout.js";
|
|
5
|
+
import ForgotPasswordForm from "../forms/auth/ForgotPasswordForm.js";
|
|
6
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
7
|
+
function ForgotPasswordScreen({ signInPath, logo, brandName, showLanguageToggle = true, showColorSchemeToggle = true }) {
|
|
8
|
+
const { t } = useToolkitTranslation("auth");
|
|
9
|
+
const { connector } = useAccount();
|
|
10
|
+
return /* @__PURE__ */ jsx(
|
|
11
|
+
AuthLayout,
|
|
12
|
+
{
|
|
13
|
+
logo,
|
|
14
|
+
brandName,
|
|
15
|
+
title: t("forgotPassword.title"),
|
|
16
|
+
description: t("forgotPassword.subtitle"),
|
|
17
|
+
showLanguageToggle,
|
|
18
|
+
showColorSchemeToggle,
|
|
19
|
+
children: /* @__PURE__ */ jsx(ForgotPasswordForm, { onSubmit: connector.requestPasswordReset, signInPath })
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
ForgotPasswordScreen as default
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=ForgotPasswordScreen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ForgotPasswordScreen.js","sources":["../../src/account/ForgotPasswordScreen.jsx"],"sourcesContent":["// «¿Olvidó su contraseña?», completa: pide el correo y avisa que revise su bandeja (ForgotPasswordForm). Lo del servidor\n// sale del conector de la cuenta (requestPasswordReset).\n//\n// <ForgotPasswordScreen signInPath=\"/sign-in\" logo={<AppLogo />} />\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useAccount} from '@/account/AccountProvider.jsx';\nimport {AuthLayout} from '@/appShell/AuthLayout.jsx';\nimport ForgotPasswordForm from '@/forms/auth/ForgotPasswordForm.jsx';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\n\n/**\n * @param {object} props\n * @param {string} [props.signInPath] la liga para regresar a entrar\n * @param {import('react').ReactNode} [props.logo]\n * @param {string} [props.brandName]\n * @param {boolean} [props.showLanguageToggle]\n * @param {boolean} [props.showColorSchemeToggle]\n */\nexport default function ForgotPasswordScreen({signInPath, logo, brandName, showLanguageToggle = true, showColorSchemeToggle = true}) {\n const {t} = useToolkitTranslation('auth');\n const {connector} = useAccount();\n\n return (\n <AuthLayout logo={logo} brandName={brandName} title={t('forgotPassword.title')} description={t('forgotPassword.subtitle')}\n showLanguageToggle={showLanguageToggle} showColorSchemeToggle={showColorSchemeToggle}>\n <ForgotPasswordForm onSubmit={connector.requestPasswordReset} signInPath={signInPath} />\n </AuthLayout>\n );\n}\n"],"names":[],"mappings":";;;;;;AAmBA,SAAwB,qBAAqB,EAAC,YAAY,MAAM,WAAW,qBAAqB,MAAM,wBAAwB,QAAO;AACjI,QAAM,EAAC,EAAA,IAAK,sBAAsB,MAAM;AACxC,QAAM,EAAC,UAAA,IAAa,WAAA;AAEpB,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MAAW;AAAA,MAAY;AAAA,MAAsB,OAAO,EAAE,sBAAsB;AAAA,MAAG,aAAa,EAAE,yBAAyB;AAAA,MAC5G;AAAA,MAAwC;AAAA,MAChD,UAAA,oBAAC,oBAAA,EAAmB,UAAU,UAAU,sBAAsB,WAAA,CAAwB;AAAA,IAAA;AAAA,EAAA;AAGlG;"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { Formik, Form } from "formik";
|
|
5
|
+
import Stack from "@mui/material/Stack";
|
|
6
|
+
import Tab from "@mui/material/Tab";
|
|
7
|
+
import Tabs from "@mui/material/Tabs";
|
|
8
|
+
import Typography from "@mui/material/Typography";
|
|
9
|
+
import AccountSecuritySection from "./AccountSecuritySection.js";
|
|
10
|
+
import { useAccount } from "./AccountProvider.js";
|
|
11
|
+
import AppearanceSettings from "../appShell/AppearanceSettings.js";
|
|
12
|
+
import { toastSuccess } from "../feedback/toast.js";
|
|
13
|
+
import FormProblemAlert from "../forms/FormProblemAlert.js";
|
|
14
|
+
import FormTextField from "../forms/FormTextField.js";
|
|
15
|
+
import SubmitButton from "../forms/SubmitButton.js";
|
|
16
|
+
import { applyServerProblem } from "../forms/applyServerProblem.js";
|
|
17
|
+
import * as Yup from "yup";
|
|
18
|
+
import TextInput from "../inputs/TextInput.js";
|
|
19
|
+
import { useToolkitNavigation } from "../toolkit/toolkitContext.js";
|
|
20
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
21
|
+
import ProfileHeader from "../ui/layout/ProfileHeader.js";
|
|
22
|
+
import SectionCard from "../ui/layout/SectionCard.js";
|
|
23
|
+
const PROFILE_TAB = Object.freeze({ data: "data", security: "security", preferences: "preferences" });
|
|
24
|
+
const TAB_PARAM = "tab";
|
|
25
|
+
const PHONE_PATTERN = /^\+?\d{7,15}$/;
|
|
26
|
+
const FORM_MAX_WIDTH = 520;
|
|
27
|
+
function ProfileDataSection() {
|
|
28
|
+
const { t } = useToolkitTranslation("account");
|
|
29
|
+
const { connector, session, refreshSession } = useAccount();
|
|
30
|
+
const schema = useMemo(() => Yup.object({
|
|
31
|
+
name: Yup.string().trim().required(),
|
|
32
|
+
phone: Yup.string().trim().matches(PHONE_PATTERN, { message: { key: "account:profile.data.phoneInvalid" }, excludeEmptyString: true })
|
|
33
|
+
}), []);
|
|
34
|
+
const save = async (values, formikHelpers) => {
|
|
35
|
+
try {
|
|
36
|
+
const response = await connector.updateProfile({ name: values.name.trim(), phone: values.phone.trim() });
|
|
37
|
+
await refreshSession();
|
|
38
|
+
toastSuccess(response?.message ?? t("profile.data.saved"));
|
|
39
|
+
} catch (error) {
|
|
40
|
+
applyServerProblem(error, { ...formikHelpers, values });
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
return /* @__PURE__ */ jsxs(SectionCard, { title: t("profile.data.title"), children: [
|
|
44
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mb: 2 }, children: t("profile.data.text") }),
|
|
45
|
+
/* @__PURE__ */ jsx(Formik, { initialValues: { name: session.user.name ?? "", phone: session.user.phone ?? "" }, validationSchema: schema, onSubmit: save, children: /* @__PURE__ */ jsx(Form, { noValidate: true, children: /* @__PURE__ */ jsxs(Stack, { spacing: 2, sx: { maxWidth: FORM_MAX_WIDTH }, children: [
|
|
46
|
+
/* @__PURE__ */ jsx(FormProblemAlert, {}),
|
|
47
|
+
/* @__PURE__ */ jsx(FormTextField, { name: "name", label: t("profile.data.name"), autoComplete: "name" }),
|
|
48
|
+
/* @__PURE__ */ jsx(
|
|
49
|
+
TextInput,
|
|
50
|
+
{
|
|
51
|
+
name: "email",
|
|
52
|
+
label: t("profile.data.email"),
|
|
53
|
+
value: session.user.email,
|
|
54
|
+
onChange: () => {
|
|
55
|
+
},
|
|
56
|
+
helperText: t("profile.data.emailHelp"),
|
|
57
|
+
disabled: true
|
|
58
|
+
}
|
|
59
|
+
),
|
|
60
|
+
/* @__PURE__ */ jsx(FormTextField, { name: "phone", label: t("profile.data.phone"), type: "tel", autoComplete: "tel", inputMode: "tel" }),
|
|
61
|
+
/* @__PURE__ */ jsx(SubmitButton, { sx: { alignSelf: "flex-start" }, children: t("profile.data.save") })
|
|
62
|
+
] }) }) })
|
|
63
|
+
] });
|
|
64
|
+
}
|
|
65
|
+
function ProfileScreen({ showColorScheme = true }) {
|
|
66
|
+
const { t } = useToolkitTranslation("account");
|
|
67
|
+
const { session } = useAccount();
|
|
68
|
+
const { useNavigate, useLocation } = useToolkitNavigation();
|
|
69
|
+
const navigate = useNavigate();
|
|
70
|
+
const { pathname, search } = useLocation();
|
|
71
|
+
const requestedTab = new URLSearchParams(search).get(TAB_PARAM);
|
|
72
|
+
const activeTab = Object.values(PROFILE_TAB).includes(requestedTab) ? requestedTab : PROFILE_TAB.data;
|
|
73
|
+
if (!session) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return /* @__PURE__ */ jsxs(Stack, { spacing: 2, children: [
|
|
77
|
+
/* @__PURE__ */ jsx(
|
|
78
|
+
ProfileHeader,
|
|
79
|
+
{
|
|
80
|
+
name: session.user.name,
|
|
81
|
+
email: session.user.email,
|
|
82
|
+
subtitle: session.user.subtitle,
|
|
83
|
+
avatarUrl: session.user.avatarUrl,
|
|
84
|
+
chips: session.labels ?? []
|
|
85
|
+
}
|
|
86
|
+
),
|
|
87
|
+
/* @__PURE__ */ jsx(
|
|
88
|
+
Tabs,
|
|
89
|
+
{
|
|
90
|
+
value: activeTab,
|
|
91
|
+
onChange: (event, tab) => navigate(`${pathname}?${TAB_PARAM}=${tab}`, { replace: true }),
|
|
92
|
+
"aria-label": t("profile.tabs.label"),
|
|
93
|
+
children: Object.values(PROFILE_TAB).map((tab) => /* @__PURE__ */ jsx(Tab, { value: tab, label: t(`profile.tabs.${tab}`) }, tab))
|
|
94
|
+
}
|
|
95
|
+
),
|
|
96
|
+
activeTab === PROFILE_TAB.data && /* @__PURE__ */ jsx(ProfileDataSection, {}),
|
|
97
|
+
activeTab === PROFILE_TAB.security && /* @__PURE__ */ jsx(AccountSecuritySection, {}),
|
|
98
|
+
activeTab === PROFILE_TAB.preferences && /* @__PURE__ */ jsxs(SectionCard, { title: t("profile.preferences.title"), children: [
|
|
99
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mb: 1 }, children: t("profile.preferences.text") }),
|
|
100
|
+
/* @__PURE__ */ jsx(Stack, { sx: { maxWidth: FORM_MAX_WIDTH, mx: -1 }, children: /* @__PURE__ */ jsx(AppearanceSettings, { showColorScheme }) })
|
|
101
|
+
] })
|
|
102
|
+
] });
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
PROFILE_TAB,
|
|
106
|
+
ProfileScreen as default
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=ProfileScreen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProfileScreen.js","sources":["../../src/account/ProfileScreen.jsx"],"sourcesContent":["// Mi perfil, completo: quién está dentro (ProfileHeader con sus perfiles como chips) y tres pestañas:\n// - Sus datos: nombre y teléfono (el correo se ve pero no se cambia aquí); al guardar se vuelve a leer la sesión, así la\n// barra y el menú de la cuenta ya dicen el nombre nuevo;\n// - Seguridad: AccountSecuritySection (contraseña, dos pasos, sesiones y bitácora);\n// - Preferencias: AppearanceSettings (tamaño de letra, idioma y modo de color).\n// La pestaña abierta va en la dirección (?tab=): se puede compartir o recargar sin perderla. Lo del servidor sale del\n// conector de la cuenta.\n//\n// <ProfileScreen />\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useMemo} from 'react';\nimport {Form, Formik} from 'formik';\nimport Stack from '@mui/material/Stack';\nimport Tab from '@mui/material/Tab';\nimport Tabs from '@mui/material/Tabs';\nimport Typography from '@mui/material/Typography';\n\nimport AccountSecuritySection from '@/account/AccountSecuritySection.jsx';\nimport {useAccount} from '@/account/AccountProvider.jsx';\nimport AppearanceSettings from '@/appShell/AppearanceSettings.jsx';\nimport {toastSuccess} from '@/feedback/toast.jsx';\nimport FormProblemAlert from '@/forms/FormProblemAlert.jsx';\nimport FormTextField from '@/forms/FormTextField.jsx';\nimport SubmitButton from '@/forms/SubmitButton.jsx';\nimport {applyServerProblem} from '@/forms/applyServerProblem.js';\nimport {Yup} from '@/forms/validation.js';\nimport TextInput from '@/inputs/TextInput.jsx';\nimport {useToolkitNavigation} from '@/toolkit/toolkitContext.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport ProfileHeader from '@/ui/layout/ProfileHeader.jsx';\nimport SectionCard from '@/ui/layout/SectionCard.jsx';\n\n/** Las pestañas, en el orden en que se pintan. */\nexport const PROFILE_TAB = Object.freeze({data: 'data', security: 'security', preferences: 'preferences'});\nconst TAB_PARAM = 'tab';\n// el teléfono: dígitos, con + opcional al inicio (formato internacional); lo largo que permite el plan de numeración\nconst PHONE_PATTERN = /^\\+?\\d{7,15}$/;\n// lo ancho de los formularios: un renglón cómodo, no toda la pantalla\nconst FORM_MAX_WIDTH = 520;\n\n/** Sus datos: nombre y teléfono. */\nfunction ProfileDataSection() {\n const {t} = useToolkitTranslation('account');\n const {connector, session, refreshSession} = useAccount();\n // el esquema se arma al pintar: yup toma sus mensajes al armarlo\n const schema = useMemo(() => Yup.object({\n name: Yup.string().trim().required(),\n phone: Yup.string().trim().matches(PHONE_PATTERN, {message: {key: 'account:profile.data.phoneInvalid'}, excludeEmptyString: true}),\n }), []);\n\n const save = async (values, formikHelpers) => {\n try {\n const response = await connector.updateProfile({name: values.name.trim(), phone: values.phone.trim()});\n await refreshSession();\n toastSuccess(response?.message ?? t('profile.data.saved'));\n } catch (error) {\n applyServerProblem(error, {...formikHelpers, values});\n }\n };\n\n return (\n <SectionCard title={t('profile.data.title')}>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{mb: 2}}>{t('profile.data.text')}</Typography>\n <Formik initialValues={{name: session.user.name ?? '', phone: session.user.phone ?? ''}} validationSchema={schema} onSubmit={save}>\n <Form noValidate>\n <Stack spacing={2} sx={{maxWidth: FORM_MAX_WIDTH}}>\n <FormProblemAlert />\n <FormTextField name=\"name\" label={t('profile.data.name')} autoComplete=\"name\" />\n {/* el correo se ve con el mismo estilo de los demás campos, pero no se cambia aquí */}\n <TextInput name=\"email\" label={t('profile.data.email')} value={session.user.email} onChange={() => {}}\n helperText={t('profile.data.emailHelp')} disabled />\n <FormTextField name=\"phone\" label={t('profile.data.phone')} type=\"tel\" autoComplete=\"tel\" inputMode=\"tel\" />\n <SubmitButton sx={{alignSelf: 'flex-start'}}>{t('profile.data.save')}</SubmitButton>\n </Stack>\n </Form>\n </Formik>\n </SectionCard>\n );\n}\n\n/**\n * @param {object} props\n * @param {boolean} [props.showColorScheme] el ajuste de claro u oscuro en Preferencias; sin modo oscuro, false\n */\nexport default function ProfileScreen({showColorScheme = true}) {\n const {t} = useToolkitTranslation('account');\n const {session} = useAccount();\n const {useNavigate, useLocation} = useToolkitNavigation();\n const navigate = useNavigate();\n const {pathname, search} = useLocation();\n const requestedTab = new URLSearchParams(search).get(TAB_PARAM);\n const activeTab = Object.values(PROFILE_TAB).includes(requestedTab) ? requestedTab : PROFILE_TAB.data;\n\n // guard clause: sin sesión no hay perfil que enseñar (el marco de la app ya lleva a entrar)\n if (!session) {\n return null;\n }\n\n return (\n <Stack spacing={2}>\n <ProfileHeader name={session.user.name} email={session.user.email} subtitle={session.user.subtitle} avatarUrl={session.user.avatarUrl}\n chips={session.labels ?? []} />\n <Tabs value={activeTab} onChange={(event, tab) => navigate(`${pathname}?${TAB_PARAM}=${tab}`, {replace: true})}\n aria-label={t('profile.tabs.label')}>\n {Object.values(PROFILE_TAB).map((tab) => <Tab key={tab} value={tab} label={t(`profile.tabs.${tab}`)} />)}\n </Tabs>\n {activeTab === PROFILE_TAB.data && <ProfileDataSection />}\n {activeTab === PROFILE_TAB.security && <AccountSecuritySection />}\n {activeTab === PROFILE_TAB.preferences && (\n <SectionCard title={t('profile.preferences.title')}>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{mb: 1}}>{t('profile.preferences.text')}</Typography>\n <Stack sx={{maxWidth: FORM_MAX_WIDTH, mx: -1}}>\n <AppearanceSettings showColorScheme={showColorScheme} />\n </Stack>\n </SectionCard>\n )}\n </Stack>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import Alert from "@mui/material/Alert";
|
|
5
|
+
import Button from "@mui/material/Button";
|
|
6
|
+
import Stack from "@mui/material/Stack";
|
|
7
|
+
import { useAccount } from "./AccountProvider.js";
|
|
8
|
+
import { AuthLayout } from "../appShell/AuthLayout.js";
|
|
9
|
+
import ChangePasswordForm from "../forms/auth/ChangePasswordForm.js";
|
|
10
|
+
import { useToolkitNavigation } from "../toolkit/toolkitContext.js";
|
|
11
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
12
|
+
function ResetPasswordScreen({
|
|
13
|
+
signInPath,
|
|
14
|
+
forgotPasswordPath,
|
|
15
|
+
tokenParam = "token",
|
|
16
|
+
logo,
|
|
17
|
+
brandName,
|
|
18
|
+
showLanguageToggle = true,
|
|
19
|
+
showColorSchemeToggle = true
|
|
20
|
+
}) {
|
|
21
|
+
const { t } = useToolkitTranslation("account");
|
|
22
|
+
const { connector } = useAccount();
|
|
23
|
+
const { useLocation, Link } = useToolkitNavigation();
|
|
24
|
+
const { search } = useLocation();
|
|
25
|
+
const [isDone, setIsDone] = useState(false);
|
|
26
|
+
const token = new URLSearchParams(search).get(tokenParam);
|
|
27
|
+
const save = async ({ newPassword }) => {
|
|
28
|
+
await connector.resetPassword({ token, newPassword });
|
|
29
|
+
setIsDone(true);
|
|
30
|
+
};
|
|
31
|
+
return /* @__PURE__ */ jsxs(
|
|
32
|
+
AuthLayout,
|
|
33
|
+
{
|
|
34
|
+
logo,
|
|
35
|
+
brandName,
|
|
36
|
+
title: t("reset.title"),
|
|
37
|
+
description: t("reset.subtitle"),
|
|
38
|
+
showLanguageToggle,
|
|
39
|
+
showColorSchemeToggle,
|
|
40
|
+
children: [
|
|
41
|
+
!token && /* @__PURE__ */ jsxs(Stack, { spacing: 2, children: [
|
|
42
|
+
/* @__PURE__ */ jsx(Alert, { severity: "error", children: t("reset.missingToken") }),
|
|
43
|
+
forgotPasswordPath && /* @__PURE__ */ jsx(Button, { component: Link, to: forgotPasswordPath, variant: "contained", children: t("reset.askAgain") })
|
|
44
|
+
] }),
|
|
45
|
+
token && isDone && /* @__PURE__ */ jsxs(Stack, { spacing: 2, children: [
|
|
46
|
+
/* @__PURE__ */ jsx(Alert, { severity: "success", role: "status", children: t("reset.done") }),
|
|
47
|
+
/* @__PURE__ */ jsx(Button, { component: Link, to: signInPath, variant: "contained", children: t("reset.goToSignIn") })
|
|
48
|
+
] }),
|
|
49
|
+
token && !isDone && /* @__PURE__ */ jsx(ChangePasswordForm, { requireCurrentPassword: false, onSubmit: save })
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
ResetPasswordScreen as default
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=ResetPasswordScreen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResetPasswordScreen.js","sources":["../../src/account/ResetPasswordScreen.jsx"],"sourcesContent":["// Elegir una contraseña nueva desde el enlace del correo, completa: ChangePasswordForm sin la contraseña actual (quien llega\n// aquí la olvidó). El enlace trae su clave (?token=) y el servidor la revisa al guardar (connector.resetPassword). Sin\n// clave en la dirección, se dice que el enlace no sirve y cómo pedir otro.\n//\n// <ResetPasswordScreen signInPath=\"/sign-in\" forgotPasswordPath=\"/forgot-password\" logo={<AppLogo />} />\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport Alert from '@mui/material/Alert';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\n\nimport {useAccount} from '@/account/AccountProvider.jsx';\nimport {AuthLayout} from '@/appShell/AuthLayout.jsx';\nimport ChangePasswordForm from '@/forms/auth/ChangePasswordForm.jsx';\nimport {useToolkitNavigation} from '@/toolkit/toolkitContext.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\n\n/**\n * @param {object} props\n * @param {string} props.signInPath a dónde ir al terminar\n * @param {string} [props.forgotPasswordPath] para pedir otro enlace si este no sirve\n * @param {string} [props.tokenParam] cómo se llama la clave en la dirección; por omisión 'token'\n * @param {import('react').ReactNode} [props.logo]\n * @param {string} [props.brandName]\n * @param {boolean} [props.showLanguageToggle]\n * @param {boolean} [props.showColorSchemeToggle]\n */\nexport default function ResetPasswordScreen({\n signInPath, forgotPasswordPath, tokenParam = 'token', logo, brandName, showLanguageToggle = true, showColorSchemeToggle = true,\n}) {\n const {t} = useToolkitTranslation('account');\n const {connector} = useAccount();\n const {useLocation, Link} = useToolkitNavigation();\n const {search} = useLocation();\n const [isDone, setIsDone] = useState(false);\n const token = new URLSearchParams(search).get(tokenParam);\n\n const save = async ({newPassword}) => {\n await connector.resetPassword({token, newPassword});\n setIsDone(true);\n };\n\n return (\n <AuthLayout logo={logo} brandName={brandName} title={t('reset.title')} description={t('reset.subtitle')}\n showLanguageToggle={showLanguageToggle} showColorSchemeToggle={showColorSchemeToggle}>\n {!token && (\n <Stack spacing={2}>\n <Alert severity=\"error\">{t('reset.missingToken')}</Alert>\n {forgotPasswordPath && <Button component={Link} to={forgotPasswordPath} variant=\"contained\">{t('reset.askAgain')}</Button>}\n </Stack>\n )}\n {token && isDone && (\n <Stack spacing={2}>\n <Alert severity=\"success\" role=\"status\">{t('reset.done')}</Alert>\n <Button component={Link} to={signInPath} variant=\"contained\">{t('reset.goToSignIn')}</Button>\n </Stack>\n )}\n {token && !isDone && <ChangePasswordForm requireCurrentPassword={false} onSubmit={save} />}\n </AuthLayout>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AA4BA,SAAwB,oBAAoB;AAAA,EACxC;AAAA,EAAY;AAAA,EAAoB,aAAa;AAAA,EAAS;AAAA,EAAM;AAAA,EAAW,qBAAqB;AAAA,EAAM,wBAAwB;AAC9H,GAAG;AACC,QAAM,EAAC,EAAA,IAAK,sBAAsB,SAAS;AAC3C,QAAM,EAAC,UAAA,IAAa,WAAA;AACpB,QAAM,EAAC,aAAa,KAAA,IAAQ,qBAAA;AAC5B,QAAM,EAAC,OAAA,IAAU,YAAA;AACjB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,QAAQ,IAAI,gBAAgB,MAAM,EAAE,IAAI,UAAU;AAExD,QAAM,OAAO,OAAO,EAAC,kBAAiB;AAClC,UAAM,UAAU,cAAc,EAAC,OAAO,aAAY;AAClD,cAAU,IAAI;AAAA,EAClB;AAEA,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MAAW;AAAA,MAAY;AAAA,MAAsB,OAAO,EAAE,aAAa;AAAA,MAAG,aAAa,EAAE,gBAAgB;AAAA,MAC1F;AAAA,MAAwC;AAAA,MAC/C,UAAA;AAAA,QAAA,CAAC,SACE,qBAAC,OAAA,EAAM,SAAS,GACZ,UAAA;AAAA,UAAA,oBAAC,OAAA,EAAM,UAAS,SAAS,UAAA,EAAE,oBAAoB,GAAE;AAAA,UAChD,sBAAsB,oBAAC,QAAA,EAAO,WAAW,MAAM,IAAI,oBAAoB,SAAQ,aAAa,UAAA,EAAE,gBAAgB,EAAA,CAAE;AAAA,QAAA,GACrH;AAAA,QAEH,SAAS,UACN,qBAAC,OAAA,EAAM,SAAS,GACZ,UAAA;AAAA,UAAA,oBAAC,SAAM,UAAS,WAAU,MAAK,UAAU,UAAA,EAAE,YAAY,GAAE;AAAA,UACzD,oBAAC,QAAA,EAAO,WAAW,MAAM,IAAI,YAAY,SAAQ,aAAa,UAAA,EAAE,kBAAkB,EAAA,CAAE;AAAA,QAAA,GACxF;AAAA,QAEH,SAAS,CAAC,UAAU,oBAAC,sBAAmB,wBAAwB,OAAO,UAAU,KAAA,CAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGpG;"}
|