@ciridae/ui 0.3.3 → 0.3.6
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 +1 -1
- package/dist/assets/ciridae/brand-background-dark.webp +0 -0
- package/dist/assets/ciridae/brand-background-light.webp +0 -0
- package/dist/assets/ciridae/ciridae-black.svg +17 -0
- package/dist/assets/ciridae/ciridae-brand-assets.d.ts +25 -0
- package/dist/assets/ciridae/ciridae-brand-assets.js +25 -0
- package/dist/assets/ciridae/ciridae-icon-black.png +0 -0
- package/dist/assets/ciridae/ciridae-icon-white.png +0 -0
- package/dist/assets/ciridae/ciridae-ui-wordmark-black.png +0 -0
- package/dist/assets/ciridae/ciridae-ui-wordmark-white.png +0 -0
- package/dist/assets/ciridae/ciridae-white.svg +17 -0
- package/dist/assets/ciridae/ciridae-wordmark-black.png +0 -0
- package/dist/assets/ciridae/ciridae-wordmark-white.png +0 -0
- package/dist/assets/ciridae/favicon.ico +0 -0
- package/dist/assets/ciridae/logo-white.png +0 -0
- package/dist/assets/ciridae/sign-in-screenshot.png +0 -0
- package/dist/ciridae.css +491 -0
- package/dist/ciridae.css.d.ts +2 -0
- package/dist/components/blocks/admin-users-table.d.ts +22 -0
- package/dist/components/blocks/admin-users-table.js +115 -0
- package/dist/components/blocks/comment-composer.d.ts +16 -0
- package/dist/components/blocks/comment-composer.js +113 -0
- package/dist/components/blocks/comment-item.d.ts +8 -0
- package/dist/components/blocks/comment-item.js +45 -0
- package/dist/components/blocks/comment-thread.d.ts +18 -0
- package/dist/components/blocks/comment-thread.js +30 -0
- package/dist/components/blocks/comment-types.d.ts +18 -0
- package/dist/components/blocks/comment-types.js +11 -0
- package/dist/components/blocks/feedback-center-comments.d.ts +12 -0
- package/dist/components/blocks/feedback-center-comments.js +11 -0
- package/dist/components/blocks/feedback-center-sheet-parts.d.ts +34 -0
- package/dist/components/blocks/feedback-center-sheet-parts.js +44 -0
- package/dist/components/blocks/feedback-center-sheet.d.ts +19 -0
- package/dist/components/blocks/feedback-center-sheet.js +46 -0
- package/dist/components/blocks/feedback-composer-parts.d.ts +16 -0
- package/dist/components/blocks/feedback-composer-parts.js +43 -0
- package/dist/components/blocks/feedback-composer-types.d.ts +11 -0
- package/dist/components/blocks/feedback-composer-types.js +1 -0
- package/dist/components/blocks/feedback-composer.d.ts +17 -0
- package/dist/components/blocks/feedback-composer.js +112 -0
- package/dist/components/blocks/feedback-date-format.d.ts +5 -0
- package/dist/components/blocks/feedback-date-format.js +11 -0
- package/dist/components/blocks/feedback-detail-sheet.d.ts +9 -0
- package/dist/components/blocks/feedback-detail-sheet.js +41 -0
- package/dist/components/blocks/feedback-metrics.d.ts +6 -0
- package/dist/components/blocks/feedback-metrics.js +15 -0
- package/dist/components/blocks/feedback-sheet.d.ts +8 -0
- package/dist/components/blocks/feedback-sheet.js +16 -0
- package/dist/components/blocks/feedback-status-badge.d.ts +6 -0
- package/dist/components/blocks/feedback-status-badge.js +14 -0
- package/dist/components/blocks/feedback-table-row.d.ts +6 -0
- package/dist/components/blocks/feedback-table-row.js +37 -0
- package/dist/components/blocks/feedback-table-sort.d.ts +11 -0
- package/dist/components/blocks/feedback-table-sort.js +81 -0
- package/dist/components/blocks/feedback-table.d.ts +16 -0
- package/dist/components/blocks/feedback-table.js +45 -0
- package/dist/components/blocks/feedback-tracking-types.d.ts +78 -0
- package/dist/components/blocks/feedback-tracking-types.js +36 -0
- package/dist/components/blocks/feedback-type-badge.d.ts +6 -0
- package/dist/components/blocks/feedback-type-badge.js +12 -0
- package/dist/components/blocks/feedback-user-detail.d.ts +10 -0
- package/dist/components/blocks/feedback-user-detail.js +57 -0
- package/dist/components/blocks/feedback-user-list.d.ts +9 -0
- package/dist/components/blocks/feedback-user-list.js +33 -0
- package/dist/components/blocks/invite-user-sheet.d.ts +20 -0
- package/dist/components/blocks/invite-user-sheet.js +72 -0
- package/dist/components/blocks/kanban-board-parts.d.ts +26 -0
- package/dist/components/blocks/kanban-board-parts.js +85 -0
- package/dist/components/blocks/kanban-board-utils.d.ts +42 -0
- package/dist/components/blocks/kanban-board-utils.js +115 -0
- package/dist/components/blocks/kanban-board.d.ts +16 -0
- package/dist/components/blocks/kanban-board.js +36 -0
- package/dist/components/blocks/kanban-card.d.ts +10 -0
- package/dist/components/blocks/kanban-card.js +34 -0
- package/dist/components/blocks/kanban-column.d.ts +17 -0
- package/dist/components/blocks/kanban-column.js +34 -0
- package/dist/components/blocks/kanban-detail-sheet.d.ts +17 -0
- package/dist/components/blocks/kanban-detail-sheet.js +34 -0
- package/dist/components/blocks/kanban-types.d.ts +24 -0
- package/dist/components/blocks/kanban-types.js +1 -0
- package/dist/components/blocks/timestamp-format.d.ts +8 -0
- package/dist/components/blocks/timestamp-format.js +66 -0
- package/dist/components/pages/admin-users-page.d.ts +11 -0
- package/dist/components/pages/admin-users-page.js +30 -0
- package/dist/components/pages/feedback-stakeholder-page-parts.d.ts +18 -0
- package/dist/components/pages/feedback-stakeholder-page-parts.js +36 -0
- package/dist/components/pages/feedback-stakeholder-page.d.ts +9 -0
- package/dist/components/pages/feedback-stakeholder-page.js +66 -0
- package/dist/components/pages/kanban-page.d.ts +13 -0
- package/dist/components/pages/kanban-page.js +68 -0
- package/dist/components/ui/accordion.js +1 -1
- package/dist/components/ui/alert-dialog.d.ts +1 -1
- package/dist/components/ui/alert-dialog.js +2 -2
- package/dist/components/ui/alert.d.ts +1 -1
- package/dist/components/ui/alert.js +1 -1
- package/dist/components/ui/app-shell-page.d.ts +1 -1
- package/dist/components/ui/app-shell-page.js +3 -3
- package/dist/components/ui/app-shell.d.ts +2 -2
- package/dist/components/ui/app-shell.js +3 -3
- package/dist/components/ui/aspect-ratio.d.ts +1 -1
- package/dist/components/ui/avatar.js +1 -1
- package/dist/components/ui/badge-variants.d.ts +1 -1
- package/dist/components/ui/badge-variants.js +1 -1
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/components/ui/badge.js +2 -2
- package/dist/components/ui/breadcrumb.js +1 -1
- package/dist/components/ui/button-group-variants.d.ts +1 -1
- package/dist/components/ui/button-group.d.ts +5 -5
- package/dist/components/ui/button-group.js +3 -3
- package/dist/components/ui/button-variants.d.ts +1 -1
- package/dist/components/ui/button-variants.js +1 -1
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/button.js +3 -3
- package/dist/components/ui/calendar.d.ts +3 -2
- package/dist/components/ui/calendar.js +4 -4
- package/dist/components/ui/card.js +1 -1
- package/dist/components/ui/carousel.d.ts +1 -1
- package/dist/components/ui/carousel.js +2 -2
- package/dist/components/ui/chart-panel.js +1 -1
- package/dist/components/ui/chart-tooltip.js +2 -2
- package/dist/components/ui/chart.d.ts +2 -2
- package/dist/components/ui/chart.js +3 -3
- package/dist/components/ui/checkbox.js +1 -1
- package/dist/components/ui/ciridae-ui-provider.d.ts +2 -2
- package/dist/components/ui/ciridae-ui-provider.js +3 -3
- package/dist/components/ui/collapsible.d.ts +3 -3
- package/dist/components/ui/combobox.js +3 -3
- package/dist/components/ui/command.d.ts +1 -1
- package/dist/components/ui/command.js +2 -2
- package/dist/components/ui/context-menu.js +1 -1
- package/dist/components/ui/data-table-controls.js +3 -3
- package/dist/components/ui/data-table-grid.js +3 -3
- package/dist/components/ui/data-table-pagination.d.ts +1 -1
- package/dist/components/ui/data-table-pagination.js +2 -2
- package/dist/components/ui/data-table-tanstack.js +2 -2
- package/dist/components/ui/data-table.d.ts +2 -2
- package/dist/components/ui/data-table.js +4 -4
- package/dist/components/ui/dialog.d.ts +2 -1
- package/dist/components/ui/dialog.js +4 -4
- package/dist/components/ui/drawer.js +1 -1
- package/dist/components/ui/dropdown-menu.js +1 -1
- package/dist/components/ui/empty.d.ts +7 -7
- package/dist/components/ui/empty.js +1 -1
- package/dist/components/ui/expandable-data-table.d.ts +1 -1
- package/dist/components/ui/expandable-data-table.js +4 -4
- package/dist/components/ui/field.d.ts +12 -12
- package/dist/components/ui/field.js +3 -3
- package/dist/components/ui/file-upload-field-parts.js +3 -3
- package/dist/components/ui/file-upload-field.js +1 -1
- package/dist/components/ui/form-context.d.ts +1 -1
- package/dist/components/ui/form.d.ts +1 -1
- package/dist/components/ui/form.js +3 -3
- package/dist/components/ui/hover-card.js +1 -1
- package/dist/components/ui/input-group.d.ts +3 -3
- package/dist/components/ui/input-group.js +4 -4
- package/dist/components/ui/input-otp.js +1 -1
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/item.d.ts +3 -3
- package/dist/components/ui/item.js +2 -2
- package/dist/components/ui/kbd.d.ts +2 -2
- package/dist/components/ui/kbd.js +1 -1
- package/dist/components/ui/label.js +1 -1
- package/dist/components/ui/loading-state.d.ts +1 -1
- package/dist/components/ui/loading-state.js +4 -4
- package/dist/components/ui/menubar.js +1 -1
- package/dist/components/ui/metrics-strip.js +1 -1
- package/dist/components/ui/native-select.js +1 -1
- package/dist/components/ui/navigation-menu-variants.d.ts +1 -1
- package/dist/components/ui/navigation-menu.js +2 -2
- package/dist/components/ui/page-header.d.ts +16 -2
- package/dist/components/ui/page-header.js +22 -4
- package/dist/components/ui/pagination.d.ts +1 -1
- package/dist/components/ui/pagination.js +4 -4
- package/dist/components/ui/popover.js +1 -1
- package/dist/components/ui/progress.js +1 -1
- package/dist/components/ui/property-list.js +1 -1
- package/dist/components/ui/radio-group.js +1 -1
- package/dist/components/ui/registry-docs-api.d.ts +1 -1
- package/dist/components/ui/registry-docs-api.js +1 -1
- package/dist/components/ui/registry-docs-code.js +2 -2
- package/dist/components/ui/registry-docs-showcase.js +2 -2
- package/dist/components/ui/registry-docs.d.ts +1 -1
- package/dist/components/ui/registry-docs.js +3 -3
- package/dist/components/ui/resizable.d.ts +10 -3
- package/dist/components/ui/resizable.js +4 -4
- package/dist/components/ui/scroll-area.js +1 -1
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/separator.js +1 -1
- package/dist/components/ui/sheet.js +1 -1
- package/dist/components/ui/sidebar/group.js +1 -1
- package/dist/components/ui/sidebar/layout.d.ts +2 -2
- package/dist/components/ui/sidebar/layout.js +5 -5
- package/dist/components/ui/sidebar/menu.d.ts +2 -2
- package/dist/components/ui/sidebar/menu.js +4 -4
- package/dist/components/ui/sidebar/provider.js +4 -4
- package/dist/components/ui/sidebar/rail.js +2 -2
- package/dist/components/ui/sidebar/trigger.d.ts +1 -1
- package/dist/components/ui/sidebar/trigger.js +3 -3
- package/dist/components/ui/sidebar-account-menu-theme.d.ts +1 -1
- package/dist/components/ui/sidebar-account-menu-theme.js +2 -2
- package/dist/components/ui/sidebar-account-menu.d.ts +2 -2
- package/dist/components/ui/sidebar-account-menu.js +7 -7
- package/dist/components/ui/sidebar.d.ts +7 -7
- package/dist/components/ui/sidebar.js +7 -7
- package/dist/components/ui/skeleton.d.ts +1 -1
- package/dist/components/ui/skeleton.js +2 -2
- package/dist/components/ui/slider.js +1 -1
- package/dist/components/ui/sonner.d.ts +3 -3
- package/dist/components/ui/sonner.js +3 -3
- package/dist/components/ui/spinner.d.ts +1 -1
- package/dist/components/ui/spinner.js +2 -2
- package/dist/components/ui/switch.js +1 -1
- package/dist/components/ui/table.js +1 -1
- package/dist/components/ui/tabs-variants.d.ts +1 -1
- package/dist/components/ui/tabs.d.ts +1 -1
- package/dist/components/ui/tabs.js +2 -2
- package/dist/components/ui/textarea.js +1 -1
- package/dist/components/ui/toggle-group.d.ts +1 -1
- package/dist/components/ui/toggle-group.js +2 -2
- package/dist/components/ui/toggle-variants.d.ts +1 -1
- package/dist/components/ui/toggle.d.ts +1 -1
- package/dist/components/ui/toggle.js +2 -2
- package/dist/components/ui/tooltip.js +1 -1
- package/dist/components/ui/workflow-timeline.js +1 -1
- package/dist/entries/accordion.d.ts +1 -0
- package/dist/entries/accordion.js +1 -0
- package/dist/entries/admin-users-page.d.ts +1 -0
- package/dist/entries/admin-users-page.js +1 -0
- package/dist/entries/admin-users-table.d.ts +1 -0
- package/dist/entries/admin-users-table.js +1 -0
- package/dist/entries/alert-dialog.d.ts +1 -0
- package/dist/entries/alert-dialog.js +1 -0
- package/dist/entries/alert.d.ts +1 -0
- package/dist/entries/alert.js +1 -0
- package/dist/entries/app-shell-page.d.ts +1 -0
- package/dist/entries/app-shell-page.js +1 -0
- package/dist/entries/app-shell.d.ts +1 -0
- package/dist/entries/app-shell.js +1 -0
- package/dist/entries/aspect-ratio.d.ts +1 -0
- package/dist/entries/aspect-ratio.js +1 -0
- package/dist/entries/avatar.d.ts +1 -0
- package/dist/entries/avatar.js +1 -0
- package/dist/entries/badge-variants.d.ts +1 -0
- package/dist/entries/badge-variants.js +1 -0
- package/dist/entries/badge.d.ts +1 -0
- package/dist/entries/badge.js +1 -0
- package/dist/entries/breadcrumb.d.ts +1 -0
- package/dist/entries/breadcrumb.js +1 -0
- package/dist/entries/button-group-variants.d.ts +1 -0
- package/dist/entries/button-group-variants.js +1 -0
- package/dist/entries/button-group.d.ts +1 -0
- package/dist/entries/button-group.js +1 -0
- package/dist/entries/button-variants.d.ts +1 -0
- package/dist/entries/button-variants.js +1 -0
- package/dist/entries/button.d.ts +1 -0
- package/dist/entries/button.js +1 -0
- package/dist/entries/calendar.d.ts +1 -0
- package/dist/entries/calendar.js +1 -0
- package/dist/entries/card.d.ts +1 -0
- package/dist/entries/card.js +1 -0
- package/dist/entries/carousel.d.ts +1 -0
- package/dist/entries/carousel.js +1 -0
- package/dist/entries/chart-context.d.ts +1 -0
- package/dist/entries/chart-context.js +1 -0
- package/dist/entries/chart-panel.d.ts +1 -0
- package/dist/entries/chart-panel.js +1 -0
- package/dist/entries/chart-tooltip.d.ts +1 -0
- package/dist/entries/chart-tooltip.js +1 -0
- package/dist/entries/chart.d.ts +1 -0
- package/dist/entries/chart.js +1 -0
- package/dist/entries/checkbox.d.ts +1 -0
- package/dist/entries/checkbox.js +1 -0
- package/dist/entries/ciridae-brand-assets.d.ts +1 -0
- package/dist/entries/ciridae-brand-assets.js +1 -0
- package/dist/entries/ciridae-ui-provider.d.ts +1 -0
- package/dist/entries/ciridae-ui-provider.js +1 -0
- package/dist/entries/collapsible.d.ts +1 -0
- package/dist/entries/collapsible.js +1 -0
- package/dist/entries/color-theme-context.d.ts +1 -0
- package/dist/entries/color-theme-context.js +1 -0
- package/dist/entries/color-theme.d.ts +1 -0
- package/dist/entries/color-theme.js +1 -0
- package/dist/entries/combobox-anchor.d.ts +1 -0
- package/dist/entries/combobox-anchor.js +1 -0
- package/dist/entries/combobox.d.ts +1 -0
- package/dist/entries/combobox.js +1 -0
- package/dist/entries/command.d.ts +1 -0
- package/dist/entries/command.js +1 -0
- package/dist/entries/comment-composer.d.ts +1 -0
- package/dist/entries/comment-composer.js +1 -0
- package/dist/entries/comment-item.d.ts +1 -0
- package/dist/entries/comment-item.js +1 -0
- package/dist/entries/comment-thread.d.ts +1 -0
- package/dist/entries/comment-thread.js +1 -0
- package/dist/entries/comment-types.d.ts +1 -0
- package/dist/entries/comment-types.js +1 -0
- package/dist/entries/context-menu.d.ts +1 -0
- package/dist/entries/context-menu.js +1 -0
- package/dist/entries/data-table-controls.d.ts +1 -0
- package/dist/entries/data-table-controls.js +1 -0
- package/dist/entries/data-table-grid.d.ts +1 -0
- package/dist/entries/data-table-grid.js +1 -0
- package/dist/entries/data-table-pagination.d.ts +1 -0
- package/dist/entries/data-table-pagination.js +1 -0
- package/dist/entries/data-table-tanstack.d.ts +1 -0
- package/dist/entries/data-table-tanstack.js +1 -0
- package/dist/entries/data-table.d.ts +1 -0
- package/dist/entries/data-table.js +1 -0
- package/dist/entries/dialog.d.ts +1 -0
- package/dist/entries/dialog.js +1 -0
- package/dist/entries/direction-context.d.ts +1 -0
- package/dist/entries/direction-context.js +1 -0
- package/dist/entries/direction.d.ts +1 -0
- package/dist/entries/direction.js +1 -0
- package/dist/entries/drawer.d.ts +1 -0
- package/dist/entries/drawer.js +1 -0
- package/dist/entries/dropdown-menu.d.ts +1 -0
- package/dist/entries/dropdown-menu.js +1 -0
- package/dist/entries/empty.d.ts +1 -0
- package/dist/entries/empty.js +1 -0
- package/dist/entries/expandable-data-table.d.ts +1 -0
- package/dist/entries/expandable-data-table.js +1 -0
- package/dist/entries/feedback-center-comments.d.ts +1 -0
- package/dist/entries/feedback-center-comments.js +1 -0
- package/dist/entries/feedback-center-sheet-parts.d.ts +1 -0
- package/dist/entries/feedback-center-sheet-parts.js +1 -0
- package/dist/entries/feedback-center-sheet.d.ts +1 -0
- package/dist/entries/feedback-center-sheet.js +1 -0
- package/dist/entries/feedback-composer-parts.d.ts +1 -0
- package/dist/entries/feedback-composer-parts.js +1 -0
- package/dist/entries/feedback-composer-types.d.ts +1 -0
- package/dist/entries/feedback-composer-types.js +1 -0
- package/dist/entries/feedback-composer.d.ts +1 -0
- package/dist/entries/feedback-composer.js +1 -0
- package/dist/entries/feedback-date-format.d.ts +1 -0
- package/dist/entries/feedback-date-format.js +1 -0
- package/dist/entries/feedback-detail-sheet.d.ts +1 -0
- package/dist/entries/feedback-detail-sheet.js +1 -0
- package/dist/entries/feedback-metrics.d.ts +1 -0
- package/dist/entries/feedback-metrics.js +1 -0
- package/dist/entries/feedback-sheet.d.ts +1 -0
- package/dist/entries/feedback-sheet.js +1 -0
- package/dist/entries/feedback-stakeholder-page-parts.d.ts +1 -0
- package/dist/entries/feedback-stakeholder-page-parts.js +1 -0
- package/dist/entries/feedback-stakeholder-page.d.ts +1 -0
- package/dist/entries/feedback-stakeholder-page.js +1 -0
- package/dist/entries/feedback-status-badge.d.ts +1 -0
- package/dist/entries/feedback-status-badge.js +1 -0
- package/dist/entries/feedback-table-row.d.ts +1 -0
- package/dist/entries/feedback-table-row.js +1 -0
- package/dist/entries/feedback-table-sort.d.ts +1 -0
- package/dist/entries/feedback-table-sort.js +1 -0
- package/dist/entries/feedback-table.d.ts +1 -0
- package/dist/entries/feedback-table.js +1 -0
- package/dist/entries/feedback-tracking-types.d.ts +1 -0
- package/dist/entries/feedback-tracking-types.js +1 -0
- package/dist/entries/feedback-type-badge.d.ts +1 -0
- package/dist/entries/feedback-type-badge.js +1 -0
- package/dist/entries/feedback-user-detail.d.ts +1 -0
- package/dist/entries/feedback-user-detail.js +1 -0
- package/dist/entries/feedback-user-list.d.ts +1 -0
- package/dist/entries/feedback-user-list.js +1 -0
- package/dist/entries/field.d.ts +1 -0
- package/dist/entries/field.js +1 -0
- package/dist/entries/file-upload-field-parts.d.ts +1 -0
- package/dist/entries/file-upload-field-parts.js +1 -0
- package/dist/entries/file-upload-field.d.ts +1 -0
- package/dist/entries/file-upload-field.js +1 -0
- package/dist/entries/form-context.d.ts +1 -0
- package/dist/entries/form-context.js +1 -0
- package/dist/entries/form.d.ts +1 -0
- package/dist/entries/form.js +1 -0
- package/dist/entries/hover-card.d.ts +1 -0
- package/dist/entries/hover-card.js +1 -0
- package/dist/entries/input-group.d.ts +1 -0
- package/dist/entries/input-group.js +1 -0
- package/dist/entries/input-otp.d.ts +1 -0
- package/dist/entries/input-otp.js +1 -0
- package/dist/entries/input.d.ts +1 -0
- package/dist/entries/input.js +1 -0
- package/dist/entries/invite-user-sheet.d.ts +1 -0
- package/dist/entries/invite-user-sheet.js +1 -0
- package/dist/entries/item.d.ts +1 -0
- package/dist/entries/item.js +1 -0
- package/dist/entries/kanban-board-parts.d.ts +1 -0
- package/dist/entries/kanban-board-parts.js +1 -0
- package/dist/entries/kanban-board-utils.d.ts +1 -0
- package/dist/entries/kanban-board-utils.js +1 -0
- package/dist/entries/kanban-board.d.ts +1 -0
- package/dist/entries/kanban-board.js +1 -0
- package/dist/entries/kanban-card.d.ts +1 -0
- package/dist/entries/kanban-card.js +1 -0
- package/dist/entries/kanban-column.d.ts +1 -0
- package/dist/entries/kanban-column.js +1 -0
- package/dist/entries/kanban-detail-sheet.d.ts +1 -0
- package/dist/entries/kanban-detail-sheet.js +1 -0
- package/dist/entries/kanban-page.d.ts +1 -0
- package/dist/entries/kanban-page.js +1 -0
- package/dist/entries/kanban-types.d.ts +1 -0
- package/dist/entries/kanban-types.js +1 -0
- package/dist/entries/kbd.d.ts +1 -0
- package/dist/entries/kbd.js +1 -0
- package/dist/entries/label.d.ts +1 -0
- package/dist/entries/label.js +1 -0
- package/dist/entries/loading-state.d.ts +1 -0
- package/dist/entries/loading-state.js +1 -0
- package/dist/entries/menubar.d.ts +1 -0
- package/dist/entries/menubar.js +1 -0
- package/dist/entries/metrics-strip.d.ts +1 -0
- package/dist/entries/metrics-strip.js +1 -0
- package/dist/entries/native-select.d.ts +1 -0
- package/dist/entries/native-select.js +1 -0
- package/dist/entries/navigation-menu-variants.d.ts +1 -0
- package/dist/entries/navigation-menu-variants.js +1 -0
- package/dist/entries/navigation-menu.d.ts +1 -0
- package/dist/entries/navigation-menu.js +1 -0
- package/dist/entries/page-header.d.ts +1 -0
- package/dist/entries/page-header.js +1 -0
- package/dist/entries/pagination.d.ts +1 -0
- package/dist/entries/pagination.js +1 -0
- package/dist/entries/popover.d.ts +1 -0
- package/dist/entries/popover.js +1 -0
- package/dist/entries/progress.d.ts +1 -0
- package/dist/entries/progress.js +1 -0
- package/dist/entries/property-list.d.ts +1 -0
- package/dist/entries/property-list.js +1 -0
- package/dist/entries/radio-group.d.ts +1 -0
- package/dist/entries/radio-group.js +1 -0
- package/dist/entries/registry-docs-api.d.ts +1 -0
- package/dist/entries/registry-docs-api.js +1 -0
- package/dist/entries/registry-docs-code.d.ts +1 -0
- package/dist/entries/registry-docs-code.js +1 -0
- package/dist/entries/registry-docs-showcase.d.ts +1 -0
- package/dist/entries/registry-docs-showcase.js +1 -0
- package/dist/entries/registry-docs.d.ts +1 -0
- package/dist/entries/registry-docs.js +1 -0
- package/dist/entries/resizable.d.ts +1 -0
- package/dist/entries/resizable.js +1 -0
- package/dist/entries/scroll-area.d.ts +1 -0
- package/dist/entries/scroll-area.js +1 -0
- package/dist/entries/select.d.ts +1 -0
- package/dist/entries/select.js +1 -0
- package/dist/entries/separator.d.ts +1 -0
- package/dist/entries/separator.js +1 -0
- package/dist/entries/sheet.d.ts +1 -0
- package/dist/entries/sheet.js +1 -0
- package/dist/entries/sidebar/context.d.ts +1 -0
- package/dist/entries/sidebar/context.js +1 -0
- package/dist/entries/sidebar/group.d.ts +1 -0
- package/dist/entries/sidebar/group.js +1 -0
- package/dist/entries/sidebar/layout.d.ts +1 -0
- package/dist/entries/sidebar/layout.js +1 -0
- package/dist/entries/sidebar/menu.d.ts +1 -0
- package/dist/entries/sidebar/menu.js +1 -0
- package/dist/entries/sidebar/provider.d.ts +1 -0
- package/dist/entries/sidebar/provider.js +1 -0
- package/dist/entries/sidebar/rail.d.ts +1 -0
- package/dist/entries/sidebar/rail.js +1 -0
- package/dist/entries/sidebar/trigger.d.ts +1 -0
- package/dist/entries/sidebar/trigger.js +1 -0
- package/dist/entries/sidebar-account-menu-theme.d.ts +1 -0
- package/dist/entries/sidebar-account-menu-theme.js +1 -0
- package/dist/entries/sidebar-account-menu.d.ts +1 -0
- package/dist/entries/sidebar-account-menu.js +1 -0
- package/dist/entries/sidebar.d.ts +1 -0
- package/dist/entries/sidebar.js +1 -0
- package/dist/entries/skeleton.d.ts +1 -0
- package/dist/entries/skeleton.js +1 -0
- package/dist/entries/slider.d.ts +1 -0
- package/dist/entries/slider.js +1 -0
- package/dist/entries/sonner.d.ts +1 -0
- package/dist/entries/sonner.js +1 -0
- package/dist/entries/spinner.d.ts +1 -0
- package/dist/entries/spinner.js +1 -0
- package/dist/entries/switch.d.ts +1 -0
- package/dist/entries/switch.js +1 -0
- package/dist/entries/table.d.ts +1 -0
- package/dist/entries/table.js +1 -0
- package/dist/entries/tabs-variants.d.ts +1 -0
- package/dist/entries/tabs-variants.js +1 -0
- package/dist/entries/tabs.d.ts +1 -0
- package/dist/entries/tabs.js +1 -0
- package/dist/entries/textarea.d.ts +1 -0
- package/dist/entries/textarea.js +1 -0
- package/dist/entries/timestamp-format.d.ts +1 -0
- package/dist/entries/timestamp-format.js +1 -0
- package/dist/entries/toggle-group.d.ts +1 -0
- package/dist/entries/toggle-group.js +1 -0
- package/dist/entries/toggle-variants.d.ts +1 -0
- package/dist/entries/toggle-variants.js +1 -0
- package/dist/entries/toggle.d.ts +1 -0
- package/dist/entries/toggle.js +1 -0
- package/dist/entries/tooltip.d.ts +1 -0
- package/dist/entries/tooltip.js +1 -0
- package/dist/entries/use-color-theme.d.ts +1 -0
- package/dist/entries/use-color-theme.js +1 -0
- package/dist/entries/use-mobile.d.ts +1 -0
- package/dist/entries/use-mobile.js +1 -0
- package/dist/entries/utils.d.ts +1 -0
- package/dist/entries/utils.js +1 -0
- package/dist/entries/workflow-timeline.d.ts +1 -0
- package/dist/entries/workflow-timeline.js +1 -0
- package/dist/lib/utils.js +1 -1
- package/dist/style-imports.d.ts +3 -0
- package/dist/styled-system/styles.css +61 -393
- package/dist/styles.css +490 -1
- package/package.json +33 -415
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { FeedbackSubmitResult, FeedbackSubmitValues, FeedbackType } from "./feedback-composer-types";
|
|
3
|
+
type FeedbackComposerProps = {
|
|
4
|
+
acceptedFileTypes?: string;
|
|
5
|
+
actions?: "inline" | "external";
|
|
6
|
+
attachmentsEnabled?: boolean;
|
|
7
|
+
defaultType?: FeedbackType;
|
|
8
|
+
formId?: string;
|
|
9
|
+
isSubmitting?: boolean;
|
|
10
|
+
maxAttachmentSizeMb?: number;
|
|
11
|
+
maxAttachments?: number;
|
|
12
|
+
onCancel?: () => void;
|
|
13
|
+
onSubmittedChange?: (submitted: boolean) => void;
|
|
14
|
+
onSubmit: (values: FeedbackSubmitValues) => void | Promise<void | FeedbackSubmitResult>;
|
|
15
|
+
};
|
|
16
|
+
declare function FeedbackComposer(props: FeedbackComposerProps): React.JSX.Element;
|
|
17
|
+
export { FeedbackComposer, type FeedbackComposerProps, type FeedbackSubmitResult, type FeedbackSubmitValues, type FeedbackType, };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { FeedbackComposerActions, FeedbackSubmittedState, FeedbackTypeField, } from "./feedback-composer-parts";
|
|
4
|
+
import { FileUploadField } from "../ui/file-upload-field";
|
|
5
|
+
import { Field, FieldContent, FieldError, FieldGroup, FieldLabel } from "../ui/field";
|
|
6
|
+
import { Input } from "../ui/input";
|
|
7
|
+
import { Textarea } from "../ui/textarea";
|
|
8
|
+
function FeedbackComposer(props) {
|
|
9
|
+
const state = useFeedbackComposerState(props.defaultType ?? "bug");
|
|
10
|
+
const ids = useFeedbackComposerIds();
|
|
11
|
+
if (state.submitResult) {
|
|
12
|
+
return (_jsx(FeedbackSubmittedState, { onCancel: props.onCancel, onSendAnother: () => {
|
|
13
|
+
state.resetForm();
|
|
14
|
+
props.onSubmittedChange?.(false);
|
|
15
|
+
}, referenceId: state.submitResult.referenceId }));
|
|
16
|
+
}
|
|
17
|
+
return _jsx(FeedbackComposerForm, { ids: ids, props: props, state: state });
|
|
18
|
+
}
|
|
19
|
+
function FeedbackComposerForm({ ids, props, state, }) {
|
|
20
|
+
const isSubmitting = props.isSubmitting ?? false;
|
|
21
|
+
return (_jsxs("form", { className: "grid gap-(--panel-gap)", id: props.formId, onSubmit: (event) => submitFeedback(event, props, state), children: [_jsxs(FieldGroup, { children: [_jsx(FeedbackTypeField, { disabled: isSubmitting, onTypeChange: state.setType, type: state.type }), _jsx(FeedbackSubjectField, { disabled: isSubmitting, error: state.error, fieldId: ids.subjectId, onSubjectChange: state.setSubject, subject: state.subject }), _jsx(FeedbackDescriptionField, { description: state.description, disabled: isSubmitting, error: state.error, fieldId: ids.descriptionId, onDescriptionChange: state.setDescription }), _jsx(FeedbackAttachmentsField, { props: props, state: state }), state.submitError ? _jsx(FieldError, { children: state.submitError }) : null] }), props.actions === "external" ? null : (_jsx(FeedbackComposerActions, { isSubmitting: isSubmitting, onCancel: props.onCancel }))] }));
|
|
22
|
+
}
|
|
23
|
+
function FeedbackSubjectField({ disabled, error, fieldId, onSubjectChange, subject, }) {
|
|
24
|
+
return (_jsxs(Field, { "data-invalid": error === "subject", children: [_jsx(FieldContent, { children: _jsx(FieldLabel, { htmlFor: fieldId, required: true, children: "Subject" }) }), _jsx(Input, { "aria-invalid": error === "subject", "aria-required": "true", disabled: disabled, id: fieldId, onChange: (event) => onSubjectChange(event.target.value), placeholder: "Short subject for the team", value: subject }), error === "subject" ? _jsx(FieldError, { children: "Subject is required." }) : null] }));
|
|
25
|
+
}
|
|
26
|
+
function FeedbackDescriptionField({ description, disabled, error, fieldId, onDescriptionChange, }) {
|
|
27
|
+
return (_jsxs(Field, { "data-invalid": error === "description", children: [_jsx(FieldContent, { children: _jsx(FieldLabel, { htmlFor: fieldId, required: true, children: "Feedback" }) }), _jsx(Textarea, { "aria-invalid": error === "description", "aria-required": "true", className: "min-h-40", disabled: disabled, id: fieldId, onChange: (event) => onDescriptionChange(event.target.value), placeholder: "What happened, what did you expect, or what would you like to see?", rows: 6, value: description }), error === "description" ? _jsx(FieldError, { children: "Feedback is required." }) : null] }));
|
|
28
|
+
}
|
|
29
|
+
function FeedbackAttachmentsField({ props, state, }) {
|
|
30
|
+
if (props.attachmentsEnabled === false)
|
|
31
|
+
return null;
|
|
32
|
+
return (_jsx(FileUploadField, { acceptedFileTypes: props.acceptedFileTypes ?? "image/*,.pdf,.csv,.txt,.doc,.docx,.xls,.xlsx", disabled: props.isSubmitting ?? false, files: state.attachments, maxAttachmentSizeMb: props.maxAttachmentSizeMb, maxAttachments: props.maxAttachments, onFilesChange: state.setAttachments, showConstraints: false, variant: "dropzone" }));
|
|
33
|
+
}
|
|
34
|
+
function useFeedbackComposerIds() {
|
|
35
|
+
const formId = React.useId();
|
|
36
|
+
return {
|
|
37
|
+
descriptionId: `${formId}-description`,
|
|
38
|
+
subjectId: `${formId}-subject`,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function useFeedbackComposerState(defaultType) {
|
|
42
|
+
const [attachments, setAttachments] = React.useState([]);
|
|
43
|
+
const [description, setDescription] = React.useState("");
|
|
44
|
+
const [error, setError] = React.useState();
|
|
45
|
+
const [submitError, setSubmitError] = React.useState();
|
|
46
|
+
const [submitResult, setSubmitResult] = React.useState();
|
|
47
|
+
const [subject, setSubject] = React.useState("");
|
|
48
|
+
const [type, setType] = React.useState(defaultType);
|
|
49
|
+
React.useEffect(() => {
|
|
50
|
+
setType(defaultType);
|
|
51
|
+
}, [defaultType]);
|
|
52
|
+
const resetForm = () => {
|
|
53
|
+
setAttachments([]);
|
|
54
|
+
setDescription("");
|
|
55
|
+
setError(undefined);
|
|
56
|
+
setSubmitError(undefined);
|
|
57
|
+
setSubmitResult(undefined);
|
|
58
|
+
setSubject("");
|
|
59
|
+
setType(defaultType);
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
attachments,
|
|
63
|
+
description,
|
|
64
|
+
error,
|
|
65
|
+
resetForm,
|
|
66
|
+
setAttachments,
|
|
67
|
+
setDescription,
|
|
68
|
+
setError,
|
|
69
|
+
setSubmitError,
|
|
70
|
+
setSubmitResult,
|
|
71
|
+
setSubject,
|
|
72
|
+
setType,
|
|
73
|
+
submitError,
|
|
74
|
+
submitResult,
|
|
75
|
+
subject,
|
|
76
|
+
type,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
async function submitFeedback(event, props, state) {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
const trimmedDescription = state.description.trim();
|
|
82
|
+
const trimmedSubject = state.subject.trim();
|
|
83
|
+
const validationError = getValidationError({
|
|
84
|
+
description: trimmedDescription,
|
|
85
|
+
subject: trimmedSubject,
|
|
86
|
+
});
|
|
87
|
+
state.setError(validationError);
|
|
88
|
+
state.setSubmitError(undefined);
|
|
89
|
+
if (validationError)
|
|
90
|
+
return;
|
|
91
|
+
try {
|
|
92
|
+
const result = await props.onSubmit({
|
|
93
|
+
attachments: state.attachments,
|
|
94
|
+
description: trimmedDescription,
|
|
95
|
+
subject: trimmedSubject,
|
|
96
|
+
type: state.type,
|
|
97
|
+
});
|
|
98
|
+
state.setSubmitResult(result ?? {});
|
|
99
|
+
props.onSubmittedChange?.(true);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
state.setSubmitError("Unable to submit feedback. Please try again.");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function getValidationError({ description, subject, }) {
|
|
106
|
+
if (!subject)
|
|
107
|
+
return "subject";
|
|
108
|
+
if (!description)
|
|
109
|
+
return "description";
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
export { FeedbackComposer, };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type TimestampFormatOptions } from "./timestamp-format";
|
|
2
|
+
declare function formatFeedbackTimestamp(value: string | undefined, options?: TimestampFormatOptions): string;
|
|
3
|
+
declare function formatFeedbackTimestampFull(value: string | undefined, options?: TimestampFormatOptions): string;
|
|
4
|
+
declare function getFeedbackTimestampDateTime(value: string | undefined): string | undefined;
|
|
5
|
+
export { formatFeedbackTimestamp, formatFeedbackTimestampFull, getFeedbackTimestampDateTime };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { formatTimestamp, formatTimestampFull, getTimestampDateTime, } from "./timestamp-format";
|
|
2
|
+
function formatFeedbackTimestamp(value, options = {}) {
|
|
3
|
+
return formatTimestamp(value, options);
|
|
4
|
+
}
|
|
5
|
+
function formatFeedbackTimestampFull(value, options = {}) {
|
|
6
|
+
return formatTimestampFull(value, options);
|
|
7
|
+
}
|
|
8
|
+
function getFeedbackTimestampDateTime(value) {
|
|
9
|
+
return getTimestampDateTime(value);
|
|
10
|
+
}
|
|
11
|
+
export { formatFeedbackTimestamp, formatFeedbackTimestampFull, getFeedbackTimestampDateTime };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
import { type StakeholderFeedbackItem } from "./feedback-tracking-types";
|
|
3
|
+
type FeedbackDetailSheetProps = {
|
|
4
|
+
feedback?: StakeholderFeedbackItem;
|
|
5
|
+
onOpenChange: (open: boolean) => void;
|
|
6
|
+
open: boolean;
|
|
7
|
+
};
|
|
8
|
+
declare function FeedbackDetailSheet({ feedback, onOpenChange, open }: FeedbackDetailSheetProps): React.JSX.Element;
|
|
9
|
+
export { FeedbackDetailSheet, type FeedbackDetailSheetProps };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { PaperclipIcon } from "lucide-react";
|
|
3
|
+
import { formatFeedbackTimestampFull, getFeedbackTimestampDateTime } from "./feedback-date-format";
|
|
4
|
+
import { FeedbackStatusBadge } from "./feedback-status-badge";
|
|
5
|
+
import { FeedbackTypeBadge } from "./feedback-type-badge";
|
|
6
|
+
import { getFeedbackInitials } from "./feedback-tracking-types";
|
|
7
|
+
import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar";
|
|
8
|
+
import { Button } from "../ui/button";
|
|
9
|
+
import { Card } from "../ui/card";
|
|
10
|
+
import { Item, ItemContent, ItemGroup, ItemMedia, ItemTitle } from "../ui/item";
|
|
11
|
+
import { PropertyList, PropertyListItem, PropertyListLabel, PropertyListValue, } from "../ui/property-list";
|
|
12
|
+
import { Sheet, SheetBody, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from "../ui/sheet";
|
|
13
|
+
function FeedbackDetailSheet({ feedback, onOpenChange, open }) {
|
|
14
|
+
return (_jsx(Sheet, { onOpenChange: onOpenChange, open: open, children: _jsxs(SheetContent, { size: "md", children: [_jsxs(SheetHeader, { children: [_jsx(SheetTitle, { children: feedback?.subject ?? "Feedback" }), _jsx(SheetDescription, { children: "Review the original submission and current progress." })] }), _jsx(SheetBody, { className: "grid content-start gap-(--panel-gap) pb-(--panel-padding)", children: feedback ? _jsx(FeedbackDetailContent, { feedback: feedback }) : null }), _jsx(SheetFooter, { children: _jsx(Button, { onClick: () => onOpenChange(false), type: "button", children: "Done" }) })] }) }));
|
|
15
|
+
}
|
|
16
|
+
function FeedbackDetailContent({ feedback }) {
|
|
17
|
+
return (_jsxs(_Fragment, { children: [_jsx(FeedbackDetailSummary, { feedback: feedback }), _jsx(FeedbackDetailBody, { feedback: feedback }), _jsx(FeedbackDetailAttachments, { feedback: feedback })] }));
|
|
18
|
+
}
|
|
19
|
+
function FeedbackDetailSummary({ feedback }) {
|
|
20
|
+
const submitter = feedback.submittedBy;
|
|
21
|
+
return (_jsxs("div", { className: "flex min-w-0 items-start justify-between gap-3 rounded-lg border bg-card p-(--panel-padding)", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [_jsxs(Avatar, { children: [_jsx(AvatarImage, { alt: "", src: submitter.imageUrl }), _jsx(AvatarFallback, { children: getFeedbackInitials(submitter.name, submitter.email) })] }), _jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium text-foreground", children: submitter.name }), _jsx("div", { className: "truncate text-xs text-muted-foreground", children: submitter.organization ?? submitter.email ?? "Stakeholder" })] })] }), _jsx(FeedbackStatusBadge, { status: feedback.status })] }));
|
|
22
|
+
}
|
|
23
|
+
function FeedbackDetailBody({ feedback }) {
|
|
24
|
+
return (_jsxs("div", { className: "grid gap-(--panel-gap)", children: [_jsxs(PropertyList, { children: [_jsx(FeedbackProperty, { label: "Type", children: _jsx(FeedbackTypeBadge, { type: feedback.type }) }), _jsx(FeedbackProperty, { label: "Submitted", children: _jsx(FeedbackDetailDateValue, { value: feedback.submittedAt }) }), _jsx(FeedbackProperty, { label: "Updated", children: _jsx(FeedbackDetailDateValue, { value: feedback.updatedAt }) }), feedback.referenceId ? (_jsx(FeedbackProperty, { label: "Reference", children: _jsx("span", { className: "font-mono text-xs tabular-nums", children: feedback.referenceId }) })) : null] }), _jsxs(Card, { className: "grid gap-2 p-(--panel-padding)", children: [_jsx("div", { className: "text-meta text-muted-foreground", children: "Feedback" }), _jsx("p", { className: "text-sm whitespace-pre-wrap text-foreground", children: feedback.description })] })] }));
|
|
25
|
+
}
|
|
26
|
+
function FeedbackProperty({ children, label }) {
|
|
27
|
+
return (_jsxs(PropertyListItem, { children: [_jsx(PropertyListLabel, { children: label }), _jsx(PropertyListValue, { children: children })] }));
|
|
28
|
+
}
|
|
29
|
+
function FeedbackDetailDateValue({ value }) {
|
|
30
|
+
return (_jsx("time", { className: "font-mono text-xs tabular-nums", dateTime: getFeedbackTimestampDateTime(value), children: formatFeedbackTimestampFull(value) }));
|
|
31
|
+
}
|
|
32
|
+
function FeedbackDetailAttachments({ feedback }) {
|
|
33
|
+
const attachments = feedback.attachments ?? [];
|
|
34
|
+
if (attachments.length === 0)
|
|
35
|
+
return null;
|
|
36
|
+
return (_jsxs("section", { className: "grid gap-2", children: [_jsx("div", { className: "text-meta text-muted-foreground", children: "Attachments" }), _jsx(ItemGroup, { children: attachments.map((attachment, index) => (_jsxs(Item, { size: "sm", variant: "outline", children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(PaperclipIcon, {}) }), _jsx(ItemContent, { children: _jsx(ItemTitle, { children: attachment.url ? (_jsx("a", { className: "underline-offset-4 hover:underline", href: attachment.url, children: attachment.name })) : (attachment.name) }) })] }, getAttachmentKey(attachment, index)))) })] }));
|
|
37
|
+
}
|
|
38
|
+
function getAttachmentKey(attachment, index) {
|
|
39
|
+
return `${attachment.url ?? attachment.name}-${index}`;
|
|
40
|
+
}
|
|
41
|
+
export { FeedbackDetailSheet };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FeedbackMetrics } from "./feedback-tracking-types";
|
|
2
|
+
type FeedbackMetricsProps = {
|
|
3
|
+
metrics: FeedbackMetrics;
|
|
4
|
+
};
|
|
5
|
+
declare function FeedbackMetricsStrip({ metrics }: FeedbackMetricsProps): import("@types/react").JSX.Element;
|
|
6
|
+
export { FeedbackMetricsStrip, type FeedbackMetricsProps };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { MetricsStrip, MetricsStripDetail, MetricsStripItem, MetricsStripLabel, MetricsStripValue, } from "../ui/metrics-strip";
|
|
3
|
+
function FeedbackMetricsStrip({ metrics }) {
|
|
4
|
+
return (_jsxs(MetricsStrip, { className: "md:grid-cols-5", children: [_jsx(FeedbackMetricItem, { detail: "New this week", label: "Received", tone: "neutral", value: metrics.receivedThisWeek }), _jsx(FeedbackMetricItem, { detail: "Needs review", label: "Awaiting review", tone: "warning", value: metrics.awaitingReview }), _jsx(FeedbackMetricItem, { detail: "Reviewed this week", label: "Triaged", tone: "info", value: metrics.triagedThisWeek }), _jsx(FeedbackMetricItem, { detail: "Active work", label: "In progress", tone: "info", value: metrics.inProgress }), _jsx(FeedbackMetricItem, { detail: "This week", label: "Resolved", tone: "success", value: metrics.resolvedThisWeek })] }));
|
|
5
|
+
}
|
|
6
|
+
function FeedbackMetricItem({ detail, label, tone, value, }) {
|
|
7
|
+
return (_jsxs(MetricsStripItem, { children: [_jsx(MetricsStripLabel, { children: label }), _jsx(MetricsStripValue, { children: value }), _jsx(MetricsStripDetail, { className: feedbackMetricToneClasses[tone], children: detail })] }));
|
|
8
|
+
}
|
|
9
|
+
const feedbackMetricToneClasses = {
|
|
10
|
+
info: "text-info",
|
|
11
|
+
neutral: "text-muted-foreground",
|
|
12
|
+
success: "text-success",
|
|
13
|
+
warning: "text-warning",
|
|
14
|
+
};
|
|
15
|
+
export { FeedbackMetricsStrip };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type FeedbackComposerProps } from "./feedback-composer";
|
|
3
|
+
type FeedbackSheetProps = Omit<FeedbackComposerProps, "actions" | "formId" | "onCancel" | "onSubmittedChange"> & {
|
|
4
|
+
onOpenChange: (open: boolean) => void;
|
|
5
|
+
open: boolean;
|
|
6
|
+
};
|
|
7
|
+
declare function FeedbackSheet({ onOpenChange, open, ...composerProps }: FeedbackSheetProps): React.JSX.Element;
|
|
8
|
+
export { FeedbackSheet, type FeedbackSheetProps };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { SendIcon } from "lucide-react";
|
|
4
|
+
import { FeedbackComposer } from "./feedback-composer";
|
|
5
|
+
import { Button } from "../ui/button";
|
|
6
|
+
import { Sheet, SheetBody, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from "../ui/sheet";
|
|
7
|
+
function FeedbackSheet({ onOpenChange, open, ...composerProps }) {
|
|
8
|
+
const formId = React.useId();
|
|
9
|
+
const [isSubmitted, setIsSubmitted] = React.useState(false);
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
if (!open)
|
|
12
|
+
setIsSubmitted(false);
|
|
13
|
+
}, [open]);
|
|
14
|
+
return (_jsx(Sheet, { onOpenChange: onOpenChange, open: open, children: _jsxs(SheetContent, { size: "md", children: [_jsxs(SheetHeader, { children: [_jsx(SheetTitle, { children: "Send feedback" }), _jsx(SheetDescription, { children: "Share a bug, feature request, or general note." })] }), _jsx(SheetBody, { children: _jsx(FeedbackComposer, { ...composerProps, actions: "external", formId: formId, onCancel: () => onOpenChange(false), onSubmittedChange: setIsSubmitted }) }), isSubmitted ? null : (_jsxs(SheetFooter, { children: [_jsx(Button, { disabled: composerProps.isSubmitting, onClick: () => onOpenChange(false), type: "button", variant: "outline", children: "Cancel" }), _jsxs(Button, { form: formId, loading: composerProps.isSubmitting, type: "submit", children: [_jsx(SendIcon, {}), "Submit feedback"] })] }))] }) }));
|
|
15
|
+
}
|
|
16
|
+
export { FeedbackSheet };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type FeedbackStatus } from "./feedback-tracking-types";
|
|
2
|
+
type FeedbackStatusBadgeProps = {
|
|
3
|
+
status: FeedbackStatus;
|
|
4
|
+
};
|
|
5
|
+
declare function FeedbackStatusBadge({ status }: FeedbackStatusBadgeProps): import("@types/react").JSX.Element;
|
|
6
|
+
export { FeedbackStatusBadge, type FeedbackStatusBadgeProps };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Badge } from "../ui/badge";
|
|
3
|
+
import { feedbackStatusLabels } from "./feedback-tracking-types";
|
|
4
|
+
function FeedbackStatusBadge({ status }) {
|
|
5
|
+
return _jsx(Badge, { variant: feedbackStatusVariants[status], children: feedbackStatusLabels[status] });
|
|
6
|
+
}
|
|
7
|
+
const feedbackStatusVariants = {
|
|
8
|
+
in_progress: "info",
|
|
9
|
+
in_review: "warning",
|
|
10
|
+
planned: "info",
|
|
11
|
+
received: "outline",
|
|
12
|
+
resolved: "success",
|
|
13
|
+
};
|
|
14
|
+
export { FeedbackStatusBadge };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type StakeholderFeedbackItem } from "./feedback-tracking-types";
|
|
2
|
+
declare function FeedbackTableRow({ item, onSelectFeedback, }: {
|
|
3
|
+
item: StakeholderFeedbackItem;
|
|
4
|
+
onSelectFeedback?: (item: StakeholderFeedbackItem) => void;
|
|
5
|
+
}): import("@types/react").JSX.Element;
|
|
6
|
+
export { FeedbackTableRow };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PaperclipIcon } from "lucide-react";
|
|
3
|
+
import { formatFeedbackTimestamp, getFeedbackTimestampDateTime } from "./feedback-date-format";
|
|
4
|
+
import { FeedbackStatusBadge } from "./feedback-status-badge";
|
|
5
|
+
import { FeedbackTypeBadge } from "./feedback-type-badge";
|
|
6
|
+
import { getFeedbackInitials } from "./feedback-tracking-types";
|
|
7
|
+
import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar";
|
|
8
|
+
import { TableCell, TableRow } from "../ui/table";
|
|
9
|
+
function FeedbackTableRow({ item, onSelectFeedback, }) {
|
|
10
|
+
return (_jsxs(TableRow, { className: onSelectFeedback ? "cursor-pointer" : undefined, onClick: () => onSelectFeedback?.(item), onKeyDown: (event) => {
|
|
11
|
+
if (!onSelectFeedback)
|
|
12
|
+
return;
|
|
13
|
+
if (event.currentTarget !== event.target)
|
|
14
|
+
return;
|
|
15
|
+
if (event.key !== "Enter" && event.key !== " ")
|
|
16
|
+
return;
|
|
17
|
+
event.preventDefault();
|
|
18
|
+
onSelectFeedback(item);
|
|
19
|
+
}, role: onSelectFeedback ? "button" : undefined, tabIndex: onSelectFeedback ? 0 : undefined, children: [_jsx(TableCell, { className: "max-w-[22rem]", children: _jsx(FeedbackSummaryCell, { item: item }) }), _jsx(TableCell, { children: _jsx(FeedbackTypeBadge, { type: item.type }) }), _jsx(TableCell, { children: _jsx(FeedbackSubmitterCell, { item: item }) }), _jsx(TableCell, { children: _jsx(FeedbackStatusBadge, { status: item.status }) }), _jsx(TableCell, { children: _jsx(FeedbackDateValue, { value: item.submittedAt }) }), _jsx(TableCell, { children: _jsx(FeedbackDateValue, { value: item.updatedAt }) }), _jsx(TableCell, { className: "text-right", children: _jsx(FeedbackAttachmentCount, { item: item }) })] }));
|
|
20
|
+
}
|
|
21
|
+
function FeedbackSummaryCell({ item }) {
|
|
22
|
+
return (_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium text-foreground", children: item.subject }), _jsx("div", { className: "truncate text-xs text-muted-foreground", children: item.description })] }));
|
|
23
|
+
}
|
|
24
|
+
function FeedbackSubmitterCell({ item }) {
|
|
25
|
+
const submitter = item.submittedBy;
|
|
26
|
+
return (_jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [_jsxs(Avatar, { size: "sm", children: [_jsx(AvatarImage, { alt: "", src: submitter.imageUrl }), _jsx(AvatarFallback, { children: getFeedbackInitials(submitter.name, submitter.email) })] }), _jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium text-foreground", children: submitter.name }), _jsx("div", { className: "truncate text-xs text-muted-foreground", children: submitter.organization ?? submitter.email ?? "Stakeholder" })] })] }));
|
|
27
|
+
}
|
|
28
|
+
function FeedbackDateValue({ value }) {
|
|
29
|
+
return (_jsx("time", { className: "font-mono text-xs text-muted-foreground tabular-nums", dateTime: getFeedbackTimestampDateTime(value), children: formatFeedbackTimestamp(value) }));
|
|
30
|
+
}
|
|
31
|
+
function FeedbackAttachmentCount({ item }) {
|
|
32
|
+
const count = item.attachments?.length ?? 0;
|
|
33
|
+
if (count === 0)
|
|
34
|
+
return _jsx("span", { className: "text-xs text-muted-foreground", children: "None" });
|
|
35
|
+
return (_jsxs("span", { className: "inline-flex items-center justify-end gap-1 font-mono text-xs text-muted-foreground tabular-nums", children: [_jsx(PaperclipIcon, { className: "size-3.5" }), count] }));
|
|
36
|
+
}
|
|
37
|
+
export { FeedbackTableRow };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SortDirection } from "../ui/data-table";
|
|
2
|
+
import type { StakeholderFeedbackItem } from "./feedback-tracking-types";
|
|
3
|
+
type FeedbackTableSortKey = "status" | "submittedAt" | "submittedBy" | "type" | "updatedAt";
|
|
4
|
+
type FeedbackTableSort = {
|
|
5
|
+
direction: SortDirection;
|
|
6
|
+
key: FeedbackTableSortKey;
|
|
7
|
+
};
|
|
8
|
+
declare function sortFeedbackItems(items: StakeholderFeedbackItem[], sort: FeedbackTableSort): StakeholderFeedbackItem[];
|
|
9
|
+
declare function getNextFeedbackTableSort(currentSort: FeedbackTableSort, key: FeedbackTableSortKey): FeedbackTableSort;
|
|
10
|
+
declare const defaultFeedbackTableSort: FeedbackTableSort;
|
|
11
|
+
export { defaultFeedbackTableSort, getNextFeedbackTableSort, sortFeedbackItems, type FeedbackTableSort, type FeedbackTableSortKey, };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
function sortFeedbackItems(items, sort) {
|
|
2
|
+
return [...items].sort((first, second) => {
|
|
3
|
+
const result = compareFeedbackItems(first, second, sort);
|
|
4
|
+
if (result !== 0)
|
|
5
|
+
return result;
|
|
6
|
+
return compareStrings(first.subject, second.subject, "asc");
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
function getNextFeedbackTableSort(currentSort, key) {
|
|
10
|
+
if (currentSort.key !== key)
|
|
11
|
+
return { direction: getDefaultSortDirection(key), key };
|
|
12
|
+
return {
|
|
13
|
+
direction: currentSort.direction === "asc" ? "desc" : "asc",
|
|
14
|
+
key,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function compareFeedbackItems(first, second, sort) {
|
|
18
|
+
if (sort.key === "type")
|
|
19
|
+
return compareFeedbackTypes(first.type, second.type, sort.direction);
|
|
20
|
+
if (sort.key === "submittedBy") {
|
|
21
|
+
return compareStrings(first.submittedBy.name, second.submittedBy.name, sort.direction);
|
|
22
|
+
}
|
|
23
|
+
if (sort.key === "status")
|
|
24
|
+
return compareFeedbackStatuses(first.status, second.status, sort.direction);
|
|
25
|
+
if (sort.key === "submittedAt") {
|
|
26
|
+
return compareTimestamps(first.submittedAt, second.submittedAt, sort.direction);
|
|
27
|
+
}
|
|
28
|
+
return compareTimestamps(first.updatedAt, second.updatedAt, sort.direction);
|
|
29
|
+
}
|
|
30
|
+
function getDefaultSortDirection(key) {
|
|
31
|
+
if (key === "submittedAt" || key === "updatedAt")
|
|
32
|
+
return "desc";
|
|
33
|
+
return "asc";
|
|
34
|
+
}
|
|
35
|
+
function compareFeedbackStatuses(first, second, direction) {
|
|
36
|
+
const result = statusSortOrder[first] - statusSortOrder[second];
|
|
37
|
+
return direction === "asc" ? result : -result;
|
|
38
|
+
}
|
|
39
|
+
function compareFeedbackTypes(first, second, direction) {
|
|
40
|
+
const result = typeSortOrder[first] - typeSortOrder[second];
|
|
41
|
+
return direction === "asc" ? result : -result;
|
|
42
|
+
}
|
|
43
|
+
function compareStrings(first, second, direction) {
|
|
44
|
+
const result = first.localeCompare(second, undefined, { sensitivity: "base" });
|
|
45
|
+
return direction === "asc" ? result : -result;
|
|
46
|
+
}
|
|
47
|
+
function compareTimestamps(first, second, direction) {
|
|
48
|
+
const firstTimestamp = getTimestamp(first);
|
|
49
|
+
const secondTimestamp = getTimestamp(second);
|
|
50
|
+
if (firstTimestamp === undefined && secondTimestamp === undefined)
|
|
51
|
+
return 0;
|
|
52
|
+
if (firstTimestamp === undefined)
|
|
53
|
+
return 1;
|
|
54
|
+
if (secondTimestamp === undefined)
|
|
55
|
+
return -1;
|
|
56
|
+
const result = firstTimestamp - secondTimestamp;
|
|
57
|
+
return direction === "asc" ? result : -result;
|
|
58
|
+
}
|
|
59
|
+
function getTimestamp(value) {
|
|
60
|
+
if (!value)
|
|
61
|
+
return undefined;
|
|
62
|
+
const timestamp = Date.parse(value);
|
|
63
|
+
return Number.isNaN(timestamp) ? undefined : timestamp;
|
|
64
|
+
}
|
|
65
|
+
const defaultFeedbackTableSort = {
|
|
66
|
+
direction: "desc",
|
|
67
|
+
key: "submittedAt",
|
|
68
|
+
};
|
|
69
|
+
const statusSortOrder = {
|
|
70
|
+
in_progress: 3,
|
|
71
|
+
in_review: 1,
|
|
72
|
+
planned: 2,
|
|
73
|
+
received: 0,
|
|
74
|
+
resolved: 4,
|
|
75
|
+
};
|
|
76
|
+
const typeSortOrder = {
|
|
77
|
+
bug: 0,
|
|
78
|
+
feature: 1,
|
|
79
|
+
general: 2,
|
|
80
|
+
};
|
|
81
|
+
export { defaultFeedbackTableSort, getNextFeedbackTableSort, sortFeedbackItems, };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { StakeholderFeedbackItem } from "./feedback-tracking-types";
|
|
3
|
+
import { type FeedbackTableSort, type FeedbackTableSortKey } from "./feedback-table-sort";
|
|
4
|
+
type FeedbackTableProps = {
|
|
5
|
+
defaultSort?: FeedbackTableSort;
|
|
6
|
+
emptyAction?: React.ReactNode;
|
|
7
|
+
emptyDescription?: string;
|
|
8
|
+
emptyTitle?: string;
|
|
9
|
+
isLoading?: boolean;
|
|
10
|
+
items: StakeholderFeedbackItem[];
|
|
11
|
+
onSelectFeedback?: (item: StakeholderFeedbackItem) => void;
|
|
12
|
+
onSortChange?: (sort: FeedbackTableSort) => void;
|
|
13
|
+
sort?: FeedbackTableSort;
|
|
14
|
+
};
|
|
15
|
+
declare function FeedbackTable({ defaultSort, emptyAction, emptyDescription, emptyTitle, isLoading, items, onSelectFeedback, onSortChange, sort, }: FeedbackTableProps): React.JSX.Element;
|
|
16
|
+
export { FeedbackTable, type FeedbackTableProps, type FeedbackTableSort, type FeedbackTableSortKey };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { InboxIcon } from "lucide-react";
|
|
4
|
+
import { DataTable, DataTableContent, DataTableEmpty, DataTableSkeleton, SortableTableHead, } from "../ui/data-table";
|
|
5
|
+
import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "../ui/empty";
|
|
6
|
+
import { Table, TableBody, TableHead, TableHeader, TableRow } from "../ui/table";
|
|
7
|
+
import { defaultFeedbackTableSort, getNextFeedbackTableSort, sortFeedbackItems, } from "./feedback-table-sort";
|
|
8
|
+
import { FeedbackTableRow } from "./feedback-table-row";
|
|
9
|
+
function FeedbackTable({ defaultSort = defaultFeedbackTableSort, emptyAction, emptyDescription = "No feedback has been submitted yet.", emptyTitle = "No feedback", isLoading = false, items, onSelectFeedback, onSortChange, sort, }) {
|
|
10
|
+
const [internalSort, setInternalSort] = React.useState(defaultSort);
|
|
11
|
+
const activeSort = sort ?? internalSort;
|
|
12
|
+
const sortedItems = React.useMemo(() => sortFeedbackItems(items, activeSort), [activeSort, items]);
|
|
13
|
+
const handleSortChange = React.useCallback((key) => {
|
|
14
|
+
const nextSort = getNextFeedbackTableSort(activeSort, key);
|
|
15
|
+
if (!sort)
|
|
16
|
+
setInternalSort(nextSort);
|
|
17
|
+
onSortChange?.(nextSort);
|
|
18
|
+
}, [activeSort, onSortChange, sort]);
|
|
19
|
+
if (isLoading)
|
|
20
|
+
return _jsx(FeedbackTableLoading, {});
|
|
21
|
+
if (items.length === 0) {
|
|
22
|
+
return (_jsx(FeedbackTableEmpty, { action: emptyAction, description: emptyDescription, title: emptyTitle }));
|
|
23
|
+
}
|
|
24
|
+
return (_jsx(DataTable, { children: _jsx(DataTableContent, { children: _jsx(FeedbackTableContent, { items: sortedItems, onSelectFeedback: onSelectFeedback, onSortChange: handleSortChange, sort: activeSort }) }) }));
|
|
25
|
+
}
|
|
26
|
+
function FeedbackTableLoading() {
|
|
27
|
+
return (_jsx(DataTable, { children: _jsx(DataTableSkeleton, { columns: 7, rows: 6 }) }));
|
|
28
|
+
}
|
|
29
|
+
function FeedbackTableEmpty({ action, description, title, }) {
|
|
30
|
+
return (_jsx(DataTable, { children: _jsx(DataTableEmpty, { className: "min-h-80 border-b-0", children: _jsx(FeedbackTableEmptyContent, { action: action, description: description, title: title }) }) }));
|
|
31
|
+
}
|
|
32
|
+
function FeedbackTableEmptyContent({ action, description, title, }) {
|
|
33
|
+
return (_jsxs(Empty, { className: "border-0", children: [_jsxs(EmptyHeader, { children: [_jsx(EmptyMedia, { variant: "icon", children: _jsx(InboxIcon, {}) }), _jsx(EmptyTitle, { children: title }), _jsx(EmptyDescription, { children: description })] }), action] }));
|
|
34
|
+
}
|
|
35
|
+
function FeedbackTableContent({ items, onSelectFeedback, onSortChange, sort, }) {
|
|
36
|
+
return (_jsxs(Table, { children: [_jsx(FeedbackTableHeader, { onSortChange: onSortChange, sort: sort }), _jsx(TableBody, { children: items.map((item) => (_jsx(FeedbackTableRow, { item: item, onSelectFeedback: onSelectFeedback }, item.id))) })] }));
|
|
37
|
+
}
|
|
38
|
+
function FeedbackTableHeader({ onSortChange, sort, }) {
|
|
39
|
+
return (_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Feedback" }), _jsx(FeedbackSortableHead, { label: "Type", onSortChange: onSortChange, sort: sort, sortKey: "type" }), _jsx(FeedbackSortableHead, { label: "Submitted by", onSortChange: onSortChange, sort: sort, sortKey: "submittedBy" }), _jsx(FeedbackSortableHead, { label: "Status", onSortChange: onSortChange, sort: sort, sortKey: "status" }), _jsx(FeedbackSortableHead, { label: "Submitted", onSortChange: onSortChange, sort: sort, sortKey: "submittedAt" }), _jsx(FeedbackSortableHead, { label: "Updated", onSortChange: onSortChange, sort: sort, sortKey: "updatedAt" }), _jsx(TableHead, { className: "text-right", children: "Files" })] }) }));
|
|
40
|
+
}
|
|
41
|
+
function FeedbackSortableHead({ label, onSortChange, sort, sortKey, }) {
|
|
42
|
+
const active = sort.key === sortKey;
|
|
43
|
+
return (_jsx(SortableTableHead, { active: active, direction: active ? sort.direction : "asc", onSort: () => onSortChange(sortKey), children: label }));
|
|
44
|
+
}
|
|
45
|
+
export { FeedbackTable };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
type FeedbackStatus = "received" | "in_review" | "planned" | "in_progress" | "resolved";
|
|
2
|
+
type StakeholderFeedbackType = "bug" | "feature" | "general";
|
|
3
|
+
type FeedbackSubmittedBy = {
|
|
4
|
+
email?: string;
|
|
5
|
+
imageUrl?: string;
|
|
6
|
+
name: string;
|
|
7
|
+
organization?: string;
|
|
8
|
+
};
|
|
9
|
+
type FeedbackAttachment = {
|
|
10
|
+
name: string;
|
|
11
|
+
url?: string;
|
|
12
|
+
};
|
|
13
|
+
type StakeholderFeedbackItem = {
|
|
14
|
+
attachments?: FeedbackAttachment[];
|
|
15
|
+
description: string;
|
|
16
|
+
id: string;
|
|
17
|
+
referenceId?: string;
|
|
18
|
+
status: FeedbackStatus;
|
|
19
|
+
subject: string;
|
|
20
|
+
submittedAt: string;
|
|
21
|
+
submittedBy: FeedbackSubmittedBy;
|
|
22
|
+
type: StakeholderFeedbackType;
|
|
23
|
+
updatedAt?: string;
|
|
24
|
+
};
|
|
25
|
+
type UserFeedbackItem = {
|
|
26
|
+
attachments?: FeedbackAttachment[];
|
|
27
|
+
description: string;
|
|
28
|
+
id: string;
|
|
29
|
+
referenceId?: string;
|
|
30
|
+
status: FeedbackStatus;
|
|
31
|
+
subject: string;
|
|
32
|
+
submittedAt: string;
|
|
33
|
+
type: StakeholderFeedbackType;
|
|
34
|
+
updatedAt?: string;
|
|
35
|
+
};
|
|
36
|
+
type FeedbackMetrics = {
|
|
37
|
+
awaitingReview: number;
|
|
38
|
+
inProgress: number;
|
|
39
|
+
receivedThisWeek: number;
|
|
40
|
+
resolvedThisWeek: number;
|
|
41
|
+
triagedThisWeek: number;
|
|
42
|
+
};
|
|
43
|
+
declare const feedbackStatusLabels: Record<FeedbackStatus, string>;
|
|
44
|
+
declare const feedbackTypeLabels: Record<StakeholderFeedbackType, string>;
|
|
45
|
+
declare const feedbackStatusOptions: readonly [{
|
|
46
|
+
readonly label: "All statuses";
|
|
47
|
+
readonly value: "all";
|
|
48
|
+
}, {
|
|
49
|
+
readonly label: string;
|
|
50
|
+
readonly value: "received";
|
|
51
|
+
}, {
|
|
52
|
+
readonly label: string;
|
|
53
|
+
readonly value: "in_review";
|
|
54
|
+
}, {
|
|
55
|
+
readonly label: string;
|
|
56
|
+
readonly value: "planned";
|
|
57
|
+
}, {
|
|
58
|
+
readonly label: string;
|
|
59
|
+
readonly value: "in_progress";
|
|
60
|
+
}, {
|
|
61
|
+
readonly label: string;
|
|
62
|
+
readonly value: "resolved";
|
|
63
|
+
}];
|
|
64
|
+
declare const feedbackTypeOptions: readonly [{
|
|
65
|
+
readonly label: "All types";
|
|
66
|
+
readonly value: "all";
|
|
67
|
+
}, {
|
|
68
|
+
readonly label: string;
|
|
69
|
+
readonly value: "bug";
|
|
70
|
+
}, {
|
|
71
|
+
readonly label: string;
|
|
72
|
+
readonly value: "feature";
|
|
73
|
+
}, {
|
|
74
|
+
readonly label: string;
|
|
75
|
+
readonly value: "general";
|
|
76
|
+
}];
|
|
77
|
+
declare function getFeedbackInitials(name: string, email: string | undefined): string;
|
|
78
|
+
export { feedbackStatusLabels, feedbackStatusOptions, feedbackTypeLabels, feedbackTypeOptions, getFeedbackInitials, type FeedbackAttachment, type FeedbackMetrics, type FeedbackStatus, type FeedbackSubmittedBy, type StakeholderFeedbackItem, type StakeholderFeedbackType, type UserFeedbackItem, };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const feedbackStatusLabels = {
|
|
2
|
+
in_progress: "In progress",
|
|
3
|
+
in_review: "In review",
|
|
4
|
+
planned: "Planned",
|
|
5
|
+
received: "Received",
|
|
6
|
+
resolved: "Resolved",
|
|
7
|
+
};
|
|
8
|
+
const feedbackTypeLabels = {
|
|
9
|
+
bug: "Bug",
|
|
10
|
+
feature: "Feature request",
|
|
11
|
+
general: "General",
|
|
12
|
+
};
|
|
13
|
+
const feedbackStatusOptions = [
|
|
14
|
+
{ label: "All statuses", value: "all" },
|
|
15
|
+
{ label: feedbackStatusLabels.received, value: "received" },
|
|
16
|
+
{ label: feedbackStatusLabels.in_review, value: "in_review" },
|
|
17
|
+
{ label: feedbackStatusLabels.planned, value: "planned" },
|
|
18
|
+
{ label: feedbackStatusLabels.in_progress, value: "in_progress" },
|
|
19
|
+
{ label: feedbackStatusLabels.resolved, value: "resolved" },
|
|
20
|
+
];
|
|
21
|
+
const feedbackTypeOptions = [
|
|
22
|
+
{ label: "All types", value: "all" },
|
|
23
|
+
{ label: feedbackTypeLabels.bug, value: "bug" },
|
|
24
|
+
{ label: feedbackTypeLabels.feature, value: "feature" },
|
|
25
|
+
{ label: feedbackTypeLabels.general, value: "general" },
|
|
26
|
+
];
|
|
27
|
+
function getFeedbackInitials(name, email) {
|
|
28
|
+
const source = name.trim() || email || "Stakeholder";
|
|
29
|
+
return source
|
|
30
|
+
.split(/\s|@/)
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.slice(0, 2)
|
|
33
|
+
.map((part) => part.charAt(0).toUpperCase())
|
|
34
|
+
.join("");
|
|
35
|
+
}
|
|
36
|
+
export { feedbackStatusLabels, feedbackStatusOptions, feedbackTypeLabels, feedbackTypeOptions, getFeedbackInitials, };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type StakeholderFeedbackType } from "./feedback-tracking-types";
|
|
2
|
+
type FeedbackTypeBadgeProps = {
|
|
3
|
+
type: StakeholderFeedbackType;
|
|
4
|
+
};
|
|
5
|
+
declare function FeedbackTypeBadge({ type }: FeedbackTypeBadgeProps): import("@types/react").JSX.Element;
|
|
6
|
+
export { FeedbackTypeBadge, type FeedbackTypeBadgeProps };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Badge } from "../ui/badge";
|
|
3
|
+
import { feedbackTypeLabels } from "./feedback-tracking-types";
|
|
4
|
+
function FeedbackTypeBadge({ type }) {
|
|
5
|
+
return _jsx(Badge, { variant: feedbackTypeVariants[type], children: feedbackTypeLabels[type] });
|
|
6
|
+
}
|
|
7
|
+
const feedbackTypeVariants = {
|
|
8
|
+
bug: "destructive",
|
|
9
|
+
feature: "info",
|
|
10
|
+
general: "outline",
|
|
11
|
+
};
|
|
12
|
+
export { FeedbackTypeBadge };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
import type { UserFeedbackItem } from "./feedback-tracking-types";
|
|
3
|
+
type FeedbackUserDetailProps = {
|
|
4
|
+
activityLabel?: string;
|
|
5
|
+
activitySlot?: React.ReactNode;
|
|
6
|
+
feedback?: UserFeedbackItem;
|
|
7
|
+
onBack?: () => void;
|
|
8
|
+
};
|
|
9
|
+
declare function FeedbackUserDetail({ activityLabel, activitySlot, feedback, onBack, }: FeedbackUserDetailProps): React.JSX.Element;
|
|
10
|
+
export { FeedbackUserDetail, type FeedbackUserDetailProps };
|