bitboss-ui 3.0.0-beta.64 → 3.0.0-beta.66
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 +78 -16
- package/bin/bitboss-ui-mcp.mjs +8 -8
- package/bin/bitboss-ui.mjs +73 -12
- package/dist/ai/BbAccordion.md +4 -3
- package/dist/ai/BbAlert.md +1 -1
- package/dist/ai/BbBadge.md +1 -0
- package/dist/ai/BbBadgeButton.md +4 -3
- package/dist/ai/BbBaseButton.md +25 -20
- package/dist/ai/BbBaseCheckboxIcon.md +1 -0
- package/dist/ai/BbBaseRadioIcon.md +1 -0
- package/dist/ai/BbBaseSwitchIcon.md +1 -0
- package/dist/ai/BbBreadcrumbs.md +8 -0
- package/dist/ai/BbButton.md +67 -21
- package/dist/ai/BbCalendar.md +56 -3
- package/dist/ai/BbCheckbox.md +1 -1
- package/dist/ai/BbCheckboxGroup.md +44 -8
- package/dist/ai/BbColorInput.md +3 -2
- package/dist/ai/BbColorPalette.md +7 -3
- package/dist/ai/BbConfirm.md +36 -80
- package/dist/ai/BbConfirmPortal.md +1 -1
- package/dist/ai/BbDatePicker.md +41 -5
- package/dist/ai/BbDatePickerInput.md +38 -6
- package/dist/ai/BbDialog.md +63 -58
- package/dist/ai/BbDropdown.md +25 -24
- package/dist/ai/BbDropdownButton.md +5 -12
- package/dist/ai/BbDropzone.md +2 -3
- package/dist/ai/BbForm.md +66 -42
- package/dist/ai/BbHost.md +29 -41
- package/dist/ai/BbIcon.md +3 -0
- package/dist/ai/BbNumberInput.md +2 -2
- package/dist/ai/BbOffCanvas.md +16 -9
- package/dist/ai/BbPagination.md +17 -17
- package/dist/ai/BbPopover.md +8 -3
- package/dist/ai/BbPtScope.md +5 -5
- package/dist/ai/BbRadio.md +1 -1
- package/dist/ai/BbRadioGroup.md +44 -7
- package/dist/ai/BbRating.md +1 -0
- package/dist/ai/BbSelect.md +146 -21
- package/dist/ai/BbSelectPopover.md +16 -12
- package/dist/ai/BbSlider.md +5 -3
- package/dist/ai/BbSwitch.md +1 -1
- package/dist/ai/BbTable.md +51 -39
- package/dist/ai/BbTabs.md +127 -63
- package/dist/ai/BbTabsList.md +4 -2
- package/dist/ai/BbTabsPanels.md +3 -1
- package/dist/ai/BbTabsRoot.md +4 -4
- package/dist/ai/BbTag.md +2 -2
- package/dist/ai/BbTextInput.md +23 -9
- package/dist/ai/BbTextarea.md +3 -3
- package/dist/ai/BbTimePicker.md +5 -4
- package/dist/ai/BbTimePickerInput.md +3 -3
- package/dist/ai/BbToast.md +33 -87
- package/dist/ai/BbToastPortal.md +1 -1
- package/dist/ai/CommonFieldInput.md +2 -1
- package/dist/ai/FlatListBox.md +1 -1
- package/dist/ai/GroupedListBox.md +1 -1
- package/dist/ai/ListBox.md +1 -1
- package/dist/ai/OptionsContainer.md +1 -1
- package/dist/ai/changelog.json +444 -4
- package/dist/ai/components.json +87 -83
- package/dist/ai/composables/useBbConfig.md +8 -1
- package/dist/ai/composables/{useBbDialogContext.md → useBbDialog.md} +18 -18
- package/dist/ai/composables/{useBbDropdownContext.md → useBbDropdown.md} +31 -31
- package/dist/ai/composables/{useBbFormContext.md → useBbForm.md} +11 -11
- package/dist/ai/composables/useBbFormField.md +2 -2
- package/dist/ai/composables/{useBbOffCanvasContext.md → useBbOffCanvas.md} +13 -13
- package/dist/ai/composables/{useBbTableContext.md → useBbTable.md} +20 -20
- package/dist/ai/composables/{useBbTabsContext.md → useBbTabs.md} +12 -12
- package/dist/ai/composables/useConfirm.md +42 -54
- package/dist/ai/composables/useToast.md +9 -26
- package/dist/ai/guides/agent-contract.md +57 -43
- package/dist/ai/guides/ai-router.md +1 -1
- package/dist/ai/guides/app-layout.md +32 -23
- package/dist/ai/guides/coherence-playbook.md +4 -2
- package/dist/ai/guides/component-picker.md +35 -32
- package/dist/ai/guides/design-language.md +26 -12
- package/dist/ai/guides/design-tokens.md +73 -32
- package/dist/ai/guides/eslint-rules.md +8 -4
- package/dist/ai/guides/fetch-items-playbook.md +3 -3
- package/dist/ai/guides/floating-bottom-panel.md +1 -1
- package/dist/ai/guides/inertia-helpers.md +1640 -337
- package/dist/ai/guides/installation-and-plugin-setup.md +6 -3
- package/dist/ai/guides/migration/adoption-checklist.md +44 -2
- package/dist/ai/guides/migration/components/bb-dialog.md +13 -13
- package/dist/ai/guides/migration/components/bb-dropdown.md +16 -16
- package/dist/ai/guides/migration/components/bb-host.md +15 -14
- package/dist/ai/guides/migration/components/bb-offcanvas.md +10 -10
- package/dist/ai/guides/migration/components/bb-pagination.md +9 -9
- package/dist/ai/guides/migration/components/bb-select.md +1 -1
- package/dist/ai/guides/migration/components/bb-table.md +12 -12
- package/dist/ai/guides/migration/components/bb-tabs.md +1 -1
- package/dist/ai/guides/migration/from-async-validator.md +9 -9
- package/dist/ai/guides/migration/v2-to-v3.md +206 -13
- package/dist/ai/guides/options-items-playbook.md +2 -2
- package/dist/ai/guides/page-shell.md +15 -3
- package/dist/ai/guides/passthrough.md +13 -7
- package/dist/ai/guides/preset-components.md +102 -43
- package/dist/ai/guides/typescript-generic-components.md +21 -5
- package/dist/ai/guides/validated-forms.md +20 -11
- package/dist/ai/guides/validation-providers.md +3 -3
- package/dist/ai/helpers/definePreset.json +11 -4
- package/dist/ai/helpers/definePreset.ts +98 -41
- package/dist/ai/helpers/inertia/manifest.json +332 -91
- package/dist/ai/helpers/inertia/messages.ts +33 -0
- package/dist/ai/helpers/inertia/useConfirmOnRouteLeave.ts +133 -21
- package/dist/ai/helpers/inertia/useHasChanged.ts +34 -16
- package/dist/ai/helpers/inertia/useLazyProp.ts +102 -36
- package/dist/ai/helpers/inertia/useLazyPropGetter.ts +3 -1
- package/dist/ai/helpers/inertia/usePaginatedResponseContext.ts +129 -24
- package/dist/ai/helpers/inertia/usePromiseForm.ts +38 -44
- package/dist/ai/helpers/inertia/usePromiseRouter.ts +295 -0
- package/dist/ai/helpers/inertia/useQuery.ts +133 -11
- package/dist/ai/helpers/inertia/useQueryObject.ts +104 -66
- package/dist/ai/helpers/inertia/useResourceContext.ts +60 -14
- package/dist/ai/helpers/inertia/useRouteQuery.ts +57 -33
- package/dist/ai/helpers/inertia/useScreenSizes.ts +9 -7
- package/dist/ai/helpers/inertia/useTableContext.ts +5 -2
- package/dist/ai/helpers/inertia/utils.ts +57 -0
- package/dist/ai/index.md +15 -15
- package/dist/ai/manifest/common.json +2 -1
- package/dist/ai/manifest/components/BbAccordion.tree.json +3 -1
- package/dist/ai/manifest/components/BbAlert.json +1 -1
- package/dist/ai/manifest/components/BbBadge.tree.json +3 -1
- package/dist/ai/manifest/components/BbBadgeButton.json +9 -4
- package/dist/ai/manifest/components/BbBadgeButton.tree.json +1 -0
- package/dist/ai/manifest/components/BbBaseButton.json +9 -4
- package/dist/ai/manifest/components/BbBaseCheckboxIcon.tree.json +3 -1
- package/dist/ai/manifest/components/BbBaseRadioIcon.tree.json +3 -1
- package/dist/ai/manifest/components/BbBaseSwitchIcon.tree.json +3 -1
- package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +7 -3
- package/dist/ai/manifest/components/BbButton.json +9 -4
- package/dist/ai/manifest/components/BbButton.tree.json +5 -3
- package/dist/ai/manifest/components/BbCalendar.json +4 -3
- package/dist/ai/manifest/components/BbCalendar.tree.json +10 -1
- package/dist/ai/manifest/components/BbCheckbox.json +1 -1
- package/dist/ai/manifest/components/BbCheckbox.tree.json +1 -1
- package/dist/ai/manifest/components/BbCheckboxGroup.json +1 -1
- package/dist/ai/manifest/components/BbCheckboxGroup.tree.json +62 -3
- package/dist/ai/manifest/components/BbCollapsible.json +4 -1
- package/dist/ai/manifest/components/BbColorInput.json +1 -1
- package/dist/ai/manifest/components/BbColorInput.tree.json +5 -3
- package/dist/ai/manifest/components/BbColorPalette.json +3 -0
- package/dist/ai/manifest/components/BbColorPalette.tree.json +7 -2
- package/dist/ai/manifest/components/BbConfirm.tree.json +2 -2
- package/dist/ai/manifest/components/BbDatePicker.json +7 -3
- package/dist/ai/manifest/components/BbDatePicker.tree.json +3 -4
- package/dist/ai/manifest/components/BbDatePickerInput.json +4 -3
- package/dist/ai/manifest/components/BbDatePickerInput.tree.json +5 -3
- package/dist/ai/manifest/components/BbDialog.json +1 -1
- package/dist/ai/manifest/components/BbDialog.tree.json +2 -2
- package/dist/ai/manifest/components/BbDropdown.json +3 -3
- package/dist/ai/manifest/components/BbDropdown.tree.json +2 -2
- package/dist/ai/manifest/components/BbDropdownButton.json +11 -6
- package/dist/ai/manifest/components/BbDropdownButton.tree.json +2 -3
- package/dist/ai/manifest/components/BbDropzone.json +4 -1
- package/dist/ai/manifest/components/BbForm.json +2 -2
- package/dist/ai/manifest/components/BbHost.json +1 -1
- package/dist/ai/manifest/components/BbHost.tree.json +1 -1
- package/dist/ai/manifest/components/BbHoverCard.json +1 -1
- package/dist/ai/manifest/components/BbNumberInput.json +1 -1
- package/dist/ai/manifest/components/BbNumberInput.tree.json +1 -1
- package/dist/ai/manifest/components/BbOffCanvas.json +1 -1
- package/dist/ai/manifest/components/BbOffCanvas.tree.json +3 -1
- package/dist/ai/manifest/components/BbPagination.json +4 -4
- package/dist/ai/manifest/components/BbPagination.tree.json +2 -1
- package/dist/ai/manifest/components/BbPopover.json +1 -1
- package/dist/ai/manifest/components/BbPopover.tree.json +1 -1
- package/dist/ai/manifest/components/BbProgress.json +4 -1
- package/dist/ai/manifest/components/BbRadio.json +1 -1
- package/dist/ai/manifest/components/BbRadio.tree.json +1 -1
- package/dist/ai/manifest/components/BbRadioGroup.json +5 -5
- package/dist/ai/manifest/components/BbRadioGroup.tree.json +62 -3
- package/dist/ai/manifest/components/BbRating.tree.json +3 -1
- package/dist/ai/manifest/components/BbSelect.json +5 -5
- package/dist/ai/manifest/components/BbSelect.tree.json +3 -3
- package/dist/ai/manifest/components/BbSelectPopover.json +7 -3
- package/dist/ai/manifest/components/BbSelectPopover.tree.json +2 -2
- package/dist/ai/manifest/components/BbSlider.json +3 -3
- package/dist/ai/manifest/components/BbSlider.tree.json +3 -0
- package/dist/ai/manifest/components/BbSmoothHeight.json +4 -1
- package/dist/ai/manifest/components/BbSwitch.json +1 -1
- package/dist/ai/manifest/components/BbSwitch.tree.json +1 -1
- package/dist/ai/manifest/components/BbSwitchGroup.tree.json +1 -1
- package/dist/ai/manifest/components/BbTable.json +6 -2
- package/dist/ai/manifest/components/BbTable.tree.json +4 -1
- package/dist/ai/manifest/components/BbTabs.json +9 -12
- package/dist/ai/manifest/components/BbTabs.tree.json +4 -1
- package/dist/ai/manifest/components/BbTabsList.json +4 -7
- package/dist/ai/manifest/components/BbTabsList.tree.json +4 -1
- package/dist/ai/manifest/components/BbTabsPanels.json +1 -1
- package/dist/ai/manifest/components/BbTabsPanels.tree.json +4 -1
- package/dist/ai/manifest/components/BbTabsRoot.json +5 -5
- package/dist/ai/manifest/components/BbTag.json +1 -1
- package/dist/ai/manifest/components/BbTag.tree.json +2 -2
- package/dist/ai/manifest/components/BbTextInput.json +4 -4
- package/dist/ai/manifest/components/BbTextInput.tree.json +1 -1
- package/dist/ai/manifest/components/BbTextarea.json +2 -2
- package/dist/ai/manifest/components/BbTextarea.tree.json +1 -1
- package/dist/ai/manifest/components/BbTimePicker.json +4 -1
- package/dist/ai/manifest/components/BbTimePicker.tree.json +5 -3
- package/dist/ai/manifest/components/BbTimePickerInput.json +2 -2
- package/dist/ai/manifest/components/BbTimePickerInput.tree.json +5 -3
- package/dist/ai/manifest/components/BbToast.json +1 -1
- package/dist/ai/manifest/components/BbToast.tree.json +3 -1
- package/dist/ai/manifest/components/BbTooltip.json +3 -0
- package/dist/ai/manifest/components/ChipsBox.tree.json +1 -1
- package/dist/ai/manifest/components/CommonField.tree.json +1 -0
- package/dist/ai/manifest/components/CommonFieldInput.tree.json +4 -2
- package/dist/ai/manifest/components/CommonTimeSelector.tree.json +1 -0
- package/dist/ai/manifest/components/FlatListBox.json +1 -1
- package/dist/ai/manifest/components/GroupedListBox.json +1 -1
- package/dist/ai/manifest/components/ListBox.json +1 -1
- package/dist/ai/manifest/components/OptionsContainer.json +2 -2
- package/dist/ai/manifest/index.json +3 -3
- package/dist/ai/manifest/meta.json +31 -16
- package/dist/ai/manifest/types.advanced.json +15 -11
- package/dist/ai/manifest/types.api.json +2 -2
- package/dist/ai/recipes/inertia/approvals-inbox.md +87 -116
- package/dist/ai/recipes/inertia/inline-edit-workspace.md +113 -121
- package/dist/ai/recipes/inertia/layout-scaffold.md +15 -4
- package/dist/ai/recipes/inertia/onboarding.md +76 -58
- package/dist/ai/recipes/inertia/ownership-atlas.md +75 -106
- package/dist/ai/recipes/inertia/record-form.md +18 -7
- package/dist/ai/recipes/inertia/records-workspace.md +107 -128
- package/dist/ai/recipes/inertia/settings-workspace.md +131 -73
- package/dist/ai/recipes/inertia/upload-center.md +98 -122
- package/dist/ai/recipes/inertia/wizard-form.md +25 -15
- package/dist/ai/recipes/nuxt/approvals-inbox.md +67 -48
- package/dist/ai/recipes/nuxt/inline-edit-workspace.md +73 -58
- package/dist/ai/recipes/nuxt/layout-scaffold.md +15 -4
- package/dist/ai/recipes/nuxt/onboarding.md +27 -10
- package/dist/ai/recipes/nuxt/ownership-atlas.md +40 -22
- package/dist/ai/recipes/nuxt/record-form.md +20 -7
- package/dist/ai/recipes/nuxt/records-workspace.md +120 -96
- package/dist/ai/recipes/nuxt/settings-workspace.md +36 -23
- package/dist/ai/recipes/nuxt/upload-center.md +63 -37
- package/dist/ai/recipes/nuxt/wizard-form.md +28 -16
- package/dist/ai/recipes/vue/approvals-inbox.md +74 -46
- package/dist/ai/recipes/vue/inline-edit-workspace.md +83 -56
- package/dist/ai/recipes/vue/layout-scaffold.md +15 -4
- package/dist/ai/recipes/vue/onboarding.md +27 -10
- package/dist/ai/recipes/vue/ownership-atlas.md +40 -22
- package/dist/ai/recipes/vue/record-form.md +20 -7
- package/dist/ai/recipes/vue/records-workspace.md +132 -95
- package/dist/ai/recipes/vue/settings-workspace.md +36 -23
- package/dist/ai/recipes/vue/upload-center.md +73 -37
- package/dist/ai/recipes/vue/wizard-form.md +28 -16
- package/dist/ai/source/BbAccordion.md +36 -6
- package/dist/ai/source/BbAlert.md +11 -5
- package/dist/ai/source/BbAsterisk.md +4 -1
- package/dist/ai/source/BbAvatar.md +11 -5
- package/dist/ai/source/BbBadge.md +42 -11
- package/dist/ai/source/BbBadgeButton.md +41 -8
- package/dist/ai/source/BbBaseButton.md +57 -15
- package/dist/ai/source/BbBaseCheckboxIcon.md +37 -13
- package/dist/ai/source/BbBaseRadioIcon.md +32 -9
- package/dist/ai/source/BbBaseSwitchIcon.md +31 -7
- package/dist/ai/source/BbBreadcrumbs.md +32 -9
- package/dist/ai/source/BbButton.md +91 -27
- package/dist/ai/source/BbCalendar.md +571 -300
- package/dist/ai/source/BbCheckbox.md +18 -7
- package/dist/ai/source/BbCheckboxGroup.md +16 -5
- package/dist/ai/source/BbCollapsible.md +15 -6
- package/dist/ai/source/BbColorInput.md +68 -20
- package/dist/ai/source/BbColorPalette.md +107 -23
- package/dist/ai/source/BbConfirmPortal.md +1 -1
- package/dist/ai/source/BbDatePicker.md +106 -25
- package/dist/ai/source/BbDatePickerInput.md +105 -42
- package/dist/ai/source/BbDialog.md +60 -44
- package/dist/ai/source/BbDropdown.md +44 -32
- package/dist/ai/source/BbDropdownButton.md +26 -20
- package/dist/ai/source/BbDropdownGroup.md +5 -5
- package/dist/ai/source/BbDropzone.md +53 -16
- package/dist/ai/source/BbForm.md +18 -7
- package/dist/ai/source/BbHost.md +25 -12
- package/dist/ai/source/BbHoverCard.md +20 -9
- package/dist/ai/source/BbIcon.md +9 -3
- package/dist/ai/source/BbIndicator.md +11 -4
- package/dist/ai/source/BbNumberInput.md +23 -6
- package/dist/ai/source/BbOffCanvas.md +73 -32
- package/dist/ai/source/BbPagination.md +59 -31
- package/dist/ai/source/BbPopover.md +28 -16
- package/dist/ai/source/BbProgress.md +13 -5
- package/dist/ai/source/BbRadio.md +16 -9
- package/dist/ai/source/BbRadioGroup.md +15 -4
- package/dist/ai/source/BbRating.md +51 -10
- package/dist/ai/source/BbSelect.md +56 -27
- package/dist/ai/source/BbSelectPopover.md +106 -36
- package/dist/ai/source/BbSlider.md +111 -33
- package/dist/ai/source/BbSmoothHeight.md +16 -7
- package/dist/ai/source/BbSpinner.md +9 -3
- package/dist/ai/source/BbSwitch.md +16 -9
- package/dist/ai/source/BbSwitchGroup.md +18 -7
- package/dist/ai/source/BbTable.md +172 -38
- package/dist/ai/source/BbTabs.md +58 -40
- package/dist/ai/source/BbTabsList.md +109 -50
- package/dist/ai/source/BbTabsPanels.md +65 -31
- package/dist/ai/source/BbTabsRoot.md +35 -24
- package/dist/ai/source/BbTag.md +18 -4
- package/dist/ai/source/BbTextInput.md +20 -3
- package/dist/ai/source/BbTextarea.md +15 -1
- package/dist/ai/source/BbTimePicker.md +81 -21
- package/dist/ai/source/BbTimePickerInput.md +63 -15
- package/dist/ai/source/BbToast.md +20 -3
- package/dist/ai/source/BbToastPortal.md +21 -4
- package/dist/ai/source/BbTooltip.md +16 -8
- package/dist/ai/source/BbTree.md +10 -3
- package/dist/ai/source/ClearableButton.md +5 -1
- package/dist/ai/source/CommonField.md +65 -9
- package/dist/ai/source/CommonFieldInput.md +61 -27
- package/dist/ai/source/CommonPopover.md +17 -6
- package/dist/ai/source/CommonTimeSelector.md +21 -2
- package/dist/ai/source/ErrorIcon.md +4 -0
- package/dist/ai/source/ListBox.md +9 -1
- package/dist/ai/source/OptionsContainer.md +5 -1
- package/dist/ai/source/WarningIcon.md +4 -0
- package/dist/components/BbAccordion/BbAccordion.vue.d.ts +2 -1
- package/dist/components/BbAccordion/BbAccordion.vue_vue_type_script_setup_true_lang.js +6 -6
- package/dist/components/BbAlert/BbAlert.vue.d.ts +2 -1
- package/dist/components/BbAlert/BbAlert.vue_vue_type_script_setup_true_lang.js +10 -10
- package/dist/components/BbAsterisk/BbAsterisk.vue.d.ts +3 -1
- package/dist/components/BbAvatar/BbAvatar.vue.d.ts +3 -1
- package/dist/components/BbAvatar/BbAvatar.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/BbBadge/BbBadge.vue.d.ts +5 -3
- package/dist/components/BbBadge/BbBadge.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/BbBadge/BbBadgeButton.vue.d.ts +3 -1
- package/dist/components/BbBadge/BbBadgeButton.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/BbBaseButton/BbBaseButton.vue.d.ts +3 -1
- package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +85 -85
- package/dist/components/BbBaseButton/types.d.ts +8 -5
- package/dist/components/BbBaseButton/useLinkState.d.ts +2 -0
- package/dist/components/BbBaseButton/useLinkState.js +21 -20
- package/dist/components/BbBaseCheckboxIcon/BbBaseCheckboxIcon.vue.d.ts +3 -1
- package/dist/components/BbBaseRadioIcon/BbBaseRadioIcon.vue.d.ts +3 -1
- package/dist/components/BbBaseSwitchIcon/BbBaseSwitchIcon.vue.d.ts +3 -1
- package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue.d.ts +3 -1
- package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/BbButton/BbButton.vue.d.ts +2 -1
- package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +93 -93
- package/dist/components/BbButton/types.d.ts +7 -4
- package/dist/components/BbCalendar/BbCalendar.vue.d.ts +157 -30
- package/dist/components/BbCalendar/BbCalendar.vue_vue_type_script_setup_true_lang.js +364 -331
- package/dist/components/BbCalendar/CalendarMonthPanel.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/BbCalendar/types.d.ts +36 -8
- package/dist/components/BbCalendar/useCalendarGrid.d.ts +133 -0
- package/dist/components/BbCalendar/useCalendarGrid.js +193 -183
- package/dist/components/BbCalendar/useDayGrid.d.ts +24 -19
- package/dist/components/BbCalendar/useDayGrid.js +105 -102
- package/dist/components/BbCheckbox/BbCheckbox.vue.d.ts +4 -2
- package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue.d.ts +327 -2
- package/dist/components/BbCollapsible/BbCollapsible.vue.d.ts +3 -1
- package/dist/components/BbCollapsible/BbCollapsible.vue_vue_type_script_setup_true_lang.js +6 -6
- package/dist/components/BbColorInput/BbColorInput.vue.d.ts +8 -5
- package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/BbColorInput/types.d.ts +2 -0
- package/dist/components/BbColorPalette/BbColorPalette.vue.d.ts +7 -5
- package/dist/components/BbColorPalette/BbColorPalette.vue_vue_type_script_setup_true_lang.js +216 -215
- package/dist/components/BbConfirm/BbConfirm.vue_vue_type_script_setup_true_lang.js +25 -25
- package/dist/components/BbDatePicker/BbDatePicker.vue.d.ts +206 -41
- package/dist/components/BbDatePicker/BbDatePicker.vue_vue_type_script_setup_true_lang.js +112 -106
- package/dist/components/BbDatePicker/types.d.ts +27 -8
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue.d.ts +519 -37
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +11 -8
- package/dist/components/BbDatePickerInput/types.d.ts +31 -9
- package/dist/components/BbDialog/BbDialog.vue.d.ts +6 -5
- package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +231 -233
- package/dist/components/BbDialog/types.d.ts +7 -7
- package/dist/components/BbDialog/useDialogStack.d.ts +2 -0
- package/dist/components/BbDialog/useDialogStack.js +6 -2
- package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +25 -25
- package/dist/components/BbDropdown/BbDropdown.vue.d.ts +8 -6
- package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +226 -225
- package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +49 -49
- package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/BbDropdown/normalizeGroups.js +14 -14
- package/dist/components/BbDropdown/types.d.ts +5 -5
- package/dist/components/BbDropdown/useDropdownContext.js +1 -1
- package/dist/components/BbDropdown/useDropdownGroupRegistry.d.ts +1 -1
- package/dist/components/BbDropdownButton/BbDropdownButton.vue.d.ts +6 -4
- package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +36 -38
- package/dist/components/BbDropdownButton/types.js +4 -4
- package/dist/components/BbDropzone/BbDropzone.vue.d.ts +57 -22
- package/dist/components/BbDropzone/BbDropzone.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/BbDropzone/types.d.ts +16 -4
- package/dist/components/BbForm/BbForm.vue.d.ts +52 -4
- package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbHost/BbHost.vue_vue_type_script_setup_true_lang.js +19 -23
- package/dist/components/BbHost/BbHostOpening.js +1 -1
- package/dist/components/BbHoverCard/BbHoverCard.vue.d.ts +5 -4
- package/dist/components/BbHoverCard/BbHoverCard.vue_vue_type_script_setup_true_lang.js +116 -116
- package/dist/components/BbIcon/BbIcon.vue.d.ts +3 -1
- package/dist/components/BbIcon/BbIcon.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/BbIndicator/BbIndicator.vue.d.ts +3 -1
- package/dist/components/BbNumberInput/BbNumberInput.vue.d.ts +6 -3
- package/dist/components/BbNumberInput/types.d.ts +2 -0
- package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +5 -4
- package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +366 -369
- package/dist/components/BbOffCanvas/sheetAttrs.d.ts +9 -0
- package/dist/components/BbOffCanvas/sheetAttrs.js +10 -0
- package/dist/components/BbOffCanvas/types.d.ts +7 -7
- package/dist/components/BbOffCanvas/useOffCanvasStack.d.ts +2 -0
- package/dist/components/BbOffCanvas/useOffCanvasStack.js +7 -3
- package/dist/components/BbPagination/BbPagination.vue.d.ts +2 -1
- package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/components/BbPagination/types.d.ts +5 -5
- package/dist/components/BbPopover/BbPopover.vue.d.ts +5 -4
- package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +92 -91
- package/dist/components/BbProgress/BbProgress.vue.d.ts +6 -1
- package/dist/components/BbRadio/BbRadio.vue.d.ts +4 -2
- package/dist/components/BbRadioGroup/BbRadioGroup.vue.d.ts +281 -1
- package/dist/components/BbRating/BbRating.vue.d.ts +4 -2
- package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/BbSelect/BbSelect.vue.d.ts +575 -4
- package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/BbSelect/types.d.ts +12 -2
- package/dist/components/BbSelectPopover/BbSelectPopover.vue.d.ts +105 -3
- package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +695 -680
- package/dist/components/BbSelectPopover/types.d.ts +9 -1
- package/dist/components/BbSlider/BbSlider.vue.d.ts +135 -33
- package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/BbSlider/types.d.ts +19 -4
- package/dist/components/BbSmoothHeight/BbSmoothHeight.vue.d.ts +3 -1
- package/dist/components/BbSpinner/BbSpinner.vue.d.ts +3 -1
- package/dist/components/BbSwitch/BbSwitch.vue.d.ts +4 -2
- package/dist/components/BbSwitchGroup/BbSwitchGroup.vue.d.ts +131 -1
- package/dist/components/BbTable/BbTable.vue.d.ts +5 -2
- package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +593 -578
- package/dist/components/BbTable/types.d.ts +14 -1
- package/dist/components/BbTable/utils.d.ts +2 -1
- package/dist/components/BbTable/utils.js +37 -38
- package/dist/components/BbTabs/BbTabs.vue.d.ts +96 -2
- package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +8 -6
- package/dist/components/BbTabs/BbTabsList.vue.d.ts +11 -1
- package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +102 -92
- package/dist/components/BbTabs/BbTabsPanels.vue.d.ts +9 -1
- package/dist/components/BbTabs/BbTabsPanels.vue_vue_type_script_setup_true_lang.js +20 -17
- package/dist/components/BbTabs/BbTabsRoot.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbTabs/types.d.ts +34 -23
- package/dist/components/BbTag/BbTag.vue.d.ts +5 -2
- package/dist/components/BbTag/types.d.ts +2 -0
- package/dist/components/BbTextInput/BbTextInput.vue.d.ts +195 -2
- package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/BbTextInput/types.d.ts +2 -0
- package/dist/components/BbTextarea/BbTextarea.vue.d.ts +193 -2
- package/dist/components/BbTextarea/types.d.ts +2 -0
- package/dist/components/BbTimePicker/BbTimePicker.vue.d.ts +78 -38
- package/dist/components/BbTimePicker/BbTimePicker.vue_vue_type_script_setup_true_lang.js +138 -137
- package/dist/components/BbTimePicker/types.d.ts +18 -4
- package/dist/components/BbTimePickerInput/BbTimePickerInput.vue.d.ts +272 -33
- package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +16 -16
- package/dist/components/BbTimePickerInput/types.d.ts +20 -5
- package/dist/components/BbToast/BbToastMessage.vue_vue_type_script_setup_true_lang.js +6 -6
- package/dist/components/BbToast/BbToastRegion.vue_vue_type_script_setup_true_lang.js +20 -20
- package/dist/components/BbTooltip/BbTooltip.vue.d.ts +3 -2
- package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +109 -109
- package/dist/components/BbTree/BbTree.vue.d.ts +1 -1
- package/dist/components/ClearableButton/ClearableButton.vue.d.ts +3 -1
- package/dist/components/CloseIcon/CloseButton.vue.d.ts +3 -1
- package/dist/components/CloseIcon/CloseButton.vue.js +1 -1
- package/dist/components/CommonField/CommonField.vue.d.ts +3 -1
- package/dist/components/CommonFieldInput/CommonFieldInput.vue.d.ts +5 -3
- package/dist/components/CommonPopover/CommonPopover.vue.d.ts +5 -4
- package/dist/components/CommonPopover/CommonPopover.vue_vue_type_script_setup_true_lang.js +55 -55
- package/dist/components/ErrorIcon/ErrorIcon.vue.d.ts +3 -1
- package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +124 -124
- package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +71 -71
- package/dist/components/ListBox/ListBox.vue.d.ts +1 -1
- package/dist/components/OptionsContainer/OptionsContainer.vue.d.ts +1 -1
- package/dist/components/OptionsContainer/OptionsContainer.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/Transitions/Slide.vue.d.ts +1 -1
- package/dist/components/WarningIcon/WarningIcon.vue.d.ts +3 -1
- package/dist/composables/autoHost.d.ts +22 -0
- package/dist/composables/autoHost.js +20 -0
- package/dist/composables/hostOpenings.d.ts +3 -3
- package/dist/composables/hostOpenings.js +1 -1
- package/dist/composables/hostRegistry.d.ts +10 -2
- package/dist/composables/hostRegistry.js +5 -3
- package/dist/composables/overlayRegistry.d.ts +1 -1
- package/dist/composables/overlayRegistry.js +2 -2
- package/dist/composables/useBbConfig.d.ts +1 -0
- package/dist/composables/useBbConfig.js +11 -7
- package/dist/composables/{useBbDialogContext.d.ts → useBbDialog.d.ts} +9 -9
- package/dist/composables/{useBbDialogContext.js → useBbDialog.js} +4 -4
- package/dist/composables/{useBbDropdownContext.d.ts → useBbDropdown.d.ts} +14 -14
- package/dist/composables/{useBbDropdownContext.js → useBbDropdown.js} +2 -2
- package/dist/composables/{useBbFormContext.d.ts → useBbForm.d.ts} +8 -8
- package/dist/composables/{useBbFormContext.js → useBbForm.js} +3 -3
- package/dist/composables/useBbOffCanvas.d.ts +23 -0
- package/dist/composables/{useBbOffCanvasContext.js → useBbOffCanvas.js} +3 -3
- package/dist/composables/{useBbTableContext.d.ts → useBbTable.d.ts} +29 -29
- package/dist/composables/{useBbTableContext.js → useBbTable.js} +2 -2
- package/dist/composables/{useBbTabsContext.d.ts → useBbTabs.d.ts} +19 -3
- package/dist/composables/useBbTabs.js +266 -0
- package/dist/composables/useConfirm.d.ts +6 -7
- package/dist/composables/useConfirm.js +1 -1
- package/dist/composables/useOnDemandOpener.d.ts +4 -4
- package/dist/composables/useOnDemandOpener.js +1 -1
- package/dist/composables/useToast.d.ts +4 -5
- package/dist/composables/useToast.js +1 -1
- package/dist/directives/bbDialog.d.ts +1 -1
- package/dist/directives/bbDropdown.js +3 -3
- package/dist/directives/bbOffCanvas.d.ts +1 -1
- package/dist/directives/overlayTrigger.js +18 -18
- package/dist/index.d.ts +15 -15
- package/dist/index.js +55 -55
- package/dist/llms-full.txt +5397 -2894
- package/dist/llms-medium.txt +127 -93
- package/dist/llms.txt +12 -12
- package/dist/nuxt-auto-imports.js +6 -6
- package/dist/nuxt.js +1 -1
- package/dist/plugin.js +30 -28
- package/dist/runtime/nuxt-plugin.js +30 -28
- package/dist/styles.css +2 -2
- package/dist/types/ShapeErased.d.ts +15 -0
- package/dist/types/fallthrough.d.ts +134 -0
- package/dist/utilities/functions/normalizeDateBound.d.ts +7 -5
- package/dist/utilities/functions/normalizeDateBound.js +9 -9
- package/dist/utils/versionCheck.js +1 -1
- package/llms.txt +12 -12
- package/package.json +3 -2
- package/scripts/lib/adoption-checklist.json +2 -1
- package/scripts/lib/css-class-surface.mjs +39 -3
- package/scripts/lib/eslint-disable.mjs +9 -1
- package/scripts/lib/eslint-plugin.d.ts +7 -1
- package/scripts/lib/eslint-plugin.mjs +280 -3
- package/scripts/lib/form-v-model.mjs +2 -2
- package/scripts/lib/helper-canon.mjs +34 -2
- package/scripts/lib/helpers-add.mjs +106 -15
- package/scripts/lib/hidden-label-placeholder.mjs +138 -0
- package/scripts/lib/html-attributes.mjs +82 -0
- package/scripts/lib/idiom-scan.mjs +175 -2
- package/scripts/lib/portal-names.mjs +3 -3
- package/scripts/lib/prefer-v-bb-dialog.mjs +1 -1
- package/scripts/lib/tab-links.mjs +209 -0
- package/scripts/lib/token-color-mix.mjs +114 -0
- package/scripts/lib/toolchain-check.mjs +34 -3
- package/scripts/lib/unstyled-variants.mjs +57 -0
- package/scripts/lib/validate-bb-markup.mjs +72 -1
- package/dist/composables/useBbOffCanvasContext.d.ts +0 -23
- package/dist/composables/useBbTabsContext.js +0 -252
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Records Workspace (Nuxt)
|
|
3
|
-
summary: Full-anatomy invoices workspace for Nuxt — breadcrumbs + page search, chip filter rail (one Filters menu + editable filter chips),
|
|
3
|
+
summary: Full-anatomy invoices workspace for Nuxt — breadcrumbs + page search, chip filter rail (one Filters menu + editable filter chips), URL status strip with counts, one-click status cells, bulk bottom panel, and a stacked peek sidebar, filters URL-synced and data fetched with useAsyncData, all through one coopting page context.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Recipe: Records Workspace (Nuxt)
|
|
7
7
|
|
|
8
8
|
The flagship advanced-page recipe adapted for **Nuxt**: the same Stripe-
|
|
9
9
|
invoices × Linear list workspace — app chrome, breadcrumbs + page search,
|
|
10
|
-
chip filter rail (one Filters menu + editable filter chips),
|
|
10
|
+
chip filter rail (one Filters menu + editable filter chips), a URL status strip with live counts, a dense server-paged table, a
|
|
11
11
|
floating bulk-action bar, and a stacked peek sidebar — but filters and the
|
|
12
12
|
active tab live in the URL and the list loads through `useAsyncData`
|
|
13
13
|
watching `route.query`. Anatomy, components, the context shape, copy and
|
|
@@ -25,7 +25,6 @@ Sibling recipes: [Vue](../vue/records-workspace.md) ·
|
|
|
25
25
|
those files before anything below, and do not hand-roll replacements —
|
|
26
26
|
the peek stack, the close semantics and the sidebar's out-of-flow
|
|
27
27
|
behaviour are all load-bearing here.
|
|
28
|
-
- `<BbHost />` mounted once in `app.vue` — never in a page.
|
|
29
28
|
- Each toast and alert variant's icon set once in the build config; the
|
|
30
29
|
code below passes no `icon` for them:
|
|
31
30
|
`toastVariants: { success: { icon: 'lucide:circle-check' }, destructive: { icon: 'lucide:circle-x' } }`
|
|
@@ -53,7 +52,7 @@ Sibling recipes: [Vue](../vue/records-workspace.md) ·
|
|
|
53
52
|
## Key ideas
|
|
54
53
|
|
|
55
54
|
- **One coopting page context.** `provideInvoicesWorkspace()` joins the
|
|
56
|
-
page-shell stack and the table
|
|
55
|
+
page-shell stack and the table handle once, owns filters/tab and when the
|
|
57
56
|
record-payment dialog opens, and exposes complete actions. Every leaf calls `useInvoicesWorkspace()`
|
|
58
57
|
and nothing else — zero prop drilling anywhere on the page.
|
|
59
58
|
- **Filters and tab live in the URL, not in local refs.** They are seeded
|
|
@@ -62,7 +61,7 @@ Sibling recipes: [Vue](../vue/records-workspace.md) ·
|
|
|
62
61
|
- **`useAsyncData` watches `route.query`.** That single watch source is
|
|
63
62
|
the whole refetch trigger — filters, tab and page changes all funnel
|
|
64
63
|
through the URL first, so there is exactly one fetch path.
|
|
65
|
-
- **The table keeps its selection/paging
|
|
64
|
+
- **The table keeps its selection/paging handle.** `useBbTable`
|
|
66
65
|
still owns `page`/`perPage`/`selected`/`totalItems` by id — only the _items_
|
|
67
66
|
become a resolved array (`:items` + `:loading`) instead of an items
|
|
68
67
|
function, since the page now owns the fetch. Select-all is the "all across
|
|
@@ -87,7 +86,7 @@ Sibling recipes: [Vue](../vue/records-workspace.md) ·
|
|
|
87
86
|
selectable/searchable group (Status, Customer); one chip per APPLIED facet
|
|
88
87
|
— never one per value — renders below it, each a small `BbDropdown` scoped
|
|
89
88
|
to that same group via an external `activator` ref, reading its label from
|
|
90
|
-
`
|
|
89
|
+
`useBbDropdown` so it never re-fetches what the menu already
|
|
91
90
|
resolved. **Never** `BbSelectPopover` + an imperative `ref.open()`: it
|
|
92
91
|
exposes nothing to call, and its floating mode closes an
|
|
93
92
|
`sr-only`/off-screen activator the instant it opens. Due date is a
|
|
@@ -140,7 +139,7 @@ Chrome assumed from the guides: [App Layout](../../guides/app-layout.md)
|
|
|
140
139
|
| 3b | Filter due date | date-range pill | `BbDatePickerInput` range — not a Filters-menu facet |
|
|
141
140
|
| 4 | Clear a filter | chip clear button / date pill | badge `@click:clear` (status/customer) or input `clearable` (due) |
|
|
142
141
|
| 4b | Clear every filter | the rail's last chip, while a filter is active | `Clear all` badge → `ctx.clearFilters` |
|
|
143
|
-
| 5 | Switch tab |
|
|
142
|
+
| 5 | Switch tab | URL status strip with counts | URL + `useAsyncData` refetch |
|
|
144
143
|
| 6 | Peek invoice | row click, peek lists | `v-model:highlighted` / `peekInvoice(id)` → shell stack |
|
|
145
144
|
| 7 | Peek customer (stacked) | customer cell / inside peeks | `stackCustomer(id)` → back arrow |
|
|
146
145
|
| 8 | Change status inline | status badge in row & peek | one-click `BbSelectPopover`; the toast's Undo saves the old status back |
|
|
@@ -149,7 +148,7 @@ Chrome assumed from the guides: [App Layout](../../guides/app-layout.md)
|
|
|
149
148
|
| 10 | Edit / duplicate | row `…` dropdown | navigation (`to`) / context action |
|
|
150
149
|
| 11 | Archive / delete | row `…`, bulk bar | destructive behind `useConfirm` |
|
|
151
150
|
| 12 | Bulk mark paid / remind | floating bottom panel | context actions on the table selection: `{ ids }`, or `{ all, unselected, filters }` |
|
|
152
|
-
| 13 | Select rows / select all | table checkboxes | table
|
|
151
|
+
| 13 | Select rows / select all | table checkboxes | table handle |
|
|
153
152
|
| 14 | Open full invoice | invoice number cell, peek footer | navigation (`to="/invoices/:id"`) |
|
|
154
153
|
| 15 | Back / close peek | shell chrome | shell stack pop / close |
|
|
155
154
|
|
|
@@ -187,11 +186,11 @@ import {
|
|
|
187
186
|
type Ref,
|
|
188
187
|
} from 'vue';
|
|
189
188
|
import {
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
useBbDialog,
|
|
190
|
+
useBbTable,
|
|
192
191
|
useConfirm,
|
|
193
192
|
useToast,
|
|
194
|
-
type
|
|
193
|
+
type BbTableHandle,
|
|
195
194
|
type BadgeVariantType,
|
|
196
195
|
} from 'bitboss-ui';
|
|
197
196
|
import {
|
|
@@ -253,7 +252,7 @@ export const PAYMENT_METHOD_OPTIONS = [
|
|
|
253
252
|
];
|
|
254
253
|
|
|
255
254
|
export interface InvoiceFilters {
|
|
256
|
-
search: string;
|
|
255
|
+
search: string | null;
|
|
257
256
|
status: InvoiceStatus[];
|
|
258
257
|
customerId: number | null;
|
|
259
258
|
/**
|
|
@@ -270,9 +269,9 @@ type InvoiceListResponse = {
|
|
|
270
269
|
};
|
|
271
270
|
|
|
272
271
|
export interface InvoicesWorkspaceContext {
|
|
273
|
-
// -- Coopted contexts
|
|
272
|
+
// -- Coopted contexts and handles ------------------------------------------
|
|
274
273
|
shell: PageShellContext<PeekItem>;
|
|
275
|
-
table:
|
|
274
|
+
table: BbTableHandle;
|
|
276
275
|
// -- Page-owned state ------------------------------------------------------
|
|
277
276
|
filters: InvoiceFilters;
|
|
278
277
|
hasActiveFilters: ComputedRef<boolean>;
|
|
@@ -314,12 +313,26 @@ const toArray = (value: unknown): string[] | null => {
|
|
|
314
313
|
|
|
315
314
|
export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
316
315
|
const { toast } = useToast();
|
|
316
|
+
// A write that fails tells the user instead of escaping as an
|
|
317
|
+
// `Uncaught (in promise)`: the action resolves, the page stays as it was.
|
|
318
|
+
const failSoft =
|
|
319
|
+
<A extends unknown[]>(action: (...args: A) => Promise<unknown>) =>
|
|
320
|
+
async (...args: A) => {
|
|
321
|
+
try {
|
|
322
|
+
await action(...args);
|
|
323
|
+
} catch {
|
|
324
|
+
toast({
|
|
325
|
+
title: 'That did not go through. Try again.',
|
|
326
|
+
variant: 'destructive',
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
};
|
|
317
330
|
const { confirm } = useConfirm();
|
|
318
331
|
const route = useRoute();
|
|
319
332
|
|
|
320
|
-
// -- Coopt the
|
|
333
|
+
// -- Coopt the shell and the table handle: once, for the whole page. -------
|
|
321
334
|
const shell = usePageShellContext<PeekItem>();
|
|
322
|
-
const table =
|
|
335
|
+
const table = useBbTable('invoices-table', { perPage: 25 });
|
|
323
336
|
|
|
324
337
|
// -- Filters + tab: seeded from the URL, the single source of truth. -------
|
|
325
338
|
const filters = reactive<InvoiceFilters>({
|
|
@@ -332,7 +345,7 @@ export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
332
345
|
|
|
333
346
|
const hasActiveFilters = computed(
|
|
334
347
|
() =>
|
|
335
|
-
filters.search
|
|
348
|
+
!!filters.search ||
|
|
336
349
|
filters.status.length > 0 ||
|
|
337
350
|
filters.customerId !== null ||
|
|
338
351
|
filters.dueBetween.length > 0
|
|
@@ -407,7 +420,7 @@ export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
407
420
|
// payment with the invoice as `data` (the peek's button through
|
|
408
421
|
// `v-bb-dialog`, the row menu through this), and it closes itself once the
|
|
409
422
|
// payment is recorded. Nothing on the page renders it or reads its state.
|
|
410
|
-
const paymentDialog =
|
|
423
|
+
const paymentDialog = useBbDialog<Invoice>(RecordPaymentDialog);
|
|
411
424
|
const openRecordPayment = (invoice: Invoice) => {
|
|
412
425
|
void paymentDialog.show(invoice);
|
|
413
426
|
};
|
|
@@ -433,32 +446,34 @@ export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
433
446
|
shell.stackItem({ type: 'customer', id, title: customerTitle(id) });
|
|
434
447
|
|
|
435
448
|
// -- Actions --------------------------------------------------------------------
|
|
436
|
-
const updateStatus =
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
449
|
+
const updateStatus = failSoft(
|
|
450
|
+
async (invoice: Invoice, status: InvoiceStatus) => {
|
|
451
|
+
// Undoable: the pre-edit value comes from the row snapshot, and Undo
|
|
452
|
+
// is the same save back to it — a real round-trip, not a guess.
|
|
453
|
+
const previous = invoice.status;
|
|
454
|
+
const save = async (value: InvoiceStatus) => {
|
|
455
|
+
await $fetch(`/api/invoices/${invoice.id}`, {
|
|
456
|
+
method: 'PATCH',
|
|
457
|
+
body: { status: value },
|
|
458
|
+
});
|
|
459
|
+
await refresh();
|
|
460
|
+
};
|
|
461
|
+
await save(status);
|
|
462
|
+
toast({
|
|
463
|
+
title: `${invoice.number} moved to ${status}.`,
|
|
464
|
+
variant: 'success',
|
|
465
|
+
actions: [
|
|
466
|
+
{
|
|
467
|
+
text: 'Undo',
|
|
468
|
+
'prepend:icon': 'lucide:undo-2',
|
|
469
|
+
onClick: () => save(previous),
|
|
470
|
+
},
|
|
471
|
+
],
|
|
444
472
|
});
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
await save(status);
|
|
448
|
-
toast({
|
|
449
|
-
title: `${invoice.number} moved to ${status}.`,
|
|
450
|
-
variant: 'success',
|
|
451
|
-
actions: [
|
|
452
|
-
{
|
|
453
|
-
text: 'Undo',
|
|
454
|
-
'prepend:icon': 'lucide:undo-2',
|
|
455
|
-
onClick: () => save(previous),
|
|
456
|
-
},
|
|
457
|
-
],
|
|
458
|
-
});
|
|
459
|
-
};
|
|
473
|
+
}
|
|
474
|
+
);
|
|
460
475
|
|
|
461
|
-
const updateDueDate = async (invoice: Invoice, dueDate: string) => {
|
|
476
|
+
const updateDueDate = failSoft(async (invoice: Invoice, dueDate: string) => {
|
|
462
477
|
// Undoable: the pre-edit value comes from the row snapshot, and Undo
|
|
463
478
|
// is the same save back to it — a real round-trip, not a guess.
|
|
464
479
|
const previous = invoice.dueDate;
|
|
@@ -481,9 +496,9 @@ export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
481
496
|
},
|
|
482
497
|
],
|
|
483
498
|
});
|
|
484
|
-
};
|
|
499
|
+
});
|
|
485
500
|
|
|
486
|
-
const duplicateInvoice = async (invoice: Invoice) => {
|
|
501
|
+
const duplicateInvoice = failSoft(async (invoice: Invoice) => {
|
|
487
502
|
const copy = await $fetch<Invoice>(
|
|
488
503
|
`/api/invoices/${invoice.id}/duplicate`,
|
|
489
504
|
{
|
|
@@ -495,30 +510,32 @@ export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
495
510
|
title: `Duplicated as ${copy.number}.`,
|
|
496
511
|
variant: 'success',
|
|
497
512
|
});
|
|
498
|
-
};
|
|
513
|
+
});
|
|
499
514
|
|
|
500
|
-
const recordPayment =
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
515
|
+
const recordPayment = failSoft(
|
|
516
|
+
async (invoice: Invoice, draft: PaymentDraft) => {
|
|
517
|
+
await $fetch(`/api/invoices/${invoice.id}/payments`, {
|
|
518
|
+
method: 'POST',
|
|
519
|
+
body: draft,
|
|
520
|
+
});
|
|
521
|
+
await refresh();
|
|
522
|
+
toast({
|
|
523
|
+
title: `Payment recorded on ${invoice.number}.`,
|
|
524
|
+
variant: 'success',
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
);
|
|
511
528
|
|
|
512
|
-
const archiveInvoice = async (invoice: Invoice) => {
|
|
529
|
+
const archiveInvoice = failSoft(async (invoice: Invoice) => {
|
|
513
530
|
await $fetch(`/api/invoices/${invoice.id}/archive`, { method: 'PATCH' });
|
|
514
531
|
await refresh();
|
|
515
532
|
toast({
|
|
516
533
|
title: `${invoice.number} archived.`,
|
|
517
534
|
variant: 'success',
|
|
518
535
|
});
|
|
519
|
-
};
|
|
536
|
+
});
|
|
520
537
|
|
|
521
|
-
const deleteInvoice = async (invoice: Invoice) => {
|
|
538
|
+
const deleteInvoice = failSoft(async (invoice: Invoice) => {
|
|
522
539
|
const ok = await confirm({
|
|
523
540
|
variant: 'destructive',
|
|
524
541
|
title: 'Delete invoice',
|
|
@@ -533,9 +550,9 @@ export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
533
550
|
title: `${invoice.number} deleted.`,
|
|
534
551
|
variant: 'success',
|
|
535
552
|
});
|
|
536
|
-
};
|
|
553
|
+
});
|
|
537
554
|
|
|
538
|
-
// Bulk actions read and clear the coopted table
|
|
555
|
+
// Bulk actions read and clear the coopted table handle themselves. The
|
|
539
556
|
// header checkbox is BbTable's "all across pages" select-all: it enumerates
|
|
540
557
|
// no ids, so the body becomes `{ all, unselected, filters }` — what is on
|
|
541
558
|
// screen minus the exceptions — and the count is the total minus those
|
|
@@ -563,7 +580,7 @@ export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
563
580
|
table.all.value = false;
|
|
564
581
|
};
|
|
565
582
|
|
|
566
|
-
const bulkMarkPaid = async () => {
|
|
583
|
+
const bulkMarkPaid = failSoft(async () => {
|
|
567
584
|
const count = selectedCount.value;
|
|
568
585
|
await $fetch('/api/invoices/bulk/mark-paid', {
|
|
569
586
|
method: 'PATCH',
|
|
@@ -575,9 +592,9 @@ export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
575
592
|
title: `${count} invoices marked as paid.`,
|
|
576
593
|
variant: 'success',
|
|
577
594
|
});
|
|
578
|
-
};
|
|
595
|
+
});
|
|
579
596
|
|
|
580
|
-
const bulkRemind = async () => {
|
|
597
|
+
const bulkRemind = failSoft(async () => {
|
|
581
598
|
const count = selectedCount.value;
|
|
582
599
|
await $fetch('/api/invoices/bulk/remind', {
|
|
583
600
|
method: 'POST',
|
|
@@ -588,9 +605,9 @@ export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
588
605
|
title: `Reminder sent for ${count} invoices.`,
|
|
589
606
|
variant: 'success',
|
|
590
607
|
});
|
|
591
|
-
};
|
|
608
|
+
});
|
|
592
609
|
|
|
593
|
-
const bulkArchive = async () => {
|
|
610
|
+
const bulkArchive = failSoft(async () => {
|
|
594
611
|
const count = selectedCount.value;
|
|
595
612
|
const ok = await confirm({
|
|
596
613
|
variant: 'destructive',
|
|
@@ -610,7 +627,7 @@ export function provideInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
610
627
|
title: `${count} invoices archived.`,
|
|
611
628
|
variant: 'success',
|
|
612
629
|
});
|
|
613
|
-
};
|
|
630
|
+
});
|
|
614
631
|
|
|
615
632
|
const ctx: InvoicesWorkspaceContext = {
|
|
616
633
|
shell,
|
|
@@ -692,35 +709,39 @@ export function useInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
692
709
|
</template>
|
|
693
710
|
|
|
694
711
|
<div class="flex flex-col gap-3 p-4">
|
|
712
|
+
<!-- The page owns one h1. The breadcrumb is the visible title, so the
|
|
713
|
+
heading is for screen readers only. -->
|
|
714
|
+
<h1 class="sr-only">Invoices</h1>
|
|
695
715
|
<FilterRail />
|
|
696
716
|
|
|
697
|
-
<!--
|
|
698
|
-
|
|
699
|
-
|
|
717
|
+
<!-- The status filter: one value over one table, so a radio group
|
|
718
|
+
with the tabs look (a tablist would promise panels). The context
|
|
719
|
+
keeps it in `?tab=`; the counts come from the server on every
|
|
720
|
+
fetch. -->
|
|
721
|
+
<BbRadioGroup
|
|
700
722
|
v-model="ctx.tab.value"
|
|
701
723
|
compact
|
|
724
|
+
hide-legend
|
|
702
725
|
:items="[
|
|
703
726
|
{
|
|
704
727
|
value: 'all',
|
|
705
728
|
label: `All · ${ctx.tabCounts.value.all}`,
|
|
706
|
-
href: '?tab=all',
|
|
707
729
|
},
|
|
708
730
|
{
|
|
709
731
|
value: 'outstanding',
|
|
710
732
|
label: `Outstanding · ${ctx.tabCounts.value.outstanding}`,
|
|
711
|
-
href: '?tab=outstanding',
|
|
712
733
|
},
|
|
713
734
|
{
|
|
714
735
|
value: 'paid',
|
|
715
736
|
label: `Paid · ${ctx.tabCounts.value.paid}`,
|
|
716
|
-
href: '?tab=paid',
|
|
717
737
|
},
|
|
718
738
|
{
|
|
719
739
|
value: 'archived',
|
|
720
740
|
label: `Archived · ${ctx.tabCounts.value.archived}`,
|
|
721
|
-
href: '?tab=archived',
|
|
722
741
|
},
|
|
723
742
|
]"
|
|
743
|
+
legend="Status"
|
|
744
|
+
variant="pill"
|
|
724
745
|
/>
|
|
725
746
|
|
|
726
747
|
<BbTable
|
|
@@ -797,7 +818,7 @@ export function useInvoicesWorkspace(): InvoicesWorkspaceContext {
|
|
|
797
818
|
</template>
|
|
798
819
|
</BbTable>
|
|
799
820
|
|
|
800
|
-
<!-- Joins the table
|
|
821
|
+
<!-- Joins the table by id: no page/totalPages wiring at all. -->
|
|
801
822
|
<BbPagination table-id="invoices-table" />
|
|
802
823
|
</div>
|
|
803
824
|
|
|
@@ -830,8 +851,8 @@ import {
|
|
|
830
851
|
BbBreadcrumbs,
|
|
831
852
|
BbButton,
|
|
832
853
|
BbPagination,
|
|
854
|
+
BbRadioGroup,
|
|
833
855
|
BbTable,
|
|
834
|
-
BbTabs,
|
|
835
856
|
BbTextInput,
|
|
836
857
|
} from 'bitboss-ui';
|
|
837
858
|
import PageShell from '~/components/PageShell.vue';
|
|
@@ -965,7 +986,9 @@ const rowClass = (item: Invoice) =>
|
|
|
965
986
|
<!-- Clear-all is the LAST CHIP, not a ghost button floated to the far
|
|
966
987
|
end by `ml-auto`: it acts on the chips, so it belongs in their row
|
|
967
988
|
and at their scale. Keep the ghost "Clear filters" for the empty
|
|
968
|
-
state (`#empty`), where there are no chips to sit beside.
|
|
989
|
+
state (`#empty`), where there are no chips to sit beside. Its text
|
|
990
|
+
stays plain: one control per action. A BbBadgeButton body would be
|
|
991
|
+
a second tab stop doing what the × already does. -->
|
|
969
992
|
<BbBadge
|
|
970
993
|
v-if="ctx.hasActiveFilters.value"
|
|
971
994
|
clearable
|
|
@@ -1047,7 +1070,7 @@ const searchCustomers = async ({
|
|
|
1047
1070
|
};
|
|
1048
1071
|
|
|
1049
1072
|
// Static enum facet: item text resolves synchronously, so its chip reads
|
|
1050
|
-
// `
|
|
1073
|
+
// `useBbDropdown` (in FilterChip.vue) with zero extra fetch.
|
|
1051
1074
|
const statusGroup: BbDropdownItem = {
|
|
1052
1075
|
id: 'status',
|
|
1053
1076
|
label: 'Status',
|
|
@@ -1143,13 +1166,13 @@ import {
|
|
|
1143
1166
|
BbBadgeButton,
|
|
1144
1167
|
BbDropdown,
|
|
1145
1168
|
BbDropdownGroup,
|
|
1146
|
-
|
|
1169
|
+
useBbDropdown,
|
|
1147
1170
|
} from 'bitboss-ui';
|
|
1148
1171
|
import type { BbDropdownItem } from 'bitboss-ui';
|
|
1149
1172
|
|
|
1150
1173
|
const props = defineProps<{
|
|
1151
1174
|
/** Matches the group's `id` in the Filters menu, and its entry in
|
|
1152
|
-
* `
|
|
1175
|
+
* `useBbDropdown('invoice-filters').groups`. */
|
|
1153
1176
|
groupKey: string;
|
|
1154
1177
|
/** Static fallback/prefix text — the group itself sets `hideLabel`. */
|
|
1155
1178
|
label: string;
|
|
@@ -1171,7 +1194,7 @@ const chipRef = useTemplateRef('chipRef');
|
|
|
1171
1194
|
// this second dropdown repeated the menu's `prefill: true` verbatim, each
|
|
1172
1195
|
// seeded pipeline facet would be fetched TWICE on page load, and the chip's
|
|
1173
1196
|
// copy of the result would feed nothing (the label below comes from the
|
|
1174
|
-
// menu's resolution via
|
|
1197
|
+
// menu's resolution via `useBbDropdown`). `'interaction'` defers this copy's fetch
|
|
1175
1198
|
// to the moment the chip's dropdown is actually opened. For static array
|
|
1176
1199
|
// facets the override is inert — arrays resolve synchronously either way.
|
|
1177
1200
|
const chipGroup = computed<BbDropdownItem>(() => ({
|
|
@@ -1183,7 +1206,7 @@ const chipGroup = computed<BbDropdownItem>(() => ({
|
|
|
1183
1206
|
// pipeline group needs `prefill: true` (set on the MENU's copy of `group` by
|
|
1184
1207
|
// FilterRail) so this never sits on a bare id/value while the menu's own
|
|
1185
1208
|
// submenu is unopened.
|
|
1186
|
-
const dropdownFilters =
|
|
1209
|
+
const dropdownFilters = useBbDropdown('invoice-filters');
|
|
1187
1210
|
const chipText = computed(() => {
|
|
1188
1211
|
const options =
|
|
1189
1212
|
dropdownFilters.groups.value[props.groupKey]?.selectedOptions ?? [];
|
|
@@ -1375,12 +1398,12 @@ import {
|
|
|
1375
1398
|
BbCalendar,
|
|
1376
1399
|
BbDatePickerInput,
|
|
1377
1400
|
BbOffCanvas,
|
|
1378
|
-
|
|
1401
|
+
useBbOffCanvas,
|
|
1379
1402
|
} from 'bitboss-ui';
|
|
1380
1403
|
import { useInvoicesWorkspace } from './context';
|
|
1381
1404
|
|
|
1382
1405
|
const ctx = useInvoicesWorkspace();
|
|
1383
|
-
const sheet =
|
|
1406
|
+
const sheet = useBbOffCanvas('due-date-sheet');
|
|
1384
1407
|
|
|
1385
1408
|
// A draft, committed on Apply: picking a range does not refetch per tap.
|
|
1386
1409
|
const from = ref<string | null>(null);
|
|
@@ -1891,7 +1914,7 @@ import {
|
|
|
1891
1914
|
BbForm,
|
|
1892
1915
|
BbNumberInput,
|
|
1893
1916
|
BbSelect,
|
|
1894
|
-
|
|
1917
|
+
useBbDialog,
|
|
1895
1918
|
} from 'bitboss-ui';
|
|
1896
1919
|
import { PAYMENT_METHOD_OPTIONS, useInvoicesWorkspace } from './context';
|
|
1897
1920
|
import type { Invoice, PaymentDraft } from '~/types';
|
|
@@ -1899,7 +1922,7 @@ import type { Invoice, PaymentDraft } from '~/types';
|
|
|
1899
1922
|
const ctx = useInvoicesWorkspace();
|
|
1900
1923
|
|
|
1901
1924
|
// The invoice the opener handed over: on demand it is already here in setup.
|
|
1902
|
-
const { data: invoice } =
|
|
1925
|
+
const { data: invoice } = useBbDialog<Invoice>('record-payment');
|
|
1903
1926
|
|
|
1904
1927
|
// Default to paying the remaining balance today.
|
|
1905
1928
|
const draft = reactive<PaymentDraft>({
|
|
@@ -1923,7 +1946,7 @@ const draft = reactive<PaymentDraft>({
|
|
|
1923
1946
|
`navigateTo` on every change (debounced for free text), and
|
|
1924
1947
|
`useAsyncData('invoices', …, { watch: [() => route.query, table.page] })`
|
|
1925
1948
|
is the single refetch trigger — there is exactly one place data loads.
|
|
1926
|
-
- **The table
|
|
1949
|
+
- **The table handle still owns paging and selection.** `useBbTable`
|
|
1927
1950
|
is unchanged from the Vue recipe: it seeds `perPage`, `BbPagination`
|
|
1928
1951
|
joins by `table-id`, and the context derives `selectedCount` from
|
|
1929
1952
|
`selected`/`all`/`unselected` for the `SelectionBar` — only the _items_
|
|
@@ -1933,10 +1956,11 @@ const draft = reactive<PaymentDraft>({
|
|
|
1933
1956
|
drill-downs push; the shell renders the back arrow when depth > 1. The
|
|
1934
1957
|
grammar lives in the context — a leaf cannot accidentally nuke the
|
|
1935
1958
|
stack.
|
|
1936
|
-
- **
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
reacts to.
|
|
1959
|
+
- **The strip keeps the URL and live counts**, like the Vue recipe: the
|
|
1960
|
+
context owns the URL, a tab change runs the same `navigateTo` as a filter
|
|
1961
|
+
change, so `route.query.tab` seeds `tab` on load and is what
|
|
1962
|
+
`useAsyncData`'s `route.query` watch reacts to. The strip is a plain
|
|
1963
|
+
`BbRadioGroup` with no URL wiring of its own, so there is one writer.
|
|
1940
1964
|
- **Internal links use `to`, not `href`.** `to` renders a real Vue Router
|
|
1941
1965
|
link (client-side navigation); a raw `href` would force a full page
|
|
1942
1966
|
reload. Every same-app link in this recipe — the primary "New invoice"
|
|
@@ -1946,7 +1970,7 @@ const draft = reactive<PaymentDraft>({
|
|
|
1946
1970
|
the peek's button opens it with
|
|
1947
1971
|
`v-bb-dialog="{ component: RecordPaymentDialog, data: invoice }"`, the row
|
|
1948
1972
|
menu with the context's `openRecordPayment(invoice)` →
|
|
1949
|
-
`
|
|
1973
|
+
`useBbDialog<Invoice>(RecordPaymentDialog).show(invoice)`, and
|
|
1950
1974
|
`<BbHost />` mounts a fresh instance per payment, its invoice already
|
|
1951
1975
|
readable in setup (so the draft is built there, with no reset). Its form
|
|
1952
1976
|
is a `BbForm`: while the payment is recorded the dialog refuses Cancel,
|
|
@@ -2000,12 +2024,12 @@ const draft = reactive<PaymentDraft>({
|
|
|
2000
2024
|
answer until the app has hydrated, so a phone hydrates the input and swaps
|
|
2001
2025
|
to the sheet right after: no `<ClientOnly>` around the switch.
|
|
2002
2026
|
|
|
2003
|
-
###
|
|
2027
|
+
### The status strip is lifecycle; chips are facets
|
|
2004
2028
|
|
|
2005
|
-
The rail and the
|
|
2029
|
+
The rail and the status strip answer two different questions, and twinning them is
|
|
2006
2030
|
the fastest way to make a workspace feel arbitrary:
|
|
2007
2031
|
|
|
2008
|
-
- **
|
|
2032
|
+
- **The strip = one lifecycle segment.** Where the record _is_ in its own flow —
|
|
2009
2033
|
All / Outstanding / Paid / Archived. Mutually exclusive, always visible,
|
|
2010
2034
|
carrying the counts.
|
|
2011
2035
|
- **Chips = cross-cutting facets.** Anything that can apply to a record in any
|
|
@@ -2013,7 +2037,7 @@ the fastest way to make a workspace feel arbitrary:
|
|
|
2013
2037
|
applied.
|
|
2014
2038
|
|
|
2015
2039
|
Never expose the same dimension both ways: a `status` facet inside the Filters
|
|
2016
|
-
menu next to a status
|
|
2040
|
+
menu next to a status strip lets the user set two conflicting answers to one
|
|
2017
2041
|
question, and neither control shows the other's state. If a dimension deserves
|
|
2018
2042
|
both roles (a lifecycle you also want to combine), pick one and give the other
|
|
2019
2043
|
distinct chrome — never the same values with different affordances.
|