@stackcraftmx/calcita 0.0.0-stage → 0.25.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 +700 -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 +128 -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 +83 -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 +107 -0
- package/cli/templates/project/src/app/AppShell.jsx.tpl +87 -0
- package/cli/templates/project/src/app/appRouter.jsx.tpl +51 -0
- package/cli/templates/project/src/app/appSettings.js.tpl +27 -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 +14 -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 +9 -0
- package/cli/templates/project/src/core/publicPaths.js.tpl +24 -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 +53 -0
- package/dist/DataTable/AuditTrailDialog.js +40 -0
- package/dist/DataTable/AuditTrailDialog.js.map +1 -0
- package/dist/DataTable/AuditTrailTable.js +89 -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 +51 -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 +63 -0
- package/dist/DataTable/GoToPage.js.map +1 -0
- package/dist/DataTable/ServerTable.js +477 -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/rowSelection.js +61 -0
- package/dist/DataTable/rowSelection.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 +84 -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 +27 -0
- package/dist/account/ForgotPasswordScreen.js.map +1 -0
- package/dist/account/ProfileScreen.js +134 -0
- package/dist/account/ProfileScreen.js.map +1 -0
- package/dist/account/ResetPasswordScreen.js +58 -0
- package/dist/account/ResetPasswordScreen.js.map +1 -0
- package/dist/account/SignInScreen.js +102 -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 +118 -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 +49 -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 +256 -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 +513 -0
- package/dist/appShell/AppLayout.js.map +1 -0
- package/dist/appShell/AppearanceSettings.js +116 -0
- package/dist/appShell/AppearanceSettings.js.map +1 -0
- package/dist/appShell/AuthLayout.js +46 -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 +105 -0
- package/dist/appShell/BarActions.js.map +1 -0
- package/dist/appShell/BarCapsule.js +50 -0
- package/dist/appShell/BarCapsule.js.map +1 -0
- package/dist/appShell/BarSearch.js +92 -0
- package/dist/appShell/BarSearch.js.map +1 -0
- package/dist/appShell/HeaderTools.js +53 -0
- package/dist/appShell/HeaderTools.js.map +1 -0
- package/dist/appShell/MobileTabBar.js +348 -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 +40 -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 +149 -0
- package/dist/calendar/EventCalendar.js.map +1 -0
- package/dist/calendar/EventDetails.js +74 -0
- package/dist/calendar/EventDetails.js.map +1 -0
- package/dist/calendar/calendarEvents.js +31 -0
- package/dist/calendar/calendarEvents.js.map +1 -0
- package/dist/calendar.js +13 -0
- package/dist/calendar.js.map +1 -0
- package/dist/charts.js +16 -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 +76 -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 +195 -0
- package/dist/downloads/DownloadManager.js.map +1 -0
- package/dist/downloads/downloadQueue.js +56 -0
- package/dist/downloads/downloadQueue.js.map +1 -0
- package/dist/downloads/downloadsMachine.js +80 -0
- package/dist/downloads/downloadsMachine.js.map +1 -0
- package/dist/downloads/fileTypes.js +22 -0
- package/dist/downloads/fileTypes.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 +73 -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 +256 -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 +205 -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 +63 -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 +47 -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 +338 -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/FormWizard.js +59 -0
- package/dist/hookForm/FormWizard.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 +104 -0
- package/dist/inbox/InboxLayout.js.map +1 -0
- package/dist/inbox/MessageList.js +114 -0
- package/dist/inbox/MessageList.js.map +1 -0
- package/dist/inbox/MessageView.js +104 -0
- package/dist/inbox/MessageView.js.map +1 -0
- package/dist/inbox/inboxDates.js +9 -0
- package/dist/inbox/inboxDates.js.map +1 -0
- package/dist/index.js +407 -0
- package/dist/index.js.map +1 -0
- package/dist/inputs/CatalogInput.js +66 -0
- package/dist/inputs/CatalogInput.js.map +1 -0
- package/dist/inputs/ColorInput.js +109 -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 +70 -0
- package/dist/inputs/NumberInput.js.map +1 -0
- package/dist/inputs/SelectInput.js +84 -0
- package/dist/inputs/SelectInput.js.map +1 -0
- package/dist/inputs/TextInput.js +101 -0
- package/dist/inputs/TextInput.js.map +1 -0
- package/dist/inputs/WizardLayout.js +54 -0
- package/dist/inputs/WizardLayout.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 +338 -0
- package/dist/kanban/KanbanBoard.js.map +1 -0
- package/dist/kanban/kanbanCards.js +19 -0
- package/dist/kanban/kanbanCards.js.map +1 -0
- package/dist/kanban/kanbanMoves.js +29 -0
- package/dist/kanban/kanbanMoves.js.map +1 -0
- package/dist/kanban.js +15 -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 +787 -0
- package/dist/locales/en.js.map +1 -0
- package/dist/locales/es.js +787 -0
- package/dist/locales/es.js.map +1 -0
- package/dist/maps/MapView.js +116 -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 +77 -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 +34 -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 +70 -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 +71 -0
- package/dist/pwa/useInstallPrompt.js.map +1 -0
- package/dist/react-hook-form.js +32 -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 +80 -0
- package/dist/security/ActivityLog.js.map +1 -0
- package/dist/security/RecoveryCodesDialog.js +85 -0
- package/dist/security/RecoveryCodesDialog.js.map +1 -0
- package/dist/security/SessionsCard.js +83 -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 +37 -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/MuiDialog.js +13 -0
- package/dist/theme/components/MuiDialog.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 +28 -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/ComponentTexts.js +13 -0
- package/dist/toolkit/ComponentTexts.js.map +1 -0
- package/dist/toolkit/ToolkitProvider.js +57 -0
- package/dist/toolkit/ToolkitProvider.js.map +1 -0
- package/dist/toolkit/browserNavigation.js +33 -0
- package/dist/toolkit/browserNavigation.js.map +1 -0
- package/dist/toolkit/componentTextsContext.js +15 -0
- package/dist/toolkit/componentTextsContext.js.map +1 -0
- package/dist/toolkit/hashNavigation.js +40 -0
- package/dist/toolkit/hashNavigation.js.map +1 -0
- package/dist/toolkit/navigationPaths.js +49 -0
- package/dist/toolkit/navigationPaths.js.map +1 -0
- package/dist/toolkit/toolkitContext.js +19 -0
- package/dist/toolkit/toolkitContext.js.map +1 -0
- package/dist/toolkit/toolkitSettings.js +107 -0
- package/dist/toolkit/toolkitSettings.js.map +1 -0
- package/dist/toolkit/useFormatters.js +12 -0
- package/dist/toolkit/useFormatters.js.map +1 -0
- package/dist/toolkit/useToolkitTranslation.js +22 -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 +30 -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 +13 -0
- package/dist/types/DataTable/FilterChips.d.ts +17 -0
- package/dist/types/DataTable/GoToPage.d.ts +13 -0
- package/dist/types/DataTable/SelectionBar.d.ts +32 -0
- package/dist/types/DataTable/ServerTable.d.ts +171 -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/rowSelection.d.ts +113 -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 +23 -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 +9 -0
- package/dist/types/account/DemoTotpCodeButton.d.ts +6 -0
- package/dist/types/account/ForgotPasswordScreen.d.ts +17 -0
- package/dist/types/account/ProfileScreen.d.ts +43 -0
- package/dist/types/account/ResetPasswordScreen.d.ts +21 -0
- package/dist/types/account/SignInScreen.d.ts +27 -0
- package/dist/types/account/accountConnector.d.ts +268 -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 +42 -0
- package/dist/types/api/ApiError.d.ts +42 -0
- package/dist/types/api/createApiClient.d.ts +174 -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 +76 -0
- package/dist/types/appShell/AppearanceSettings.d.ts +41 -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 +23 -0
- package/dist/types/appShell/BarCapsule.d.ts +20 -0
- package/dist/types/appShell/BarSearch.d.ts +24 -0
- package/dist/types/appShell/HeaderTools.d.ts +27 -0
- package/dist/types/appShell/MobileTabBar.d.ts +20 -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 +46 -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 +13 -0
- package/dist/types/auth/passwordRules.d.ts +34 -0
- package/dist/types/calendar/EventCalendar.d.ts +63 -0
- package/dist/types/calendar/EventDetails.d.ts +36 -0
- package/dist/types/calendar/calendarEvents.d.ts +27 -0
- package/dist/types/calendar.d.ts +3 -0
- package/dist/types/charts.d.ts +6 -0
- package/dist/types/date-pickers.d.ts +2 -0
- package/dist/types/datePickers/DateInput.d.ts +41 -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 +7 -0
- package/dist/types/downloads/downloadQueue.d.ts +50 -0
- package/dist/types/downloads/downloadsMachine.d.ts +10 -0
- package/dist/types/downloads/fileTypes.d.ts +39 -0
- package/dist/types/downloads/index.d.ts +4 -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 +31 -0
- package/dist/types/feedback/ModalWaiting.d.ts +13 -0
- package/dist/types/feedback/NewBuildNotice.d.ts +20 -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 +61 -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 +61 -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 +22 -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 +17 -0
- package/dist/types/forms/auth/ForgotPasswordForm.d.ts +14 -0
- package/dist/types/forms/auth/SignInForm.d.ts +20 -0
- package/dist/types/forms/index.d.ts +19 -0
- package/dist/types/forms/security/SecondStepForm.d.ts +30 -0
- package/dist/types/forms/security/TwoStepVerificationCard.d.ts +83 -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/FormWizard.d.ts +22 -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 +38 -0
- package/dist/types/inbox/MessageList.d.ts +52 -0
- package/dist/types/inbox/MessageView.d.ts +55 -0
- package/dist/types/inbox/inboxDates.d.ts +11 -0
- package/dist/types/index.d.ts +91 -0
- package/dist/types/inputs/CatalogInput.d.ts +45 -0
- package/dist/types/inputs/ColorInput.d.ts +30 -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 +38 -0
- package/dist/types/inputs/SelectInput.d.ts +38 -0
- package/dist/types/inputs/TextInput.d.ts +62 -0
- package/dist/types/inputs/WizardLayout.d.ts +34 -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 +88 -0
- package/dist/types/kanban/kanbanCards.d.ts +22 -0
- package/dist/types/kanban/kanbanMoves.d.ts +38 -0
- package/dist/types/kanban.d.ts +3 -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 +788 -0
- package/dist/types/locales/es.d.ts +788 -0
- package/dist/types/maps/MapView.d.ts +41 -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 +18 -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 +7 -0
- package/dist/types/pwa/InstallInstructionsDialog.d.ts +20 -0
- package/dist/types/pwa/InstallPromptBanner.d.ts +16 -0
- package/dist/types/pwa/installInstructions.d.ts +52 -0
- package/dist/types/pwa/useInstallPrompt.d.ts +13 -0
- package/dist/types/react-hook-form.d.ts +12 -0
- package/dist/types/react-router.d.ts +2 -0
- package/dist/types/security/ActivityLog.d.ts +33 -0
- package/dist/types/security/RecoveryCodesDialog.d.ts +16 -0
- package/dist/types/security/SessionsCard.d.ts +24 -0
- package/dist/types/security/passkeys.d.ts +18 -0
- package/dist/types/table.d.ts +3 -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/MuiDialog.d.ts +9 -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/ComponentTexts.d.ts +11 -0
- package/dist/types/toolkit/ToolkitProvider.d.ts +47 -0
- package/dist/types/toolkit/browserNavigation.d.ts +27 -0
- package/dist/types/toolkit/componentTextsContext.d.ts +20 -0
- package/dist/types/toolkit/hashNavigation.d.ts +12 -0
- package/dist/types/toolkit/navigationPaths.d.ts +43 -0
- package/dist/types/toolkit/toolkitContext.d.ts +28 -0
- package/dist/types/toolkit/toolkitSettings.d.ts +113 -0
- package/dist/types/toolkit/useFormatters.d.ts +6 -0
- package/dist/types/toolkit/useToolkitTranslation.d.ts +11 -0
- package/dist/types/ui/actions/ActionsMenu.d.ts +20 -0
- package/dist/types/ui/actions/CopyButton.d.ts +15 -0
- package/dist/types/ui/actions/DownloadMenu.d.ts +55 -0
- package/dist/types/ui/actions/SecretField.d.ts +17 -0
- package/dist/types/ui/actions/SelectionActions.d.ts +39 -0
- package/dist/types/ui/filters/DateRangeFilter.d.ts +18 -0
- package/dist/types/ui/filters/PeriodRangeSelector.d.ts +28 -0
- package/dist/types/ui/filters/QuickFilters.d.ts +23 -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/labels/tagOf.d.ts +13 -0
- package/dist/types/ui/layout/CollapsibleSection.d.ts +18 -0
- package/dist/types/ui/layout/ContentDialog.d.ts +15 -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 +35 -0
- package/dist/types/ui/layout/FullPageLoader.d.ts +7 -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 +20 -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 +25 -0
- package/dist/types/ui/metrics/CalendarHeatmap.d.ts +34 -0
- package/dist/types/ui/metrics/ChartTooltip.d.ts +11 -0
- package/dist/types/ui/metrics/ColumnChart.d.ts +47 -0
- package/dist/types/ui/metrics/LineChart.d.ts +41 -0
- package/dist/types/ui/metrics/MetricCard.d.ts +39 -0
- package/dist/types/ui/metrics/TableToggle.d.ts +14 -0
- package/dist/types/ui/metrics/barListLabels.d.ts +17 -0
- package/dist/types/ui/metrics/chartParts.d.ts +112 -0
- package/dist/types/ui/metrics/heatmapScale.d.ts +45 -0
- package/dist/types/ui/navigation/BackButton.d.ts +13 -0
- package/dist/types/ui/navigation/ColorSchemeToggle.d.ts +13 -0
- package/dist/types/ui/navigation/DocumentTitle.d.ts +6 -0
- package/dist/types/ui/navigation/FontSizeToggle.d.ts +11 -0
- package/dist/types/ui/navigation/LanguageToggle.d.ts +13 -0
- package/dist/types/ui/navigation/PageBreadcrumbs.d.ts +12 -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 +41 -0
- package/dist/types/ui/timeline/timelineDot.d.ts +19 -0
- package/dist/types/upload/FileDropzone.d.ts +36 -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/ActionsMenu.js +51 -0
- package/dist/ui/actions/ActionsMenu.js.map +1 -0
- package/dist/ui/actions/CopyButton.js +28 -0
- package/dist/ui/actions/CopyButton.js.map +1 -0
- package/dist/ui/actions/DownloadMenu.js +162 -0
- package/dist/ui/actions/DownloadMenu.js.map +1 -0
- package/dist/ui/actions/SecretField.js +61 -0
- package/dist/ui/actions/SecretField.js.map +1 -0
- package/dist/ui/actions/SelectionActions.js +142 -0
- package/dist/ui/actions/SelectionActions.js.map +1 -0
- package/dist/ui/filters/DateRangeFilter.js +87 -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/labels/tagOf.js +7 -0
- package/dist/ui/labels/tagOf.js.map +1 -0
- package/dist/ui/layout/CollapsibleSection.js +52 -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 +54 -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 +94 -0
- package/dist/ui/metrics/BarList.js.map +1 -0
- package/dist/ui/metrics/CalendarHeatmap.js +136 -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 +106 -0
- package/dist/ui/metrics/ColumnChart.js.map +1 -0
- package/dist/ui/metrics/LineChart.js +117 -0
- package/dist/ui/metrics/LineChart.js.map +1 -0
- package/dist/ui/metrics/MetricCard.js +97 -0
- package/dist/ui/metrics/MetricCard.js.map +1 -0
- package/dist/ui/metrics/TableToggle.js +15 -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/chartParts.js +93 -0
- package/dist/ui/metrics/chartParts.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 +40 -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 +41 -0
- package/dist/ui/navigation/FontSizeToggle.js.map +1 -0
- package/dist/ui/navigation/LanguageToggle.js +48 -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 +106 -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 +145 -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 +311 -5
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
const VALUE_FORMAT = Object.freeze({ count: "count", money: "money", percent: "percent" });
|
|
2
|
+
const SHEET_ROW_KIND = Object.freeze({ section: "section", figures: "figures" });
|
|
3
|
+
const NOT_APPLICABLE_TEXT = "—";
|
|
4
|
+
const PERCENT_PER_UNIT = 100;
|
|
5
|
+
const EXCEL_SIGNIFICANT_DIGITS = 15;
|
|
6
|
+
const UTF8_BYTE_ORDER_MARK = "\uFEFF";
|
|
7
|
+
const CSV_SEPARATOR = ",";
|
|
8
|
+
const CSV_LINE_END = "\r\n";
|
|
9
|
+
const EXCEL_SHEET_NAME_MAX_LENGTH = 31;
|
|
10
|
+
const EXCEL_SHEET_NAME_FORBIDDEN_CHARACTERS = /[\\/?*[\]:]/g;
|
|
11
|
+
const CSS_HEX_COLOR = /^#?([0-9a-f]{6})$/i;
|
|
12
|
+
const EXCEL_OPAQUE_ALPHA = "FF";
|
|
13
|
+
const DEFAULT_REPORT_STYLE = Object.freeze({
|
|
14
|
+
brandColor: "FF1976D2",
|
|
15
|
+
headerFontColor: "FFFFFFFF",
|
|
16
|
+
sectionFill: "FFF5F5F5",
|
|
17
|
+
totalsFill: "FFE3F2FD",
|
|
18
|
+
borderColor: "FFE0E0E0",
|
|
19
|
+
// en Datos cada sección empieza con una raya más marcada a su izquierda
|
|
20
|
+
sectionBorderColor: "FF9E9E9E",
|
|
21
|
+
secondaryFontColor: "FF757575",
|
|
22
|
+
titleFontSize: 14,
|
|
23
|
+
secondaryFontSize: 9,
|
|
24
|
+
// el encabezado alcanza para dos líneas: una columna de cifras se ensancha si su título no cabe en ellas (las letras en
|
|
25
|
+
// negritas ocupan más que la unidad de ancho de Excel, por eso el margen)
|
|
26
|
+
headerRowHeight: 30,
|
|
27
|
+
headerLineCount: 2,
|
|
28
|
+
headerWidthMargin: 4,
|
|
29
|
+
conceptColumnWidth: 36,
|
|
30
|
+
howColumnWidth: 22,
|
|
31
|
+
figureColumnWidth: 20,
|
|
32
|
+
// los conceptos van con sangría bajo el título de su sección
|
|
33
|
+
conceptIndent: 1,
|
|
34
|
+
// el concepto largo se dobla en su celda y su renglón crece: cuántas letras caben por línea en la columna (su ancho
|
|
35
|
+
// menos la sangría) y cuánto mide una línea. El alto va escrito porque no todos los programas lo calculan al abrir
|
|
36
|
+
conceptCharactersPerLine: 33,
|
|
37
|
+
lineHeightPoints: 15,
|
|
38
|
+
// el formato de Excel de cada VALUE_FORMAT; el del dinero lleva el signo de la moneda del proyecto
|
|
39
|
+
numberFormats: Object.freeze({
|
|
40
|
+
[VALUE_FORMAT.count]: "#,##0",
|
|
41
|
+
[VALUE_FORMAT.money]: '"$"#,##0.00',
|
|
42
|
+
[VALUE_FORMAT.percent]: "0%"
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
const EXCEL_DATA_SECTION_ROW = 1;
|
|
46
|
+
const EXCEL_DATA_CONCEPT_ROW = 2;
|
|
47
|
+
const EXCEL_DATA_HOW_ROW = 3;
|
|
48
|
+
const EXCEL_DATA_PERIOD_COLUMN_WIDTH = 24;
|
|
49
|
+
const EXCEL_DATA_CONCEPT_COLUMN_WIDTH = 20;
|
|
50
|
+
const EXCEL_DATA_CONCEPT_ROW_HEIGHT = 45;
|
|
51
|
+
const EXCEL_TITLE_ROW = 1;
|
|
52
|
+
const EXCEL_SUBTITLE_ROW = 2;
|
|
53
|
+
const EXCEL_HEADER_ROW = 4;
|
|
54
|
+
function excelColorOf(cssColor) {
|
|
55
|
+
const match = CSS_HEX_COLOR.exec(cssColor.trim());
|
|
56
|
+
if (!match) {
|
|
57
|
+
throw new Error(`excelColorOf espera un color #rrggbb y recibió «${cssColor}»`);
|
|
58
|
+
}
|
|
59
|
+
return `${EXCEL_OPAQUE_ALPHA}${match[1].toUpperCase()}`;
|
|
60
|
+
}
|
|
61
|
+
function fileNameSlugOf(name) {
|
|
62
|
+
return name.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
63
|
+
}
|
|
64
|
+
function reportSheetOf({ conceptLabel, howColumnLabel, periodLabels, totalsLabel, sections, dataLabels }) {
|
|
65
|
+
const hasHowColumn = Boolean(howColumnLabel);
|
|
66
|
+
const hasTotals = Boolean(totalsLabel);
|
|
67
|
+
const periods = [...periodLabels, ...hasTotals ? [totalsLabel] : []];
|
|
68
|
+
const header = [conceptLabel, ...hasHowColumn ? [howColumnLabel] : [], ...periods];
|
|
69
|
+
const dataHeaderLabels = { section: dataLabels.section, concept: conceptLabel, period: dataLabels.period };
|
|
70
|
+
const rows = [];
|
|
71
|
+
for (const section of sections) {
|
|
72
|
+
rows.push({ kind: SHEET_ROW_KIND.section, label: section.label });
|
|
73
|
+
for (const row of section.rows) {
|
|
74
|
+
rows.push({
|
|
75
|
+
kind: SHEET_ROW_KIND.figures,
|
|
76
|
+
sectionLabel: section.label,
|
|
77
|
+
label: row.label,
|
|
78
|
+
howLabel: row.howLabel ?? "",
|
|
79
|
+
format: row.format,
|
|
80
|
+
isTotal: Boolean(row.isTotal),
|
|
81
|
+
values: row.values
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return { header, dataHeaderLabels, periods, rows, hasHowColumn, hasTotals };
|
|
86
|
+
}
|
|
87
|
+
function reportDataTableOf(sheet) {
|
|
88
|
+
const concepts = sheet.rows.filter((row) => row.kind === SHEET_ROW_KIND.figures);
|
|
89
|
+
const periodRows = sheet.periods.map((period, position) => ({
|
|
90
|
+
period,
|
|
91
|
+
// el último periodo son los Totales, si el reporte los lleva
|
|
92
|
+
isTotals: sheet.hasTotals && position === sheet.periods.length - 1,
|
|
93
|
+
values: concepts.map((concept) => concept.values[position])
|
|
94
|
+
}));
|
|
95
|
+
return { concepts, periodRows };
|
|
96
|
+
}
|
|
97
|
+
function csvValueOf(value, format) {
|
|
98
|
+
if (value === null || value === void 0) {
|
|
99
|
+
return NOT_APPLICABLE_TEXT;
|
|
100
|
+
}
|
|
101
|
+
return format === VALUE_FORMAT.percent ? `${value}%` : String(value);
|
|
102
|
+
}
|
|
103
|
+
function csvFieldOf(field) {
|
|
104
|
+
return /[",\r\n]/.test(field) ? `"${field.replaceAll('"', '""')}"` : field;
|
|
105
|
+
}
|
|
106
|
+
function dataHeaderLinesOf(sheet, concepts) {
|
|
107
|
+
const sectionLine = [sheet.dataHeaderLabels.section, ...concepts.map((concept) => concept.sectionLabel)];
|
|
108
|
+
const conceptNames = concepts.map((concept) => concept.label);
|
|
109
|
+
if (!sheet.hasHowColumn) {
|
|
110
|
+
return [sectionLine, [sheet.dataHeaderLabels.period, ...conceptNames]];
|
|
111
|
+
}
|
|
112
|
+
return [
|
|
113
|
+
sectionLine,
|
|
114
|
+
[sheet.dataHeaderLabels.concept, ...conceptNames],
|
|
115
|
+
[sheet.dataHeaderLabels.period, ...concepts.map((concept) => concept.howLabel)]
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
function reportCsvOf(sheet) {
|
|
119
|
+
const { concepts, periodRows } = reportDataTableOf(sheet);
|
|
120
|
+
const lines = dataHeaderLinesOf(sheet, concepts);
|
|
121
|
+
for (const periodRow of periodRows) {
|
|
122
|
+
lines.push([periodRow.period, ...periodRow.values.map((value, position) => csvValueOf(value, concepts[position].format))]);
|
|
123
|
+
}
|
|
124
|
+
return UTF8_BYTE_ORDER_MARK + lines.map((fields) => fields.map(csvFieldOf).join(CSV_SEPARATOR)).join(CSV_LINE_END) + CSV_LINE_END;
|
|
125
|
+
}
|
|
126
|
+
function excelValueOf(value, format) {
|
|
127
|
+
if (value === null || value === void 0) {
|
|
128
|
+
return NOT_APPLICABLE_TEXT;
|
|
129
|
+
}
|
|
130
|
+
if (format === VALUE_FORMAT.percent) {
|
|
131
|
+
return Number((Number(value) / PERCENT_PER_UNIT).toPrecision(EXCEL_SIGNIFICANT_DIGITS));
|
|
132
|
+
}
|
|
133
|
+
return Number(value);
|
|
134
|
+
}
|
|
135
|
+
function excelSheetNameOf(name) {
|
|
136
|
+
return name.replace(EXCEL_SHEET_NAME_FORBIDDEN_CHARACTERS, " ").slice(0, EXCEL_SHEET_NAME_MAX_LENGTH);
|
|
137
|
+
}
|
|
138
|
+
function wrapConceptOf(row, label, alignment, style) {
|
|
139
|
+
const lineCount = Math.ceil(label.length / style.conceptCharactersPerLine);
|
|
140
|
+
row.getCell(1).alignment = { ...alignment, wrapText: true, vertical: "middle" };
|
|
141
|
+
if (lineCount > 1) {
|
|
142
|
+
row.height = lineCount * style.lineHeightPoints;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function figureColumnWidthOf(headerTitle, style) {
|
|
146
|
+
return Math.max(style.figureColumnWidth, Math.ceil(headerTitle.length / style.headerLineCount) + style.headerWidthMargin);
|
|
147
|
+
}
|
|
148
|
+
function reportWorkbookOf(ExcelJS, sheet, { summarySheetName, dataSheetName, title, subtitle = "", style: customStyle = {} }) {
|
|
149
|
+
const style = {
|
|
150
|
+
...DEFAULT_REPORT_STYLE,
|
|
151
|
+
...customStyle,
|
|
152
|
+
numberFormats: { ...DEFAULT_REPORT_STYLE.numberFormats, ...customStyle.numberFormats }
|
|
153
|
+
};
|
|
154
|
+
const workbook = new ExcelJS.Workbook();
|
|
155
|
+
const leadingColumnWidths = sheet.hasHowColumn ? [style.conceptColumnWidth, style.howColumnWidth] : [style.conceptColumnWidth];
|
|
156
|
+
const worksheet = workbook.addWorksheet(excelSheetNameOf(summarySheetName), {
|
|
157
|
+
views: [{ state: "frozen", xSplit: leadingColumnWidths.length, ySplit: EXCEL_HEADER_ROW }],
|
|
158
|
+
pageSetup: { orientation: "landscape", fitToPage: true, fitToWidth: 1, fitToHeight: 0, printTitlesRow: `${EXCEL_HEADER_ROW}:${EXCEL_HEADER_ROW}` }
|
|
159
|
+
});
|
|
160
|
+
const columnCount = sheet.header.length;
|
|
161
|
+
const totalsColumnNumber = columnCount;
|
|
162
|
+
const firstFigureColumnNumber = leadingColumnWidths.length + 1;
|
|
163
|
+
const fillOf = (color) => ({ type: "pattern", pattern: "solid", fgColor: { argb: color } });
|
|
164
|
+
const thinBorder = { style: "thin", color: { argb: style.borderColor } };
|
|
165
|
+
const cellBorder = { top: thinBorder, left: thinBorder, bottom: thinBorder, right: thinBorder };
|
|
166
|
+
worksheet.columns = sheet.header.map((headerTitle, position) => ({
|
|
167
|
+
width: leadingColumnWidths[position] ?? figureColumnWidthOf(headerTitle, style)
|
|
168
|
+
}));
|
|
169
|
+
worksheet.getCell(EXCEL_TITLE_ROW, 1).value = title;
|
|
170
|
+
worksheet.getCell(EXCEL_TITLE_ROW, 1).font = { bold: true, size: style.titleFontSize, color: { argb: style.brandColor } };
|
|
171
|
+
worksheet.getCell(EXCEL_SUBTITLE_ROW, 1).value = subtitle;
|
|
172
|
+
worksheet.getCell(EXCEL_SUBTITLE_ROW, 1).font = { color: { argb: style.secondaryFontColor } };
|
|
173
|
+
const headerRow = worksheet.getRow(EXCEL_HEADER_ROW);
|
|
174
|
+
headerRow.values = sheet.header;
|
|
175
|
+
headerRow.height = style.headerRowHeight;
|
|
176
|
+
headerRow.eachCell((cell, columnNumber) => {
|
|
177
|
+
cell.font = { bold: true, color: { argb: style.headerFontColor } };
|
|
178
|
+
cell.fill = fillOf(style.brandColor);
|
|
179
|
+
cell.border = cellBorder;
|
|
180
|
+
cell.alignment = { vertical: "middle", wrapText: true, horizontal: columnNumber >= firstFigureColumnNumber ? "right" : "left" };
|
|
181
|
+
});
|
|
182
|
+
for (const row of sheet.rows) {
|
|
183
|
+
if (row.kind === SHEET_ROW_KIND.section) {
|
|
184
|
+
const sectionRow = worksheet.addRow([row.label]);
|
|
185
|
+
for (let columnNumber = 1; columnNumber <= columnCount; columnNumber += 1) {
|
|
186
|
+
const cell = sectionRow.getCell(columnNumber);
|
|
187
|
+
cell.font = { bold: true };
|
|
188
|
+
cell.fill = fillOf(style.sectionFill);
|
|
189
|
+
cell.border = cellBorder;
|
|
190
|
+
}
|
|
191
|
+
wrapConceptOf(sectionRow, row.label, {}, style);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
const figuresRow = worksheet.addRow([
|
|
195
|
+
row.label,
|
|
196
|
+
...sheet.hasHowColumn ? [row.howLabel] : [],
|
|
197
|
+
...row.values.map((value) => excelValueOf(value, row.format))
|
|
198
|
+
]);
|
|
199
|
+
for (let columnNumber = 1; columnNumber <= columnCount; columnNumber += 1) {
|
|
200
|
+
figuresRow.getCell(columnNumber).border = cellBorder;
|
|
201
|
+
}
|
|
202
|
+
figuresRow.getCell(1).font = { bold: row.isTotal };
|
|
203
|
+
wrapConceptOf(figuresRow, row.label, { indent: style.conceptIndent }, style);
|
|
204
|
+
if (sheet.hasHowColumn) {
|
|
205
|
+
figuresRow.getCell(2).font = { italic: true, size: style.secondaryFontSize, color: { argb: style.secondaryFontColor } };
|
|
206
|
+
}
|
|
207
|
+
row.values.forEach((value, position) => {
|
|
208
|
+
const cell = figuresRow.getCell(firstFigureColumnNumber + position);
|
|
209
|
+
cell.numFmt = style.numberFormats[row.format];
|
|
210
|
+
cell.alignment = { horizontal: "right" };
|
|
211
|
+
cell.font = { bold: row.isTotal };
|
|
212
|
+
});
|
|
213
|
+
if (sheet.hasTotals) {
|
|
214
|
+
const totalsCell = figuresRow.getCell(totalsColumnNumber);
|
|
215
|
+
totalsCell.font = { bold: true };
|
|
216
|
+
totalsCell.fill = fillOf(style.totalsFill);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
addDataWorksheet(workbook, sheet, dataSheetName, { style, fillOf, cellBorder });
|
|
220
|
+
return workbook;
|
|
221
|
+
}
|
|
222
|
+
function addDataWorksheet(workbook, sheet, dataSheetName, { style, fillOf, cellBorder }) {
|
|
223
|
+
const { concepts, periodRows } = reportDataTableOf(sheet);
|
|
224
|
+
const headerLines = dataHeaderLinesOf(sheet, concepts);
|
|
225
|
+
const lastHeaderRow = headerLines.length;
|
|
226
|
+
const worksheet = workbook.addWorksheet(excelSheetNameOf(dataSheetName), { views: [{ state: "frozen", xSplit: 1, ySplit: lastHeaderRow }] });
|
|
227
|
+
const columnCount = concepts.length + 1;
|
|
228
|
+
const sectionBorder = { style: "medium", color: { argb: style.sectionBorderColor } };
|
|
229
|
+
const startsSectionAt = concepts.map((concept, position) => position === 0 || concept.sectionLabel !== concepts[position - 1].sectionLabel);
|
|
230
|
+
const periodColumnWidth = Math.max(
|
|
231
|
+
EXCEL_DATA_PERIOD_COLUMN_WIDTH,
|
|
232
|
+
...periodRows.map((periodRow) => periodRow.period.length + style.headerWidthMargin)
|
|
233
|
+
);
|
|
234
|
+
worksheet.columns = [{ width: periodColumnWidth }, ...concepts.map(() => ({ width: EXCEL_DATA_CONCEPT_COLUMN_WIDTH }))];
|
|
235
|
+
headerLines.forEach((headerLine, position) => {
|
|
236
|
+
worksheet.getRow(EXCEL_DATA_SECTION_ROW + position).values = headerLine;
|
|
237
|
+
});
|
|
238
|
+
worksheet.getRow(EXCEL_DATA_CONCEPT_ROW).height = EXCEL_DATA_CONCEPT_ROW_HEIGHT;
|
|
239
|
+
for (let columnNumber = 1; columnNumber <= columnCount; columnNumber += 1) {
|
|
240
|
+
const sectionCell = worksheet.getCell(EXCEL_DATA_SECTION_ROW, columnNumber);
|
|
241
|
+
sectionCell.font = { bold: true, color: { argb: style.headerFontColor } };
|
|
242
|
+
sectionCell.fill = fillOf(style.brandColor);
|
|
243
|
+
sectionCell.alignment = { vertical: "middle", horizontal: columnNumber === 1 ? "left" : "center" };
|
|
244
|
+
const conceptCell = worksheet.getCell(EXCEL_DATA_CONCEPT_ROW, columnNumber);
|
|
245
|
+
conceptCell.font = { bold: true };
|
|
246
|
+
conceptCell.fill = fillOf(style.sectionFill);
|
|
247
|
+
conceptCell.alignment = { vertical: "middle", wrapText: true, horizontal: columnNumber === 1 ? "left" : "right" };
|
|
248
|
+
if (!sheet.hasHowColumn) {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const howCell = worksheet.getCell(EXCEL_DATA_HOW_ROW, columnNumber);
|
|
252
|
+
howCell.font = columnNumber === 1 ? { bold: true } : { italic: true, size: style.secondaryFontSize, color: { argb: style.secondaryFontColor } };
|
|
253
|
+
howCell.alignment = { horizontal: columnNumber === 1 ? "left" : "right" };
|
|
254
|
+
}
|
|
255
|
+
for (const periodRow of periodRows) {
|
|
256
|
+
const dataRow = worksheet.addRow([periodRow.period, ...periodRow.values.map((value, position) => excelValueOf(value, concepts[position].format))]);
|
|
257
|
+
dataRow.font = { bold: periodRow.isTotals };
|
|
258
|
+
concepts.forEach((concept, position) => {
|
|
259
|
+
const cell = dataRow.getCell(position + 2);
|
|
260
|
+
cell.numFmt = style.numberFormats[concept.format];
|
|
261
|
+
cell.alignment = { horizontal: "right" };
|
|
262
|
+
});
|
|
263
|
+
if (periodRow.isTotals) {
|
|
264
|
+
dataRow.eachCell((cell) => {
|
|
265
|
+
cell.fill = fillOf(style.totalsFill);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
for (let rowNumber = EXCEL_DATA_SECTION_ROW; rowNumber <= worksheet.rowCount; rowNumber += 1) {
|
|
270
|
+
for (let columnNumber = 1; columnNumber <= columnCount; columnNumber += 1) {
|
|
271
|
+
const startsSection = columnNumber > 1 && startsSectionAt[columnNumber - 2];
|
|
272
|
+
worksheet.getCell(rowNumber, columnNumber).border = startsSection ? { ...cellBorder, left: sectionBorder } : cellBorder;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
let sectionStartColumn = 2;
|
|
276
|
+
for (let position = 1; position <= concepts.length; position += 1) {
|
|
277
|
+
const sectionEnds = position === concepts.length || startsSectionAt[position];
|
|
278
|
+
if (sectionEnds) {
|
|
279
|
+
const sectionEndColumn = position + 1;
|
|
280
|
+
if (sectionEndColumn > sectionStartColumn) {
|
|
281
|
+
worksheet.mergeCells(EXCEL_DATA_SECTION_ROW, sectionStartColumn, EXCEL_DATA_SECTION_ROW, sectionEndColumn);
|
|
282
|
+
}
|
|
283
|
+
sectionStartColumn = sectionEndColumn + 1;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
worksheet.autoFilter = { from: { row: lastHeaderRow, column: 1 }, to: { row: worksheet.rowCount, column: columnCount } };
|
|
287
|
+
}
|
|
288
|
+
export {
|
|
289
|
+
DEFAULT_REPORT_STYLE,
|
|
290
|
+
SHEET_ROW_KIND,
|
|
291
|
+
VALUE_FORMAT,
|
|
292
|
+
excelColorOf,
|
|
293
|
+
fileNameSlugOf,
|
|
294
|
+
reportCsvOf,
|
|
295
|
+
reportDataTableOf,
|
|
296
|
+
reportSheetOf,
|
|
297
|
+
reportWorkbookOf
|
|
298
|
+
};
|
|
299
|
+
//# sourceMappingURL=reportWorkbook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reportWorkbook.js","sources":["../../src/excel/reportWorkbook.js"],"sourcesContent":["// Un reporte de cifras por periodo como archivo: libro de Excel o CSV, armado en el navegador con lo que ya se ve en\n// pantalla (no se vuelve a contar nada).\n//\n// Primero se arma la «hoja» (reportSheetOf: encabezado y renglones ya con sus textos) y de ahí salen las dos hojas del\n// libro, así siempre dicen lo mismo. Van en dos formas, con los mismos números:\n// A lo ancho (Resumen) como una pantalla: un renglón por concepto y una columna por periodo, con los Totales al final\n// si el reporte los lleva. Para leer e imprimir.\n// Hacia abajo (Datos) la misma tabla volteada: un renglón por periodo y una columna por concepto. Lo que es fijo de\n// cada concepto (su sección, su nombre y cómo sale su total) va UNA vez arriba y no se repite en\n// cada renglón. Los filtros de Excel van en el último renglón del encabezado. El CSV va así.\n//\n// El Excel se arma con ExcelJS (MIT), el mismo que usa por dentro el DataGrid Premium de MUI. Pesa casi 1 MB: el paquete\n// no lo importa; quien llama lo carga solo al pedir el archivo (import dinámico) y se lo pasa a reportWorkbookOf.\n//\n// Los colores por omisión son los del tema por omisión de MUI (azul primary); cada proyecto pasa los de su tema en\n// `style` (excelColorOf convierte un color CSS #rrggbb al ARGB que pide Excel).\n//\n// Funciones puras, sin React: function (regla de la casa).\n\n/** Cómo se escribe cada cifra: conteo con miles, dinero con dos decimales o porcentaje. */\nexport const VALUE_FORMAT = Object.freeze({count: 'count', money: 'money', percent: 'percent'});\n\n/** Los dos tipos de renglón de la hoja: el título de una sección y un concepto con sus cifras. */\nexport const SHEET_ROW_KIND = Object.freeze({section: 'section', figures: 'figures'});\n\n// lo que se escribe cuando una celda no aplica: nunca un 0, que diría «no hubo»\nconst NOT_APPLICABLE_TEXT = '—';\n\n// el porcentaje llega como porcentaje (13 = 13 %); Excel lo guarda como fracción (0.13)\nconst PERCENT_PER_UNIT = 100;\n// Excel guarda 15 cifras significativas: se redondea a ellas para que no se cuele el ruido de los decimales de\n// JavaScript (5.2 / 100 = 0.052000000000000005)\nconst EXCEL_SIGNIFICANT_DIGITS = 15;\n\n// la marca que avisa a Excel que el CSV va en UTF-8: sin ella rompe los acentos y la ñ\nconst UTF8_BYTE_ORDER_MARK = '';\nconst CSV_SEPARATOR = ',';\nconst CSV_LINE_END = '\\r\\n';\n\n// Excel no acepta hojas con más de 31 letras en el nombre ni con estos signos\nconst EXCEL_SHEET_NAME_MAX_LENGTH = 31;\nconst EXCEL_SHEET_NAME_FORBIDDEN_CHARACTERS = /[\\\\/?*[\\]:]/g;\n\n// un color CSS de seis cifras (#1976d2) y la opacidad completa que Excel pone adelante (FF)\nconst CSS_HEX_COLOR = /^#?([0-9a-f]{6})$/i;\nconst EXCEL_OPAQUE_ALPHA = 'FF';\n\n/**\n * Cómo se ve el Excel, como un reporte: título arriba, encabezado del color principal con letra blanca, secciones con su\n * fondo, bordes delgados en toda la tabla y los Totales con su fondo. Los colores van en ARGB, como los pide Excel; por\n * omisión, los del tema por omisión de MUI (primary #1976d2, blue[50], grey).\n */\nexport const DEFAULT_REPORT_STYLE = Object.freeze({\n brandColor: 'FF1976D2',\n headerFontColor: 'FFFFFFFF',\n sectionFill: 'FFF5F5F5',\n totalsFill: 'FFE3F2FD',\n borderColor: 'FFE0E0E0',\n // en Datos cada sección empieza con una raya más marcada a su izquierda\n sectionBorderColor: 'FF9E9E9E',\n secondaryFontColor: 'FF757575',\n titleFontSize: 14,\n secondaryFontSize: 9,\n // el encabezado alcanza para dos líneas: una columna de cifras se ensancha si su título no cabe en ellas (las letras en\n // negritas ocupan más que la unidad de ancho de Excel, por eso el margen)\n headerRowHeight: 30,\n headerLineCount: 2,\n headerWidthMargin: 4,\n conceptColumnWidth: 36,\n howColumnWidth: 22,\n figureColumnWidth: 20,\n // los conceptos van con sangría bajo el título de su sección\n conceptIndent: 1,\n // el concepto largo se dobla en su celda y su renglón crece: cuántas letras caben por línea en la columna (su ancho\n // menos la sangría) y cuánto mide una línea. El alto va escrito porque no todos los programas lo calculan al abrir\n conceptCharactersPerLine: 33,\n lineHeightPoints: 15,\n // el formato de Excel de cada VALUE_FORMAT; el del dinero lleva el signo de la moneda del proyecto\n numberFormats: Object.freeze({\n [VALUE_FORMAT.count]: '#,##0',\n [VALUE_FORMAT.money]: '\"$\"#,##0.00',\n [VALUE_FORMAT.percent]: '0%',\n }),\n});\n\n// la hoja de Datos (hacia abajo): sin título; los renglones de encabezado (sección, concepto y, si el reporte la lleva,\n// cómo sale) y luego un renglón por periodo. La primera columna dice el periodo; las demás, un concepto cada una\nconst EXCEL_DATA_SECTION_ROW = 1;\nconst EXCEL_DATA_CONCEPT_ROW = 2;\nconst EXCEL_DATA_HOW_ROW = 3;\nconst EXCEL_DATA_PERIOD_COLUMN_WIDTH = 24;\nconst EXCEL_DATA_CONCEPT_COLUMN_WIDTH = 20;\n// el nombre del concepto se dobla en su celda: el renglón alcanza para tres líneas\nconst EXCEL_DATA_CONCEPT_ROW_HEIGHT = 45;\n\n// dónde va cada cosa en Resumen: el título y el subtítulo arriba, un renglón en blanco y luego la tabla\nconst EXCEL_TITLE_ROW = 1;\nconst EXCEL_SUBTITLE_ROW = 2;\nconst EXCEL_HEADER_ROW = 4;\n\n/**\n * Un color CSS de seis cifras (#017f31) como lo pide Excel (FF017F31). Sirve para pasar el color del tema de MUI a `style`.\n *\n * @param {string} cssColor #rrggbb\n * @returns {string} ARGB\n */\nexport function excelColorOf(cssColor) {\n const match = CSS_HEX_COLOR.exec(cssColor.trim());\n if (!match) {\n throw new Error(`excelColorOf espera un color #rrggbb y recibió «${cssColor}»`);\n }\n\n return `${EXCEL_OPAQUE_ALPHA}${match[1].toUpperCase()}`;\n}\n\n/**\n * Un nombre como pedazo del nombre de un archivo: sin acentos, en minúsculas y con guiones («Plan Básico» →\n * plan-basico).\n *\n * @param {string} name\n * @returns {string}\n */\nexport function fileNameSlugOf(name) {\n return name.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');\n}\n\n/**\n * La hoja del reporte: el encabezado y los renglones con sus textos, en el orden de la pantalla.\n *\n * @param {object} report\n * @param {string} report.conceptLabel título de la primera columna («Concepto»)\n * @param {string} [report.howColumnLabel] título de la columna que explica cómo sale cada total («Cómo salen los\n * totales»); sin él no va esa columna\n * @param {string[]} report.periodLabels un título por periodo, en orden\n * @param {string} [report.totalsLabel] título de la columna de los Totales; sin él no va (y los renglones no traen su\n * total)\n * @param {Object[]} report.sections las secciones en orden, cada una con sus renglones\n * @param {string} report.sections[].label\n * @param {Array<{label: string, howLabel?: string, format: string, isTotal?: boolean, values: Array<number|string|null>}>} report.sections[].rows\n * values: una cifra por periodo y, si hay totalsLabel, al final la del total\n * @param {{section: string, period: string}} report.dataLabels lo que dice la primera columna de los Datos\n * @returns {{header: string[], dataHeaderLabels: {section: string, concept: string, period: string}, periods: string[], rows: Array<object>, hasHowColumn: boolean, hasTotals: boolean}}\n */\nexport function reportSheetOf({conceptLabel, howColumnLabel, periodLabels, totalsLabel, sections, dataLabels}) {\n const hasHowColumn = Boolean(howColumnLabel);\n const hasTotals = Boolean(totalsLabel);\n // los periodos de cada concepto: cada periodo y al final los Totales\n const periods = [...periodLabels, ...(hasTotals ? [totalsLabel] : [])];\n const header = [conceptLabel, ...(hasHowColumn ? [howColumnLabel] : []), ...periods];\n const dataHeaderLabels = {section: dataLabels.section, concept: conceptLabel, period: dataLabels.period};\n const rows = [];\n\n for (const section of sections) {\n rows.push({kind: SHEET_ROW_KIND.section, label: section.label});\n\n for (const row of section.rows) {\n rows.push({\n kind: SHEET_ROW_KIND.figures,\n sectionLabel: section.label,\n label: row.label,\n howLabel: row.howLabel ?? '',\n format: row.format,\n isTotal: Boolean(row.isTotal),\n values: row.values,\n });\n }\n }\n\n return {header, dataHeaderLabels, periods, rows, hasHowColumn, hasTotals};\n}\n\n/**\n * La tabla volteada de los Datos: un renglón por periodo y una columna por concepto.\n *\n * @param {{periods: string[], rows: Array<object>, hasTotals: boolean}} sheet de reportSheetOf\n * @returns {{concepts: Array<object>, periodRows: Array<{period: string, isTotals: boolean, values: Array<number|string|null>}>}}\n * concepts: los renglones de cifras de la hoja, uno por columna (con su sección, nombre, cómo sale y formato)\n */\nexport function reportDataTableOf(sheet) {\n const concepts = sheet.rows.filter((row) => row.kind === SHEET_ROW_KIND.figures);\n const periodRows = sheet.periods.map((period, position) => ({\n period,\n // el último periodo son los Totales, si el reporte los lleva\n isTotals: sheet.hasTotals && position === sheet.periods.length - 1,\n values: concepts.map((concept) => concept.values[position]),\n }));\n\n return {concepts, periodRows};\n}\n\n/**\n * Una cifra como texto del CSV: sin separador de miles, para que Excel la lea como número.\n *\n * @param {number|string|null} value\n * @param {string} format VALUE_FORMAT\n * @returns {string}\n */\nfunction csvValueOf(value, format) {\n if (value === null || value === undefined) {\n return NOT_APPLICABLE_TEXT;\n }\n\n return format === VALUE_FORMAT.percent ? `${value}%` : String(value);\n}\n\n/**\n * Un campo del CSV entre comillas cuando lo necesita (una coma, unas comillas o un salto de renglón adentro).\n *\n * @param {string} field\n * @returns {string}\n */\nfunction csvFieldOf(field) {\n return /[\",\\r\\n]/.test(field) ? `\"${field.replaceAll('\"', '\"\"')}\"` : field;\n}\n\n/**\n * Los renglones de encabezado de los Datos y del CSV: la sección y el concepto de cada columna y, si el reporte la\n * lleva, cómo sale. El primer campo dice qué es cada renglón; el del último encabeza la columna de los periodos (ahí van\n * los filtros de Excel), por eso dice «Periodo».\n *\n * @param {object} sheet de reportSheetOf\n * @param {Array<object>} concepts los conceptos de reportDataTableOf\n * @returns {string[][]}\n */\nfunction dataHeaderLinesOf(sheet, concepts) {\n const sectionLine = [sheet.dataHeaderLabels.section, ...concepts.map((concept) => concept.sectionLabel)];\n const conceptNames = concepts.map((concept) => concept.label);\n\n // sin la columna de cómo sale, el renglón del concepto es el último del encabezado\n if (!sheet.hasHowColumn) {\n return [sectionLine, [sheet.dataHeaderLabels.period, ...conceptNames]];\n }\n\n return [\n sectionLine,\n [sheet.dataHeaderLabels.concept, ...conceptNames],\n [sheet.dataHeaderLabels.period, ...concepts.map((concept) => concept.howLabel)],\n ];\n}\n\n/**\n * El CSV de la hoja, igual que los Datos: sus renglones de encabezado y un renglón por periodo, con la marca de UTF-8 al\n * principio. La sección va en cada columna de su concepto: el CSV no une celdas.\n *\n * @param {object} sheet de reportSheetOf\n * @returns {string}\n */\nexport function reportCsvOf(sheet) {\n const {concepts, periodRows} = reportDataTableOf(sheet);\n const lines = dataHeaderLinesOf(sheet, concepts);\n\n for (const periodRow of periodRows) {\n lines.push([periodRow.period, ...periodRow.values.map((value, position) => csvValueOf(value, concepts[position].format))]);\n }\n\n return UTF8_BYTE_ORDER_MARK + lines.map((fields) => fields.map(csvFieldOf).join(CSV_SEPARATOR)).join(CSV_LINE_END) + CSV_LINE_END;\n}\n\n/**\n * Una cifra como la guarda Excel: número (el porcentaje como fracción) o el texto de «no aplica».\n *\n * @param {number|string|null} value\n * @param {string} format VALUE_FORMAT\n * @returns {number|string}\n */\nfunction excelValueOf(value, format) {\n if (value === null || value === undefined) {\n return NOT_APPLICABLE_TEXT;\n }\n\n if (format === VALUE_FORMAT.percent) {\n return Number((Number(value) / PERCENT_PER_UNIT).toPrecision(EXCEL_SIGNIFICANT_DIGITS));\n }\n\n return Number(value);\n}\n\n/**\n * El nombre de la hoja de Excel: sin los signos que Excel no acepta y de 31 letras a lo más.\n *\n * @param {string} name\n * @returns {string}\n */\nfunction excelSheetNameOf(name) {\n return name.replace(EXCEL_SHEET_NAME_FORBIDDEN_CHARACTERS, ' ').slice(0, EXCEL_SHEET_NAME_MAX_LENGTH);\n}\n\n/**\n * Dobla el concepto en su celda y le da a su renglón el alto de las líneas que ocupa.\n *\n * @param {object} row el renglón de ExcelJS\n * @param {string} label el concepto o el título de la sección\n * @param {object} alignment lo demás de su alineación (la sangría del concepto)\n * @param {object} style el estilo del reporte\n * @returns {void}\n */\nfunction wrapConceptOf(row, label, alignment, style) {\n const lineCount = Math.ceil(label.length / style.conceptCharactersPerLine);\n row.getCell(1).alignment = {...alignment, wrapText: true, vertical: 'middle'};\n\n // con una sola línea se queda el alto de siempre\n if (lineCount > 1) {\n row.height = lineCount * style.lineHeightPoints;\n }\n}\n\n/**\n * El ancho de una columna de cifras: el de siempre, o más si su título no cabe en las líneas del encabezado.\n *\n * @param {string} headerTitle el título de la columna\n * @param {object} style el estilo del reporte\n * @returns {number}\n */\nfunction figureColumnWidthOf(headerTitle, style) {\n return Math.max(style.figureColumnWidth, Math.ceil(headerTitle.length / style.headerLineCount) + style.headerWidthMargin);\n}\n\n/**\n * El libro de Excel con sus dos hojas:\n * Resumen a lo ancho, con formato de reporte: el título, el encabezado del color principal, las secciones con su\n * fondo, cada cifra con su formato (conteo, dinero, porcentaje), bordes, los Totales con su fondo y Concepto\n * (y Cómo sale, si va) y el encabezado fijos. Se imprime acostado y ajustado al ancho, con el encabezado en\n * cada hoja.\n * Datos hacia abajo, con los filtros de Excel en el encabezado (ahí sí sirven: por sección, concepto o periodo).\n *\n * @param {object} ExcelJS el paquete exceljs ya cargado\n * @param {object} sheet de reportSheetOf\n * @param {{summarySheetName: string, dataSheetName: string, title: string, subtitle?: string, style?: object}} texts\n * los nombres de las dos hojas, lo que va arriba del Resumen y, si se quiere, lo que cambia de DEFAULT_REPORT_STYLE\n * @returns {{xlsx: {writeBuffer: () => Promise<ArrayBuffer>}} & Record<string, any>} el libro (ExcelJS.Workbook); se escribe\n * con workbook.xlsx.writeBuffer(). Tipo propio y no el de ExcelJS: el paquete no depende de sus tipos\n */\nexport function reportWorkbookOf(ExcelJS, sheet, {summarySheetName, dataSheetName, title, subtitle = '', style: customStyle = {}}) {\n const style = {\n ...DEFAULT_REPORT_STYLE,\n ...customStyle,\n numberFormats: {...DEFAULT_REPORT_STYLE.numberFormats, ...customStyle.numberFormats},\n };\n const workbook = new ExcelJS.Workbook();\n // las columnas antes de las cifras, que se quedan fijas al deslizar: Concepto y, si el reporte la lleva, cómo sale\n const leadingColumnWidths = sheet.hasHowColumn ? [style.conceptColumnWidth, style.howColumnWidth] : [style.conceptColumnWidth];\n const worksheet = workbook.addWorksheet(excelSheetNameOf(summarySheetName), {\n views: [{state: 'frozen', xSplit: leadingColumnWidths.length, ySplit: EXCEL_HEADER_ROW}],\n pageSetup: {orientation: 'landscape', fitToPage: true, fitToWidth: 1, fitToHeight: 0, printTitlesRow: `${EXCEL_HEADER_ROW}:${EXCEL_HEADER_ROW}`},\n });\n const columnCount = sheet.header.length;\n const totalsColumnNumber = columnCount;\n const firstFigureColumnNumber = leadingColumnWidths.length + 1;\n const fillOf = (color) => ({type: 'pattern', pattern: 'solid', fgColor: {argb: color}});\n const thinBorder = {style: 'thin', color: {argb: style.borderColor}};\n const cellBorder = {top: thinBorder, left: thinBorder, bottom: thinBorder, right: thinBorder};\n\n worksheet.columns = sheet.header.map((headerTitle, position) => ({\n width: leadingColumnWidths[position] ?? figureColumnWidthOf(headerTitle, style),\n }));\n\n // arriba: el título y el subtítulo\n worksheet.getCell(EXCEL_TITLE_ROW, 1).value = title;\n worksheet.getCell(EXCEL_TITLE_ROW, 1).font = {bold: true, size: style.titleFontSize, color: {argb: style.brandColor}};\n worksheet.getCell(EXCEL_SUBTITLE_ROW, 1).value = subtitle;\n worksheet.getCell(EXCEL_SUBTITLE_ROW, 1).font = {color: {argb: style.secondaryFontColor}};\n\n // el encabezado: el color principal con letra blanca; las cifras alineadas a la derecha\n const headerRow = worksheet.getRow(EXCEL_HEADER_ROW);\n headerRow.values = sheet.header;\n headerRow.height = style.headerRowHeight;\n headerRow.eachCell((cell, columnNumber) => {\n cell.font = {bold: true, color: {argb: style.headerFontColor}};\n cell.fill = fillOf(style.brandColor);\n cell.border = cellBorder;\n cell.alignment = {vertical: 'middle', wrapText: true, horizontal: columnNumber >= firstFigureColumnNumber ? 'right' : 'left'};\n });\n\n for (const row of sheet.rows) {\n // el título de la sección, con su fondo a todo lo ancho\n if (row.kind === SHEET_ROW_KIND.section) {\n const sectionRow = worksheet.addRow([row.label]);\n for (let columnNumber = 1; columnNumber <= columnCount; columnNumber += 1) {\n const cell = sectionRow.getCell(columnNumber);\n cell.font = {bold: true};\n cell.fill = fillOf(style.sectionFill);\n cell.border = cellBorder;\n }\n wrapConceptOf(sectionRow, row.label, {}, style);\n continue;\n }\n\n const figuresRow = worksheet.addRow([\n row.label,\n ...(sheet.hasHowColumn ? [row.howLabel] : []),\n ...row.values.map((value) => excelValueOf(value, row.format)),\n ]);\n for (let columnNumber = 1; columnNumber <= columnCount; columnNumber += 1) {\n figuresRow.getCell(columnNumber).border = cellBorder;\n }\n\n figuresRow.getCell(1).font = {bold: row.isTotal};\n wrapConceptOf(figuresRow, row.label, {indent: style.conceptIndent}, style);\n // cómo sale el total: más chico y en gris, para que no compita con las cifras\n if (sheet.hasHowColumn) {\n figuresRow.getCell(2).font = {italic: true, size: style.secondaryFontSize, color: {argb: style.secondaryFontColor}};\n }\n\n row.values.forEach((value, position) => {\n const cell = figuresRow.getCell(firstFigureColumnNumber + position);\n cell.numFmt = style.numberFormats[row.format];\n cell.alignment = {horizontal: 'right'};\n cell.font = {bold: row.isTotal};\n });\n\n // la columna de los Totales, con su fondo y en negritas (si el reporte la lleva)\n if (sheet.hasTotals) {\n const totalsCell = figuresRow.getCell(totalsColumnNumber);\n totalsCell.font = {bold: true};\n totalsCell.fill = fillOf(style.totalsFill);\n }\n }\n\n addDataWorksheet(workbook, sheet, dataSheetName, {style, fillOf, cellBorder});\n\n return workbook;\n}\n\n/**\n * La hoja de Datos: la tabla volteada, un renglón por periodo y una columna por concepto. Arriba, lo fijo de cada\n * concepto: su sección (una sola celda a lo ancho de sus conceptos, del color principal), su nombre y, si el reporte la\n * lleva, cómo sale; abajo, cada periodo con su valor en el formato de su concepto, y el renglón de los Totales con su\n * fondo y en negritas como en el Resumen. Cada sección empieza con una raya más marcada; la columna del periodo y el\n * encabezado quedan fijos, y los filtros de Excel van en el último renglón del encabezado.\n *\n * @param {object} workbook el libro de ExcelJS\n * @param {object} sheet de reportSheetOf\n * @param {string} dataSheetName el nombre de la hoja\n * @param {{style: object, fillOf: Function, cellBorder: object}} look el estilo, el relleno y el borde del Resumen\n * @returns {void}\n */\nfunction addDataWorksheet(workbook, sheet, dataSheetName, {style, fillOf, cellBorder}) {\n const {concepts, periodRows} = reportDataTableOf(sheet);\n const headerLines = dataHeaderLinesOf(sheet, concepts);\n const lastHeaderRow = headerLines.length;\n const worksheet = workbook.addWorksheet(excelSheetNameOf(dataSheetName), {views: [{state: 'frozen', xSplit: 1, ySplit: lastHeaderRow}]});\n const columnCount = concepts.length + 1;\n const sectionBorder = {style: 'medium', color: {argb: style.sectionBorderColor}};\n // por concepto, si con él empieza una sección (su columna en la hoja es su lugar + 2: la 1 es el periodo)\n const startsSectionAt = concepts.map((concept, position) => position === 0 || concept.sectionLabel !== concepts[position - 1].sectionLabel);\n // la columna del periodo se ensancha si un periodo no cabe\n const periodColumnWidth = Math.max(\n EXCEL_DATA_PERIOD_COLUMN_WIDTH,\n ...periodRows.map((periodRow) => periodRow.period.length + style.headerWidthMargin),\n );\n\n worksheet.columns = [{width: periodColumnWidth}, ...concepts.map(() => ({width: EXCEL_DATA_CONCEPT_COLUMN_WIDTH}))];\n\n headerLines.forEach((headerLine, position) => {\n worksheet.getRow(EXCEL_DATA_SECTION_ROW + position).values = headerLine;\n });\n worksheet.getRow(EXCEL_DATA_CONCEPT_ROW).height = EXCEL_DATA_CONCEPT_ROW_HEIGHT;\n\n for (let columnNumber = 1; columnNumber <= columnCount; columnNumber += 1) {\n const sectionCell = worksheet.getCell(EXCEL_DATA_SECTION_ROW, columnNumber);\n sectionCell.font = {bold: true, color: {argb: style.headerFontColor}};\n sectionCell.fill = fillOf(style.brandColor);\n sectionCell.alignment = {vertical: 'middle', horizontal: columnNumber === 1 ? 'left' : 'center'};\n\n const conceptCell = worksheet.getCell(EXCEL_DATA_CONCEPT_ROW, columnNumber);\n conceptCell.font = {bold: true};\n conceptCell.fill = fillOf(style.sectionFill);\n conceptCell.alignment = {vertical: 'middle', wrapText: true, horizontal: columnNumber === 1 ? 'left' : 'right'};\n\n // sin la columna de cómo sale no hay su renglón\n if (!sheet.hasHowColumn) {\n continue;\n }\n\n const howCell = worksheet.getCell(EXCEL_DATA_HOW_ROW, columnNumber);\n howCell.font = columnNumber === 1\n ? {bold: true}\n : {italic: true, size: style.secondaryFontSize, color: {argb: style.secondaryFontColor}};\n howCell.alignment = {horizontal: columnNumber === 1 ? 'left' : 'right'};\n }\n\n // un renglón por periodo, cada valor con el formato de su concepto; el de los Totales con su fondo y en negritas\n for (const periodRow of periodRows) {\n const dataRow = worksheet.addRow([periodRow.period, ...periodRow.values.map((value, position) => excelValueOf(value, concepts[position].format))]);\n dataRow.font = {bold: periodRow.isTotals};\n\n concepts.forEach((concept, position) => {\n const cell = dataRow.getCell(position + 2);\n cell.numFmt = style.numberFormats[concept.format];\n cell.alignment = {horizontal: 'right'};\n });\n\n if (periodRow.isTotals) {\n dataRow.eachCell((cell) => {\n cell.fill = fillOf(style.totalsFill);\n });\n }\n }\n\n // bordes en toda la tabla, con la raya más marcada donde empieza cada sección (y a la derecha del periodo)\n for (let rowNumber = EXCEL_DATA_SECTION_ROW; rowNumber <= worksheet.rowCount; rowNumber += 1) {\n for (let columnNumber = 1; columnNumber <= columnCount; columnNumber += 1) {\n const startsSection = columnNumber > 1 && startsSectionAt[columnNumber - 2];\n worksheet.getCell(rowNumber, columnNumber).border = startsSection ? {...cellBorder, left: sectionBorder} : cellBorder;\n }\n }\n\n // la sección va una sola vez a lo ancho de sus conceptos (es encabezado: unirla no estorba a los filtros, que van abajo)\n let sectionStartColumn = 2;\n for (let position = 1; position <= concepts.length; position += 1) {\n const sectionEnds = position === concepts.length || startsSectionAt[position];\n if (sectionEnds) {\n const sectionEndColumn = position + 1;\n if (sectionEndColumn > sectionStartColumn) {\n worksheet.mergeCells(EXCEL_DATA_SECTION_ROW, sectionStartColumn, EXCEL_DATA_SECTION_ROW, sectionEndColumn);\n }\n sectionStartColumn = sectionEndColumn + 1;\n }\n }\n\n // los filtros de Excel en el último renglón del encabezado (la flechita de cada columna para buscar y filtrar)\n worksheet.autoFilter = {from: {row: lastHeaderRow, column: 1}, to: {row: worksheet.rowCount, column: columnCount}};\n}\n"],"names":[],"mappings":"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"}
|
package/dist/excel.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DEFAULT_REPORT_STYLE, SHEET_ROW_KIND, VALUE_FORMAT, excelColorOf, fileNameSlugOf, reportCsvOf, reportDataTableOf, reportSheetOf, reportWorkbookOf } from "./excel/reportWorkbook.js";
|
|
2
|
+
export {
|
|
3
|
+
DEFAULT_REPORT_STYLE,
|
|
4
|
+
SHEET_ROW_KIND,
|
|
5
|
+
VALUE_FORMAT,
|
|
6
|
+
excelColorOf,
|
|
7
|
+
fileNameSlugOf,
|
|
8
|
+
reportCsvOf,
|
|
9
|
+
reportDataTableOf,
|
|
10
|
+
reportSheetOf,
|
|
11
|
+
reportWorkbookOf
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=excel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"excel.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useId } from "react";
|
|
4
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
5
|
+
import Alert from "@mui/material/Alert";
|
|
6
|
+
import Button from "@mui/material/Button";
|
|
7
|
+
import CircularProgress from "@mui/material/CircularProgress";
|
|
8
|
+
import Dialog from "@mui/material/Dialog";
|
|
9
|
+
import DialogActions from "@mui/material/DialogActions";
|
|
10
|
+
import DialogContent from "@mui/material/DialogContent";
|
|
11
|
+
import DialogContentText from "@mui/material/DialogContentText";
|
|
12
|
+
import DialogTitle from "@mui/material/DialogTitle";
|
|
13
|
+
function ConfirmDialog({
|
|
14
|
+
open,
|
|
15
|
+
title,
|
|
16
|
+
description,
|
|
17
|
+
confirmLabel,
|
|
18
|
+
cancelLabel,
|
|
19
|
+
tone = "primary",
|
|
20
|
+
isPending = false,
|
|
21
|
+
isConfirmDisabled = false,
|
|
22
|
+
errorMessage = null,
|
|
23
|
+
onConfirm,
|
|
24
|
+
onClose,
|
|
25
|
+
children,
|
|
26
|
+
texts
|
|
27
|
+
}) {
|
|
28
|
+
const { t } = useToolkitTranslation("common", texts);
|
|
29
|
+
const dialogId = useId();
|
|
30
|
+
const handleClose = () => {
|
|
31
|
+
if (isPending) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
onClose();
|
|
35
|
+
};
|
|
36
|
+
return /* @__PURE__ */ jsxs(
|
|
37
|
+
Dialog,
|
|
38
|
+
{
|
|
39
|
+
open,
|
|
40
|
+
onClose: handleClose,
|
|
41
|
+
maxWidth: "xs",
|
|
42
|
+
fullWidth: true,
|
|
43
|
+
"aria-labelledby": `${dialogId}-title`,
|
|
44
|
+
"aria-describedby": `${dialogId}-description`,
|
|
45
|
+
children: [
|
|
46
|
+
/* @__PURE__ */ jsx(DialogTitle, { id: `${dialogId}-title`, children: title }),
|
|
47
|
+
/* @__PURE__ */ jsxs(DialogContent, { children: [
|
|
48
|
+
errorMessage && /* @__PURE__ */ jsx(Alert, { severity: "error", role: "alert", sx: { mb: 2 }, children: errorMessage }),
|
|
49
|
+
description && /* @__PURE__ */ jsx(DialogContentText, { id: `${dialogId}-description`, children: description }),
|
|
50
|
+
children
|
|
51
|
+
] }),
|
|
52
|
+
/* @__PURE__ */ jsxs(DialogActions, { sx: { px: 3, pb: 2.5 }, children: [
|
|
53
|
+
/* @__PURE__ */ jsx(Button, { variant: "outlined", color: "inherit", onClick: handleClose, disabled: isPending, children: cancelLabel ?? t("actions.cancel") }),
|
|
54
|
+
/* @__PURE__ */ jsx(
|
|
55
|
+
Button,
|
|
56
|
+
{
|
|
57
|
+
variant: "contained",
|
|
58
|
+
color: tone,
|
|
59
|
+
onClick: onConfirm,
|
|
60
|
+
disabled: isPending || isConfirmDisabled,
|
|
61
|
+
"aria-busy": isPending,
|
|
62
|
+
children: isPending ? /* @__PURE__ */ jsx(CircularProgress, { size: 20, color: "inherit" }) : confirmLabel ?? t("actions.confirm")
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
] })
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
ConfirmDialog as default
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=ConfirmDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmDialog.js","sources":["../../src/feedback/ConfirmDialog.jsx"],"sourcesContent":["// Diálogo de confirmación: toda acción que cambia algo, manda un correo o descarga un archivo pasa por aquí antes de\n// ejecutarse (regla de tablas). Dice en lenguaje ciudadano QUÉ va a pasar y a QUÉ renglón («¿Dar de baja a Ana López?\n// Ya no podrá entrar; se puede reactivar después»).\n//\n// Recibe el estado de la petición por props (pending, error) en vez de hacerla él: core no conoce el API. Lo normal es\n// alimentarlo con useConfirmAction (máquina confirmActionMachine), que ya garantiza que cancelar no ejecuta y que un\n// doble clic no manda dos peticiones. Mientras la petición está en curso no se puede cerrar ni volver a confirmar.\n//\n// children: lo que el diálogo necesita pedir antes de confirmar (p. ej. el motivo de una baja), debajo del texto.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useId} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Alert from '@mui/material/Alert';\nimport Button from '@mui/material/Button';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Dialog from '@mui/material/Dialog';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogContentText from '@mui/material/DialogContentText';\nimport DialogTitle from '@mui/material/DialogTitle';\n\n/**\n * @param {object} props\n * @param {boolean} props.open\n * @param {string} props.title texto ya traducido, con el renglón («¿Dar de baja a Ana López?»)\n * @param {import('react').ReactNode} [props.description] qué va a pasar, en palabras normales\n * @param {string} [props.confirmLabel]\n * @param {string} [props.cancelLabel]\n * @param {'primary'|'error'|'warning'} [props.tone]\n * @param {boolean} [props.isPending]\n * @param {boolean} [props.isConfirmDisabled] la acción ya no aplica (p. ej. conflicto: el registro cambió)\n * @param {string|null} [props.errorMessage] mensaje ya traducido (ApiError.message)\n * @param {() => void} props.onConfirm\n * @param {() => void} props.onClose\n * @param {import('react').ReactNode} [props.children]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function ConfirmDialog({\n open, title, description, confirmLabel, cancelLabel, tone = 'primary',\n isPending = false, isConfirmDisabled = false, errorMessage = null, onConfirm, onClose, children, texts,\n}) {\n const {t} = useToolkitTranslation('common', texts);\n // ids propios: una pantalla puede tener varios diálogos montados y los aria-* no deben apuntar al de otro\n const dialogId = useId();\n\n const handleClose = () => {\n // guard clause: no se cierra a media petición\n if (isPending) {\n return;\n }\n onClose();\n };\n\n return (\n <Dialog open={open} onClose={handleClose} maxWidth=\"xs\" fullWidth\n aria-labelledby={`${dialogId}-title`} aria-describedby={`${dialogId}-description`}>\n <DialogTitle id={`${dialogId}-title`}>{title}</DialogTitle>\n <DialogContent>\n {errorMessage && <Alert severity=\"error\" role=\"alert\" sx={{mb: 2}}>{errorMessage}</Alert>}\n {description && (\n <DialogContentText id={`${dialogId}-description`}>{description}</DialogContentText>\n )}\n {children}\n </DialogContent>\n <DialogActions sx={{px: 3, pb: 2.5}}>\n <Button variant=\"outlined\" color=\"inherit\" onClick={handleClose} disabled={isPending}>\n {cancelLabel ?? t('actions.cancel')}\n </Button>\n <Button variant=\"contained\" color={tone} onClick={onConfirm} disabled={isPending || isConfirmDisabled}\n aria-busy={isPending}>\n {isPending ? <CircularProgress size={20} color=\"inherit\" /> : (confirmLabel ?? t('actions.confirm'))}\n </Button>\n </DialogActions>\n </Dialog>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAsCA,SAAwB,cAAc;AAAA,EAClC;AAAA,EAAM;AAAA,EAAO;AAAA,EAAa;AAAA,EAAc;AAAA,EAAa,OAAO;AAAA,EAC5D,YAAY;AAAA,EAAO,oBAAoB;AAAA,EAAO,eAAe;AAAA,EAAM;AAAA,EAAW;AAAA,EAAS;AAAA,EAAU;AACrG,GAAG;AACC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AAEjD,QAAM,WAAW,MAAA;AAEjB,QAAM,cAAc,MAAM;AAEtB,QAAI,WAAW;AACX;AAAA,IACJ;AACA,YAAA;AAAA,EACJ;AAEA,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MAAO;AAAA,MAAY,SAAS;AAAA,MAAa,UAAS;AAAA,MAAK,WAAS;AAAA,MACzD,mBAAiB,GAAG,QAAQ;AAAA,MAAU,oBAAkB,GAAG,QAAQ;AAAA,MACvE,UAAA;AAAA,QAAA,oBAAC,aAAA,EAAY,IAAI,GAAG,QAAQ,UAAW,UAAA,OAAM;AAAA,6BAC5C,eAAA,EACI,UAAA;AAAA,UAAA,gBAAgB,oBAAC,OAAA,EAAM,UAAS,SAAQ,MAAK,SAAQ,IAAI,EAAC,IAAI,EAAA,GAAK,UAAA,aAAA,CAAa;AAAA,UAChF,eACG,oBAAC,mBAAA,EAAkB,IAAI,GAAG,QAAQ,gBAAiB,UAAA,aAAY;AAAA,UAElE;AAAA,QAAA,GACL;AAAA,QACA,qBAAC,iBAAc,IAAI,EAAC,IAAI,GAAG,IAAI,OAC3B,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAO,SAAQ,YAAW,OAAM,WAAU,SAAS,aAAa,UAAU,WACtE,UAAA,eAAe,EAAE,gBAAgB,GACtC;AAAA,UACA;AAAA,YAAC;AAAA,YAAA;AAAA,cAAO,SAAQ;AAAA,cAAY,OAAO;AAAA,cAAM,SAAS;AAAA,cAAW,UAAU,aAAa;AAAA,cAC5E,aAAW;AAAA,cACd,UAAA,YAAY,oBAAC,kBAAA,EAAiB,MAAM,IAAI,OAAM,UAAA,CAAU,IAAM,gBAAgB,EAAE,iBAAiB;AAAA,YAAA;AAAA,UAAA;AAAA,QACtG,EAAA,CACJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGZ;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
4
|
+
import CircularProgress from "@mui/material/CircularProgress";
|
|
5
|
+
import Dialog from "@mui/material/Dialog";
|
|
6
|
+
import DialogContent from "@mui/material/DialogContent";
|
|
7
|
+
import DialogContentText from "@mui/material/DialogContentText";
|
|
8
|
+
import DialogTitle from "@mui/material/DialogTitle";
|
|
9
|
+
import Stack from "@mui/material/Stack";
|
|
10
|
+
function ModalWaiting({ open, title, text, texts }) {
|
|
11
|
+
const { t } = useToolkitTranslation("common", texts);
|
|
12
|
+
return /* @__PURE__ */ jsxs(Dialog, { open, disableEscapeKeyDown: true, "aria-busy": "true", sx: { zIndex: (theme) => theme.zIndex.tooltip + 10 }, children: [
|
|
13
|
+
/* @__PURE__ */ jsx(DialogTitle, { sx: { textAlign: "center" }, children: title ?? t("waiting.title") }),
|
|
14
|
+
/* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs(Stack, { spacing: 2, sx: { alignItems: "center" }, children: [
|
|
15
|
+
/* @__PURE__ */ jsx(CircularProgress, { size: 28 }),
|
|
16
|
+
/* @__PURE__ */ jsx(DialogContentText, { sx: { textAlign: "center" }, children: text ?? t("waiting.text") })
|
|
17
|
+
] }) })
|
|
18
|
+
] });
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
ModalWaiting as default
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=ModalWaiting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalWaiting.js","sources":["../../src/feedback/ModalWaiting.jsx"],"sourcesContent":["// Bloqueo general \"espere un momento\" como diálogo modal, para una acción que no se puede interrumpir (p. ej. generar\n// un archivo grande).\n//\n// OJO zIndex: HASTA ARRIBA de todo, encima de modal (1300), snackbar (1400) y tooltip (1500), para que ningún elemento\n// de la interfaz se le monte mientras bloquea. No se cierra con Escape a propósito.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Dialog from '@mui/material/Dialog';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogContentText from '@mui/material/DialogContentText';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport Stack from '@mui/material/Stack';\n\n/**\n * @param {object} props\n * @param {boolean} props.open\n * @param {string} [props.title] ya traducido; por omisión common:waiting.title\n * @param {string} [props.text] ya traducido; por omisión common:waiting.text\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function ModalWaiting({open, title, text, texts}) {\n const {t} = useToolkitTranslation('common', texts);\n\n return (\n <Dialog open={open} disableEscapeKeyDown aria-busy=\"true\" sx={{zIndex: (theme) => theme.zIndex.tooltip + 10}}>\n <DialogTitle sx={{textAlign: 'center'}}>{title ?? t('waiting.title')}</DialogTitle>\n <DialogContent>\n <Stack spacing={2} sx={{alignItems: 'center'}}>\n <CircularProgress size={28} />\n <DialogContentText sx={{textAlign: 'center'}}>{text ?? t('waiting.text')}</DialogContentText>\n </Stack>\n </DialogContent>\n </Dialog>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAsBA,SAAwB,aAAa,EAAC,MAAM,OAAO,MAAM,SAAQ;AAC7D,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AAEjD,8BACK,QAAA,EAAO,MAAY,sBAAoB,MAAC,aAAU,QAAO,IAAI,EAAC,QAAQ,CAAC,UAAU,MAAM,OAAO,UAAU,MACrG,UAAA;AAAA,IAAA,oBAAC,aAAA,EAAY,IAAI,EAAC,WAAW,YAAY,UAAA,SAAS,EAAE,eAAe,EAAA,CAAE;AAAA,IACrE,oBAAC,eAAA,EACG,UAAA,qBAAC,OAAA,EAAM,SAAS,GAAG,IAAI,EAAC,YAAY,SAAA,GAChC,UAAA;AAAA,MAAA,oBAAC,kBAAA,EAAiB,MAAM,GAAA,CAAI;AAAA,MAC5B,oBAAC,mBAAA,EAAkB,IAAI,EAAC,WAAW,YAAY,UAAA,QAAQ,EAAE,cAAc,EAAA,CAAE;AAAA,IAAA,EAAA,CAC7E,EAAA,CACJ;AAAA,EAAA,GACJ;AAER;"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
4
|
+
import Alert from "@mui/material/Alert";
|
|
5
|
+
import Box from "@mui/material/Box";
|
|
6
|
+
import Button from "@mui/material/Button";
|
|
7
|
+
import Typography from "@mui/material/Typography";
|
|
8
|
+
import RefreshRoundedIcon from "@mui/icons-material/RefreshRounded";
|
|
9
|
+
import { useNewBuildPublished } from "../observability/publishedBuild.js";
|
|
10
|
+
import { aboveMobileTabBarOf, GLASS_PANEL_GAP_PIXELS } from "../appShell/shellSizes.js";
|
|
11
|
+
import { minimalFloatingStylesOf } from "../theme/components/minimalComponents.js";
|
|
12
|
+
import { isGlassTheme, glassStylesOf } from "../theme/glassSurface.js";
|
|
13
|
+
import { APP_BAR_HEIGHT } from "../ui/layout/appBarHeight.js";
|
|
14
|
+
const NEW_BUILD_NOTICE_VARIANT = Object.freeze({ ribbon: "ribbon", floating: "floating" });
|
|
15
|
+
const FLOATING_GAP_PIXELS = 8;
|
|
16
|
+
const FLOATING_ENTER_MILLISECONDS = 280;
|
|
17
|
+
function reloadPage() {
|
|
18
|
+
window.location.reload();
|
|
19
|
+
}
|
|
20
|
+
function floatingSxOf(theme) {
|
|
21
|
+
return {
|
|
22
|
+
// con vidrio, cápsula de vidrio; con el minimalista (barra en cápsulas), sólida del gris de lo que flota
|
|
23
|
+
...isGlassTheme(theme) ? glassStylesOf(theme) : minimalFloatingStylesOf(theme),
|
|
24
|
+
position: "fixed",
|
|
25
|
+
left: "50%",
|
|
26
|
+
transform: "translateX(-50%)",
|
|
27
|
+
zIndex: theme.zIndex.appBar,
|
|
28
|
+
display: "flex",
|
|
29
|
+
alignItems: "center",
|
|
30
|
+
gap: 1.5,
|
|
31
|
+
width: "max-content",
|
|
32
|
+
maxWidth: `calc(100% - ${GLASS_PANEL_GAP_PIXELS * 2}px)`,
|
|
33
|
+
borderRadius: "999px",
|
|
34
|
+
py: 0.75,
|
|
35
|
+
pl: 2,
|
|
36
|
+
pr: 0.75,
|
|
37
|
+
top: `calc(${APP_BAR_HEIGHT} + ${FLOATING_GAP_PIXELS}px)`,
|
|
38
|
+
...aboveMobileTabBarOf(FLOATING_GAP_PIXELS),
|
|
39
|
+
// aparece subiendo un poco y aclarándose; sin movimiento si la persona lo pidió así en su equipo
|
|
40
|
+
"@keyframes calcitaNoticeEnter": {
|
|
41
|
+
from: { opacity: 0, transform: "translate(-50%, 8px) scale(0.96)" },
|
|
42
|
+
to: { opacity: 1, transform: "translate(-50%, 0) scale(1)" }
|
|
43
|
+
},
|
|
44
|
+
animation: `calcitaNoticeEnter ${FLOATING_ENTER_MILLISECONDS}ms ${theme.transitions.easing.easeOut}`,
|
|
45
|
+
"@media (prefers-reduced-motion: reduce)": { animation: "none" }
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function NewBuildNotice({ message, reloadLabel, onReload = reloadPage, variant = NEW_BUILD_NOTICE_VARIANT.ribbon, texts }) {
|
|
49
|
+
const { t } = useToolkitTranslation("common", texts);
|
|
50
|
+
const isNewBuildPublished = useNewBuildPublished();
|
|
51
|
+
if (!isNewBuildPublished) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const buttonLabel = reloadLabel ?? t("newBuild.reload");
|
|
55
|
+
if (variant === NEW_BUILD_NOTICE_VARIANT.floating) {
|
|
56
|
+
return /* @__PURE__ */ jsxs(Box, { role: "status", "aria-live": "polite", "aria-label": message ?? t("newBuild.message"), sx: floatingSxOf, children: [
|
|
57
|
+
/* @__PURE__ */ jsx(RefreshRoundedIcon, { fontSize: "small", sx: { color: "text.secondary" } }),
|
|
58
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", noWrap: true, sx: { fontWeight: 500, minWidth: 0 }, children: message ?? t("newBuild.short") }),
|
|
59
|
+
/* @__PURE__ */ jsx(Button, { size: "small", variant: "contained", onClick: onReload, sx: { flexShrink: 0 }, children: buttonLabel })
|
|
60
|
+
] });
|
|
61
|
+
}
|
|
62
|
+
return /* @__PURE__ */ jsx(
|
|
63
|
+
Alert,
|
|
64
|
+
{
|
|
65
|
+
severity: "warning",
|
|
66
|
+
square: true,
|
|
67
|
+
role: "status",
|
|
68
|
+
"aria-live": "polite",
|
|
69
|
+
sx: { py: 0, px: { xs: 2, md: 3 }, alignItems: "center" },
|
|
70
|
+
action: /* @__PURE__ */ jsx(Button, { size: "small", variant: "outlined", color: "inherit", onClick: onReload, sx: { flexShrink: 0 }, children: buttonLabel }),
|
|
71
|
+
children: message ?? t("newBuild.message")
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
NEW_BUILD_NOTICE_VARIANT,
|
|
77
|
+
NewBuildNotice as default
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=NewBuildNotice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NewBuildNotice.js","sources":["../../src/feedback/NewBuildNotice.jsx"],"sourcesContent":["// Aviso «Hay una versión nueva» con su botón de recargar.\n//\n// Sale cuando el servidor anuncia una compilación del front distinta a la que corre en la pestaña\n// (observability/publishedBuild.js) y se queda hasta que la persona recarga. No recarga solo: la persona puede estar a\n// media captura y decide cuándo.\n//\n// Dos formas, el mismo aviso:\n// - «ribbon» (por omisión): una franja a todo lo ancho que el proyecto pone donde se vea siempre, normalmente dentro de\n// su AppBar, debajo de la barra. Se arma con el Alert de MUI, que ya trae sus colores para claro y oscuro.\n// - «floating»: una cápsula de vidrio que flota aparte, sin tocar la barra, como el reproductor chico que Apple pone\n// encima de las pestañas en el iPhone. En escritorio, centrada debajo de la barra de arriba; en el teléfono, encima de\n// la barra de pestañas. Es la que usa AppLayout con vidrio: dentro de la cápsula de la barra la franja la hacía crecer al\n// doble, la curva cortaba el texto y el botón se salía por la orilla (lo reportaron).\n// Sin compilación nueva no pinta nada ni ocupa lugar.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Typography from '@mui/material/Typography';\nimport RefreshRoundedIcon from '@mui/icons-material/RefreshRounded';\n\nimport {useNewBuildPublished} from '@/observability/publishedBuild.js';\nimport {GLASS_PANEL_GAP_PIXELS, aboveMobileTabBarOf} from '@/appShell/shellSizes.js';\nimport {minimalFloatingStylesOf} from '@/theme/components/minimalComponents.js';\nimport {glassStylesOf, isGlassTheme} from '@/theme/glassSurface.js';\nimport {APP_BAR_HEIGHT} from '@/ui/layout/appBarHeight.js';\n\n/** Las formas del aviso: franja (dentro de la barra del proyecto) o cápsula flotante (la del marco con vidrio). */\nexport const NEW_BUILD_NOTICE_VARIANT = Object.freeze({ribbon: 'ribbon', floating: 'floating'});\n\n// lo que se separa la cápsula de la barra (px) y lo que tarda en aparecer (ms)\nconst FLOATING_GAP_PIXELS = 8;\nconst FLOATING_ENTER_MILLISECONDS = 280;\n\n/** Lo que hace el botón si el proyecto no dice otra cosa: recargar la página, que trae la compilación nueva. */\nfunction reloadPage() {\n window.location.reload();\n}\n\n/**\n * La cápsula flotante: fija a la ventana y centrada. En escritorio queda debajo de la barra de arriba (su alto real,\n * APP_BAR_HEIGHT); en el teléfono, encima de la barra de pestañas (su alto, sus separaciones y la zona del gesto de inicio).\n *\n * Va centrada en la VENTANA, debajo del centro de la barra (que va de orilla a orilla): centrada en el contenido quedaba\n * corrida a la derecha respecto a la barra (lo reportaron).\n *\n * @param {object} theme\n * @returns {object}\n */\nfunction floatingSxOf(theme) {\n return {\n // con vidrio, cápsula de vidrio; con el minimalista (barra en cápsulas), sólida del gris de lo que flota\n ...(isGlassTheme(theme) ? glassStylesOf(theme) : minimalFloatingStylesOf(theme)),\n position: 'fixed',\n left: '50%',\n transform: 'translateX(-50%)',\n zIndex: theme.zIndex.appBar,\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n width: 'max-content',\n maxWidth: `calc(100% - ${GLASS_PANEL_GAP_PIXELS * 2}px)`,\n borderRadius: '999px',\n py: 0.75,\n pl: 2,\n pr: 0.75,\n top: `calc(${APP_BAR_HEIGHT} + ${FLOATING_GAP_PIXELS}px)`,\n ...aboveMobileTabBarOf(FLOATING_GAP_PIXELS),\n // aparece subiendo un poco y aclarándose; sin movimiento si la persona lo pidió así en su equipo\n '@keyframes calcitaNoticeEnter': {\n from: {opacity: 0, transform: 'translate(-50%, 8px) scale(0.96)'},\n to: {opacity: 1, transform: 'translate(-50%, 0) scale(1)'},\n },\n animation: `calcitaNoticeEnter ${FLOATING_ENTER_MILLISECONDS}ms ${theme.transitions.easing.easeOut}`,\n '@media (prefers-reduced-motion: reduce)': {animation: 'none'},\n };\n}\n\n/**\n * @param {object} [props]\n * @param {string} [props.message] ya traducido; por omisión el del paquete (en la cápsula, el corto: common:newBuild.short)\n * @param {string} [props.reloadLabel] ya traducido; por omisión «Recargar»\n * @param {() => void} [props.onReload] por omisión recarga la página\n * @param {'ribbon'|'floating'} [props.variant] franja o cápsula flotante (NEW_BUILD_NOTICE_VARIANT); por omisión franja\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function NewBuildNotice({message, reloadLabel, onReload = reloadPage, variant = NEW_BUILD_NOTICE_VARIANT.ribbon, texts}) {\n const {t} = useToolkitTranslation('common', texts);\n const isNewBuildPublished = useNewBuildPublished();\n\n // guard clause: la compilación de la pestaña sigue siendo la publicada; el aviso no ocupa lugar\n if (!isNewBuildPublished) {\n return null;\n }\n\n const buttonLabel = reloadLabel ?? t('newBuild.reload');\n\n if (variant === NEW_BUILD_NOTICE_VARIANT.floating) {\n // el texto largo va para el lector de pantalla; a la vista, el corto (una cápsula de un renglón)\n return (\n <Box role=\"status\" aria-live=\"polite\" aria-label={message ?? t('newBuild.message')} sx={floatingSxOf}>\n <RefreshRoundedIcon fontSize=\"small\" sx={{color: 'text.secondary'}} />\n <Typography variant=\"body2\" noWrap sx={{fontWeight: 500, minWidth: 0}}>{message ?? t('newBuild.short')}</Typography>\n <Button size=\"small\" variant=\"contained\" onClick={onReload} sx={{flexShrink: 0}}>{buttonLabel}</Button>\n </Box>\n );\n }\n\n return (\n <Alert severity=\"warning\" square role=\"status\" aria-live=\"polite\"\n sx={{py: 0, px: {xs: 2, md: 3}, alignItems: 'center'}}\n action={(\n <Button size=\"small\" variant=\"outlined\" color=\"inherit\" onClick={onReload} sx={{flexShrink: 0}}>\n {buttonLabel}\n </Button>\n )}>\n {message ?? t('newBuild.message')}\n </Alert>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;AA8BO,MAAM,2BAA2B,OAAO,OAAO,EAAC,QAAQ,UAAU,UAAU,YAAW;AAG9F,MAAM,sBAAsB;AAC5B,MAAM,8BAA8B;AAGpC,SAAS,aAAa;AAClB,SAAO,SAAS,OAAA;AACpB;AAYA,SAAS,aAAa,OAAO;AACzB,SAAO;AAAA;AAAA,IAEH,GAAI,aAAa,KAAK,IAAI,cAAc,KAAK,IAAI,wBAAwB,KAAK;AAAA,IAC9E,UAAU;AAAA,IACV,MAAM;AAAA,IACN,WAAW;AAAA,IACX,QAAQ,MAAM,OAAO;AAAA,IACrB,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,KAAK;AAAA,IACL,OAAO;AAAA,IACP,UAAU,eAAe,yBAAyB,CAAC;AAAA,IACnD,cAAc;AAAA,IACd,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,KAAK,QAAQ,cAAc,MAAM,mBAAmB;AAAA,IACpD,GAAG,oBAAoB,mBAAmB;AAAA;AAAA,IAE1C,iCAAiC;AAAA,MAC7B,MAAM,EAAC,SAAS,GAAG,WAAW,mCAAA;AAAA,MAC9B,IAAI,EAAC,SAAS,GAAG,WAAW,8BAAA;AAAA,IAA6B;AAAA,IAE7D,WAAW,sBAAsB,2BAA2B,MAAM,MAAM,YAAY,OAAO,OAAO;AAAA,IAClG,2CAA2C,EAAC,WAAW,OAAA;AAAA,EAAM;AAErE;AAUA,SAAwB,eAAe,EAAC,SAAS,aAAa,WAAW,YAAY,UAAU,yBAAyB,QAAQ,SAAQ;AACpI,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,sBAAsB,qBAAA;AAG5B,MAAI,CAAC,qBAAqB;AACtB,WAAO;AAAA,EACX;AAEA,QAAM,cAAc,eAAe,EAAE,iBAAiB;AAEtD,MAAI,YAAY,yBAAyB,UAAU;AAE/C,WACI,qBAAC,KAAA,EAAI,MAAK,UAAS,aAAU,UAAS,cAAY,WAAW,EAAE,kBAAkB,GAAG,IAAI,cACpF,UAAA;AAAA,MAAA,oBAAC,sBAAmB,UAAS,SAAQ,IAAI,EAAC,OAAO,oBAAmB;AAAA,0BACnE,YAAA,EAAW,SAAQ,SAAQ,QAAM,MAAC,IAAI,EAAC,YAAY,KAAK,UAAU,KAAK,UAAA,WAAW,EAAE,gBAAgB,GAAE;AAAA,MACvG,oBAAC,QAAA,EAAO,MAAK,SAAQ,SAAQ,aAAY,SAAS,UAAU,IAAI,EAAC,YAAY,EAAA,GAAK,UAAA,YAAA,CAAY;AAAA,IAAA,GAClG;AAAA,EAER;AAEA,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MAAM,UAAS;AAAA,MAAU,QAAM;AAAA,MAAC,MAAK;AAAA,MAAS,aAAU;AAAA,MAClD,IAAI,EAAC,IAAI,GAAG,IAAI,EAAC,IAAI,GAAG,IAAI,KAAI,YAAY,SAAA;AAAA,MAC5C,QACI,oBAAC,QAAA,EAAO,MAAK,SAAQ,SAAQ,YAAW,OAAM,WAAU,SAAS,UAAU,IAAI,EAAC,YAAY,KACvF,UAAA,aACL;AAAA,MAEN,UAAA,WAAW,EAAE,kBAAkB;AAAA,IAAA;AAAA,EAAA;AAG5C;"}
|