@stackcraftmx/calcita 0.32.2 → 0.51.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/README.md +426 -4
- package/cli/calcita.js +15 -0
- package/cli/checkTexts.js +209 -0
- package/cli/packageVersions.js +17 -3
- package/cli/projectFiles.js +7 -2
- package/cli/templates/module/__Name__Page.test.jsx.tpl +24 -0
- package/cli/templates/project/README.md.tpl +35 -2
- package/cli/templates/project/eslint.config.js.tpl +27 -0
- package/cli/templates/project/src/app/appRouter.jsx.tpl +5 -2
- package/cli/templates/project/src/app/appTexts.js.tpl +2 -1
- package/cli/templates/project/src/core/accountConnector.js.tpl +4 -2
- package/cli/templates/project/src/core/publicPaths.js.tpl +10 -2
- package/cli/templates/project/src/modules/auth/SignInPage.test.jsx.tpl +20 -0
- package/cli/templates/project/src/modules/home/HomePage.test.jsx.tpl +16 -0
- package/cli/templates/project/src/testing/browserGaps.js.tpl +70 -0
- package/cli/templates/project/src/testing/openScreen.jsx.tpl +58 -0
- package/cli/templates/project/src/testing/setup.js.tpl +25 -0
- package/cli/templates/project/vite.config.js.tpl +20 -1
- package/dist/DataTable/AuditTrailDialog.js +3 -2
- package/dist/DataTable/AuditTrailDialog.js.map +1 -1
- package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js +3 -2
- package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js.map +1 -1
- package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js +3 -2
- package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js.map +1 -1
- package/dist/DataTable/ColumnFilters/SortableFilterHeader.js +3 -2
- package/dist/DataTable/ColumnFilters/SortableFilterHeader.js.map +1 -1
- package/dist/DataTable/EmptyState.js +3 -2
- package/dist/DataTable/EmptyState.js.map +1 -1
- package/dist/DataTable/FilterChips.js +3 -2
- package/dist/DataTable/FilterChips.js.map +1 -1
- package/dist/DataTable/GoToPage.js +71 -14
- package/dist/DataTable/GoToPage.js.map +1 -1
- package/dist/DataTable/ServerTable.js +97 -28
- package/dist/DataTable/ServerTable.js.map +1 -1
- package/dist/DataTable/ServerTableFilterDrawer.js +57 -0
- package/dist/DataTable/ServerTableFilterDrawer.js.map +1 -0
- package/dist/DataTable/StackedCell.js +60 -0
- package/dist/DataTable/StackedCell.js.map +1 -0
- package/dist/DataTable/TableCardsView.js +88 -0
- package/dist/DataTable/TableCardsView.js.map +1 -0
- package/dist/DataTable/columnWidths.js +30 -0
- package/dist/DataTable/columnWidths.js.map +1 -0
- package/dist/DataTable/columns.js +47 -1
- package/dist/DataTable/columns.js.map +1 -1
- package/dist/DataTable/filterContext.js.map +1 -1
- package/dist/DataTable/fixedColumns.js +24 -0
- package/dist/DataTable/fixedColumns.js.map +1 -0
- package/dist/DataTable/goToPageOptions.js +17 -0
- package/dist/DataTable/goToPageOptions.js.map +1 -0
- package/dist/DataTable/useTableView.js +29 -0
- package/dist/DataTable/useTableView.js.map +1 -0
- package/dist/access/PermissionMatrix.js +3 -2
- package/dist/access/PermissionMatrix.js.map +1 -1
- package/dist/account/AccountProvider.js +1 -1
- package/dist/account/AccountSecuritySection.js +3 -2
- package/dist/account/AccountSecuritySection.js.map +1 -1
- package/dist/account/DemoTotpCodeButton.js +3 -2
- package/dist/account/DemoTotpCodeButton.js.map +1 -1
- package/dist/account/ProfileScreen.js +3 -2
- package/dist/account/ProfileScreen.js.map +1 -1
- package/dist/account/SignInScreen.js +3 -2
- package/dist/account/SignInScreen.js.map +1 -1
- package/dist/appShell/AccountMenu.js +3 -2
- package/dist/appShell/AccountMenu.js.map +1 -1
- package/dist/appShell/AppLayout.js +3 -2
- package/dist/appShell/AppLayout.js.map +1 -1
- package/dist/appShell/AppearanceSettings.js +3 -2
- package/dist/appShell/AppearanceSettings.js.map +1 -1
- package/dist/appShell/AuthLayout.js +3 -2
- package/dist/appShell/AuthLayout.js.map +1 -1
- package/dist/appShell/BarActionButton.js +11 -4
- package/dist/appShell/BarActionButton.js.map +1 -1
- package/dist/appShell/BarActions.js +3 -2
- package/dist/appShell/BarActions.js.map +1 -1
- package/dist/appShell/BarCapsule.js +3 -2
- package/dist/appShell/BarCapsule.js.map +1 -1
- package/dist/appShell/BarSearch.js +3 -2
- package/dist/appShell/BarSearch.js.map +1 -1
- package/dist/appShell/HeaderTools.js +3 -2
- package/dist/appShell/HeaderTools.js.map +1 -1
- package/dist/appShell/MobileTabBar.js +3 -2
- package/dist/appShell/MobileTabBar.js.map +1 -1
- package/dist/appShell/SettingsMenu.js +3 -2
- package/dist/appShell/SettingsMenu.js.map +1 -1
- package/dist/appShell/SideMenu.js +3 -2
- package/dist/appShell/SideMenu.js.map +1 -1
- package/dist/appShell/SideMenuEntry.js +3 -2
- package/dist/appShell/SideMenuEntry.js.map +1 -1
- package/dist/appShell/SubmenuActionsMenu.js +3 -2
- package/dist/appShell/SubmenuActionsMenu.js.map +1 -1
- package/dist/appShell/TabBarEditor.js +3 -2
- package/dist/appShell/TabBarEditor.js.map +1 -1
- package/dist/appShell/TopMenu.js +3 -2
- package/dist/appShell/TopMenu.js.map +1 -1
- package/dist/appShell/Wordmark.js +3 -2
- package/dist/appShell/Wordmark.js.map +1 -1
- package/dist/auth/PasswordChecklist.js +3 -2
- package/dist/auth/PasswordChecklist.js.map +1 -1
- package/dist/calendar/EventCalendar.js +3 -2
- package/dist/calendar/EventCalendar.js.map +1 -1
- package/dist/calendar/EventDetails.js +3 -2
- package/dist/calendar/EventDetails.js.map +1 -1
- package/dist/date-pickers.js +28 -2
- package/dist/date-pickers.js.map +1 -1
- package/dist/datePickers/DateInput.js +41 -54
- package/dist/datePickers/DateInput.js.map +1 -1
- package/dist/datePickers/DateTimeInput.js +81 -0
- package/dist/datePickers/DateTimeInput.js.map +1 -0
- package/dist/datePickers/FormDateTimeField.js +12 -0
- package/dist/datePickers/FormDateTimeField.js.map +1 -0
- package/dist/datePickers/FormMonthField.js +12 -0
- package/dist/datePickers/FormMonthField.js.map +1 -0
- package/dist/datePickers/FormTimeField.js +12 -0
- package/dist/datePickers/FormTimeField.js.map +1 -0
- package/dist/datePickers/MonthInput.js +64 -0
- package/dist/datePickers/MonthInput.js.map +1 -0
- package/dist/datePickers/PickerFrame.js +27 -0
- package/dist/datePickers/PickerFrame.js.map +1 -0
- package/dist/datePickers/TimeInput.js +61 -0
- package/dist/datePickers/TimeInput.js.map +1 -0
- package/dist/datePickers/dateTimeRules.js +24 -0
- package/dist/datePickers/dateTimeRules.js.map +1 -0
- package/dist/datePickers/pickerValues.js +106 -0
- package/dist/datePickers/pickerValues.js.map +1 -0
- package/dist/datePickers/useCurrentMinute.js +28 -0
- package/dist/datePickers/useCurrentMinute.js.map +1 -0
- package/dist/datePickers/usePickerField.js +23 -0
- package/dist/datePickers/usePickerField.js.map +1 -0
- package/dist/dictionaries/dictionaries.js +3 -1
- package/dist/dictionaries/dictionaries.js.map +1 -1
- package/dist/downloads/DownloadManager.js +3 -2
- package/dist/downloads/DownloadManager.js.map +1 -1
- package/dist/feedback/ConfirmDialog.js +3 -2
- package/dist/feedback/ConfirmDialog.js.map +1 -1
- package/dist/feedback/ModalWaiting.js +3 -2
- package/dist/feedback/ModalWaiting.js.map +1 -1
- package/dist/feedback/NewBuildNotice.js +3 -2
- package/dist/feedback/NewBuildNotice.js.map +1 -1
- package/dist/filepond/FileDropzone.js +3 -2
- package/dist/filepond/FileDropzone.js.map +1 -1
- package/dist/forms/FormAttachmentsField.js +12 -0
- package/dist/forms/FormAttachmentsField.js.map +1 -0
- package/dist/forms/FormCheckboxGroupField.js +12 -0
- package/dist/forms/FormCheckboxGroupField.js.map +1 -0
- package/dist/forms/FormFileField.js +12 -0
- package/dist/forms/FormFileField.js.map +1 -0
- package/dist/forms/FormFileUploadField.js +12 -0
- package/dist/forms/FormFileUploadField.js.map +1 -0
- package/dist/forms/FormImageField.js +12 -0
- package/dist/forms/FormImageField.js.map +1 -0
- package/dist/forms/FormMaskedField.js +12 -0
- package/dist/forms/FormMaskedField.js.map +1 -0
- package/dist/forms/FormProblemAlert.js +3 -2
- package/dist/forms/FormProblemAlert.js.map +1 -1
- package/dist/forms/FormRepeatingFields.js +54 -0
- package/dist/forms/FormRepeatingFields.js.map +1 -0
- package/dist/forms/FormTransferListField.js +12 -0
- package/dist/forms/FormTransferListField.js.map +1 -0
- package/dist/forms/SubmitButton.js +7 -2
- package/dist/forms/SubmitButton.js.map +1 -1
- package/dist/forms/applyServerProblem.js +10 -3
- package/dist/forms/applyServerProblem.js.map +1 -1
- package/dist/forms/auth/SignInForm.js +3 -2
- package/dist/forms/auth/SignInForm.js.map +1 -1
- package/dist/forms/fieldRules.js +30 -0
- package/dist/forms/fieldRules.js.map +1 -0
- package/dist/forms/listRules.js +111 -0
- package/dist/forms/listRules.js.map +1 -0
- package/dist/forms/security/SecondStepForm.js +3 -2
- package/dist/forms/security/SecondStepForm.js.map +1 -1
- package/dist/forms/security/TwoStepVerificationCard.js +3 -2
- package/dist/forms/security/TwoStepVerificationCard.js.map +1 -1
- package/dist/forms/serverProblemFields.js +17 -0
- package/dist/forms/serverProblemFields.js.map +1 -1
- package/dist/forms/useValidationText.js +18 -0
- package/dist/forms/useValidationText.js.map +1 -0
- package/dist/forms/validation.js +35 -31
- package/dist/forms/validation.js.map +1 -1
- package/dist/forms/validationMessages.js +64 -7
- package/dist/forms/validationMessages.js.map +1 -1
- package/dist/forms.js +54 -29
- package/dist/forms.js.map +1 -1
- package/dist/hookForm/FormAttachmentsField.js +12 -0
- package/dist/hookForm/FormAttachmentsField.js.map +1 -0
- package/dist/hookForm/FormCheckboxGroupField.js +12 -0
- package/dist/hookForm/FormCheckboxGroupField.js.map +1 -0
- package/dist/hookForm/FormFileField.js +12 -0
- package/dist/hookForm/FormFileField.js.map +1 -0
- package/dist/hookForm/FormFileUploadField.js +12 -0
- package/dist/hookForm/FormFileUploadField.js.map +1 -0
- package/dist/hookForm/FormImageField.js +12 -0
- package/dist/hookForm/FormImageField.js.map +1 -0
- package/dist/hookForm/FormMaskedField.js +12 -0
- package/dist/hookForm/FormMaskedField.js.map +1 -0
- package/dist/hookForm/FormProblemAlert.js +3 -2
- package/dist/hookForm/FormProblemAlert.js.map +1 -1
- package/dist/hookForm/FormRepeatingFields.js +44 -0
- package/dist/hookForm/FormRepeatingFields.js.map +1 -0
- package/dist/hookForm/FormTransferListField.js +12 -0
- package/dist/hookForm/FormTransferListField.js.map +1 -0
- package/dist/hookForm/SubmitButton.js +7 -2
- package/dist/hookForm/SubmitButton.js.map +1 -1
- package/dist/hookForm/applyServerProblem.js +8 -3
- package/dist/hookForm/applyServerProblem.js.map +1 -1
- package/dist/inbox/InboxLayout.js +3 -2
- package/dist/inbox/InboxLayout.js.map +1 -1
- package/dist/inbox/MessageList.js +3 -2
- package/dist/inbox/MessageList.js.map +1 -1
- package/dist/inbox/MessageView.js +3 -2
- package/dist/inbox/MessageView.js.map +1 -1
- package/dist/index.js +235 -124
- package/dist/index.js.map +1 -1
- package/dist/inputs/CatalogInput.js +103 -29
- package/dist/inputs/CatalogInput.js.map +1 -1
- package/dist/inputs/CheckboxGroupInput.js +103 -0
- package/dist/inputs/CheckboxGroupInput.js.map +1 -0
- package/dist/inputs/ColorInput.js +7 -4
- package/dist/inputs/ColorInput.js.map +1 -1
- package/dist/inputs/FieldFrame.js +10 -4
- package/dist/inputs/FieldFrame.js.map +1 -1
- package/dist/inputs/FormSection.js +1 -1
- package/dist/inputs/MaskedInput.js +87 -0
- package/dist/inputs/MaskedInput.js.map +1 -0
- package/dist/inputs/NumberInput.js +41 -25
- package/dist/inputs/NumberInput.js.map +1 -1
- package/dist/inputs/RepeatingFields.js +180 -0
- package/dist/inputs/RepeatingFields.js.map +1 -0
- package/dist/inputs/SelectInput.js +50 -9
- package/dist/inputs/SelectInput.js.map +1 -1
- package/dist/inputs/TextInput.js +5 -3
- package/dist/inputs/TextInput.js.map +1 -1
- package/dist/inputs/TransferListInput.js +218 -0
- package/dist/inputs/TransferListInput.js.map +1 -0
- package/dist/inputs/WizardLayout.js +3 -2
- package/dist/inputs/WizardLayout.js.map +1 -1
- package/dist/inputs/inputMasks.js +84 -0
- package/dist/inputs/inputMasks.js.map +1 -0
- package/dist/inputs/selectAllState.js +20 -0
- package/dist/inputs/selectAllState.js.map +1 -0
- package/dist/inputs/useRowKeys.js +26 -0
- package/dist/inputs/useRowKeys.js.map +1 -0
- package/dist/kanban/KanbanBoard.js +3 -2
- package/dist/kanban/KanbanBoard.js.map +1 -1
- package/dist/legal/CookieNotice.js +80 -0
- package/dist/legal/CookieNotice.js.map +1 -0
- package/dist/legal/TermsAcceptanceDialog.js +130 -0
- package/dist/legal/TermsAcceptanceDialog.js.map +1 -0
- package/dist/legal/consentStorage.js +18 -0
- package/dist/legal/consentStorage.js.map +1 -0
- package/dist/legal/useCookieConsent.js +17 -0
- package/dist/legal/useCookieConsent.js.map +1 -0
- package/dist/locales/en.js +257 -1
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es.js +257 -1
- package/dist/locales/es.js.map +1 -1
- package/dist/maps/MapView.js +3 -2
- package/dist/maps/MapView.js.map +1 -1
- package/dist/mexico/CfdiSummary.js +82 -0
- package/dist/mexico/CfdiSummary.js.map +1 -0
- package/dist/mexico/EfirmaFields.js +168 -0
- package/dist/mexico/EfirmaFields.js.map +1 -0
- package/dist/mexico/certificateReader.js +79 -0
- package/dist/mexico/certificateReader.js.map +1 -0
- package/dist/mexico/cfdiReader.js +81 -0
- package/dist/mexico/cfdiReader.js.map +1 -0
- package/dist/mexico/derReader.js +81 -0
- package/dist/mexico/derReader.js.map +1 -0
- package/dist/mexico/efirmaKey.js +51 -0
- package/dist/mexico/efirmaKey.js.map +1 -0
- package/dist/mexico/mexicoIdentifiers.js +91 -0
- package/dist/mexico/mexicoIdentifiers.js.map +1 -0
- package/dist/mexico/mexicoRules.js +21 -0
- package/dist/mexico/mexicoRules.js.map +1 -0
- package/dist/mexico.js +34 -0
- package/dist/mexico.js.map +1 -0
- package/dist/pwa/InstallAppSetting.js +3 -2
- package/dist/pwa/InstallAppSetting.js.map +1 -1
- package/dist/pwa/InstallInstructionsDialog.js +3 -2
- package/dist/pwa/InstallInstructionsDialog.js.map +1 -1
- package/dist/pwa/InstallPromptBanner.js +3 -2
- package/dist/pwa/InstallPromptBanner.js.map +1 -1
- package/dist/react-hook-form.js +43 -17
- package/dist/react-hook-form.js.map +1 -1
- package/dist/rich-text.js +19 -0
- package/dist/rich-text.js.map +1 -0
- package/dist/richText/FormRichTextField.js +12 -0
- package/dist/richText/FormRichTextField.js.map +1 -0
- package/dist/richText/RichTextEditor.js +111 -0
- package/dist/richText/RichTextEditor.js.map +1 -0
- package/dist/richText/RichTextLinkPopover.js +57 -0
- package/dist/richText/RichTextLinkPopover.js.map +1 -0
- package/dist/richText/RichTextToolbar.js +189 -0
- package/dist/richText/RichTextToolbar.js.map +1 -0
- package/dist/richText/RichTextView.js +27 -0
- package/dist/richText/RichTextView.js.map +1 -0
- package/dist/richText/richTextContentSx.js +42 -0
- package/dist/richText/richTextContentSx.js.map +1 -0
- package/dist/richText/richTextExtensions.js +44 -0
- package/dist/richText/richTextExtensions.js.map +1 -0
- package/dist/richText/richTextRules.js +46 -0
- package/dist/richText/richTextRules.js.map +1 -0
- package/dist/security/ActivityLog.js +3 -2
- package/dist/security/ActivityLog.js.map +1 -1
- package/dist/security/RecoveryCodesDialog.js +3 -2
- package/dist/security/RecoveryCodesDialog.js.map +1 -1
- package/dist/security/SessionsCard.js +3 -2
- package/dist/security/SessionsCard.js.map +1 -1
- package/dist/table.js +23 -2
- package/dist/table.js.map +1 -1
- package/dist/theme/components/glassComponents.js +27 -0
- package/dist/theme/components/glassComponents.js.map +1 -1
- package/dist/theme/components/minimalComponents.js +12 -0
- package/dist/theme/components/minimalComponents.js.map +1 -1
- package/dist/theme/themePieces.js +70 -4
- package/dist/theme/themePieces.js.map +1 -1
- package/dist/toolkit/ToolkitProvider.js +8 -1
- package/dist/toolkit/ToolkitProvider.js.map +1 -1
- package/dist/toolkit/browserNavigation.js +19 -4
- package/dist/toolkit/browserNavigation.js.map +1 -1
- package/dist/toolkit/combineTexts.js +32 -0
- package/dist/toolkit/combineTexts.js.map +1 -0
- package/dist/toolkit/hashNavigation.js +17 -3
- package/dist/toolkit/hashNavigation.js.map +1 -1
- package/dist/toolkit/navigationPaths.js +15 -0
- package/dist/toolkit/navigationPaths.js.map +1 -1
- package/dist/toolkit/pathIndex.js +66 -0
- package/dist/toolkit/pathIndex.js.map +1 -0
- package/dist/toolkit/toolkitSettings.js +19 -1
- package/dist/toolkit/toolkitSettings.js.map +1 -1
- package/dist/types/DataTable/AuditTrailDialog.d.ts +6 -17
- package/dist/types/DataTable/ColumnFilters/HeaderFilterPopover.d.ts +6 -5
- package/dist/types/DataTable/ColumnFilters/MultiSelectColumnFilter.d.ts +6 -9
- package/dist/types/DataTable/ColumnFilters/SortableFilterHeader.d.ts +6 -14
- package/dist/types/DataTable/EmptyState.d.ts +6 -9
- package/dist/types/DataTable/FilterChips.d.ts +6 -11
- package/dist/types/DataTable/GoToPage.d.ts +6 -9
- package/dist/types/DataTable/ServerTable.d.ts +16 -80
- package/dist/types/DataTable/ServerTableFilterDrawer.d.ts +14 -0
- package/dist/types/DataTable/StackedCell.d.ts +12 -0
- package/dist/types/DataTable/TableCardsView.d.ts +27 -0
- package/dist/types/DataTable/columnWidths.d.ts +21 -0
- package/dist/types/DataTable/columns.d.ts +111 -0
- package/dist/types/DataTable/filterContext.d.ts +2 -1
- package/dist/types/DataTable/fixedColumns.d.ts +29 -0
- package/dist/types/DataTable/goToPageOptions.d.ts +15 -0
- package/dist/types/DataTable/index.d.ts +7 -1
- package/dist/types/DataTable/useTableView.d.ts +22 -0
- package/dist/types/access/PermissionMatrix.d.ts +6 -10
- package/dist/types/account/AccountSecuritySection.d.ts +6 -7
- package/dist/types/account/DemoTotpCodeButton.d.ts +6 -5
- package/dist/types/account/ProfileScreen.d.ts +6 -18
- package/dist/types/account/SignInScreen.d.ts +6 -13
- package/dist/types/appShell/AccountMenu.d.ts +6 -11
- package/dist/types/appShell/AppLayout.d.ts +3 -40
- package/dist/types/appShell/AppearanceSettings.d.ts +6 -12
- package/dist/types/appShell/AuthLayout.d.ts +3 -11
- package/dist/types/appShell/BarActionButton.d.ts +6 -10
- package/dist/types/appShell/BarActions.d.ts +6 -15
- package/dist/types/appShell/BarCapsule.d.ts +6 -9
- package/dist/types/appShell/BarSearch.d.ts +6 -15
- package/dist/types/appShell/HeaderTools.d.ts +6 -16
- package/dist/types/appShell/MobileTabBar.d.ts +6 -13
- package/dist/types/appShell/SettingsMenu.d.ts +6 -10
- package/dist/types/appShell/SideMenu.d.ts +6 -20
- package/dist/types/appShell/SideMenuEntry.d.ts +6 -11
- package/dist/types/appShell/SubmenuActionsMenu.d.ts +6 -12
- package/dist/types/appShell/TabBarEditor.d.ts +6 -9
- package/dist/types/appShell/TopMenu.d.ts +6 -5
- package/dist/types/appShell/Wordmark.d.ts +6 -7
- package/dist/types/auth/PasswordChecklist.d.ts +6 -9
- package/dist/types/calendar/EventCalendar.d.ts +6 -23
- package/dist/types/calendar/EventDetails.d.ts +6 -10
- package/dist/types/date-pickers.d.ts +10 -1
- package/dist/types/datePickers/DateInput.d.ts +10 -23
- package/dist/types/datePickers/DateTimeInput.d.ts +30 -0
- package/dist/types/datePickers/FormDateTimeField.d.ts +7 -0
- package/dist/types/datePickers/FormMonthField.d.ts +7 -0
- package/dist/types/datePickers/FormTimeField.d.ts +7 -0
- package/dist/types/datePickers/MonthInput.d.ts +25 -0
- package/dist/types/datePickers/PickerFrame.d.ts +22 -0
- package/dist/types/datePickers/TimeInput.d.ts +24 -0
- package/dist/types/datePickers/dateTimeRules.d.ts +31 -0
- package/dist/types/datePickers/pickerValues.d.ts +114 -0
- package/dist/types/datePickers/useCurrentMinute.d.ts +5 -0
- package/dist/types/datePickers/usePickerField.d.ts +28 -0
- package/dist/types/dictionaries/dictionaries.d.ts +6 -3
- package/dist/types/downloads/DownloadManager.d.ts +6 -6
- package/dist/types/feedback/ConfirmDialog.d.ts +6 -18
- package/dist/types/feedback/ModalWaiting.d.ts +6 -9
- package/dist/types/feedback/NewBuildNotice.d.ts +6 -10
- package/dist/types/filepond/FileDropzone.d.ts +6 -29
- package/dist/types/forms/FormAttachmentsField.d.ts +7 -0
- package/dist/types/forms/FormCheckboxGroupField.d.ts +7 -0
- package/dist/types/forms/FormFileField.d.ts +7 -0
- package/dist/types/forms/FormFileUploadField.d.ts +7 -0
- package/dist/types/forms/FormImageField.d.ts +7 -0
- package/dist/types/forms/FormMaskedField.d.ts +7 -0
- package/dist/types/forms/FormProblemAlert.d.ts +6 -5
- package/dist/types/forms/FormRepeatingFields.d.ts +25 -0
- package/dist/types/forms/FormTransferListField.d.ts +7 -0
- package/dist/types/forms/SubmitButton.d.ts +6 -6
- package/dist/types/forms/auth/SignInForm.d.ts +6 -11
- package/dist/types/forms/fieldRules.d.ts +44 -0
- package/dist/types/forms/index.d.ts +11 -1
- package/dist/types/forms/listRules.d.ts +48 -0
- package/dist/types/forms/security/SecondStepForm.d.ts +6 -14
- package/dist/types/forms/security/TwoStepVerificationCard.d.ts +6 -21
- package/dist/types/forms/serverProblemFields.d.ts +13 -0
- package/dist/types/forms/useValidationText.d.ts +12 -0
- package/dist/types/forms/validation.d.ts +117 -174
- package/dist/types/forms/validationMessages.d.ts +54 -6
- package/dist/types/forms.d.ts +1 -1
- package/dist/types/hookForm/FormAttachmentsField.d.ts +8 -0
- package/dist/types/hookForm/FormCheckboxGroupField.d.ts +8 -0
- package/dist/types/hookForm/FormFileField.d.ts +8 -0
- package/dist/types/hookForm/FormFileUploadField.d.ts +8 -0
- package/dist/types/hookForm/FormImageField.d.ts +8 -0
- package/dist/types/hookForm/FormMaskedField.d.ts +9 -0
- package/dist/types/hookForm/FormProblemAlert.d.ts +6 -5
- package/dist/types/hookForm/FormRepeatingFields.d.ts +27 -0
- package/dist/types/hookForm/FormTransferListField.d.ts +8 -0
- package/dist/types/hookForm/SubmitButton.d.ts +6 -13
- package/dist/types/inbox/InboxLayout.d.ts +6 -17
- package/dist/types/inbox/MessageList.d.ts +6 -18
- package/dist/types/inbox/MessageView.d.ts +6 -14
- package/dist/types/index.d.ts +33 -4
- package/dist/types/inputs/CatalogInput.d.ts +10 -21
- package/dist/types/inputs/CheckboxGroupInput.d.ts +28 -0
- package/dist/types/inputs/ColorInput.d.ts +7 -16
- package/dist/types/inputs/FieldFrame.d.ts +6 -10
- package/dist/types/inputs/MaskedInput.d.ts +38 -0
- package/dist/types/inputs/NumberInput.d.ts +7 -20
- package/dist/types/inputs/RepeatingFields.d.ts +31 -0
- package/dist/types/inputs/SelectInput.d.ts +10 -18
- package/dist/types/inputs/TextInput.d.ts +3 -0
- package/dist/types/inputs/TransferListInput.d.ts +30 -0
- package/dist/types/inputs/WizardLayout.d.ts +6 -19
- package/dist/types/inputs/inputMasks.d.ts +52 -0
- package/dist/types/inputs/selectAllState.d.ts +11 -0
- package/dist/types/inputs/useRowKeys.d.ts +11 -0
- package/dist/types/kanban/KanbanBoard.d.ts +6 -25
- package/dist/types/legal/CookieNotice.d.ts +20 -0
- package/dist/types/legal/TermsAcceptanceDialog.d.ts +20 -0
- package/dist/types/legal/consentStorage.d.ts +16 -0
- package/dist/types/legal/useCookieConsent.d.ts +13 -0
- package/dist/types/locales/en.d.ts +256 -0
- package/dist/types/locales/es.d.ts +256 -0
- package/dist/types/maps/MapView.d.ts +6 -17
- package/dist/types/mexico/CfdiSummary.d.ts +12 -0
- package/dist/types/mexico/EfirmaFields.d.ts +28 -0
- package/dist/types/mexico/certificateReader.d.ts +37 -0
- package/dist/types/mexico/cfdiReader.d.ts +95 -0
- package/dist/types/mexico/derReader.d.ts +54 -0
- package/dist/types/mexico/efirmaKey.d.ts +26 -0
- package/dist/types/mexico/mexicoIdentifiers.d.ts +68 -0
- package/dist/types/mexico/mexicoRules.d.ts +45 -0
- package/dist/types/mexico.d.ts +11 -0
- package/dist/types/pwa/InstallAppSetting.d.ts +6 -6
- package/dist/types/pwa/InstallInstructionsDialog.d.ts +6 -9
- package/dist/types/pwa/InstallPromptBanner.d.ts +6 -11
- package/dist/types/react-hook-form.d.ts +11 -1
- package/dist/types/rich-text.d.ts +5 -0
- package/dist/types/richText/FormRichTextField.d.ts +7 -0
- package/dist/types/richText/RichTextEditor.d.ts +27 -0
- package/dist/types/richText/RichTextLinkPopover.d.ts +17 -0
- package/dist/types/richText/RichTextToolbar.d.ts +15 -0
- package/dist/types/richText/RichTextView.d.ts +10 -0
- package/dist/types/richText/richTextContentSx.d.ts +7 -0
- package/dist/types/richText/richTextExtensions.d.ts +15 -0
- package/dist/types/richText/richTextRules.d.ts +41 -0
- package/dist/types/security/ActivityLog.d.ts +6 -9
- package/dist/types/security/RecoveryCodesDialog.d.ts +6 -11
- package/dist/types/security/SessionsCard.d.ts +6 -11
- package/dist/types/table.d.ts +3 -1
- package/dist/types/theme/themePieces.d.ts +55 -3
- package/dist/types/toolkit/ToolkitProvider.d.ts +13 -1
- package/dist/types/toolkit/browserNavigation.d.ts +7 -3
- package/dist/types/toolkit/combineTexts.d.ts +6 -0
- package/dist/types/toolkit/hashNavigation.d.ts +4 -2
- package/dist/types/toolkit/navigationPaths.d.ts +35 -0
- package/dist/types/toolkit/pathIndex.d.ts +27 -0
- package/dist/types/toolkit/toolkitSettings.d.ts +7 -4
- package/dist/types/ui/actions/ActionsMenu.d.ts +24 -11
- package/dist/types/ui/actions/CopyButton.d.ts +8 -11
- package/dist/types/ui/actions/DownloadMenu.d.ts +6 -29
- package/dist/types/ui/actions/SecretField.d.ts +6 -11
- package/dist/types/ui/actions/SelectionActions.d.ts +6 -13
- package/dist/types/ui/actions/tableRowText.d.ts +6 -0
- package/dist/types/ui/cards/RecordCard.d.ts +40 -0
- package/dist/types/ui/cards/RecordCardSkeleton.d.ts +12 -0
- package/dist/types/ui/countdown/Countdown.d.ts +22 -0
- package/dist/types/ui/countdown/countdownParts.d.ts +39 -0
- package/dist/types/ui/countdown/useCountdown.d.ts +14 -0
- package/dist/types/ui/documents/PdfViewerDialog.d.ts +14 -0
- package/dist/types/ui/filters/DateRangeFilter.d.ts +6 -10
- package/dist/types/ui/filters/FilterDrawer.d.ts +23 -0
- package/dist/types/ui/filters/PeriodRangeSelector.d.ts +6 -13
- package/dist/types/ui/filters/QuickFilters.d.ts +6 -12
- package/dist/types/ui/filters/filterDrawerFields.d.ts +139 -0
- package/dist/types/ui/help/HelpButton.d.ts +11 -0
- package/dist/types/ui/help/HelpCarouselDialog.d.ts +27 -0
- package/dist/types/ui/help/useHelpCarousel.d.ts +21 -0
- package/dist/types/ui/index.d.ts +10 -0
- package/dist/types/ui/labels/IconBadge.d.ts +34 -0
- package/dist/types/ui/labels/MarkedText.d.ts +10 -0
- package/dist/types/ui/labels/Tag.d.ts +6 -12
- package/dist/types/ui/labels/markedTextPieces.d.ts +22 -0
- package/dist/types/ui/layout/CollapsibleSection.d.ts +6 -12
- package/dist/types/ui/layout/ContentDialog.d.ts +6 -10
- package/dist/types/ui/layout/DefinitionList.d.ts +6 -9
- package/dist/types/ui/layout/DetailHeader.d.ts +6 -10
- package/dist/types/ui/layout/ErrorPage.d.ts +6 -17
- package/dist/types/ui/layout/FullPageLoader.d.ts +6 -6
- package/dist/types/ui/layout/GlassPanel.d.ts +6 -8
- package/dist/types/ui/layout/PageHeader.d.ts +6 -10
- package/dist/types/ui/layout/PageHeading.d.ts +6 -11
- package/dist/types/ui/layout/ProfileHeader.d.ts +6 -11
- package/dist/types/ui/layout/ScrollableRow.d.ts +6 -13
- package/dist/types/ui/layout/SectionCard.d.ts +6 -8
- package/dist/types/ui/metrics/BarList.d.ts +6 -12
- package/dist/types/ui/metrics/CalendarHeatmap.d.ts +6 -19
- package/dist/types/ui/metrics/ChartTooltip.d.ts +6 -6
- package/dist/types/ui/metrics/ColumnChart.d.ts +6 -25
- package/dist/types/ui/metrics/LineChart.d.ts +6 -20
- package/dist/types/ui/metrics/MetricCard.d.ts +6 -17
- package/dist/types/ui/metrics/TableToggle.d.ts +6 -6
- package/dist/types/ui/metrics/chartParts.d.ts +15 -30
- package/dist/types/ui/navigation/BackButton.d.ts +6 -9
- package/dist/types/ui/navigation/ColorSchemeToggle.d.ts +6 -9
- package/dist/types/ui/navigation/FontSizeToggle.d.ts +6 -8
- package/dist/types/ui/navigation/LanguageToggle.d.ts +6 -8
- package/dist/types/ui/navigation/PageBreadcrumbs.d.ts +6 -7
- package/dist/types/ui/navigation/RouteTabs.d.ts +39 -0
- package/dist/types/ui/navigation/routeTabMatching.d.ts +27 -0
- package/dist/types/ui/timeline/GroupedTimeline.d.ts +6 -23
- package/dist/types/upload/AttachmentsInput.d.ts +72 -0
- package/dist/types/upload/FileChip.d.ts +18 -0
- package/dist/types/upload/FileDropzone.d.ts +7 -19
- package/dist/types/upload/FileInput.d.ts +31 -0
- package/dist/types/upload/FileUploadInput.d.ts +56 -0
- package/dist/types/upload/ImageInput.d.ts +35 -0
- package/dist/types/upload/TemplateDownloadButton.d.ts +27 -0
- package/dist/types/upload/fileAppearance.d.ts +8 -0
- package/dist/types/upload/fileRules.d.ts +38 -0
- package/dist/types/upload/transferProgress.d.ts +18 -0
- package/dist/types/upload/uploadMachine.d.ts +6 -2
- package/dist/types/upload/uploadWithProgress.d.ts +6 -2
- package/dist/types/upload/useFilePicker.d.ts +39 -0
- package/dist/ui/actions/ActionsMenu.js +109 -17
- package/dist/ui/actions/ActionsMenu.js.map +1 -1
- package/dist/ui/actions/CopyButton.js +37 -12
- package/dist/ui/actions/CopyButton.js.map +1 -1
- package/dist/ui/actions/DownloadMenu.js +3 -2
- package/dist/ui/actions/DownloadMenu.js.map +1 -1
- package/dist/ui/actions/SecretField.js +8 -3
- package/dist/ui/actions/SecretField.js.map +1 -1
- package/dist/ui/actions/SelectionActions.js +3 -2
- package/dist/ui/actions/SelectionActions.js.map +1 -1
- package/dist/ui/actions/tableRowText.js +7 -0
- package/dist/ui/actions/tableRowText.js.map +1 -0
- package/dist/ui/cards/RecordCard.js +146 -0
- package/dist/ui/cards/RecordCard.js.map +1 -0
- package/dist/ui/cards/RecordCardSkeleton.js +38 -0
- package/dist/ui/cards/RecordCardSkeleton.js.map +1 -0
- package/dist/ui/countdown/Countdown.js +39 -0
- package/dist/ui/countdown/Countdown.js.map +1 -0
- package/dist/ui/countdown/countdownParts.js +34 -0
- package/dist/ui/countdown/countdownParts.js.map +1 -0
- package/dist/ui/countdown/useCountdown.js +35 -0
- package/dist/ui/countdown/useCountdown.js.map +1 -0
- package/dist/ui/documents/PdfViewerDialog.js +82 -0
- package/dist/ui/documents/PdfViewerDialog.js.map +1 -0
- package/dist/ui/filters/DateRangeFilter.js +3 -2
- package/dist/ui/filters/DateRangeFilter.js.map +1 -1
- package/dist/ui/filters/FilterDrawer.js +212 -0
- package/dist/ui/filters/FilterDrawer.js.map +1 -0
- package/dist/ui/filters/PeriodRangeSelector.js +3 -2
- package/dist/ui/filters/PeriodRangeSelector.js.map +1 -1
- package/dist/ui/filters/QuickFilters.js +3 -2
- package/dist/ui/filters/QuickFilters.js.map +1 -1
- package/dist/ui/filters/filterDrawerFields.js +119 -0
- package/dist/ui/filters/filterDrawerFields.js.map +1 -0
- package/dist/ui/help/HelpButton.js +22 -0
- package/dist/ui/help/HelpButton.js.map +1 -0
- package/dist/ui/help/HelpCarouselDialog.js +155 -0
- package/dist/ui/help/HelpCarouselDialog.js.map +1 -0
- package/dist/ui/help/useHelpCarousel.js +25 -0
- package/dist/ui/help/useHelpCarousel.js.map +1 -0
- package/dist/ui/labels/IconBadge.js +82 -0
- package/dist/ui/labels/IconBadge.js.map +1 -0
- package/dist/ui/labels/MarkedText.js +31 -0
- package/dist/ui/labels/MarkedText.js.map +1 -0
- package/dist/ui/labels/Tag.js +3 -2
- package/dist/ui/labels/Tag.js.map +1 -1
- package/dist/ui/labels/markedTextPieces.js +64 -0
- package/dist/ui/labels/markedTextPieces.js.map +1 -0
- package/dist/ui/layout/CollapsibleSection.js +3 -2
- package/dist/ui/layout/CollapsibleSection.js.map +1 -1
- package/dist/ui/layout/ContentDialog.js +3 -2
- package/dist/ui/layout/ContentDialog.js.map +1 -1
- package/dist/ui/layout/DefinitionList.js +3 -2
- package/dist/ui/layout/DefinitionList.js.map +1 -1
- package/dist/ui/layout/DetailHeader.js +3 -2
- package/dist/ui/layout/DetailHeader.js.map +1 -1
- package/dist/ui/layout/ErrorPage.js +3 -2
- package/dist/ui/layout/ErrorPage.js.map +1 -1
- package/dist/ui/layout/FullPageLoader.js +3 -2
- package/dist/ui/layout/FullPageLoader.js.map +1 -1
- package/dist/ui/layout/GlassPanel.js +3 -2
- package/dist/ui/layout/GlassPanel.js.map +1 -1
- package/dist/ui/layout/PageHeader.js +3 -2
- package/dist/ui/layout/PageHeader.js.map +1 -1
- package/dist/ui/layout/PageHeading.js +3 -2
- package/dist/ui/layout/PageHeading.js.map +1 -1
- package/dist/ui/layout/ProfileHeader.js +3 -2
- package/dist/ui/layout/ProfileHeader.js.map +1 -1
- package/dist/ui/layout/ScrollableRow.js +3 -2
- package/dist/ui/layout/ScrollableRow.js.map +1 -1
- package/dist/ui/layout/SectionCard.js +3 -2
- package/dist/ui/layout/SectionCard.js.map +1 -1
- package/dist/ui/metrics/BarList.js +3 -2
- package/dist/ui/metrics/BarList.js.map +1 -1
- package/dist/ui/metrics/CalendarHeatmap.js +3 -2
- package/dist/ui/metrics/CalendarHeatmap.js.map +1 -1
- package/dist/ui/metrics/ChartTooltip.js +3 -2
- package/dist/ui/metrics/ChartTooltip.js.map +1 -1
- package/dist/ui/metrics/ColumnChart.js +3 -2
- package/dist/ui/metrics/ColumnChart.js.map +1 -1
- package/dist/ui/metrics/LineChart.js +3 -2
- package/dist/ui/metrics/LineChart.js.map +1 -1
- package/dist/ui/metrics/MetricCard.js +3 -2
- package/dist/ui/metrics/MetricCard.js.map +1 -1
- package/dist/ui/metrics/TableToggle.js +3 -2
- package/dist/ui/metrics/TableToggle.js.map +1 -1
- package/dist/ui/metrics/chartParts.js +7 -4
- package/dist/ui/metrics/chartParts.js.map +1 -1
- package/dist/ui/navigation/BackButton.js +7 -2
- package/dist/ui/navigation/BackButton.js.map +1 -1
- package/dist/ui/navigation/ColorSchemeToggle.js +3 -2
- package/dist/ui/navigation/ColorSchemeToggle.js.map +1 -1
- package/dist/ui/navigation/FontSizeToggle.js +3 -2
- package/dist/ui/navigation/FontSizeToggle.js.map +1 -1
- package/dist/ui/navigation/LanguageToggle.js +3 -2
- package/dist/ui/navigation/LanguageToggle.js.map +1 -1
- package/dist/ui/navigation/PageBreadcrumbs.js +3 -2
- package/dist/ui/navigation/PageBreadcrumbs.js.map +1 -1
- package/dist/ui/navigation/RouteTabs.js +79 -0
- package/dist/ui/navigation/RouteTabs.js.map +1 -0
- package/dist/ui/navigation/routeTabMatching.js +23 -0
- package/dist/ui/navigation/routeTabMatching.js.map +1 -0
- package/dist/ui/timeline/GroupedTimeline.js +3 -2
- package/dist/ui/timeline/GroupedTimeline.js.map +1 -1
- package/dist/upload/AttachmentsInput.js +130 -0
- package/dist/upload/AttachmentsInput.js.map +1 -0
- package/dist/upload/FileChip.js +28 -0
- package/dist/upload/FileChip.js.map +1 -0
- package/dist/upload/FileDropzone.js +23 -87
- package/dist/upload/FileDropzone.js.map +1 -1
- package/dist/upload/FileInput.js +115 -0
- package/dist/upload/FileInput.js.map +1 -0
- package/dist/upload/FileUploadInput.js +288 -0
- package/dist/upload/FileUploadInput.js.map +1 -0
- package/dist/upload/ImageInput.js +128 -0
- package/dist/upload/ImageInput.js.map +1 -0
- package/dist/upload/TemplateDownloadButton.js +68 -0
- package/dist/upload/TemplateDownloadButton.js.map +1 -0
- package/dist/upload/fileAppearance.js +21 -0
- package/dist/upload/fileAppearance.js.map +1 -0
- package/dist/upload/fileRules.js +27 -1
- package/dist/upload/fileRules.js.map +1 -1
- package/dist/upload/transferProgress.js +23 -0
- package/dist/upload/transferProgress.js.map +1 -0
- package/dist/upload/uploadMachine.js +8 -8
- package/dist/upload/uploadMachine.js.map +1 -1
- package/dist/upload/uploadWithProgress.js +1 -1
- package/dist/upload/uploadWithProgress.js.map +1 -1
- package/dist/upload/useFilePicker.js +101 -0
- package/dist/upload/useFilePicker.js.map +1 -0
- package/package.json +44 -1
- package/cli/templates/project/src/app/combineTexts.js.tpl +0 -31
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServerTableFilterDrawer.js","sources":["../../src/DataTable/ServerTableFilterDrawer.jsx"],"sourcesContent":["// El botón «Filtros» de ServerTable con su cajón de búsqueda (FilterDrawer): se pone en toolbarExtra y lee y cambia los\n// filtros de SU tabla (los de la dirección, los mismos de los chips). El botón dice cuántos filtros del cajón hay puestos.\n//\n// const FILTER_FIELDS = [{name: 'total', label: 'Total', kind: FILTER_FIELD_KIND.comparison, prefix: '$'}, …];\n// <ServerTable … filterDefaults={{...MIS_DEFAULTS, ...filterDrawerDefaultsOf(FILTER_FIELDS)}}\n// filterKinds={{...MIS_KINDS, ...filterDrawerKindsOf(FILTER_FIELDS)}}\n// chipConfig={buildChipConfig(filterDrawerChipsOf(FILTER_FIELDS, {t, formatDate}))}\n// toolbarExtra={<ServerTableFilterDrawer fields={FILTER_FIELDS} />} />\n//\n// filterDefaults: la tabla solo guarda en la dirección lo que declara ahí. filterKinds: las listas se leen como lista. Los\n// chips dicen cada filtro en palabras y cada uno se quita con su ×.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaServerTableFilterDrawer con defaultProps, styleOverrides de\n// sus partes (button) y slots/slotProps para cambiarlas.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport Button from '@mui/material/Button';\nimport TuneRoundedIcon from '@mui/icons-material/TuneRounded';\n\nimport {useTableFilter} from '@/DataTable/filterContext.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport FilterDrawer from '@/ui/filters/FilterDrawer.jsx';\nimport {activeDrawerFilterCountOf} from '@/ui/filters/filterDrawerFields.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaServerTableFilterDrawer)\nconst THEME_NAME = 'CalcitaServerTableFilterDrawer';\nconst ServerTableFilterDrawerButton = piecePart(THEME_NAME, 'Button', Button);\n\n/**\n * @param {object} props\n * @param {object[]} props.fields los campos del cajón (filterDrawerFields.js)\n * @param {'left'|'right'} [props.anchor] de qué lado sale; por omisión la derecha\n * @param {number} [props.width] su ancho en escritorio\n * @param {string} [props.title] ya traducido; por omisión «Filtros»\n * @param {string} [props.buttonLabel] ya traducido; por omisión «Filtros» (con los puestos, «Filtros (3)»)\n * @param {(values: Record<string, unknown>) => void} [props.onApply] aviso de lo que se buscó (la tabla ya se filtró)\n * @param {import('react').ReactNode} [props.children] algo más abajo de los campos del cajón\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction ServerTableFilterDrawerContent(props) {\n const {fields, anchor, width, title, buttonLabel, onApply, children, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const {filters, setFilters} = useTableFilter();\n const [isOpen, setIsOpen] = useState(false);\n const activeCount = activeDrawerFilterCountOf(fields, filters);\n\n return (\n <>\n <ServerTableFilterDrawerButton size=\"small\" variant={activeCount > 0 ? 'contained' : 'outlined'} startIcon={<TuneRoundedIcon />}\n aria-haspopup=\"dialog\" onClick={() => setIsOpen(true)}>\n {activeCount > 0 ? t('filterDrawer.openWithCount', {count: activeCount}) : (buttonLabel ?? t('filterDrawer.open'))}\n </ServerTableFilterDrawerButton>\n <FilterDrawer open={isOpen} onClose={() => setIsOpen(false)} fields={fields} values={filters} anchor={anchor} width={width} title={title}\n texts={texts}\n onApply={(values) => {\n setFilters(values);\n onApply?.(values);\n }}>\n {children}\n </FilterDrawer>\n </>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst ServerTableFilterDrawer = withPieceSlots(ServerTableFilterDrawerContent, THEME_NAME);\nexport default ServerTableFilterDrawer;\n"],"names":[],"mappings":";;;;;;;;;;;AA4BA,MAAM,aAAa;AACnB,MAAM,gCAAgC,UAAU,YAAY,UAAU,MAAM;AAa5E,SAAS,+BAA+B,OAAO;AAC3C,QAAM,EAAC,QAAQ,QAAQ,OAAO,OAAO,aAAa,SAAS,UAAU,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC9H,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,EAAC,SAAS,WAAA,IAAc,eAAA;AAC9B,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,cAAc,0BAA0B,QAAQ,OAAO;AAE7D,SACI,qBAAA,UAAA,EACI,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QAA8B,MAAK;AAAA,QAAQ,SAAS,cAAc,IAAI,cAAc;AAAA,QAAY,+BAAY,iBAAA,EAAgB;AAAA,QACrH,iBAAc;AAAA,QAAS,SAAS,MAAM,UAAU,IAAI;AAAA,QACvD,UAAA,cAAc,IAAI,EAAE,8BAA8B,EAAC,OAAO,YAAA,CAAY,IAAK,eAAe,EAAE,mBAAmB;AAAA,MAAA;AAAA,IAAA;AAAA,IAEpH;AAAA,MAAC;AAAA,MAAA;AAAA,QAAa,MAAM;AAAA,QAAQ,SAAS,MAAM,UAAU,KAAK;AAAA,QAAG;AAAA,QAAgB,QAAQ;AAAA,QAAS;AAAA,QAAgB;AAAA,QAAc;AAAA,QAC9G;AAAA,QACA,SAAS,CAAC,WAAW;AACjB,qBAAW,MAAM;AACjB,oBAAU,MAAM;AAAA,QACpB;AAAA,QACT;AAAA,MAAA;AAAA,IAAA;AAAA,EACL,GACJ;AAER;AAGA,MAAM,0BAA0B,eAAe,gCAAgC,UAAU;"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { isValidElement } from "react";
|
|
4
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
5
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
6
|
+
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
7
|
+
const THEME_NAME = "CalcitaStackedCell";
|
|
8
|
+
const StackedRoot = piecePart(THEME_NAME, "Root", "div");
|
|
9
|
+
const StackedLine = piecePart(THEME_NAME, "Line", "div");
|
|
10
|
+
const StackedLabel = piecePart(THEME_NAME, "Label", "span");
|
|
11
|
+
const StackedValueRow = piecePart(THEME_NAME, "ValueRow", "span");
|
|
12
|
+
const StackedPrimary = piecePart(THEME_NAME, "Primary", "span");
|
|
13
|
+
const StackedSecondary = piecePart(THEME_NAME, "Secondary", "span");
|
|
14
|
+
const StackedNote = piecePart(THEME_NAME, "Note", "span");
|
|
15
|
+
const ONE_LINE_STYLES = Object.freeze({ display: "block", minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", lineHeight: 1.4 });
|
|
16
|
+
const LABEL_STYLES = Object.freeze({ ...ONE_LINE_STYLES, color: "text.secondary", fontSize: "0.6875rem", lineHeight: 1.3 });
|
|
17
|
+
const VALUE_ROW_STYLES = Object.freeze({ display: "flex", alignItems: "baseline", gap: 0.75, minWidth: 0 });
|
|
18
|
+
const NOTE_STYLES = Object.freeze({ flexShrink: 0, fontStyle: "italic", color: "text.secondary", fontSize: "0.75rem" });
|
|
19
|
+
function isEmpty(value) {
|
|
20
|
+
return value === void 0 || value === null || value === "" || value === false;
|
|
21
|
+
}
|
|
22
|
+
function entryOf(entry) {
|
|
23
|
+
const hasShape = typeof entry === "object" && entry !== null && !isValidElement(entry) && !Array.isArray(entry) && "value" in entry;
|
|
24
|
+
return hasShape ? { label: entry.label, value: entry.value, note: entry.note, hasLabel: !isEmpty(entry.label) } : { label: void 0, value: entry, note: void 0, hasLabel: false };
|
|
25
|
+
}
|
|
26
|
+
function visibleEntriesOf(entries) {
|
|
27
|
+
return entries.map(entryOf).filter((entry, index) => index === 0 || entry.hasLabel || !isEmpty(entry.value));
|
|
28
|
+
}
|
|
29
|
+
function StackedCellContent(props) {
|
|
30
|
+
const { entries, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
31
|
+
warnUnknownProps("StackedCell", unknownProps);
|
|
32
|
+
const { t } = useToolkitTranslation("table");
|
|
33
|
+
return /* @__PURE__ */ jsx(StackedRoot, { ownSx: { display: "flex", flexDirection: "column", justifyContent: "center", gap: 0.25, minWidth: 0, py: 0.75 }, children: visibleEntriesOf(entries ?? []).map((entry, index) => {
|
|
34
|
+
const isPrimary = index === 0;
|
|
35
|
+
const Value = isPrimary ? StackedPrimary : StackedSecondary;
|
|
36
|
+
const value = isEmpty(entry.value) ? t("cells.empty") : entry.value;
|
|
37
|
+
return (
|
|
38
|
+
// la posición es la llave: los datos de una celda no se reordenan
|
|
39
|
+
/* @__PURE__ */ jsxs(StackedLine, { ownSx: { minWidth: 0 }, children: [
|
|
40
|
+
entry.hasLabel && /* @__PURE__ */ jsx(StackedLabel, { ownSx: LABEL_STYLES, children: entry.label }),
|
|
41
|
+
/* @__PURE__ */ jsxs(StackedValueRow, { ownSx: VALUE_ROW_STYLES, children: [
|
|
42
|
+
/* @__PURE__ */ jsx(
|
|
43
|
+
Value,
|
|
44
|
+
{
|
|
45
|
+
ownSx: isPrimary ? { ...ONE_LINE_STYLES, fontWeight: 600 } : { ...ONE_LINE_STYLES, color: "text.secondary", fontSize: "0.8125rem" },
|
|
46
|
+
title: typeof value === "string" ? value : void 0,
|
|
47
|
+
children: value
|
|
48
|
+
}
|
|
49
|
+
),
|
|
50
|
+
!isEmpty(entry.note) && /* @__PURE__ */ jsx(StackedNote, { ownSx: NOTE_STYLES, children: entry.note })
|
|
51
|
+
] })
|
|
52
|
+
] }, index)
|
|
53
|
+
);
|
|
54
|
+
}) });
|
|
55
|
+
}
|
|
56
|
+
const StackedCell = withPieceSlots(StackedCellContent, THEME_NAME);
|
|
57
|
+
export {
|
|
58
|
+
StackedCell as default
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=StackedCell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StackedCell.js","sources":["../../src/DataTable/StackedCell.jsx"],"sourcesContent":["// La celda con varios datos apilados (la de stackedColumn): el principal arriba en negritas y los demás debajo en gris,\n// los que hagan falta. Lo que se lee de corrido va junto en una columna (la empresa, su RFC y su régimen; el contacto, su\n// correo y su teléfono) y la tabla no pide deslizar de lado con ocho columnas sueltas.\n//\n// Cada dato va solo o con su etiqueta arriba:\n// - solo, cuando el encabezado de la columna ya dice qué son («Empresa»: la razón social y el RFC se reconocen);\n// - con etiqueta ({label, value}), cuando el encabezado nombra al grupo y no a cada dato («Fechas»: alta y último\n// cambio), como en una tarjeta. La etiqueta va arriba y no al lado: así el dato se queda con todo el ancho.\n//\n// Un dato vacío (null, undefined, '' o false) no se pinta, salvo el principal o uno con etiqueta: esos enseñan «—» (el\n// texto table.cells.empty, que un proyecto cambia), para que se vea qué falta en vez de que el renglón se recorra.\n//\n// Pieza genérica: function (regla de la casa).\nimport {isValidElement} from 'react';\n\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// las partes con su lugar en el tema (theme.components.CalcitaStackedCell)\nconst THEME_NAME = 'CalcitaStackedCell';\nconst StackedRoot = piecePart(THEME_NAME, 'Root', 'div');\nconst StackedLine = piecePart(THEME_NAME, 'Line', 'div');\nconst StackedLabel = piecePart(THEME_NAME, 'Label', 'span');\nconst StackedValueRow = piecePart(THEME_NAME, 'ValueRow', 'span');\nconst StackedPrimary = piecePart(THEME_NAME, 'Primary', 'span');\nconst StackedSecondary = piecePart(THEME_NAME, 'Secondary', 'span');\nconst StackedNote = piecePart(THEME_NAME, 'Note', 'span');\n\n// cada dato en su línea y con «…» si no cabe; la altura de línea propia (la de la celda no sirve: ver ServerTable)\nconst ONE_LINE_STYLES = Object.freeze({display: 'block', minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', lineHeight: 1.4});\nconst LABEL_STYLES = Object.freeze({...ONE_LINE_STYLES, color: 'text.secondary', fontSize: '0.6875rem', lineHeight: 1.3});\nconst VALUE_ROW_STYLES = Object.freeze({display: 'flex', alignItems: 'baseline', gap: 0.75, minWidth: 0});\nconst NOTE_STYLES = Object.freeze({flexShrink: 0, fontStyle: 'italic', color: 'text.secondary', fontSize: '0.75rem'});\n\n/**\n * Un dato de la celda: el valor solo, o con su etiqueta arriba y una nota corta junto al valor («nuevo», «sombra»).\n *\n * @typedef {import('react').ReactNode | {label?: import('react').ReactNode, value: import('react').ReactNode, note?: import('react').ReactNode}} StackedEntry\n */\n\nfunction isEmpty(value) {\n return value === undefined || value === null || value === '' || value === false;\n}\n\n/** El dato con su forma completa: {label, value, note}; el que llegó solo, sin etiqueta. */\nfunction entryOf(entry) {\n const hasShape = typeof entry === 'object' && entry !== null && !isValidElement(entry) && !Array.isArray(entry) && 'value' in entry;\n return hasShape ? {label: entry.label, value: entry.value, note: entry.note, hasLabel: !isEmpty(entry.label)}\n : {label: undefined, value: entry, note: undefined, hasLabel: false};\n}\n\n/**\n * Los datos que se pintan: el principal (el primero) siempre; de los demás, los que traen valor o etiqueta.\n *\n * @param {StackedEntry[]} entries\n */\nfunction visibleEntriesOf(entries) {\n return entries.map(entryOf).filter((entry, index) => index === 0 || entry.hasLabel || !isEmpty(entry.value));\n}\n\n/**\n * La celda con varios datos, uno debajo del otro (lo que pinta stackedColumn; sirve también dentro de un renderCell propio).\n *\n * <StackedCell entries={[row.business_name, row.rfc, {label: 'Régimen', value: row.regime, note: 'nuevo'}]} />\n *\n * @param {object} props\n * @param {StackedEntry[]} props.entries los datos en orden: el primero es el principal (negritas)\n * @returns {import('react').JSX.Element}\n */\nfunction StackedCellContent(props) {\n const {entries, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps('StackedCell', unknownProps);\n const {t} = useToolkitTranslation('table');\n\n return (\n <StackedRoot ownSx={{display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: 0.25, minWidth: 0, py: 0.75}}>\n {visibleEntriesOf(entries ?? []).map((entry, index) => {\n const isPrimary = index === 0;\n const Value = isPrimary ? StackedPrimary : StackedSecondary;\n const value = isEmpty(entry.value) ? t('cells.empty') : entry.value;\n return (\n // la posición es la llave: los datos de una celda no se reordenan\n <StackedLine key={index} ownSx={{minWidth: 0}}>\n {entry.hasLabel && <StackedLabel ownSx={LABEL_STYLES}>{entry.label}</StackedLabel>}\n <StackedValueRow ownSx={VALUE_ROW_STYLES}>\n <Value ownSx={isPrimary ? {...ONE_LINE_STYLES, fontWeight: 600} : {...ONE_LINE_STYLES, color: 'text.secondary', fontSize: '0.8125rem'}}\n // completo al pasar el cursor, por si la columna lo corta\n title={typeof value === 'string' ? value : undefined}>\n {value}\n </Value>\n {!isEmpty(entry.note) && <StackedNote ownSx={NOTE_STYLES}>{entry.note}</StackedNote>}\n </StackedValueRow>\n </StackedLine>\n );\n })}\n </StackedRoot>\n );\n}\n\nconst StackedCell = withPieceSlots(StackedCellContent, THEME_NAME);\nexport default StackedCell;\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
3
|
+
import LinearProgress from "@mui/material/LinearProgress";
|
|
4
|
+
import Pagination from "@mui/material/Pagination";
|
|
5
|
+
import Stack from "@mui/material/Stack";
|
|
6
|
+
import ToggleButton from "@mui/material/ToggleButton";
|
|
7
|
+
import ToggleButtonGroup from "@mui/material/ToggleButtonGroup";
|
|
8
|
+
import Tooltip from "@mui/material/Tooltip";
|
|
9
|
+
import TableRowsRoundedIcon from "@mui/icons-material/TableRowsRounded";
|
|
10
|
+
import ViewAgendaOutlinedIcon from "@mui/icons-material/ViewAgendaOutlined";
|
|
11
|
+
import EmptyState from "./EmptyState.js";
|
|
12
|
+
import { TABLE_VIEW } from "./useTableView.js";
|
|
13
|
+
import { piecePart, withPieceSlots } from "../theme/themePieces.js";
|
|
14
|
+
import RecordCardSkeleton from "../ui/cards/RecordCardSkeleton.js";
|
|
15
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
16
|
+
const THEME_NAME = "CalcitaServerTable";
|
|
17
|
+
const TableCards = piecePart(THEME_NAME, "Cards", "div");
|
|
18
|
+
const TableCardsPagination = piecePart(THEME_NAME, "CardsPagination", Stack);
|
|
19
|
+
const TableViewToggleGroup = piecePart(THEME_NAME, "ViewToggle", ToggleButtonGroup);
|
|
20
|
+
const MAX_SKELETON_CARDS = 3;
|
|
21
|
+
function TableViewToggleContent({ view, onChange }) {
|
|
22
|
+
const { t } = useToolkitTranslation("table");
|
|
23
|
+
return /* @__PURE__ */ jsxs(
|
|
24
|
+
TableViewToggleGroup,
|
|
25
|
+
{
|
|
26
|
+
size: "small",
|
|
27
|
+
exclusive: true,
|
|
28
|
+
value: view,
|
|
29
|
+
"aria-label": t("views.label"),
|
|
30
|
+
onChange: (event, nextView) => nextView && onChange(nextView),
|
|
31
|
+
ownSx: { flexShrink: 0, alignSelf: { xs: "flex-end", md: "center" } },
|
|
32
|
+
children: [
|
|
33
|
+
/* @__PURE__ */ jsx(ToggleButton, { value: TABLE_VIEW.table, "aria-label": t("views.table"), children: /* @__PURE__ */ jsx(Tooltip, { title: t("views.table"), children: /* @__PURE__ */ jsx(TableRowsRoundedIcon, { fontSize: "small" }) }) }),
|
|
34
|
+
/* @__PURE__ */ jsx(ToggleButton, { value: TABLE_VIEW.cards, "aria-label": t("views.cards"), children: /* @__PURE__ */ jsx(Tooltip, { title: t("views.cards"), children: /* @__PURE__ */ jsx(ViewAgendaOutlinedIcon, { fontSize: "small" }) }) })
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
function TableCardsViewContent({
|
|
40
|
+
rows,
|
|
41
|
+
renderCard,
|
|
42
|
+
rowIdOf,
|
|
43
|
+
isLoading,
|
|
44
|
+
page,
|
|
45
|
+
pageCount,
|
|
46
|
+
onPageChange,
|
|
47
|
+
hasActiveFilters,
|
|
48
|
+
emptyLabel,
|
|
49
|
+
onClearFilters,
|
|
50
|
+
skeleton,
|
|
51
|
+
ariaLabel
|
|
52
|
+
}) {
|
|
53
|
+
const { t } = useToolkitTranslation("table");
|
|
54
|
+
const isFirstLoad = isLoading && rows.length === 0;
|
|
55
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
56
|
+
isLoading && !isFirstLoad && /* @__PURE__ */ jsx(LinearProgress, { sx: { mb: 1, borderRadius: 1 } }),
|
|
57
|
+
/* @__PURE__ */ jsxs(
|
|
58
|
+
TableCards,
|
|
59
|
+
{
|
|
60
|
+
role: "list",
|
|
61
|
+
"aria-label": ariaLabel ?? t("cards.label"),
|
|
62
|
+
"aria-busy": isLoading,
|
|
63
|
+
ownSx: { display: "grid", gap: 1.5, minWidth: 0 },
|
|
64
|
+
children: [
|
|
65
|
+
isFirstLoad && Array.from({ length: MAX_SKELETON_CARDS }, (unused, index) => /* @__PURE__ */ jsx("div", { role: "listitem", children: skeleton ?? /* @__PURE__ */ jsx(RecordCardSkeleton, {}) }, index)),
|
|
66
|
+
rows.map((row, index) => /* @__PURE__ */ jsx("div", { role: "listitem", children: renderCard(row, { index }) }, rowIdOf(row)))
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
!isLoading && rows.length === 0 && /* @__PURE__ */ jsx(EmptyState, { filtered: hasActiveFilters, label: emptyLabel, onClearFilters }),
|
|
71
|
+
pageCount > 1 && /* @__PURE__ */ jsx(TableCardsPagination, { direction: "row", ownSx: { justifyContent: "center", mt: 2 }, children: /* @__PURE__ */ jsx(
|
|
72
|
+
Pagination,
|
|
73
|
+
{
|
|
74
|
+
count: pageCount,
|
|
75
|
+
page: page + 1,
|
|
76
|
+
onChange: (event, nextPage) => onPageChange(nextPage - 1),
|
|
77
|
+
getItemAriaLabel: (type, itemPage) => t(`cards.pagination.${type}`, { page: itemPage })
|
|
78
|
+
}
|
|
79
|
+
) })
|
|
80
|
+
] });
|
|
81
|
+
}
|
|
82
|
+
const TableCardsView = withPieceSlots(TableCardsViewContent, THEME_NAME, { sharedWithParent: true });
|
|
83
|
+
const TableViewToggle = withPieceSlots(TableViewToggleContent, THEME_NAME, { sharedWithParent: true });
|
|
84
|
+
export {
|
|
85
|
+
TableViewToggle,
|
|
86
|
+
TableCardsView as default
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=TableCardsView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableCardsView.js","sources":["../../src/DataTable/TableCardsView.jsx"],"sourcesContent":["// La otra vista de ServerTable: los mismos renglones (la misma búsqueda, filtros, orden y página) en tarjetas, una por\n// renglón, con lo que pinte la pantalla (renderCard; normalmente RecordCard). Mientras llega la primera página, esqueletos\n// con la forma de la tarjeta; al cambiar de página se quedan las de antes con una barra arriba (no brinca la pantalla).\n//\n// Se cambia desde el tema del proyecto, como la tabla: components.CalcitaServerTable con styleOverrides de sus partes\n// cards (la lista: una columna por omisión; con display grid se hacen columnas), cardsPagination y viewToggle.\n//\n// Genéricos del paquete: function (regla de la casa).\nimport LinearProgress from '@mui/material/LinearProgress';\nimport Pagination from '@mui/material/Pagination';\nimport Stack from '@mui/material/Stack';\nimport ToggleButton from '@mui/material/ToggleButton';\nimport ToggleButtonGroup from '@mui/material/ToggleButtonGroup';\nimport Tooltip from '@mui/material/Tooltip';\nimport TableRowsRoundedIcon from '@mui/icons-material/TableRowsRounded';\nimport ViewAgendaOutlinedIcon from '@mui/icons-material/ViewAgendaOutlined';\n\nimport EmptyState from '@/DataTable/EmptyState.jsx';\nimport {TABLE_VIEW} from '@/DataTable/useTableView.js';\nimport {piecePart, withPieceSlots} from '@/theme/themePieces.js';\nimport RecordCardSkeleton from '@/ui/cards/RecordCardSkeleton.jsx';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\n\n// el nombre de la pieza en el tema: el de la tabla (theme.components.CalcitaServerTable)\nconst THEME_NAME = 'CalcitaServerTable';\nconst TableCards = piecePart(THEME_NAME, 'Cards', 'div');\nconst TableCardsPagination = piecePart(THEME_NAME, 'CardsPagination', Stack);\nconst TableViewToggleGroup = piecePart(THEME_NAME, 'ViewToggle', ToggleButtonGroup);\n\n// cuántos esqueletos mientras llega la primera página: los de una pantalla, no los de toda la página\nconst MAX_SKELETON_CARDS = 3;\n\n/**\n * El botón de dos posiciones para ver la lista en tabla o en tarjetas.\n *\n * @param {{view: 'table'|'cards', onChange: (view: 'table'|'cards') => void}} props\n */\nfunction TableViewToggleContent({view, onChange}) {\n const {t} = useToolkitTranslation('table');\n return (\n <TableViewToggleGroup size=\"small\" exclusive value={view} aria-label={t('views.label')}\n onChange={(event, nextView) => nextView && onChange(nextView)} ownSx={{flexShrink: 0, alignSelf: {xs: 'flex-end', md: 'center'}}}>\n <ToggleButton value={TABLE_VIEW.table} aria-label={t('views.table')}>\n <Tooltip title={t('views.table')}><TableRowsRoundedIcon fontSize=\"small\" /></Tooltip>\n </ToggleButton>\n <ToggleButton value={TABLE_VIEW.cards} aria-label={t('views.cards')}>\n <Tooltip title={t('views.cards')}><ViewAgendaOutlinedIcon fontSize=\"small\" /></Tooltip>\n </ToggleButton>\n </TableViewToggleGroup>\n );\n}\n\n/**\n * @param {object} props\n * @param {any[]} props.rows los renglones de la página\n * @param {(row: any, helpers: {index: number}) => import('react').ReactNode} props.renderCard\n * @param {(row: any) => string|number} props.rowIdOf\n * @param {boolean} props.isLoading\n * @param {number} props.page desde 0\n * @param {number} props.pageCount\n * @param {(page: number) => void} props.onPageChange recibe la página desde 0\n * @param {boolean} props.hasActiveFilters\n * @param {string} [props.emptyLabel]\n * @param {() => void} props.onClearFilters\n * @param {import('react').ReactNode} [props.skeleton] el esqueleto de una tarjeta (por omisión RecordCardSkeleton)\n * @param {string} [props.ariaLabel] el nombre de la lista para el lector de pantalla\n */\nfunction TableCardsViewContent({\n rows, renderCard, rowIdOf, isLoading, page, pageCount, onPageChange, hasActiveFilters, emptyLabel, onClearFilters, skeleton, ariaLabel,\n}) {\n const {t} = useToolkitTranslation('table');\n const isFirstLoad = isLoading && rows.length === 0;\n\n return (\n <>\n {/* al cambiar de página se quedan las tarjetas de antes con una barra arriba: no brinca la pantalla */}\n {isLoading && !isFirstLoad && <LinearProgress sx={{mb: 1, borderRadius: 1}} />}\n <TableCards role=\"list\" aria-label={ariaLabel ?? t('cards.label')} aria-busy={isLoading}\n ownSx={{display: 'grid', gap: 1.5, minWidth: 0}}>\n {isFirstLoad && Array.from({length: MAX_SKELETON_CARDS}, (unused, index) => (\n <div key={index} role=\"listitem\">{skeleton ?? <RecordCardSkeleton />}</div>\n ))}\n {rows.map((row, index) => <div key={rowIdOf(row)} role=\"listitem\">{renderCard(row, {index})}</div>)}\n </TableCards>\n {!isLoading && rows.length === 0 && (\n <EmptyState filtered={hasActiveFilters} label={emptyLabel} onClearFilters={onClearFilters} />\n )}\n {pageCount > 1 && (\n <TableCardsPagination direction=\"row\" ownSx={{justifyContent: 'center', mt: 2}}>\n <Pagination count={pageCount} page={page + 1} onChange={(event, nextPage) => onPageChange(nextPage - 1)}\n getItemAriaLabel={(type, itemPage) => t(`cards.pagination.${type}`, {page: itemPage})} />\n </TableCardsPagination>\n )}\n </>\n );\n}\n\n// dentro de ServerTable (mismo nombre en el tema) usan los slots de la tabla; solas, los suyos\nconst TableCardsView = withPieceSlots(TableCardsViewContent, THEME_NAME, {sharedWithParent: true});\nexport const TableViewToggle = withPieceSlots(TableViewToggleContent, THEME_NAME, {sharedWithParent: true});\nexport default TableCardsView;\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const STATUS_FONT_SIZE_PIXELS = 13;
|
|
2
|
+
const STATUS_FONT_WEIGHT = 500;
|
|
3
|
+
const AVERAGE_CHARACTER_WIDTH_PIXELS = 7.4;
|
|
4
|
+
const STATUS_EXTRA_PIXELS = Object.freeze({ dot: 40, chip: 52 });
|
|
5
|
+
const HEADER_ICONS_PIXELS = 56;
|
|
6
|
+
let measuringContext = null;
|
|
7
|
+
function textWidthOf(text, { fontSize = STATUS_FONT_SIZE_PIXELS, fontWeight = STATUS_FONT_WEIGHT } = {}) {
|
|
8
|
+
const value = String(text ?? "");
|
|
9
|
+
if (typeof document === "undefined") {
|
|
10
|
+
return value.length * AVERAGE_CHARACTER_WIDTH_PIXELS * (fontSize / STATUS_FONT_SIZE_PIXELS);
|
|
11
|
+
}
|
|
12
|
+
measuringContext ??= document.createElement("canvas").getContext("2d");
|
|
13
|
+
if (!measuringContext) {
|
|
14
|
+
return value.length * AVERAGE_CHARACTER_WIDTH_PIXELS * (fontSize / STATUS_FONT_SIZE_PIXELS);
|
|
15
|
+
}
|
|
16
|
+
const fontFamily = getComputedStyle(document.body).fontFamily || "system-ui, sans-serif";
|
|
17
|
+
measuringContext.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
18
|
+
return measuringContext.measureText(value).width;
|
|
19
|
+
}
|
|
20
|
+
function statusColumnWidthOf([header, ...labels], { variant = "dot" } = {}) {
|
|
21
|
+
const extra = STATUS_EXTRA_PIXELS[variant] ?? STATUS_EXTRA_PIXELS.dot;
|
|
22
|
+
const widest = Math.max(0, ...labels.map((label) => textWidthOf(label) + extra));
|
|
23
|
+
const headerWidth = textWidthOf(header, { fontWeight: 600 }) + HEADER_ICONS_PIXELS;
|
|
24
|
+
return Math.ceil(Math.max(widest, headerWidth));
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
statusColumnWidthOf,
|
|
28
|
+
textWidthOf
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=columnWidths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columnWidths.js","sources":["../../src/DataTable/columnWidths.js"],"sourcesContent":["// Cuánto mide una columna para que su texto más largo no se corte: se mide el texto con la letra de la página (en el\n// navegador, con un canvas) y se le suma lo que lleva alrededor. Sin navegador (al pintar en el servidor) se calcula por\n// letras: un poco de más es mejor que «Registrado pendiente de docum…».\n//\n// Funciones puras, no renderizan: function (regla de la casa). Pruebas en columnWidths.test.js.\n\n// la letra del estatus (StatusChip): 13 px de grosor medio\nconst STATUS_FONT_SIZE_PIXELS = 13;\nconst STATUS_FONT_WEIGHT = 500;\n// el ancho promedio de una letra de 13 px cuando no hay con qué medir\nconst AVERAGE_CHARACTER_WIDTH_PIXELS = 7.4;\n// lo que va alrededor del texto: el punto y su espacio (o el contorno del chip) y el respiro de la celda\nconst STATUS_EXTRA_PIXELS = Object.freeze({dot: 40, chip: 52});\n// el encabezado lleva además sus íconos de orden y de filtro\nconst HEADER_ICONS_PIXELS = 56;\n\nlet measuringContext = null;\n\n/**\n * El ancho de un texto en px con la letra de la página; sin navegador, por número de letras.\n *\n * @param {string} text\n * @param {{fontSize?: number, fontWeight?: number}} [options]\n * @returns {number}\n */\nexport function textWidthOf(text, {fontSize = STATUS_FONT_SIZE_PIXELS, fontWeight = STATUS_FONT_WEIGHT} = {}) {\n const value = String(text ?? '');\n if (typeof document === 'undefined') {\n return value.length * AVERAGE_CHARACTER_WIDTH_PIXELS * (fontSize / STATUS_FONT_SIZE_PIXELS);\n }\n measuringContext ??= document.createElement('canvas').getContext('2d');\n if (!measuringContext) {\n return value.length * AVERAGE_CHARACTER_WIDTH_PIXELS * (fontSize / STATUS_FONT_SIZE_PIXELS);\n }\n const fontFamily = getComputedStyle(document.body).fontFamily || 'system-ui, sans-serif';\n measuringContext.font = `${fontWeight} ${fontSize}px ${fontFamily}`;\n return measuringContext.measureText(value).width;\n}\n\n/**\n * El ancho de una columna de estatus: el de su etiqueta más larga (o el del encabezado, con sus íconos) más lo de alrededor.\n *\n * @param {string[]} labels el encabezado primero y luego las etiquetas, ya traducidos\n * @param {{variant?: 'dot'|'chip'}} [options]\n * @returns {number} px, redondeado hacia arriba\n */\nexport function statusColumnWidthOf([header, ...labels], {variant = 'dot'} = {}) {\n const extra = STATUS_EXTRA_PIXELS[variant] ?? STATUS_EXTRA_PIXELS.dot;\n const widest = Math.max(0, ...labels.map((label) => textWidthOf(label) + extra));\n const headerWidth = textWidthOf(header, {fontWeight: 600}) + HEADER_ICONS_PIXELS;\n return Math.ceil(Math.max(widest, headerWidth));\n}\n"],"names":[],"mappings":"AAOA,MAAM,0BAA0B;AAChC,MAAM,qBAAqB;AAE3B,MAAM,iCAAiC;AAEvC,MAAM,sBAAsB,OAAO,OAAO,EAAC,KAAK,IAAI,MAAM,GAAE,CAAC;AAE7D,MAAM,sBAAsB;AAE5B,IAAI,mBAAmB;AAShB,SAAS,YAAY,MAAM,EAAC,WAAW,yBAAyB,aAAa,mBAAkB,IAAI,IAAI;AAC1G,QAAM,QAAQ,OAAO,QAAQ,EAAE;AAC/B,MAAI,OAAO,aAAa,aAAa;AACjC,WAAO,MAAM,SAAS,kCAAkC,WAAW;AAAA,EACvE;AACA,uBAAqB,SAAS,cAAc,QAAQ,EAAE,WAAW,IAAI;AACrE,MAAI,CAAC,kBAAkB;AACnB,WAAO,MAAM,SAAS,kCAAkC,WAAW;AAAA,EACvE;AACA,QAAM,aAAa,iBAAiB,SAAS,IAAI,EAAE,cAAc;AACjE,mBAAiB,OAAO,GAAG,UAAU,IAAI,QAAQ,MAAM,UAAU;AACjE,SAAO,iBAAiB,YAAY,KAAK,EAAE;AAC/C;AASO,SAAS,oBAAoB,CAAC,QAAQ,GAAG,MAAM,GAAG,EAAC,UAAU,MAAK,IAAI,IAAI;AAC7E,QAAM,QAAQ,oBAAoB,OAAO,KAAK,oBAAoB;AAClE,QAAM,SAAS,KAAK,IAAI,GAAG,GAAG,OAAO,IAAI,CAAC,UAAU,YAAY,KAAK,IAAI,KAAK,CAAC;AAC/E,QAAM,cAAc,YAAY,QAAQ,EAAC,YAAY,IAAG,CAAC,IAAI;AAC7D,SAAO,KAAK,KAAK,KAAK,IAAI,QAAQ,WAAW,CAAC;AAClD;"}
|
|
@@ -8,9 +8,19 @@ import "./ColumnFilters/HeaderFilterPopover.js";
|
|
|
8
8
|
import MultiSelectColumnFilter from "./ColumnFilters/MultiSelectColumnFilter.js";
|
|
9
9
|
import SortableFilterHeader from "./ColumnFilters/SortableFilterHeader.js";
|
|
10
10
|
import TextColumnFilter from "./ColumnFilters/TextColumnFilter.js";
|
|
11
|
+
import { statusColumnWidthOf } from "./columnWidths.js";
|
|
12
|
+
import StackedCell from "./StackedCell.js";
|
|
11
13
|
import { useTableFilter } from "./filterContext.js";
|
|
12
14
|
import { FILTER_KINDS, isFilterActive } from "./useTableState.js";
|
|
15
|
+
import { labelOf, lookup } from "../dictionaries/dictionaries.js";
|
|
16
|
+
import ActionsMenu from "../ui/actions/ActionsMenu.js";
|
|
17
|
+
import DictionaryText from "../ui/labels/DictionaryText.js";
|
|
18
|
+
import StatusChip from "../ui/labels/StatusChip.js";
|
|
13
19
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
20
|
+
const DETAIL_COLUMN_FIELD = "__detail";
|
|
21
|
+
const ACTIONS_COLUMN_FIELD = "__actions";
|
|
22
|
+
const ACTIONS_COLUMN_WIDTH = 56;
|
|
23
|
+
const COLUMN_STACKED_KEY = "calcitaStacked";
|
|
14
24
|
function activeCountOf(kind, value) {
|
|
15
25
|
if (!isFilterActive(kind, value)) {
|
|
16
26
|
return 0;
|
|
@@ -99,7 +109,7 @@ function DetailCell({ row, onOpen, ariaLabelOf }) {
|
|
|
99
109
|
function detailColumn({ onOpen, ariaLabelOf, ...unknownOptions }) {
|
|
100
110
|
warnUnknownProps("detailColumn", unknownOptions);
|
|
101
111
|
return {
|
|
102
|
-
field:
|
|
112
|
+
field: DETAIL_COLUMN_FIELD,
|
|
103
113
|
headerName: "",
|
|
104
114
|
sortable: false,
|
|
105
115
|
filterable: false,
|
|
@@ -109,9 +119,45 @@ function detailColumn({ onOpen, ariaLabelOf, ...unknownOptions }) {
|
|
|
109
119
|
renderCell: ({ row }) => /* @__PURE__ */ jsx(DetailCell, { row, onOpen, ariaLabelOf })
|
|
110
120
|
};
|
|
111
121
|
}
|
|
122
|
+
function stackedColumn({ field, label, entries, sort = true, filter = true, ...gridColumnProps }) {
|
|
123
|
+
return {
|
|
124
|
+
...textColumn({ field, label, sort, filter, ...gridColumnProps }),
|
|
125
|
+
[COLUMN_STACKED_KEY]: true,
|
|
126
|
+
renderCell: (params) => /* @__PURE__ */ jsx(StackedCell, { entries: entries(params.row, params.formattedValue ?? params.value) })
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function statusColumn({ field, label, dictionary, t, short = false, variant = "dot", sort = true, filter = true, facetKey, ...gridColumnProps }) {
|
|
130
|
+
const labels = t ? Object.keys(dictionary).map((value) => labelOf(lookup(dictionary, value), t)) : [];
|
|
131
|
+
const width = gridColumnProps.width ?? (labels.length > 0 ? statusColumnWidthOf([label, ...labels], { variant }) : 160);
|
|
132
|
+
const renderOption = (value) => /* @__PURE__ */ jsx(DictionaryText, { dictionary, value });
|
|
133
|
+
const base = filter ? facetColumn({ field, label, facetKey, renderOption, sort, ...gridColumnProps, width }) : textColumn({ field, label, sort, filter: false, ...gridColumnProps, width });
|
|
134
|
+
return {
|
|
135
|
+
...base,
|
|
136
|
+
renderCell: ({ row }) => /* @__PURE__ */ jsx(StatusChip, { dictionary, value: row[field], short, variant })
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function actionsColumn({ label, actionsOf, labelOf: labelOfRow, width = ACTIONS_COLUMN_WIDTH, ...unknownOptions }) {
|
|
140
|
+
warnUnknownProps("actionsColumn", unknownOptions);
|
|
141
|
+
return {
|
|
142
|
+
field: ACTIONS_COLUMN_FIELD,
|
|
143
|
+
headerName: "",
|
|
144
|
+
sortable: false,
|
|
145
|
+
filterable: false,
|
|
146
|
+
disableColumnMenu: true,
|
|
147
|
+
width,
|
|
148
|
+
align: "center",
|
|
149
|
+
renderCell: ({ row }) => /* @__PURE__ */ jsx(ActionsMenu, { label: labelOfRow?.(row) ?? label, actions: actionsOf(row) })
|
|
150
|
+
};
|
|
151
|
+
}
|
|
112
152
|
export {
|
|
153
|
+
ACTIONS_COLUMN_FIELD,
|
|
154
|
+
COLUMN_STACKED_KEY,
|
|
155
|
+
DETAIL_COLUMN_FIELD,
|
|
156
|
+
actionsColumn,
|
|
113
157
|
detailColumn,
|
|
114
158
|
facetColumn,
|
|
159
|
+
stackedColumn,
|
|
160
|
+
statusColumn,
|
|
115
161
|
textColumn
|
|
116
162
|
};
|
|
117
163
|
//# sourceMappingURL=columns.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"columns.js","sources":["../../src/DataTable/columns.jsx"],"sourcesContent":["// Armadores de columna para ServerTable: la definición del DataGrid + su encabezado con orden y filtro.\n//\n// El filtro vive en el ENCABEZADO de su columna porque ahí está el dato. Aquí solo se COMPONE: el encabezado, el\n// globo y cada tipo de filtro viven en ColumnFilters/, uno por archivo.\n//\n// OJO: sortable y filterable del DataGrid van en false siempre. El orden y el filtro los pide la tabla al SERVIDOR;\n// los nativos del DataGrid ordenarían y filtrarían solo la página que ya llegó.\n//\n// Armadores genéricos: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';\n\nimport {MultiSelectColumnFilter, SortableFilterHeader, TextColumnFilter} from '@/DataTable/ColumnFilters';\nimport {useTableFilter} from '@/DataTable/filterContext.js';\nimport {FILTER_KINDS, isFilterActive} from '@/DataTable/useTableState.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n/** Cuántos valores tiene puestos esta columna (lo que muestra el badge). */\nfunction activeCountOf(kind, value) {\n if (!isFilterActive(kind, value)) {\n return 0;\n }\n return kind === FILTER_KINDS.multiSelect ? value.length : 1;\n}\n\n/** Lo que todo encabezado necesita del contexto de la tabla. */\nfunction useColumnHeader(field, kind) {\n const {filters, setFilter, clearFilter, sortOrders, toggleSort, clearSort, facets} = useTableFilter();\n\n return {\n value: filters[field],\n setValue: (value) => setFilter(field, value),\n onClear: () => clearFilter(field),\n sortEntry: sortOrders.find((sortOrder) => sortOrder.column === field),\n onSort: () => toggleSort(field),\n onClearSort: clearSort,\n activeCount: activeCountOf(kind, filters[field]),\n facets,\n };\n}\n\nfunction TextHeader({field, label, sort, filter}) {\n const header = useColumnHeader(field, FILTER_KINDS.text);\n\n return (\n <SortableFilterHeader label={label} sortable={sort} filterable={filter} sortEntry={header.sortEntry}\n onSort={header.onSort} onClearSort={header.onClearSort} activeCount={header.activeCount}\n onClear={header.onClear}>\n <TextColumnFilter value={header.value ?? ''} onChange={header.setValue} />\n </SortableFilterHeader>\n );\n}\n\nfunction FacetHeader({field, label, facetKey, renderOption, sort}) {\n const header = useColumnHeader(field, FILTER_KINDS.multiSelect);\n\n return (\n <SortableFilterHeader label={label} sortable={sort} sortEntry={header.sortEntry} onSort={header.onSort}\n onClearSort={header.onClearSort} activeCount={header.activeCount} onClear={header.onClear}>\n <MultiSelectColumnFilter value={header.value ?? []} onChange={header.setValue}\n options={header.facets[facetKey] ?? []} renderOption={renderOption} />\n </SortableFilterHeader>\n );\n}\n\n/**\n * Las props de columna del DataGrid que más se usan, con su tipo, y cualquier otra suya (Record). OJO: tipo propio y no\n * GridColDef del DataGrid: apuntar a sus tipos hace que un proyecto estricto (skipLibCheck: false) revise los internos del\n * DataGrid, que no compilan con TypeScript 7.\n *\n * @typedef {{width?: number, minWidth?: number, maxWidth?: number, flex?: number, align?: 'left'|'center'|'right', headerAlign?: 'left'|'center'|'right', valueFormatter?: (value: any, row: any) => string, valueGetter?: (value: any, row: any) => any, renderCell?: (params: any) => import('react').ReactNode} & Record<string, any>} GridColumnProps\n */\n\n/**\n * Columna de texto con orden y filtro \"contiene\" en el servidor.\n *\n * @param {{field: string, label: string, sort?: boolean, filter?: boolean} & GridColumnProps} columnDeclaration\n * label ya traducido; lo demás son props de columna del DataGrid (width, flex, valueFormatter, renderCell…)\n */\nexport function textColumn({field, label, sort = true, filter = true, ...gridColumnProps}) {\n return {\n field,\n headerName: label,\n sortable: false,\n filterable: false,\n ...gridColumnProps,\n renderHeader: () => <TextHeader field={field} label={label} sort={sort} filter={filter} />,\n };\n}\n\n/**\n * Columna con filtro de opciones alimentado por las FACETAS del servidor.\n *\n * @param {{field: string, label: string, facetKey?: string, renderOption?: (value: string) => import('react').ReactNode, sort?: boolean} & GridColumnProps} columnDeclaration\n */\nexport function facetColumn({field, label, facetKey, renderOption, sort = true, ...gridColumnProps}) {\n return {\n field,\n headerName: label,\n sortable: false,\n filterable: false,\n ...gridColumnProps,\n renderHeader: () => (\n <FacetHeader field={field} label={label} facetKey={facetKey ?? field} renderOption={renderOption} sort={sort} />\n ),\n };\n}\n\nfunction DetailCell({row, onOpen, ariaLabelOf}) {\n const {t} = useToolkitTranslation('table');\n const ariaLabel = ariaLabelOf?.(row) ?? t('detail.ariaLabel');\n\n return (\n <Tooltip title={t('detail.tooltip')}>\n <IconButton size=\"small\" aria-label={ariaLabel} onClick={() => onOpen(row)}>\n <VisibilityOutlinedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n );\n}\n\n/**\n * Columna de acción al final de la fila: un icono que abre el detalle (la ruta propia del renglón). Un icono y no la\n * fila entera a propósito: la fila como botón se dispara al seleccionar texto y no se ve que se puede abrir.\n *\n * El globo del icono se cambia con los textos de la tabla (ServerTable texts={{detail: {tooltip: '…'}}}), no aquí.\n *\n * @param {{onOpen: (row: any) => void, ariaLabelOf?: (row: any) => string}} declaration ariaLabelOf ya traducido\n */\nexport function detailColumn({onOpen, ariaLabelOf, ...unknownOptions}) {\n // un nombre que no existe (label, tooltip) se perdía sin decir nada: se avisa mientras se programa\n warnUnknownProps('detailColumn', unknownOptions);\n return {\n field: '__detail',\n headerName: '',\n sortable: false,\n filterable: false,\n disableColumnMenu: true,\n width: 64,\n align: 'center',\n renderCell: ({row}) => <DetailCell row={row} onOpen={onOpen} ariaLabelOf={ariaLabelOf} />,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"columns.js","sources":["../../src/DataTable/columns.jsx"],"sourcesContent":["// Armadores de columna para ServerTable: la definición del DataGrid + su encabezado con orden y filtro.\n//\n// El filtro vive en el ENCABEZADO de su columna porque ahí está el dato. Aquí solo se COMPONE: el encabezado, el\n// globo y cada tipo de filtro viven en ColumnFilters/, uno por archivo.\n//\n// OJO: sortable y filterable del DataGrid van en false siempre. El orden y el filtro los pide la tabla al SERVIDOR;\n// los nativos del DataGrid ordenarían y filtrarían solo la página que ya llegó.\n//\n// Armadores genéricos: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';\n\nimport {MultiSelectColumnFilter, SortableFilterHeader, TextColumnFilter} from '@/DataTable/ColumnFilters';\nimport {statusColumnWidthOf} from '@/DataTable/columnWidths.js';\nimport StackedCell from '@/DataTable/StackedCell.jsx';\nimport {useTableFilter} from '@/DataTable/filterContext.js';\nimport {FILTER_KINDS, isFilterActive} from '@/DataTable/useTableState.js';\nimport {labelOf, lookup} from '@/dictionaries/dictionaries.js';\nimport ActionsMenu from '@/ui/actions/ActionsMenu.jsx';\nimport DictionaryText from '@/ui/labels/DictionaryText.jsx';\nimport StatusChip from '@/ui/labels/StatusChip.jsx';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n/** El campo de las columnas de la casa que no son datos: para nombrarlas en fixedColumn ({fixedColumn: [ACTIONS_COLUMN_FIELD, …]}). */\nexport const DETAIL_COLUMN_FIELD = '__detail';\nexport const ACTIONS_COLUMN_FIELD = '__actions';\n// el ancho de la columna del «⋯»: el botón de 34 px y su respiro\nconst ACTIONS_COLUMN_WIDTH = 56;\n// la marca que deja una columna de datos apilados: con ella la tabla pone los renglones a su alto (ServerTable)\nexport const COLUMN_STACKED_KEY = 'calcitaStacked';\n\n/** Cuántos valores tiene puestos esta columna (lo que muestra el badge). */\nfunction activeCountOf(kind, value) {\n if (!isFilterActive(kind, value)) {\n return 0;\n }\n return kind === FILTER_KINDS.multiSelect ? value.length : 1;\n}\n\n/** Lo que todo encabezado necesita del contexto de la tabla. */\nfunction useColumnHeader(field, kind) {\n const {filters, setFilter, clearFilter, sortOrders, toggleSort, clearSort, facets} = useTableFilter();\n\n return {\n value: filters[field],\n setValue: (value) => setFilter(field, value),\n onClear: () => clearFilter(field),\n sortEntry: sortOrders.find((sortOrder) => sortOrder.column === field),\n onSort: () => toggleSort(field),\n onClearSort: clearSort,\n activeCount: activeCountOf(kind, filters[field]),\n facets,\n };\n}\n\nfunction TextHeader({field, label, sort, filter}) {\n const header = useColumnHeader(field, FILTER_KINDS.text);\n\n return (\n <SortableFilterHeader label={label} sortable={sort} filterable={filter} sortEntry={header.sortEntry}\n onSort={header.onSort} onClearSort={header.onClearSort} activeCount={header.activeCount}\n onClear={header.onClear}>\n <TextColumnFilter value={header.value ?? ''} onChange={header.setValue} />\n </SortableFilterHeader>\n );\n}\n\nfunction FacetHeader({field, label, facetKey, renderOption, sort}) {\n const header = useColumnHeader(field, FILTER_KINDS.multiSelect);\n\n return (\n <SortableFilterHeader label={label} sortable={sort} sortEntry={header.sortEntry} onSort={header.onSort}\n onClearSort={header.onClearSort} activeCount={header.activeCount} onClear={header.onClear}>\n <MultiSelectColumnFilter value={header.value ?? []} onChange={header.setValue}\n options={header.facets[facetKey] ?? []} renderOption={renderOption} />\n </SortableFilterHeader>\n );\n}\n\n/**\n * Las props de columna del DataGrid que más se usan, con su tipo, y cualquier otra suya (Record). OJO: tipo propio y no\n * GridColDef del DataGrid: apuntar a sus tipos hace que un proyecto estricto (skipLibCheck: false) revise los internos del\n * DataGrid, que no compilan con TypeScript 7.\n *\n * @typedef {{width?: number, minWidth?: number, maxWidth?: number, flex?: number, align?: 'left'|'center'|'right', headerAlign?: 'left'|'center'|'right', valueFormatter?: (value: any, row: any) => string, valueGetter?: (value: any, row: any) => any, renderCell?: (params: any) => import('react').ReactNode} & Record<string, any>} GridColumnProps\n */\n\n/**\n * Columna de texto con orden y filtro \"contiene\" en el servidor.\n *\n * @param {{field: string, label: string, sort?: boolean, filter?: boolean} & GridColumnProps} columnDeclaration\n * label ya traducido; lo demás son props de columna del DataGrid (width, flex, valueFormatter, renderCell…)\n */\nexport function textColumn({field, label, sort = true, filter = true, ...gridColumnProps}) {\n return {\n field,\n headerName: label,\n sortable: false,\n filterable: false,\n ...gridColumnProps,\n renderHeader: () => <TextHeader field={field} label={label} sort={sort} filter={filter} />,\n };\n}\n\n/**\n * Columna con filtro de opciones alimentado por las FACETAS del servidor.\n *\n * @param {{field: string, label: string, facetKey?: string, renderOption?: (value: string) => import('react').ReactNode, sort?: boolean} & GridColumnProps} columnDeclaration\n */\nexport function facetColumn({field, label, facetKey, renderOption, sort = true, ...gridColumnProps}) {\n return {\n field,\n headerName: label,\n sortable: false,\n filterable: false,\n ...gridColumnProps,\n renderHeader: () => (\n <FacetHeader field={field} label={label} facetKey={facetKey ?? field} renderOption={renderOption} sort={sort} />\n ),\n };\n}\n\nfunction DetailCell({row, onOpen, ariaLabelOf}) {\n const {t} = useToolkitTranslation('table');\n const ariaLabel = ariaLabelOf?.(row) ?? t('detail.ariaLabel');\n\n return (\n <Tooltip title={t('detail.tooltip')}>\n <IconButton size=\"small\" aria-label={ariaLabel} onClick={() => onOpen(row)}>\n <VisibilityOutlinedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n );\n}\n\n/**\n * Columna de acción al final de la fila: un icono que abre el detalle (la ruta propia del renglón). Un icono y no la\n * fila entera a propósito: la fila como botón se dispara al seleccionar texto y no se ve que se puede abrir.\n *\n * El globo del icono se cambia con los textos de la tabla (ServerTable texts={{detail: {tooltip: '…'}}}), no aquí.\n *\n * @param {{onOpen: (row: any) => void, ariaLabelOf?: (row: any) => string}} declaration ariaLabelOf ya traducido\n */\nexport function detailColumn({onOpen, ariaLabelOf, ...unknownOptions}) {\n // un nombre que no existe (label, tooltip) se perdía sin decir nada: se avisa mientras se programa\n warnUnknownProps('detailColumn', unknownOptions);\n return {\n field: DETAIL_COLUMN_FIELD,\n headerName: '',\n sortable: false,\n filterable: false,\n disableColumnMenu: true,\n width: 64,\n align: 'center',\n renderCell: ({row}) => <DetailCell row={row} onOpen={onOpen} ariaLabelOf={ariaLabelOf} />,\n };\n}\n\n/**\n * Columna de datos apilados: los que se leen de corrido en un solo lugar, uno debajo del otro, los que hagan falta (la\n * empresa, su RFC y su régimen; el contacto, su correo y su teléfono). El primero es el principal (en negritas) y los demás\n * van en gris. Cada dato va solo, si el encabezado ya dice qué son, o con su etiqueta arriba ({label, value}) si el\n * encabezado nombra al grupo. Con orden y filtro en el servidor como textColumn, por el campo de la columna. La tabla pone\n * los renglones a su alto sola.\n *\n * stackedColumn({field: 'business_name', label: 'Empresa', entries: (row) => [row.business_name, row.rfc, row.regime]})\n * stackedColumn({field: 'created_at', label: 'Fechas', entries: (row) => [\n * {label: 'Alta', value: formatDate(row.created_at)},\n * {label: 'Último cambio', value: formatDate(row.updated_at)},\n * ]})\n *\n * @param {{field: string, label: string, entries: (row: any, value: any) => import('@/DataTable/StackedCell.jsx').StackedEntry[], sort?: boolean, filter?: boolean} & GridColumnProps} columnDeclaration\n * entries: los datos de cada renglón en orden; `value` es el de la columna ya con su valueFormatter. Un dato vacío\n * no se pinta (salvo el principal o uno con etiqueta: enseñan «—»)\n */\nexport function stackedColumn({field, label, entries, sort = true, filter = true, ...gridColumnProps}) {\n return {\n ...textColumn({field, label, sort, filter, ...gridColumnProps}),\n [COLUMN_STACKED_KEY]: true,\n renderCell: (params) => <StackedCell entries={entries(params.row, params.formattedValue ?? params.value)} />,\n };\n}\n\n/**\n * Columna de estatus desde un diccionario: el estatus con su color y su explicación (StatusChip), filtro con las facetas del\n * servidor (como facetColumn) y un ancho que alcanza para la etiqueta más larga del diccionario. Con `t` el ancho se mide\n * con las etiquetas en el idioma de la pantalla (sin él, 160 px o el `width` que se le dé).\n *\n * statusColumn({field: 'status', label: 'Estado', dictionary: ORDER_STATUS, t})\n *\n * @param {{field: string, label: string, dictionary: Record<string, object>, t?: (key: string) => string, short?: boolean, variant?: 'dot'|'chip', sort?: boolean, filter?: boolean, facetKey?: string} & GridColumnProps} columnDeclaration\n * filter false: sin filtro en el encabezado (cuando el servidor no da facetas de este campo)\n */\nexport function statusColumn({field, label, dictionary, t, short = false, variant = 'dot', sort = true, filter = true, facetKey, ...gridColumnProps}) {\n const labels = t ? Object.keys(dictionary).map((value) => labelOf(lookup(dictionary, value), t)) : [];\n const width = gridColumnProps.width ?? (labels.length > 0 ? statusColumnWidthOf([label, ...labels], {variant}) : 160);\n const renderOption = (value) => <DictionaryText dictionary={dictionary} value={value} />;\n const base = filter\n ? facetColumn({field, label, facetKey, renderOption, sort, ...gridColumnProps, width})\n : textColumn({field, label, sort, filter: false, ...gridColumnProps, width});\n return {\n ...base,\n renderCell: ({row}) => <StatusChip dictionary={dictionary} value={row[field]} short={short} variant={variant} />,\n };\n}\n\n/**\n * Columna con el menú «⋯» de cada renglón (ActionsMenu): las acciones van en su columna con un ícono, no con clic en toda\n * la fila. Va de un ancho fijo, así se puede dejar pegada al deslizar: fixedColumn={[ACTIONS_COLUMN_FIELD, 'company']}.\n *\n * actionsColumn({label: 'Acciones del cliente', actionsOf: (row) => [{key: 'open', label: 'Abrir', to: `/clientes/${row.id}`}]})\n *\n * @param {object} declaration\n * @param {string} declaration.label el nombre del botón (lector de pantalla y su globo), ya traducido\n * @param {(row: any) => Array<object>} declaration.actionsOf las acciones de ese renglón, con la forma de ActionsMenu\n * @param {(row: any) => string} [declaration.labelOf] el nombre del botón por renglón («Acciones de Acme»)\n * @param {number} [declaration.width] por omisión 56\n */\nexport function actionsColumn({label, actionsOf, labelOf: labelOfRow, width = ACTIONS_COLUMN_WIDTH, ...unknownOptions}) {\n warnUnknownProps('actionsColumn', unknownOptions);\n return {\n field: ACTIONS_COLUMN_FIELD,\n headerName: '',\n sortable: false,\n filterable: false,\n disableColumnMenu: true,\n width,\n align: 'center',\n renderCell: ({row}) => <ActionsMenu label={labelOfRow?.(row) ?? label} actions={actionsOf(row)} />,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterContext.js","sources":["../../src/DataTable/filterContext.js"],"sourcesContent":["// Contexto que comparten los encabezados de columna con la tabla.\n//\n// Existe para que renderHeader de cada columna no reciba media docena de props: el encabezado pide lo que necesita\n// (el filtro de SU campo, el orden y las facetas del servidor) y la tabla no se entera.\n//\n// Funciones puras, no renderizan: function (regla de la casa).\nimport {createContext, useContext} from 'react';\n\nexport const TableFilterContext = createContext(null);\n\n/**\n * @returns {{filters: object, setFilter: Function, clearFilter: Function, sortOrders: Array, toggleSort: Function, clearSort: Function, facets: object}}\n */\nexport function useTableFilter() {\n const tableFilterValue = useContext(TableFilterContext);\n if (!tableFilterValue) {\n // mejor tronar aquí que pintar un encabezado muerto que no filtra y nadie entiende por qué\n throw new Error('Un encabezado de columna se montó fuera de <ServerTable>.');\n }\n return tableFilterValue;\n}\n"],"names":[],"mappings":";;AAQY,MAAC,qBAAqB,cAAc,IAAI;AAK7C,SAAS,iBAAiB;AAC7B,QAAM,mBAAmB,WAAW,kBAAkB;AACtD,MAAI,CAAC,kBAAkB;AAEnB,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC/E;AACA,SAAO;AACX;"}
|
|
1
|
+
{"version":3,"file":"filterContext.js","sources":["../../src/DataTable/filterContext.js"],"sourcesContent":["// Contexto que comparten los encabezados de columna con la tabla.\n//\n// Existe para que renderHeader de cada columna no reciba media docena de props: el encabezado pide lo que necesita\n// (el filtro de SU campo, el orden y las facetas del servidor) y la tabla no se entera.\n//\n// Funciones puras, no renderizan: function (regla de la casa).\nimport {createContext, useContext} from 'react';\n\nexport const TableFilterContext = createContext(null);\n\n/**\n * @returns {{filters: object, setFilter: Function, setFilters: Function, clearFilter: Function, sortOrders: Array, toggleSort: Function, clearSort: Function, facets: object}}\n */\nexport function useTableFilter() {\n const tableFilterValue = useContext(TableFilterContext);\n if (!tableFilterValue) {\n // mejor tronar aquí que pintar un encabezado muerto que no filtra y nadie entiende por qué\n throw new Error('Un encabezado de columna se montó fuera de <ServerTable>.');\n }\n return tableFilterValue;\n}\n"],"names":[],"mappings":";;AAQY,MAAC,qBAAqB,cAAc,IAAI;AAK7C,SAAS,iBAAiB;AAC7B,QAAM,mBAAmB,WAAW,kBAAkB;AACtD,MAAI,CAAC,kBAAkB;AAEnB,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC/E;AACA,SAAO;AACX;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const DATA_GRID_DEFAULT_COLUMN_WIDTH = 100;
|
|
2
|
+
function fixedFieldsOf(fixedColumn) {
|
|
3
|
+
if (!fixedColumn) {
|
|
4
|
+
return [];
|
|
5
|
+
}
|
|
6
|
+
return Array.isArray(fixedColumn) ? fixedColumn.filter(Boolean) : [fixedColumn];
|
|
7
|
+
}
|
|
8
|
+
function fixedColumnOffsetsOf(fields, columns, { startLeft = 0 } = {}) {
|
|
9
|
+
const byField = new Map(columns.map((column) => [column.field, column]));
|
|
10
|
+
let left = startLeft;
|
|
11
|
+
return fields.map((field, index) => {
|
|
12
|
+
const column = byField.get(field) ?? {};
|
|
13
|
+
const isLast = index === fields.length - 1;
|
|
14
|
+
const hasFixedWidth = typeof column.width === "number" && !column.flex;
|
|
15
|
+
const placed = { field, left, isLast, hasUnknownWidth: !isLast && !hasFixedWidth };
|
|
16
|
+
left += hasFixedWidth ? column.width : column.minWidth ?? column.width ?? DATA_GRID_DEFAULT_COLUMN_WIDTH;
|
|
17
|
+
return placed;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
fixedColumnOffsetsOf,
|
|
22
|
+
fixedFieldsOf
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=fixedColumns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixedColumns.js","sources":["../../src/DataTable/fixedColumns.js"],"sourcesContent":["// Dónde se pega cada columna fija de la tabla al deslizar de lado: la primera junto a la orilla (o junto a la casilla de\n// elegir renglones) y cada siguiente corrida lo que miden las de antes.\n//\n// OJO: el desplazamiento sale del ancho que la columna declara (`width`). Una columna fija que NO es la última y no trae un\n// ancho fijo (va con `flex` o sin ancho) no se puede sumar: su ancho real lo decide el navegador. Ahí se usa su minWidth\n// (o el de siempre del DataGrid, 100 px) y se avisa: la que sigue podría quedar encima. La ÚLTIMA puede ser flexible\n// (su ancho no mueve a nadie).\n//\n// Funciones puras, no renderizan: function (regla de la casa).\n\n// el ancho de una columna del DataGrid que no dice el suyo\nconst DATA_GRID_DEFAULT_COLUMN_WIDTH = 100;\n\n/**\n * Los campos fijos como lista, con el orden en que se dieron.\n *\n * @param {string|string[]|null|undefined} fixedColumn\n * @returns {string[]}\n */\nexport function fixedFieldsOf(fixedColumn) {\n if (!fixedColumn) {\n return [];\n }\n return Array.isArray(fixedColumn) ? fixedColumn.filter(Boolean) : [fixedColumn];\n}\n\n/**\n * Cada columna fija con su `left` en px.\n *\n * @param {string[]} fields los campos fijos, de izquierda a derecha\n * @param {Array<{field: string, width?: number, minWidth?: number, flex?: number}>} columns las columnas de la tabla\n * @param {{startLeft?: number}} [options] startLeft: lo que ya va pegado antes (la casilla de elegir renglones)\n * @returns {Array<{field: string, left: number, isLast: boolean, hasUnknownWidth: boolean}>} hasUnknownWidth: no es la última\n * y su ancho no es fijo (la siguiente podría encimarse)\n */\nexport function fixedColumnOffsetsOf(fields, columns, {startLeft = 0} = {}) {\n const byField = new Map(columns.map((column) => [column.field, column]));\n let left = startLeft;\n return fields.map((field, index) => {\n const column = byField.get(field) ?? {};\n const isLast = index === fields.length - 1;\n const hasFixedWidth = typeof column.width === 'number' && !column.flex;\n const placed = {field, left, isLast, hasUnknownWidth: !isLast && !hasFixedWidth};\n left += hasFixedWidth ? column.width : (column.minWidth ?? column.width ?? DATA_GRID_DEFAULT_COLUMN_WIDTH);\n return placed;\n });\n}\n"],"names":[],"mappings":"AAWA,MAAM,iCAAiC;AAQhC,SAAS,cAAc,aAAa;AACvC,MAAI,CAAC,aAAa;AACd,WAAO,CAAA;AAAA,EACX;AACA,SAAO,MAAM,QAAQ,WAAW,IAAI,YAAY,OAAO,OAAO,IAAI,CAAC,WAAW;AAClF;AAWO,SAAS,qBAAqB,QAAQ,SAAS,EAAC,YAAY,EAAC,IAAI,IAAI;AACxE,QAAM,UAAU,IAAI,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,OAAO,OAAO,MAAM,CAAC,CAAC;AACvE,MAAI,OAAO;AACX,SAAO,OAAO,IAAI,CAAC,OAAO,UAAU;AAChC,UAAM,SAAS,QAAQ,IAAI,KAAK,KAAK,CAAA;AACrC,UAAM,SAAS,UAAU,OAAO,SAAS;AACzC,UAAM,gBAAgB,OAAO,OAAO,UAAU,YAAY,CAAC,OAAO;AAClE,UAAM,SAAS,EAAC,OAAO,MAAM,QAAQ,iBAAiB,CAAC,UAAU,CAAC,cAAa;AAC/E,YAAQ,gBAAgB,OAAO,QAAS,OAAO,YAAY,OAAO,SAAS;AAC3E,WAAO;AAAA,EACX,CAAC;AACL;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function pageNumbersOf(pageCount) {
|
|
2
|
+
return Array.from({ length: pageCount }, (unused, position) => position + 1);
|
|
3
|
+
}
|
|
4
|
+
function filterPages(pageNumbers, { inputValue }) {
|
|
5
|
+
const typedText = inputValue.trim();
|
|
6
|
+
if (!typedText) {
|
|
7
|
+
return pageNumbers;
|
|
8
|
+
}
|
|
9
|
+
const startingWith = pageNumbers.filter((pageNumber) => String(pageNumber).startsWith(typedText));
|
|
10
|
+
const containing = pageNumbers.filter((pageNumber) => !String(pageNumber).startsWith(typedText) && String(pageNumber).includes(typedText));
|
|
11
|
+
return [...startingWith, ...containing];
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
filterPages,
|
|
15
|
+
pageNumbersOf
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=goToPageOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goToPageOptions.js","sources":["../../src/DataTable/goToPageOptions.js"],"sourcesContent":["// «Ir a la página N»: qué páginas enseña la lista según lo que se teclea.\n//\n// Sin recorte: GoToPage pinta solo las páginas que se ven (react-window), así que la lista puede traer decenas de miles de\n// páginas y deslizarse hasta la última. Al teclear, primero las que EMPIEZAN con lo tecleado (13 da 13, 130, 131...) y\n// después las que lo contienen (213, 1013...).\n//\n// Puro (sin React): se prueba con node (goToPageOptions.test.js).\n//\n// Genérico del paquete: function (regla de la casa).\n\n/**\n * @param {number} pageCount cuántas páginas tiene la tabla\n * @returns {number[]} las páginas como las cuenta una persona: 1, 2, 3... pageCount\n */\nexport function pageNumbersOf(pageCount) {\n return Array.from({length: pageCount}, (unused, position) => position + 1);\n}\n\n/**\n * filterOptions del Autocomplete.\n *\n * @param {number[]} pageNumbers todas las páginas\n * @param {{inputValue: string}} state lo que lleva tecleado la persona\n * @returns {number[]} sin teclear, todas; tecleando, primero las que empiezan así y luego las que lo contienen\n */\nexport function filterPages(pageNumbers, {inputValue}) {\n const typedText = inputValue.trim();\n if (!typedText) {\n return pageNumbers;\n }\n\n const startingWith = pageNumbers.filter((pageNumber) => String(pageNumber).startsWith(typedText));\n const containing = pageNumbers.filter((pageNumber) => !String(pageNumber).startsWith(typedText) && String(pageNumber).includes(typedText));\n return [...startingWith, ...containing];\n}\n"],"names":[],"mappings":"AAcO,SAAS,cAAc,WAAW;AACrC,SAAO,MAAM,KAAK,EAAC,QAAQ,UAAS,GAAG,CAAC,QAAQ,aAAa,WAAW,CAAC;AAC7E;AASO,SAAS,YAAY,aAAa,EAAC,WAAU,GAAG;AACnD,QAAM,YAAY,WAAW,KAAI;AACjC,MAAI,CAAC,WAAW;AACZ,WAAO;AAAA,EACX;AAEA,QAAM,eAAe,YAAY,OAAO,CAAC,eAAe,OAAO,UAAU,EAAE,WAAW,SAAS,CAAC;AAChG,QAAM,aAAa,YAAY,OAAO,CAAC,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,SAAS,KAAK,OAAO,UAAU,EAAE,SAAS,SAAS,CAAC;AACzI,SAAO,CAAC,GAAG,cAAc,GAAG,UAAU;AAC1C;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useQueryState, parseAsStringLiteral } from "nuqs";
|
|
4
|
+
const TABLE_VIEW = Object.freeze({ table: "table", cards: "cards" });
|
|
5
|
+
const VIEWS = Object.freeze(Object.values(TABLE_VIEW));
|
|
6
|
+
function useTableView({ prefix, view, defaultView = TABLE_VIEW.table, onViewChange }) {
|
|
7
|
+
const [urlView, setUrlView] = useQueryState(
|
|
8
|
+
`${prefix ?? "table"}_view`,
|
|
9
|
+
parseAsStringLiteral(VIEWS).withDefault(defaultView).withOptions({ history: "replace" })
|
|
10
|
+
);
|
|
11
|
+
const [localView, setLocalView] = useState(defaultView);
|
|
12
|
+
const currentView = view ?? (prefix ? urlView : localView);
|
|
13
|
+
const setView = (nextView) => {
|
|
14
|
+
if (view === void 0) {
|
|
15
|
+
if (prefix) {
|
|
16
|
+
setUrlView(nextView === defaultView ? null : nextView);
|
|
17
|
+
} else {
|
|
18
|
+
setLocalView(nextView);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
onViewChange?.(nextView);
|
|
22
|
+
};
|
|
23
|
+
return { view: currentView, setView };
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
TABLE_VIEW,
|
|
27
|
+
useTableView
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=useTableView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTableView.js","sources":["../../src/DataTable/useTableView.js"],"sourcesContent":["// Cómo se ve la lista de la tabla: en tabla o en tarjetas (ServerTable con renderCard). Con `prefix` vive en la dirección\n// (?orders_view=cards: se comparte la liga y sobrevive a recargar) y cambiarla REEMPLAZA la entrada del historial: es la misma\n// lista vista de otra forma, «atrás» sale de ella. Sin prefijo, en memoria. Con `view` la decide la pantalla.\n//\n// Hook genérico: function (regla de la casa).\nimport {useState} from 'react';\nimport {parseAsStringLiteral, useQueryState} from 'nuqs';\n\n/** Las dos vistas de la lista. */\nexport const TABLE_VIEW = Object.freeze({table: 'table', cards: 'cards'});\nconst VIEWS = Object.freeze(Object.values(TABLE_VIEW));\n\n/**\n * @param {object} options\n * @param {string} [options.prefix] el de la tabla: con él, la vista va en la dirección\n * @param {'table'|'cards'} [options.view] la vista que decide la pantalla (controlada)\n * @param {'table'|'cards'} [options.defaultView] por omisión 'table'\n * @param {(view: 'table'|'cards') => void} [options.onViewChange]\n * @returns {{view: 'table'|'cards', setView: (view: 'table'|'cards') => void}}\n */\nexport function useTableView({prefix, view, defaultView = TABLE_VIEW.table, onViewChange}) {\n // OJO: los dos se piden siempre (un hook no puede ir dentro de un if); se usa el que toca\n const [urlView, setUrlView] = useQueryState(`${prefix ?? 'table'}_view`,\n parseAsStringLiteral(VIEWS).withDefault(defaultView).withOptions({history: 'replace'}));\n const [localView, setLocalView] = useState(defaultView);\n const currentView = view ?? (prefix ? urlView : localView);\n\n const setView = (nextView) => {\n if (view === undefined) {\n if (prefix) {\n setUrlView(nextView === defaultView ? null : nextView);\n } else {\n setLocalView(nextView);\n }\n }\n onViewChange?.(nextView);\n };\n return {view: currentView, setView};\n}\n"],"names":[],"mappings":";;;AASY,MAAC,aAAa,OAAO,OAAO,EAAC,OAAO,SAAS,OAAO,QAAO,CAAC;AACxE,MAAM,QAAQ,OAAO,OAAO,OAAO,OAAO,UAAU,CAAC;AAU9C,SAAS,aAAa,EAAC,QAAQ,MAAM,cAAc,WAAW,OAAO,aAAY,GAAG;AAEvF,QAAM,CAAC,SAAS,UAAU,IAAI;AAAA,IAAc,GAAG,UAAU,OAAO;AAAA,IAC5D,qBAAqB,KAAK,EAAE,YAAY,WAAW,EAAE,YAAY,EAAC,SAAS,UAAS,CAAC;AAAA,EAAC;AAC1F,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,WAAW;AACtD,QAAM,cAAc,SAAS,SAAS,UAAU;AAEhD,QAAM,UAAU,CAAC,aAAa;AAC1B,QAAI,SAAS,QAAW;AACpB,UAAI,QAAQ;AACR,mBAAW,aAAa,cAAc,OAAO,QAAQ;AAAA,MACzD,OAAO;AACH,qBAAa,QAAQ;AAAA,MACzB;AAAA,IACJ;AACA,mBAAe,QAAQ;AAAA,EAC3B;AACA,SAAO,EAAC,MAAM,aAAa,QAAO;AACtC;"}
|
|
@@ -11,7 +11,7 @@ import Stack from "@mui/material/Stack";
|
|
|
11
11
|
import Typography from "@mui/material/Typography";
|
|
12
12
|
import { groupStateOf, withPermissionGroup, withPermission } from "./permissionGroups.js";
|
|
13
13
|
import ComponentTexts from "../toolkit/ComponentTexts.js";
|
|
14
|
-
import { piecePart, usePieceProps } from "../theme/themePieces.js";
|
|
14
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
15
15
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
16
16
|
const THEME_NAME = "CalcitaPermissionMatrix";
|
|
17
17
|
const PermissionsPermission = piecePart(THEME_NAME, "Permission", FormControlLabel);
|
|
@@ -83,12 +83,13 @@ function PermissionGroup({ group, value, onChange, isReadOnly }) {
|
|
|
83
83
|
)) })
|
|
84
84
|
] });
|
|
85
85
|
}
|
|
86
|
-
function
|
|
86
|
+
function PermissionMatrixContent(props) {
|
|
87
87
|
const { groups, value, onChange, readOnly = false, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
88
88
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
89
89
|
const isReadOnly = readOnly || !onChange;
|
|
90
90
|
return /* @__PURE__ */ jsx(ComponentTexts, { namespace: "access", texts, children: /* @__PURE__ */ jsx(Stack, { spacing: 1.5, children: groups.map((group) => /* @__PURE__ */ jsx(PermissionGroup, { group, value, onChange, isReadOnly }, group.key)) }) });
|
|
91
91
|
}
|
|
92
|
+
const PermissionMatrix = withPieceSlots(PermissionMatrixContent, THEME_NAME);
|
|
92
93
|
export {
|
|
93
94
|
PermissionMatrix as default
|
|
94
95
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionMatrix.js","sources":["../../src/access/PermissionMatrix.jsx"],"sourcesContent":["// Los permisos de un perfil, agrupados (un grupo por módulo), para la pantalla de «Perfiles y permisos»: cada grupo con\n// su casilla de «todos» (a medias si tiene algunos) y cuántos tiene, y cada permiso con su nombre y, si hace falta, qué\n// deja hacer en palabras normales.\n//\n// <PermissionMatrix groups={PERMISSION_GROUPS} value={profile.abilities} onChange={setAbilities} />\n//\n// Los permisos son los mismos textos que piden los menu.js y las rutas (access: {ability: 'orders.view'}), así que lo que\n// se palomea aquí es lo que el menú enseña o esconde. La lista de grupos la arma el proyecto (RBAC propio); guardar es\n// cosa de la pantalla.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPermissionMatrix con defaultProps y\n// styleOverrides de sus partes: permission, checkbox, group, groupHeader, groupTitle, grid.\n//\n// Genérico del paquete: function (regla de la casa). No sabe de negocio: todo llega ya traducido.\nimport {useId} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Checkbox from '@mui/material/Checkbox';\nimport Chip from '@mui/material/Chip';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {groupStateOf, withPermission, withPermissionGroup} from '@/access/permissionGroups.js';\nimport ComponentTexts from '@/toolkit/ComponentTexts.jsx';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaPermissionMatrix)\nconst THEME_NAME = 'CalcitaPermissionMatrix';\nconst PermissionsPermission = piecePart(THEME_NAME, 'Permission', FormControlLabel);\nconst PermissionsCheckbox = piecePart(THEME_NAME, 'Checkbox', Checkbox);\nconst PermissionsGroup = piecePart(THEME_NAME, 'Group', Paper);\nconst PermissionsGroupHeader = piecePart(THEME_NAME, 'GroupHeader', Stack);\nconst PermissionsGroupTitle = piecePart(THEME_NAME, 'GroupTitle', Typography);\nconst PermissionsGrid = piecePart(THEME_NAME, 'Grid', Box);\n\n/**\n * Un permiso: su casilla, su nombre y qué deja hacer.\n *\n * @param {{permission: {key: string, label: string, description?: string}, isGranted: boolean, readOnly: boolean, onToggle: (isGranted: boolean) => void}} props\n */\nfunction PermissionOption({permission, isGranted, readOnly, onToggle}) {\n return (\n <PermissionsPermission\n ownSx={{alignItems: 'flex-start', m: 0, gap: 0.5}}\n control={<PermissionsCheckbox size=\"small\" checked={isGranted} disabled={readOnly} onChange={(event) => onToggle(event.target.checked)}\n slotProps={{input: {'data-permission': permission.key}}} ownSx={{mt: -0.5}} />}\n label={(\n <Box>\n <Typography variant=\"body2\">{permission.label}</Typography>\n {permission.description && <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">{permission.description}</Typography>}\n </Box>\n )}\n />\n );\n}\n\n/**\n * Un grupo: su encabezado con «todos» y cuántos tiene, y sus permisos.\n *\n * OJO: es un grupo con role=\"group\" y no un <fieldset>: el navegador pinta el <legend> encima del borde y dejaba una franja\n * blanca arriba del encabezado.\n *\n * @param {{group: object, value: string[], onChange: Function, isReadOnly: boolean}} props\n */\nfunction PermissionGroup({group, value, onChange, isReadOnly}) {\n const {t} = useToolkitTranslation('access');\n const titleId = useId();\n const state = groupStateOf(group, value);\n return (\n <PermissionsGroup variant=\"outlined\" role=\"group\" aria-labelledby={titleId} data-group={group.key} ownSx={{overflow: 'hidden'}}>\n <PermissionsGroupHeader direction=\"row\" spacing={1} ownSx={{alignItems: 'center', px: 1.5, py: 0.75, borderBottom: 1, borderColor: 'divider', bgcolor: 'action.hover'}}>\n <Checkbox size=\"small\" checked={state.isAll} indeterminate={state.isSome} disabled={isReadOnly || state.total === 0}\n onChange={(event) => onChange(withPermissionGroup(value, group, event.target.checked))}\n slotProps={{input: {'aria-label': t('permissions.allOf', {group: group.label})}}} />\n <PermissionsGroupTitle id={titleId} variant=\"subtitle2\" component=\"h3\" ownSx={{flexGrow: 1}}>{group.label}</PermissionsGroupTitle>\n <Chip size=\"small\" label={t('permissions.countOf', {count: state.grantedCount, total: state.total})}\n color={state.grantedCount > 0 ? 'primary' : 'default'} variant={state.isAll ? 'filled' : 'outlined'} />\n </PermissionsGroupHeader>\n <PermissionsGrid ownSx={{display: 'grid', gridTemplateColumns: {xs: '1fr', md: 'repeat(2, minmax(0, 1fr))'}, gap: 1.5, p: 2}}>\n {group.permissions.map((permission) => (\n <PermissionOption key={permission.key} permission={permission} isGranted={value.includes(permission.key)} readOnly={isReadOnly}\n onToggle={(isGranted) => onChange(withPermission(value, permission.key, isGranted))} />\n ))}\n </PermissionsGrid>\n </PermissionsGroup>\n );\n}\n\n/**\n * @param {object} props\n * @param {Array<{key: string, label: string, permissions: Array<{key: string, label: string, description?: string}>}>} props.groups\n * @param {string[]} props.value los permisos del perfil\n * @param {(value: string[]) => void} [props.onChange] sin ella, o con readOnly, solo se ven\n * @param {boolean} [props.readOnly] un perfil que no se puede cambiar (el de administración)\n * @param {object} [props.texts] los textos que cambian, con la forma de `access` en los textos del paquete\n */\
|
|
1
|
+
{"version":3,"file":"PermissionMatrix.js","sources":["../../src/access/PermissionMatrix.jsx"],"sourcesContent":["// Los permisos de un perfil, agrupados (un grupo por módulo), para la pantalla de «Perfiles y permisos»: cada grupo con\n// su casilla de «todos» (a medias si tiene algunos) y cuántos tiene, y cada permiso con su nombre y, si hace falta, qué\n// deja hacer en palabras normales.\n//\n// <PermissionMatrix groups={PERMISSION_GROUPS} value={profile.abilities} onChange={setAbilities} />\n//\n// Los permisos son los mismos textos que piden los menu.js y las rutas (access: {ability: 'orders.view'}), así que lo que\n// se palomea aquí es lo que el menú enseña o esconde. La lista de grupos la arma el proyecto (RBAC propio); guardar es\n// cosa de la pantalla.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPermissionMatrix con defaultProps y\n// styleOverrides de sus partes: permission, checkbox, group, groupHeader, groupTitle, grid.\n//\n// Genérico del paquete: function (regla de la casa). No sabe de negocio: todo llega ya traducido.\nimport {useId} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Checkbox from '@mui/material/Checkbox';\nimport Chip from '@mui/material/Chip';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {groupStateOf, withPermission, withPermissionGroup} from '@/access/permissionGroups.js';\nimport ComponentTexts from '@/toolkit/ComponentTexts.jsx';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaPermissionMatrix)\nconst THEME_NAME = 'CalcitaPermissionMatrix';\nconst PermissionsPermission = piecePart(THEME_NAME, 'Permission', FormControlLabel);\nconst PermissionsCheckbox = piecePart(THEME_NAME, 'Checkbox', Checkbox);\nconst PermissionsGroup = piecePart(THEME_NAME, 'Group', Paper);\nconst PermissionsGroupHeader = piecePart(THEME_NAME, 'GroupHeader', Stack);\nconst PermissionsGroupTitle = piecePart(THEME_NAME, 'GroupTitle', Typography);\nconst PermissionsGrid = piecePart(THEME_NAME, 'Grid', Box);\n\n/**\n * Un permiso: su casilla, su nombre y qué deja hacer.\n *\n * @param {{permission: {key: string, label: string, description?: string}, isGranted: boolean, readOnly: boolean, onToggle: (isGranted: boolean) => void}} props\n */\nfunction PermissionOption({permission, isGranted, readOnly, onToggle}) {\n return (\n <PermissionsPermission\n ownSx={{alignItems: 'flex-start', m: 0, gap: 0.5}}\n control={<PermissionsCheckbox size=\"small\" checked={isGranted} disabled={readOnly} onChange={(event) => onToggle(event.target.checked)}\n slotProps={{input: {'data-permission': permission.key}}} ownSx={{mt: -0.5}} />}\n label={(\n <Box>\n <Typography variant=\"body2\">{permission.label}</Typography>\n {permission.description && <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">{permission.description}</Typography>}\n </Box>\n )}\n />\n );\n}\n\n/**\n * Un grupo: su encabezado con «todos» y cuántos tiene, y sus permisos.\n *\n * OJO: es un grupo con role=\"group\" y no un <fieldset>: el navegador pinta el <legend> encima del borde y dejaba una franja\n * blanca arriba del encabezado.\n *\n * @param {{group: object, value: string[], onChange: Function, isReadOnly: boolean}} props\n */\nfunction PermissionGroup({group, value, onChange, isReadOnly}) {\n const {t} = useToolkitTranslation('access');\n const titleId = useId();\n const state = groupStateOf(group, value);\n return (\n <PermissionsGroup variant=\"outlined\" role=\"group\" aria-labelledby={titleId} data-group={group.key} ownSx={{overflow: 'hidden'}}>\n <PermissionsGroupHeader direction=\"row\" spacing={1} ownSx={{alignItems: 'center', px: 1.5, py: 0.75, borderBottom: 1, borderColor: 'divider', bgcolor: 'action.hover'}}>\n <Checkbox size=\"small\" checked={state.isAll} indeterminate={state.isSome} disabled={isReadOnly || state.total === 0}\n onChange={(event) => onChange(withPermissionGroup(value, group, event.target.checked))}\n slotProps={{input: {'aria-label': t('permissions.allOf', {group: group.label})}}} />\n <PermissionsGroupTitle id={titleId} variant=\"subtitle2\" component=\"h3\" ownSx={{flexGrow: 1}}>{group.label}</PermissionsGroupTitle>\n <Chip size=\"small\" label={t('permissions.countOf', {count: state.grantedCount, total: state.total})}\n color={state.grantedCount > 0 ? 'primary' : 'default'} variant={state.isAll ? 'filled' : 'outlined'} />\n </PermissionsGroupHeader>\n <PermissionsGrid ownSx={{display: 'grid', gridTemplateColumns: {xs: '1fr', md: 'repeat(2, minmax(0, 1fr))'}, gap: 1.5, p: 2}}>\n {group.permissions.map((permission) => (\n <PermissionOption key={permission.key} permission={permission} isGranted={value.includes(permission.key)} readOnly={isReadOnly}\n onToggle={(isGranted) => onChange(withPermission(value, permission.key, isGranted))} />\n ))}\n </PermissionsGrid>\n </PermissionsGroup>\n );\n}\n\n/**\n * @param {object} props\n * @param {Array<{key: string, label: string, permissions: Array<{key: string, label: string, description?: string}>}>} props.groups\n * @param {string[]} props.value los permisos del perfil\n * @param {(value: string[]) => void} [props.onChange] sin ella, o con readOnly, solo se ven\n * @param {boolean} [props.readOnly] un perfil que no se puede cambiar (el de administración)\n * @param {object} [props.texts] los textos que cambian, con la forma de `access` en los textos del paquete\n */\nfunction PermissionMatrixContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaPermissionMatrix.defaultProps) y encima lo que llega aquí\n const {groups, value, onChange, readOnly = false, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const isReadOnly = readOnly || !onChange;\n return (\n <ComponentTexts namespace=\"access\" texts={texts}>\n <Stack spacing={1.5}>\n {groups.map((group) => <PermissionGroup key={group.key} group={group} value={value} onChange={onChange} isReadOnly={isReadOnly} />)}\n </Stack>\n </ComponentTexts>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst PermissionMatrix = withPieceSlots(PermissionMatrixContent, THEME_NAME);\nexport default PermissionMatrix;\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import { createContext, useState, useCallback, useRef, useEffect, useMemo
|
|
3
|
+
import { createContext, useContext, useState, useCallback, useRef, useEffect, useMemo } from "react";
|
|
4
4
|
import { missingConnectorFunctionsOf } from "./accountConnector.js";
|
|
5
5
|
import { createAccessChecker } from "../access/accessRules.js";
|
|
6
6
|
import ErrorPage, { ERROR_PAGE_KIND } from "../ui/layout/ErrorPage.js";
|
|
@@ -14,14 +14,14 @@ import { createPasskey, passkeysSupported } from "../security/passkeys.js";
|
|
|
14
14
|
import SessionsCard from "../security/SessionsCard.js";
|
|
15
15
|
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
16
16
|
import SectionCard from "../ui/layout/SectionCard.js";
|
|
17
|
-
import { piecePart, usePieceProps } from "../theme/themePieces.js";
|
|
17
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
18
18
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
19
19
|
const THEME_NAME = "CalcitaAccountSecurity";
|
|
20
20
|
const SecurityTitle = piecePart(THEME_NAME, "Title", Typography);
|
|
21
21
|
const SecurityForm = piecePart(THEME_NAME, "Form", Stack);
|
|
22
22
|
const FORM_MAX_WIDTH = 520;
|
|
23
23
|
const LOADING_HEIGHT_PIXELS = 220;
|
|
24
|
-
function
|
|
24
|
+
function AccountSecuritySectionContent(props) {
|
|
25
25
|
const { showPasswordChange = true, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
26
26
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
27
27
|
const { t } = useToolkitTranslation("account", texts);
|
|
@@ -82,6 +82,7 @@ function AccountSecuritySection(props) {
|
|
|
82
82
|
/* @__PURE__ */ jsx(ActivityLog, { events })
|
|
83
83
|
] });
|
|
84
84
|
}
|
|
85
|
+
const AccountSecuritySection = withPieceSlots(AccountSecuritySectionContent, THEME_NAME);
|
|
85
86
|
export {
|
|
86
87
|
AccountSecuritySection as default
|
|
87
88
|
};
|