@aglyn/plugins-crm 1.0.0-beta.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +7 -0
- package/package.json +57 -0
- package/src/index.d.ts +21 -0
- package/src/index.js +29 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/activity-list.d.ts +98 -0
- package/src/lib/components/activity-list.js +321 -0
- package/src/lib/components/activity-list.js.map +1 -0
- package/src/lib/components/activity-queries.d.ts +117 -0
- package/src/lib/components/activity-queries.js +198 -0
- package/src/lib/components/activity-queries.js.map +1 -0
- package/src/lib/components/add-to-list-button.d.ts +25 -0
- package/src/lib/components/add-to-list-button.js +64 -0
- package/src/lib/components/add-to-list-button.js.map +1 -0
- package/src/lib/components/add-to-list-dialog.d.ts +24 -0
- package/src/lib/components/add-to-list-dialog.js +327 -0
- package/src/lib/components/add-to-list-dialog.js.map +1 -0
- package/src/lib/components/assignment-rule-drawer.d.ts +43 -0
- package/src/lib/components/assignment-rule-drawer.js +293 -0
- package/src/lib/components/assignment-rule-drawer.js.map +1 -0
- package/src/lib/components/companies-bulk-bar.d.ts +29 -0
- package/src/lib/components/companies-bulk-bar.js +274 -0
- package/src/lib/components/companies-bulk-bar.js.map +1 -0
- package/src/lib/components/companies-section.d.ts +54 -0
- package/src/lib/components/companies-section.js +522 -0
- package/src/lib/components/companies-section.js.map +1 -0
- package/src/lib/components/company-contacts-card.d.ts +49 -0
- package/src/lib/components/company-contacts-card.js +435 -0
- package/src/lib/components/company-contacts-card.js.map +1 -0
- package/src/lib/components/company-deals-card.d.ts +20 -0
- package/src/lib/components/company-deals-card.js +38 -0
- package/src/lib/components/company-deals-card.js.map +1 -0
- package/src/lib/components/company-detail-page.d.ts +20 -0
- package/src/lib/components/company-detail-page.js +165 -0
- package/src/lib/components/company-detail-page.js.map +1 -0
- package/src/lib/components/company-edit-drawer.d.ts +65 -0
- package/src/lib/components/company-edit-drawer.js +433 -0
- package/src/lib/components/company-edit-drawer.js.map +1 -0
- package/src/lib/components/company-import-drawer.d.ts +42 -0
- package/src/lib/components/company-import-drawer.js +99 -0
- package/src/lib/components/company-import-drawer.js.map +1 -0
- package/src/lib/components/company-picker.d.ts +127 -0
- package/src/lib/components/company-picker.js +323 -0
- package/src/lib/components/company-picker.js.map +1 -0
- package/src/lib/components/company-properties-card.d.ts +47 -0
- package/src/lib/components/company-properties-card.js +289 -0
- package/src/lib/components/company-properties-card.js.map +1 -0
- package/src/lib/components/contact-address-fields.d.ts +29 -0
- package/src/lib/components/contact-address-fields.js +149 -0
- package/src/lib/components/contact-address-fields.js.map +1 -0
- package/src/lib/components/contact-associations-card.d.ts +72 -0
- package/src/lib/components/contact-associations-card.js +296 -0
- package/src/lib/components/contact-associations-card.js.map +1 -0
- package/src/lib/components/contact-custom-columns.d.ts +38 -0
- package/src/lib/components/contact-custom-columns.js +102 -0
- package/src/lib/components/contact-custom-columns.js.map +1 -0
- package/src/lib/components/contact-custom-fields-card.d.ts +39 -0
- package/src/lib/components/contact-custom-fields-card.js +204 -0
- package/src/lib/components/contact-custom-fields-card.js.map +1 -0
- package/src/lib/components/contact-deals-card.d.ts +20 -0
- package/src/lib/components/contact-deals-card.js +38 -0
- package/src/lib/components/contact-deals-card.js.map +1 -0
- package/src/lib/components/contact-detail-page.d.ts +46 -0
- package/src/lib/components/contact-detail-page.js +535 -0
- package/src/lib/components/contact-detail-page.js.map +1 -0
- package/src/lib/components/contact-duplicates-card.d.ts +42 -0
- package/src/lib/components/contact-duplicates-card.js +167 -0
- package/src/lib/components/contact-duplicates-card.js.map +1 -0
- package/src/lib/components/contact-field-drawer.d.ts +64 -0
- package/src/lib/components/contact-field-drawer.js +251 -0
- package/src/lib/components/contact-field-drawer.js.map +1 -0
- package/src/lib/components/contact-import-drawer.d.ts +46 -0
- package/src/lib/components/contact-import-drawer.js +149 -0
- package/src/lib/components/contact-import-drawer.js.map +1 -0
- package/src/lib/components/contact-known-by-card.d.ts +39 -0
- package/src/lib/components/contact-known-by-card.js +142 -0
- package/src/lib/components/contact-known-by-card.js.map +1 -0
- package/src/lib/components/contact-list-columns.d.ts +53 -0
- package/src/lib/components/contact-list-columns.js +288 -0
- package/src/lib/components/contact-list-columns.js.map +1 -0
- package/src/lib/components/contact-merge-dialog.d.ts +79 -0
- package/src/lib/components/contact-merge-dialog.js +405 -0
- package/src/lib/components/contact-merge-dialog.js.map +1 -0
- package/src/lib/components/contact-properties-card.d.ts +89 -0
- package/src/lib/components/contact-properties-card.js +492 -0
- package/src/lib/components/contact-properties-card.js.map +1 -0
- package/src/lib/components/contact-timeline-card.d.ts +68 -0
- package/src/lib/components/contact-timeline-card.js +435 -0
- package/src/lib/components/contact-timeline-card.js.map +1 -0
- package/src/lib/components/contacts-bulk-bar.d.ts +91 -0
- package/src/lib/components/contacts-bulk-bar.js +493 -0
- package/src/lib/components/contacts-bulk-bar.js.map +1 -0
- package/src/lib/components/contacts-section.d.ts +26 -0
- package/src/lib/components/contacts-section.js +1025 -0
- package/src/lib/components/contacts-section.js.map +1 -0
- package/src/lib/components/copy-capture-address-button.d.ts +33 -0
- package/src/lib/components/copy-capture-address-button.js +60 -0
- package/src/lib/components/copy-capture-address-button.js.map +1 -0
- package/src/lib/components/crm-attribution-zone.d.ts +38 -0
- package/src/lib/components/crm-attribution-zone.js +36 -0
- package/src/lib/components/crm-attribution-zone.js.map +1 -0
- package/src/lib/components/crm-booking-zone.d.ts +61 -0
- package/src/lib/components/crm-booking-zone.js +50 -0
- package/src/lib/components/crm-booking-zone.js.map +1 -0
- package/src/lib/components/crm-bulk-bar-frame.d.ts +47 -0
- package/src/lib/components/crm-bulk-bar-frame.js +137 -0
- package/src/lib/components/crm-bulk-bar-frame.js.map +1 -0
- package/src/lib/components/crm-call-actions.d.ts +65 -0
- package/src/lib/components/crm-call-actions.js +110 -0
- package/src/lib/components/crm-call-actions.js.map +1 -0
- package/src/lib/components/crm-column-menu.d.ts +21 -0
- package/src/lib/components/crm-column-menu.js +103 -0
- package/src/lib/components/crm-column-menu.js.map +1 -0
- package/src/lib/components/crm-console-page.d.ts +19 -0
- package/src/lib/components/crm-console-page.js +151 -0
- package/src/lib/components/crm-console-page.js.map +1 -0
- package/src/lib/components/crm-console-sections.d.ts +52 -0
- package/src/lib/components/crm-console-sections.js +83 -0
- package/src/lib/components/crm-console-sections.js.map +1 -0
- package/src/lib/components/crm-custom-field-control.d.ts +26 -0
- package/src/lib/components/crm-custom-field-control.js +131 -0
- package/src/lib/components/crm-custom-field-control.js.map +1 -0
- package/src/lib/components/crm-email-template-tools.d.ts +69 -0
- package/src/lib/components/crm-email-template-tools.js +240 -0
- package/src/lib/components/crm-email-template-tools.js.map +1 -0
- package/src/lib/components/crm-export-all-button.d.ts +39 -0
- package/src/lib/components/crm-export-all-button.js +98 -0
- package/src/lib/components/crm-export-all-button.js.map +1 -0
- package/src/lib/components/crm-filter-bar.d.ts +53 -0
- package/src/lib/components/crm-filter-bar.js +294 -0
- package/src/lib/components/crm-filter-bar.js.map +1 -0
- package/src/lib/components/crm-glance-card.d.ts +54 -0
- package/src/lib/components/crm-glance-card.js +219 -0
- package/src/lib/components/crm-glance-card.js.map +1 -0
- package/src/lib/components/crm-next-activity-column.d.ts +35 -0
- package/src/lib/components/crm-next-activity-column.js +100 -0
- package/src/lib/components/crm-next-activity-column.js.map +1 -0
- package/src/lib/components/crm-record-header.d.ts +97 -0
- package/src/lib/components/crm-record-header.js +160 -0
- package/src/lib/components/crm-record-header.js.map +1 -0
- package/src/lib/components/crm-record-insights-zone.d.ts +50 -0
- package/src/lib/components/crm-record-insights-zone.js +169 -0
- package/src/lib/components/crm-record-insights-zone.js.map +1 -0
- package/src/lib/components/crm-record-picker.d.ts +42 -0
- package/src/lib/components/crm-record-picker.js +104 -0
- package/src/lib/components/crm-record-picker.js.map +1 -0
- package/src/lib/components/crm-send-email-button.d.ts +39 -0
- package/src/lib/components/crm-send-email-button.js +81 -0
- package/src/lib/components/crm-send-email-button.js.map +1 -0
- package/src/lib/components/crm-send-email-dialog.d.ts +61 -0
- package/src/lib/components/crm-send-email-dialog.js +851 -0
- package/src/lib/components/crm-send-email-dialog.js.map +1 -0
- package/src/lib/components/crm-site-picker.d.ts +61 -0
- package/src/lib/components/crm-site-picker.js +99 -0
- package/src/lib/components/crm-site-picker.js.map +1 -0
- package/src/lib/components/crm-suite-lock.d.ts +29 -0
- package/src/lib/components/crm-suite-lock.js +114 -0
- package/src/lib/components/crm-suite-lock.js.map +1 -0
- package/src/lib/components/crm-tasks-due-card.d.ts +42 -0
- package/src/lib/components/crm-tasks-due-card.js +225 -0
- package/src/lib/components/crm-tasks-due-card.js.map +1 -0
- package/src/lib/components/crm-views-control.d.ts +65 -0
- package/src/lib/components/crm-views-control.js +518 -0
- package/src/lib/components/crm-views-control.js.map +1 -0
- package/src/lib/components/csv-import-drawer.d.ts +132 -0
- package/src/lib/components/csv-import-drawer.js +746 -0
- package/src/lib/components/csv-import-drawer.js.map +1 -0
- package/src/lib/components/deal-board.d.ts +70 -0
- package/src/lib/components/deal-board.js +478 -0
- package/src/lib/components/deal-board.js.map +1 -0
- package/src/lib/components/deal-detail-page.d.ts +18 -0
- package/src/lib/components/deal-detail-page.js +323 -0
- package/src/lib/components/deal-detail-page.js.map +1 -0
- package/src/lib/components/deal-edit-drawer.d.ts +59 -0
- package/src/lib/components/deal-edit-drawer.js +640 -0
- package/src/lib/components/deal-edit-drawer.js.map +1 -0
- package/src/lib/components/deal-import-drawer.d.ts +24 -0
- package/src/lib/components/deal-import-drawer.js +83 -0
- package/src/lib/components/deal-import-drawer.js.map +1 -0
- package/src/lib/components/deal-products-card.d.ts +48 -0
- package/src/lib/components/deal-products-card.js +614 -0
- package/src/lib/components/deal-products-card.js.map +1 -0
- package/src/lib/components/deal-properties-card.d.ts +29 -0
- package/src/lib/components/deal-properties-card.js +144 -0
- package/src/lib/components/deal-properties-card.js.map +1 -0
- package/src/lib/components/deal-stage-card.d.ts +24 -0
- package/src/lib/components/deal-stage-card.js +199 -0
- package/src/lib/components/deal-stage-card.js.map +1 -0
- package/src/lib/components/deals-bulk-bar.d.ts +31 -0
- package/src/lib/components/deals-bulk-bar.js +340 -0
- package/src/lib/components/deals-bulk-bar.js.map +1 -0
- package/src/lib/components/deals-section.d.ts +49 -0
- package/src/lib/components/deals-section.js +767 -0
- package/src/lib/components/deals-section.js.map +1 -0
- package/src/lib/components/email-capture-card.d.ts +42 -0
- package/src/lib/components/email-capture-card.js +134 -0
- package/src/lib/components/email-capture-card.js.map +1 -0
- package/src/lib/components/email-template-drawer.d.ts +33 -0
- package/src/lib/components/email-template-drawer.js +209 -0
- package/src/lib/components/email-template-drawer.js.map +1 -0
- package/src/lib/components/email-templates-card.d.ts +33 -0
- package/src/lib/components/email-templates-card.js +370 -0
- package/src/lib/components/email-templates-card.js.map +1 -0
- package/src/lib/components/erase-person-action.d.ts +92 -0
- package/src/lib/components/erase-person-action.js +261 -0
- package/src/lib/components/erase-person-action.js.map +1 -0
- package/src/lib/components/fields-section.d.ts +37 -0
- package/src/lib/components/fields-section.js +641 -0
- package/src/lib/components/fields-section.js.map +1 -0
- package/src/lib/components/form-contact-fields-card.d.ts +46 -0
- package/src/lib/components/form-contact-fields-card.js +253 -0
- package/src/lib/components/form-contact-fields-card.js.map +1 -0
- package/src/lib/components/insert-link-at-caret.d.ts +28 -0
- package/src/lib/components/insert-link-at-caret.js +37 -0
- package/src/lib/components/insert-link-at-caret.js.map +1 -0
- package/src/lib/components/lead-convert-dialog.d.ts +32 -0
- package/src/lib/components/lead-convert-dialog.js +493 -0
- package/src/lib/components/lead-convert-dialog.js.map +1 -0
- package/src/lib/components/lead-detail-page.d.ts +16 -0
- package/src/lib/components/lead-detail-page.js +163 -0
- package/src/lib/components/lead-detail-page.js.map +1 -0
- package/src/lib/components/lead-history-card.d.ts +32 -0
- package/src/lib/components/lead-history-card.js +165 -0
- package/src/lib/components/lead-history-card.js.map +1 -0
- package/src/lib/components/lead-import-drawer.d.ts +24 -0
- package/src/lib/components/lead-import-drawer.js +95 -0
- package/src/lib/components/lead-import-drawer.js.map +1 -0
- package/src/lib/components/lead-owner-select.d.ts +35 -0
- package/src/lib/components/lead-owner-select.js +91 -0
- package/src/lib/components/lead-owner-select.js.map +1 -0
- package/src/lib/components/lead-properties-card.d.ts +61 -0
- package/src/lib/components/lead-properties-card.js +395 -0
- package/src/lib/components/lead-properties-card.js.map +1 -0
- package/src/lib/components/lead-status-chip.d.ts +12 -0
- package/src/lib/components/lead-status-chip.js +43 -0
- package/src/lib/components/lead-status-chip.js.map +1 -0
- package/src/lib/components/lead-surfaces-note.d.ts +126 -0
- package/src/lib/components/lead-surfaces-note.js +262 -0
- package/src/lib/components/lead-surfaces-note.js.map +1 -0
- package/src/lib/components/lead-unqualify-dialog.d.ts +24 -0
- package/src/lib/components/lead-unqualify-dialog.js +125 -0
- package/src/lib/components/lead-unqualify-dialog.js.map +1 -0
- package/src/lib/components/leads-bulk-bar.d.ts +58 -0
- package/src/lib/components/leads-bulk-bar.js +307 -0
- package/src/lib/components/leads-bulk-bar.js.map +1 -0
- package/src/lib/components/leads-section.d.ts +23 -0
- package/src/lib/components/leads-section.js +664 -0
- package/src/lib/components/leads-section.js.map +1 -0
- package/src/lib/components/linked-deals-card.d.ts +32 -0
- package/src/lib/components/linked-deals-card.js +163 -0
- package/src/lib/components/linked-deals-card.js.map +1 -0
- package/src/lib/components/log-activity-dialog.d.ts +60 -0
- package/src/lib/components/log-activity-dialog.js +368 -0
- package/src/lib/components/log-activity-dialog.js.map +1 -0
- package/src/lib/components/lost-reason-dialog.d.ts +26 -0
- package/src/lib/components/lost-reason-dialog.js +95 -0
- package/src/lib/components/lost-reason-dialog.js.map +1 -0
- package/src/lib/components/new-contact-drawer.d.ts +78 -0
- package/src/lib/components/new-contact-drawer.js +343 -0
- package/src/lib/components/new-contact-drawer.js.map +1 -0
- package/src/lib/components/org-lead-surfaces-note.d.ts +57 -0
- package/src/lib/components/org-lead-surfaces-note.js +172 -0
- package/src/lib/components/org-lead-surfaces-note.js.map +1 -0
- package/src/lib/components/owner-avatar.d.ts +18 -0
- package/src/lib/components/owner-avatar.js +61 -0
- package/src/lib/components/owner-avatar.js.map +1 -0
- package/src/lib/components/pipeline-stages-dialog.d.ts +43 -0
- package/src/lib/components/pipeline-stages-dialog.js +339 -0
- package/src/lib/components/pipeline-stages-dialog.js.map +1 -0
- package/src/lib/components/pipelines-dialog.d.ts +55 -0
- package/src/lib/components/pipelines-dialog.js +517 -0
- package/src/lib/components/pipelines-dialog.js.map +1 -0
- package/src/lib/components/recent-activity-feed.d.ts +39 -0
- package/src/lib/components/recent-activity-feed.js +103 -0
- package/src/lib/components/recent-activity-feed.js.map +1 -0
- package/src/lib/components/recipes-card.d.ts +39 -0
- package/src/lib/components/recipes-card.js +485 -0
- package/src/lib/components/recipes-card.js.map +1 -0
- package/src/lib/components/record-activity-card.d.ts +26 -0
- package/src/lib/components/record-activity-card.js +121 -0
- package/src/lib/components/record-activity-card.js.map +1 -0
- package/src/lib/components/record-files-card.d.ts +67 -0
- package/src/lib/components/record-files-card.js +290 -0
- package/src/lib/components/record-files-card.js.map +1 -0
- package/src/lib/components/record-tasks-card.d.ts +32 -0
- package/src/lib/components/record-tasks-card.js +306 -0
- package/src/lib/components/record-tasks-card.js.map +1 -0
- package/src/lib/components/reports/activity-card.d.ts +57 -0
- package/src/lib/components/reports/activity-card.js +281 -0
- package/src/lib/components/reports/activity-card.js.map +1 -0
- package/src/lib/components/reports/closed-deals-card.d.ts +20 -0
- package/src/lib/components/reports/closed-deals-card.js +194 -0
- package/src/lib/components/reports/closed-deals-card.js.map +1 -0
- package/src/lib/components/reports/contacts-mix-card.d.ts +27 -0
- package/src/lib/components/reports/contacts-mix-card.js +161 -0
- package/src/lib/components/reports/contacts-mix-card.js.map +1 -0
- package/src/lib/components/reports/contacts-trend-card.d.ts +31 -0
- package/src/lib/components/reports/contacts-trend-card.js +144 -0
- package/src/lib/components/reports/contacts-trend-card.js.map +1 -0
- package/src/lib/components/reports/forecast-card.d.ts +22 -0
- package/src/lib/components/reports/forecast-card.js +251 -0
- package/src/lib/components/reports/forecast-card.js.map +1 -0
- package/src/lib/components/reports/lead-counts.d.ts +32 -0
- package/src/lib/components/reports/lead-counts.js +44 -0
- package/src/lib/components/reports/lead-counts.js.map +1 -0
- package/src/lib/components/reports/lead-funnel-card.d.ts +38 -0
- package/src/lib/components/reports/lead-funnel-card.js +375 -0
- package/src/lib/components/reports/lead-funnel-card.js.map +1 -0
- package/src/lib/components/reports/pipeline-card.d.ts +19 -0
- package/src/lib/components/reports/pipeline-card.js +338 -0
- package/src/lib/components/reports/pipeline-card.js.map +1 -0
- package/src/lib/components/reports/report-bar-chart.d.ts +39 -0
- package/src/lib/components/reports/report-bar-chart.js +133 -0
- package/src/lib/components/reports/report-bar-chart.js.map +1 -0
- package/src/lib/components/reports/report-breakdown.d.ts +32 -0
- package/src/lib/components/reports/report-breakdown.js +105 -0
- package/src/lib/components/reports/report-breakdown.js.map +1 -0
- package/src/lib/components/reports/report-export.d.ts +37 -0
- package/src/lib/components/reports/report-export.js +66 -0
- package/src/lib/components/reports/report-export.js.map +1 -0
- package/src/lib/components/reports/report-format.d.ts +36 -0
- package/src/lib/components/reports/report-format.js +43 -0
- package/src/lib/components/reports/report-format.js.map +1 -0
- package/src/lib/components/reports/report-scope.d.ts +81 -0
- package/src/lib/components/reports/report-scope.js +58 -0
- package/src/lib/components/reports/report-scope.js.map +1 -0
- package/src/lib/components/reports/report-stat-tile.d.ts +47 -0
- package/src/lib/components/reports/report-stat-tile.js +96 -0
- package/src/lib/components/reports/report-stat-tile.js.map +1 -0
- package/src/lib/components/reports/source-conversion-card.d.ts +28 -0
- package/src/lib/components/reports/source-conversion-card.js +205 -0
- package/src/lib/components/reports/source-conversion-card.js.map +1 -0
- package/src/lib/components/reports/tasks-card.d.ts +26 -0
- package/src/lib/components/reports/tasks-card.js +279 -0
- package/src/lib/components/reports/tasks-card.js.map +1 -0
- package/src/lib/components/reports/use-aggregate-read.d.ts +99 -0
- package/src/lib/components/reports/use-aggregate-read.js +195 -0
- package/src/lib/components/reports/use-aggregate-read.js.map +1 -0
- package/src/lib/components/reports/won-lost-by-owner-card.d.ts +30 -0
- package/src/lib/components/reports/won-lost-by-owner-card.js +168 -0
- package/src/lib/components/reports/won-lost-by-owner-card.js.map +1 -0
- package/src/lib/components/reports-section.d.ts +42 -0
- package/src/lib/components/reports-section.js +308 -0
- package/src/lib/components/reports-section.js.map +1 -0
- package/src/lib/components/sending-addresses-card.d.ts +49 -0
- package/src/lib/components/sending-addresses-card.js +262 -0
- package/src/lib/components/sending-addresses-card.js.map +1 -0
- package/src/lib/components/settings-section.d.ts +151 -0
- package/src/lib/components/settings-section.js +783 -0
- package/src/lib/components/settings-section.js.map +1 -0
- package/src/lib/components/task-cells.d.ts +51 -0
- package/src/lib/components/task-cells.js +139 -0
- package/src/lib/components/task-cells.js.map +1 -0
- package/src/lib/components/task-edit-drawer.d.ts +53 -0
- package/src/lib/components/task-edit-drawer.js +483 -0
- package/src/lib/components/task-edit-drawer.js.map +1 -0
- package/src/lib/components/task-import-drawer.d.ts +24 -0
- package/src/lib/components/task-import-drawer.js +82 -0
- package/src/lib/components/task-import-drawer.js.map +1 -0
- package/src/lib/components/task-snooze-menu.d.ts +65 -0
- package/src/lib/components/task-snooze-menu.js +207 -0
- package/src/lib/components/task-snooze-menu.js.map +1 -0
- package/src/lib/components/tasks-bulk-bar.d.ts +25 -0
- package/src/lib/components/tasks-bulk-bar.js +348 -0
- package/src/lib/components/tasks-bulk-bar.js.map +1 -0
- package/src/lib/components/tasks-calendar.d.ts +38 -0
- package/src/lib/components/tasks-calendar.js +228 -0
- package/src/lib/components/tasks-calendar.js.map +1 -0
- package/src/lib/components/tasks-section.d.ts +27 -0
- package/src/lib/components/tasks-section.js +579 -0
- package/src/lib/components/tasks-section.js.map +1 -0
- package/src/lib/components/use-contact-campaign-emails.d.ts +32 -0
- package/src/lib/components/use-contact-campaign-emails.js +83 -0
- package/src/lib/components/use-contact-campaign-emails.js.map +1 -0
- package/src/lib/components/use-crm-api.d.ts +44 -0
- package/src/lib/components/use-crm-api.js +84 -0
- package/src/lib/components/use-crm-api.js.map +1 -0
- package/src/lib/components/use-crm-inbound-address.d.ts +60 -0
- package/src/lib/components/use-crm-inbound-address.js +124 -0
- package/src/lib/components/use-crm-inbound-address.js.map +1 -0
- package/src/lib/components/use-emails-hub-path.d.ts +24 -0
- package/src/lib/components/use-emails-hub-path.js +59 -0
- package/src/lib/components/use-emails-hub-path.js.map +1 -0
- package/src/lib/components/use-member-email-aliases.d.ts +54 -0
- package/src/lib/components/use-member-email-aliases.js +186 -0
- package/src/lib/components/use-member-email-aliases.js.map +1 -0
- package/src/lib/components/use-org-members.d.ts +40 -0
- package/src/lib/components/use-org-members.js +100 -0
- package/src/lib/components/use-org-members.js.map +1 -0
- package/src/lib/constants/api-routes.d.ts +109 -0
- package/src/lib/constants/api-routes.js +74 -0
- package/src/lib/constants/api-routes.js.map +1 -0
- package/src/lib/constants/bundle-common.d.ts +14 -0
- package/src/lib/constants/bundle-common.js +14 -0
- package/src/lib/constants/bundle-common.js.map +1 -0
- package/src/lib/constants/company-filters.d.ts +18 -0
- package/src/lib/constants/company-filters.js +51 -0
- package/src/lib/constants/company-filters.js.map +1 -0
- package/src/lib/constants/contact-filters.d.ts +38 -0
- package/src/lib/constants/contact-filters.js +294 -0
- package/src/lib/constants/contact-filters.js.map +1 -0
- package/src/lib/hooks/use-contact-field-definitions.d.ts +48 -0
- package/src/lib/hooks/use-contact-field-definitions.js +72 -0
- package/src/lib/hooks/use-contact-field-definitions.js.map +1 -0
- package/src/lib/hooks/use-contact-update.d.ts +25 -0
- package/src/lib/hooks/use-contact-update.js +80 -0
- package/src/lib/hooks/use-contact-update.js.map +1 -0
- package/src/lib/hooks/use-crm-activity-logger.d.ts +73 -0
- package/src/lib/hooks/use-crm-activity-logger.js +101 -0
- package/src/lib/hooks/use-crm-activity-logger.js.map +1 -0
- package/src/lib/hooks/use-crm-bulk-apply.d.ts +52 -0
- package/src/lib/hooks/use-crm-bulk-apply.js +112 -0
- package/src/lib/hooks/use-crm-bulk-apply.js.map +1 -0
- package/src/lib/hooks/use-crm-default-view.d.ts +24 -0
- package/src/lib/hooks/use-crm-default-view.js +64 -0
- package/src/lib/hooks/use-crm-default-view.js.map +1 -0
- package/src/lib/hooks/use-crm-email-templates.d.ts +59 -0
- package/src/lib/hooks/use-crm-email-templates.js +103 -0
- package/src/lib/hooks/use-crm-email-templates.js.map +1 -0
- package/src/lib/hooks/use-crm-hub-path.d.ts +29 -0
- package/src/lib/hooks/use-crm-hub-path.js +41 -0
- package/src/lib/hooks/use-crm-hub-path.js.map +1 -0
- package/src/lib/hooks/use-crm-org-mount.d.ts +97 -0
- package/src/lib/hooks/use-crm-org-mount.js +215 -0
- package/src/lib/hooks/use-crm-org-mount.js.map +1 -0
- package/src/lib/hooks/use-crm-record-names.d.ts +52 -0
- package/src/lib/hooks/use-crm-record-names.js +126 -0
- package/src/lib/hooks/use-crm-record-names.js.map +1 -0
- package/src/lib/hooks/use-crm-records-quota.d.ts +68 -0
- package/src/lib/hooks/use-crm-records-quota.js +118 -0
- package/src/lib/hooks/use-crm-records-quota.js.map +1 -0
- package/src/lib/hooks/use-crm-saved-view.d.ts +96 -0
- package/src/lib/hooks/use-crm-saved-view.js +329 -0
- package/src/lib/hooks/use-crm-saved-view.js.map +1 -0
- package/src/lib/hooks/use-crm-scope.d.ts +117 -0
- package/src/lib/hooks/use-crm-scope.js +147 -0
- package/src/lib/hooks/use-crm-scope.js.map +1 -0
- package/src/lib/hooks/use-crm-tasks.d.ts +85 -0
- package/src/lib/hooks/use-crm-tasks.js +153 -0
- package/src/lib/hooks/use-crm-tasks.js.map +1 -0
- package/src/lib/hooks/use-crm-view-grid.d.ts +55 -0
- package/src/lib/hooks/use-crm-view-grid.js +170 -0
- package/src/lib/hooks/use-crm-view-grid.js.map +1 -0
- package/src/lib/hooks/use-crm-views.d.ts +42 -0
- package/src/lib/hooks/use-crm-views.js +84 -0
- package/src/lib/hooks/use-crm-views.js.map +1 -0
- package/src/lib/hooks/use-deal-stage-api.d.ts +69 -0
- package/src/lib/hooks/use-deal-stage-api.js +78 -0
- package/src/lib/hooks/use-deal-stage-api.js.map +1 -0
- package/src/lib/hooks/use-deals.d.ts +47 -0
- package/src/lib/hooks/use-deals.js +105 -0
- package/src/lib/hooks/use-deals.js.map +1 -0
- package/src/lib/hooks/use-org-leads.d.ts +53 -0
- package/src/lib/hooks/use-org-leads.js +114 -0
- package/src/lib/hooks/use-org-leads.js.map +1 -0
- package/src/lib/hooks/use-org-member-directory.d.ts +36 -0
- package/src/lib/hooks/use-org-member-directory.js +116 -0
- package/src/lib/hooks/use-org-member-directory.js.map +1 -0
- package/src/lib/hooks/use-org-member-options.d.ts +38 -0
- package/src/lib/hooks/use-org-member-options.js +131 -0
- package/src/lib/hooks/use-org-member-options.js.map +1 -0
- package/src/lib/hooks/use-pipeline.d.ts +71 -0
- package/src/lib/hooks/use-pipeline.js +159 -0
- package/src/lib/hooks/use-pipeline.js.map +1 -0
- package/src/lib/model/companies-bulk-writes.d.ts +40 -0
- package/src/lib/model/companies-bulk-writes.js +103 -0
- package/src/lib/model/companies-bulk-writes.js.map +1 -0
- package/src/lib/model/companies-csv.d.ts +36 -0
- package/src/lib/model/companies-csv.js +38 -0
- package/src/lib/model/companies-csv.js.map +1 -0
- package/src/lib/model/companies.d.ts +99 -0
- package/src/lib/model/companies.js +168 -0
- package/src/lib/model/companies.js.map +1 -0
- package/src/lib/model/company-delete-route.d.ts +43 -0
- package/src/lib/model/company-delete-route.js +31 -0
- package/src/lib/model/company-delete-route.js.map +1 -0
- package/src/lib/model/company-delete.d.ts +42 -0
- package/src/lib/model/company-delete.js +52 -0
- package/src/lib/model/company-delete.js.map +1 -0
- package/src/lib/model/contact-duplicates.d.ts +58 -0
- package/src/lib/model/contact-duplicates.js +67 -0
- package/src/lib/model/contact-duplicates.js.map +1 -0
- package/src/lib/model/contact-record.d.ts +113 -0
- package/src/lib/model/contact-record.js +70 -0
- package/src/lib/model/contact-record.js.map +1 -0
- package/src/lib/model/contact-update.d.ts +93 -0
- package/src/lib/model/contact-update.js +50 -0
- package/src/lib/model/contact-update.js.map +1 -0
- package/src/lib/model/contacts-bulk-writes.d.ts +173 -0
- package/src/lib/model/contacts-bulk-writes.js +196 -0
- package/src/lib/model/contacts-bulk-writes.js.map +1 -0
- package/src/lib/model/contacts-csv.d.ts +54 -0
- package/src/lib/model/contacts-csv.js +67 -0
- package/src/lib/model/contacts-csv.js.map +1 -0
- package/src/lib/model/contacts-list-seed.d.ts +51 -0
- package/src/lib/model/contacts-list-seed.js +63 -0
- package/src/lib/model/contacts-list-seed.js.map +1 -0
- package/src/lib/model/crm-activity-report.d.ts +27 -0
- package/src/lib/model/crm-activity-report.js +56 -0
- package/src/lib/model/crm-activity-report.js.map +1 -0
- package/src/lib/model/crm-api.d.ts +49 -0
- package/src/lib/model/crm-api.js +47 -0
- package/src/lib/model/crm-api.js.map +1 -0
- package/src/lib/model/crm-bulk-writes.d.ts +147 -0
- package/src/lib/model/crm-bulk-writes.js +207 -0
- package/src/lib/model/crm-bulk-writes.js.map +1 -0
- package/src/lib/model/crm-company-import.d.ts +154 -0
- package/src/lib/model/crm-company-import.js +331 -0
- package/src/lib/model/crm-company-import.js.map +1 -0
- package/src/lib/model/crm-custom-draft.d.ts +62 -0
- package/src/lib/model/crm-custom-draft.js +67 -0
- package/src/lib/model/crm-custom-draft.js.map +1 -0
- package/src/lib/model/crm-deal-import.d.ts +112 -0
- package/src/lib/model/crm-deal-import.js +263 -0
- package/src/lib/model/crm-deal-import.js.map +1 -0
- package/src/lib/model/crm-import.d.ts +244 -0
- package/src/lib/model/crm-import.js +466 -0
- package/src/lib/model/crm-import.js.map +1 -0
- package/src/lib/model/crm-lead-import.d.ts +105 -0
- package/src/lib/model/crm-lead-import.js +255 -0
- package/src/lib/model/crm-lead-import.js.map +1 -0
- package/src/lib/model/crm-record-routes.d.ts +21 -0
- package/src/lib/model/crm-record-routes.js +70 -0
- package/src/lib/model/crm-record-routes.js.map +1 -0
- package/src/lib/model/crm-routes.d.ts +101 -0
- package/src/lib/model/crm-routes.js +92 -0
- package/src/lib/model/crm-routes.js.map +1 -0
- package/src/lib/model/crm-task-import.d.ts +94 -0
- package/src/lib/model/crm-task-import.js +275 -0
- package/src/lib/model/crm-task-import.js.map +1 -0
- package/src/lib/model/crm-view-param.d.ts +43 -0
- package/src/lib/model/crm-view-param.js +49 -0
- package/src/lib/model/crm-view-param.js.map +1 -0
- package/src/lib/model/deal-board-model.d.ts +241 -0
- package/src/lib/model/deal-board-model.js +439 -0
- package/src/lib/model/deal-board-model.js.map +1 -0
- package/src/lib/model/deal-form-model.d.ts +114 -0
- package/src/lib/model/deal-form-model.js +218 -0
- package/src/lib/model/deal-form-model.js.map +1 -0
- package/src/lib/model/deals-csv.d.ts +32 -0
- package/src/lib/model/deals-csv.js +37 -0
- package/src/lib/model/deals-csv.js.map +1 -0
- package/src/lib/model/import-column-shapes.d.ts +36 -0
- package/src/lib/model/import-column-shapes.js +76 -0
- package/src/lib/model/import-column-shapes.js.map +1 -0
- package/src/lib/model/lead-company-suggestion.d.ts +61 -0
- package/src/lib/model/lead-company-suggestion.js +65 -0
- package/src/lib/model/lead-company-suggestion.js.map +1 -0
- package/src/lib/model/lead-filters.d.ts +29 -0
- package/src/lib/model/lead-filters.js +39 -0
- package/src/lib/model/lead-filters.js.map +1 -0
- package/src/lib/model/lead-surfaces.d.ts +58 -0
- package/src/lib/model/lead-surfaces.js +67 -0
- package/src/lib/model/lead-surfaces.js.map +1 -0
- package/src/lib/model/leads-csv.d.ts +40 -0
- package/src/lib/model/leads-csv.js +40 -0
- package/src/lib/model/leads-csv.js.map +1 -0
- package/src/lib/model/next-activity-api.d.ts +31 -0
- package/src/lib/model/next-activity-api.js +57 -0
- package/src/lib/model/next-activity-api.js.map +1 -0
- package/src/lib/model/next-activity.d.ts +64 -0
- package/src/lib/model/next-activity.js +47 -0
- package/src/lib/model/next-activity.js.map +1 -0
- package/src/lib/model/person-key-web.d.ts +43 -0
- package/src/lib/model/person-key-web.js +52 -0
- package/src/lib/model/person-key-web.js.map +1 -0
- package/src/lib/model/record-facts.d.ts +282 -0
- package/src/lib/model/record-facts.js +434 -0
- package/src/lib/model/record-facts.js.map +1 -0
- package/src/lib/model/task-api.d.ts +28 -0
- package/src/lib/model/task-api.js +57 -0
- package/src/lib/model/task-api.js.map +1 -0
- package/src/lib/model/task-calendar.d.ts +108 -0
- package/src/lib/model/task-calendar.js +139 -0
- package/src/lib/model/task-calendar.js.map +1 -0
- package/src/lib/model/task-routes.d.ts +177 -0
- package/src/lib/model/task-routes.js +197 -0
- package/src/lib/model/task-routes.js.map +1 -0
- package/src/lib/model/task-scope.d.ts +45 -0
- package/src/lib/model/task-scope.js +51 -0
- package/src/lib/model/task-scope.js.map +1 -0
- package/src/lib/model/task-views.d.ts +149 -0
- package/src/lib/model/task-views.js +286 -0
- package/src/lib/model/task-views.js.map +1 -0
- package/src/lib/model/tasks-csv.d.ts +28 -0
- package/src/lib/model/tasks-csv.js +28 -0
- package/src/lib/model/tasks-csv.js.map +1 -0
- package/src/lib/plugin.d.ts +32 -0
- package/src/lib/plugin.js +208 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/server/companies-import.d.ts +57 -0
- package/src/lib/server/companies-import.js +242 -0
- package/src/lib/server/companies-import.js.map +1 -0
- package/src/lib/server/company-delete.d.ts +59 -0
- package/src/lib/server/company-delete.js +146 -0
- package/src/lib/server/company-delete.js.map +1 -0
- package/src/lib/server/contact-email-history.d.ts +82 -0
- package/src/lib/server/contact-email-history.js +264 -0
- package/src/lib/server/contact-email-history.js.map +1 -0
- package/src/lib/server/contact-profile.d.ts +41 -0
- package/src/lib/server/contact-profile.js +45 -0
- package/src/lib/server/contact-profile.js.map +1 -0
- package/src/lib/server/contact-update.d.ts +92 -0
- package/src/lib/server/contact-update.js +512 -0
- package/src/lib/server/contact-update.js.map +1 -0
- package/src/lib/server/contacts-import.d.ts +73 -0
- package/src/lib/server/contacts-import.js +263 -0
- package/src/lib/server/contacts-import.js.map +1 -0
- package/src/lib/server/contacts-merge.d.ts +86 -0
- package/src/lib/server/contacts-merge.js +206 -0
- package/src/lib/server/contacts-merge.js.map +1 -0
- package/src/lib/server/deals-import.d.ts +76 -0
- package/src/lib/server/deals-import.js +246 -0
- package/src/lib/server/deals-import.js.map +1 -0
- package/src/lib/server/email-send.d.ts +119 -0
- package/src/lib/server/email-send.js +667 -0
- package/src/lib/server/email-send.js.map +1 -0
- package/src/lib/server/email-template-duplicate.d.ts +19 -0
- package/src/lib/server/email-template-duplicate.js +206 -0
- package/src/lib/server/email-template-duplicate.js.map +1 -0
- package/src/lib/server/erase-person.d.ts +108 -0
- package/src/lib/server/erase-person.js +309 -0
- package/src/lib/server/erase-person.js.map +1 -0
- package/src/lib/server/import-context.d.ts +85 -0
- package/src/lib/server/import-context.js +181 -0
- package/src/lib/server/import-context.js.map +1 -0
- package/src/lib/server/inbound-address.d.ts +61 -0
- package/src/lib/server/inbound-address.js +188 -0
- package/src/lib/server/inbound-address.js.map +1 -0
- package/src/lib/server/lead-convert.d.ts +78 -0
- package/src/lib/server/lead-convert.js +250 -0
- package/src/lib/server/lead-convert.js.map +1 -0
- package/src/lib/server/leads-import.d.ts +84 -0
- package/src/lib/server/leads-import.js +261 -0
- package/src/lib/server/leads-import.js.map +1 -0
- package/src/lib/server/next-activity-routes.d.ts +33 -0
- package/src/lib/server/next-activity-routes.js +110 -0
- package/src/lib/server/next-activity-routes.js.map +1 -0
- package/src/lib/server/org-activity.d.ts +61 -0
- package/src/lib/server/org-activity.js +120 -0
- package/src/lib/server/org-activity.js.map +1 -0
- package/src/lib/server/org-caller.d.ts +110 -0
- package/src/lib/server/org-caller.js +154 -0
- package/src/lib/server/org-caller.js.map +1 -0
- package/src/lib/server/recipe-routes.d.ts +75 -0
- package/src/lib/server/recipe-routes.js +442 -0
- package/src/lib/server/recipe-routes.js.map +1 -0
- package/src/lib/server/record-facts.d.ts +65 -0
- package/src/lib/server/record-facts.js +337 -0
- package/src/lib/server/record-facts.js.map +1 -0
- package/src/lib/server/record-timeline.d.ts +51 -0
- package/src/lib/server/record-timeline.js +215 -0
- package/src/lib/server/record-timeline.js.map +1 -0
- package/src/lib/server/suite-gate.d.ts +42 -0
- package/src/lib/server/suite-gate.js +87 -0
- package/src/lib/server/suite-gate.js.map +1 -0
- package/src/lib/server/task-routes.d.ts +132 -0
- package/src/lib/server/task-routes.js +699 -0
- package/src/lib/server/task-routes.js.map +1 -0
- package/src/lib/server/tasks-import.d.ts +54 -0
- package/src/lib/server/tasks-import.js +157 -0
- package/src/lib/server/tasks-import.js.map +1 -0
- package/src/lib/server-deal-stage.d.ts +88 -0
- package/src/lib/server-deal-stage.js +316 -0
- package/src/lib/server-deal-stage.js.map +1 -0
- package/src/lib/server.d.ts +149 -0
- package/src/lib/server.js +615 -0
- package/src/lib/server.js.map +1 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import { Box, Stack, Typography } from "@mui/material";
|
|
19
|
+
/**
|
|
20
|
+
* One horizontal bar per category — contacts by source, deals by stage,
|
|
21
|
+
* the lifecycle funnel — each labeled, each with its figure at the end of
|
|
22
|
+
* the row.
|
|
23
|
+
*
|
|
24
|
+
* Horizontal rather than the vertical bars of the trend chart because the
|
|
25
|
+
* categories have NAMES, and a name under a thin vertical bar truncates
|
|
26
|
+
* while a name beside a horizontal one reads. The bar is a share of the
|
|
27
|
+
* largest row, not of the total, so a funnel's top step is always the full
|
|
28
|
+
* width and every step below it is visibly a fraction of the one above.
|
|
29
|
+
*/ export function ReportBreakdown(props) {
|
|
30
|
+
const { rows, emptyText } = props;
|
|
31
|
+
if (!rows.length) {
|
|
32
|
+
return /*#__PURE__*/ _jsx(Typography, {
|
|
33
|
+
variant: "body2",
|
|
34
|
+
color: "text.secondary",
|
|
35
|
+
children: emptyText
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const max = Math.max(1, ...rows.map((row)=>row.value));
|
|
39
|
+
return /*#__PURE__*/ _jsx(Stack, {
|
|
40
|
+
spacing: 1,
|
|
41
|
+
children: rows.map((row)=>{
|
|
42
|
+
var _row_display, _row_color, _row_display1;
|
|
43
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
44
|
+
direction: "row",
|
|
45
|
+
spacing: 1.5,
|
|
46
|
+
sx: {
|
|
47
|
+
alignItems: 'center'
|
|
48
|
+
},
|
|
49
|
+
children: [
|
|
50
|
+
/*#__PURE__*/ _jsxs(Box, {
|
|
51
|
+
sx: {
|
|
52
|
+
flex: '0 0 36%',
|
|
53
|
+
minWidth: 0
|
|
54
|
+
},
|
|
55
|
+
children: [
|
|
56
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
57
|
+
variant: "body2",
|
|
58
|
+
noWrap: true,
|
|
59
|
+
children: row.label
|
|
60
|
+
}),
|
|
61
|
+
row.note ? /*#__PURE__*/ _jsx(Typography, {
|
|
62
|
+
variant: "caption",
|
|
63
|
+
color: "text.secondary",
|
|
64
|
+
noWrap: true,
|
|
65
|
+
component: "div",
|
|
66
|
+
children: row.note
|
|
67
|
+
}) : null
|
|
68
|
+
]
|
|
69
|
+
}),
|
|
70
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
71
|
+
sx: {
|
|
72
|
+
flex: 1,
|
|
73
|
+
height: 8,
|
|
74
|
+
borderRadius: 0.5,
|
|
75
|
+
bgcolor: 'action.hover',
|
|
76
|
+
overflow: 'hidden'
|
|
77
|
+
},
|
|
78
|
+
children: /*#__PURE__*/ _jsx(Box, {
|
|
79
|
+
title: (_row_display = row.display) != null ? _row_display : row.value.toLocaleString(),
|
|
80
|
+
sx: {
|
|
81
|
+
width: `${Math.max(row.value > 0 ? 2 : 0, Math.round(row.value / max * 100))}%`,
|
|
82
|
+
height: '100%',
|
|
83
|
+
bgcolor: (_row_color = row.color) != null ? _row_color : 'primary.main',
|
|
84
|
+
opacity: 0.9
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
}),
|
|
88
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
89
|
+
variant: "body2",
|
|
90
|
+
sx: {
|
|
91
|
+
flex: '0 0 auto',
|
|
92
|
+
minWidth: 64,
|
|
93
|
+
textAlign: 'right'
|
|
94
|
+
},
|
|
95
|
+
children: (_row_display1 = row.display) != null ? _row_display1 : row.value.toLocaleString()
|
|
96
|
+
})
|
|
97
|
+
]
|
|
98
|
+
}, row.key);
|
|
99
|
+
})
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
ReportBreakdown.displayName = 'ReportBreakdown';
|
|
103
|
+
export default ReportBreakdown;
|
|
104
|
+
|
|
105
|
+
//# sourceMappingURL=report-breakdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/crm/src/lib/components/reports/report-breakdown.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { Box, Stack, Typography } from '@mui/material'\n\nexport interface ReportBreakdownRow {\n key: string\n label: string\n /** What the bar's length is a share of the largest of. */\n value: number\n /** The figure on the right; the value itself when omitted. */\n display?: string\n /** A line under the label — a count, a rate with its denominator. */\n note?: string\n /** A theme palette path; `primary.main` when omitted. */\n color?: string\n}\n\nexport interface ReportBreakdownProps {\n rows: ReportBreakdownRow[]\n emptyText: string\n}\n\n/**\n * One horizontal bar per category — contacts by source, deals by stage,\n * the lifecycle funnel — each labeled, each with its figure at the end of\n * the row.\n *\n * Horizontal rather than the vertical bars of the trend chart because the\n * categories have NAMES, and a name under a thin vertical bar truncates\n * while a name beside a horizontal one reads. The bar is a share of the\n * largest row, not of the total, so a funnel's top step is always the full\n * width and every step below it is visibly a fraction of the one above.\n */\nexport function ReportBreakdown(props: ReportBreakdownProps) {\n const { rows, emptyText } = props\n if (!rows.length) {\n return (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {emptyText}\n </Typography>\n )\n }\n const max = Math.max(1, ...rows.map((row) => row.value))\n return (\n <Stack spacing={1}>\n {rows.map((row) => (\n <Stack\n key={row.key}\n direction=\"row\"\n spacing={1.5}\n sx={{ alignItems: 'center' }}\n >\n <Box sx={{ flex: '0 0 36%', minWidth: 0 }}>\n <Typography variant=\"body2\" noWrap>\n {row.label}\n </Typography>\n {row.note ? (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n noWrap\n component=\"div\"\n >\n {row.note}\n </Typography>\n ) : null}\n </Box>\n <Box\n sx={{\n flex: 1,\n height: 8,\n borderRadius: 0.5,\n bgcolor: 'action.hover',\n overflow: 'hidden',\n }}\n >\n <Box\n title={row.display ?? row.value.toLocaleString()}\n sx={{\n width: `${Math.max(row.value > 0 ? 2 : 0, Math.round((row.value / max) * 100))}%`,\n height: '100%',\n bgcolor: row.color ?? 'primary.main',\n opacity: 0.9,\n }}\n />\n </Box>\n <Typography\n variant=\"body2\"\n sx={{ flex: '0 0 auto', minWidth: 64, textAlign: 'right' }}\n >\n {row.display ?? row.value.toLocaleString()}\n </Typography>\n </Stack>\n ))}\n </Stack>\n )\n}\nReportBreakdown.displayName = 'ReportBreakdown'\n\nexport default ReportBreakdown\n"],"names":["Box","Stack","Typography","ReportBreakdown","props","rows","emptyText","length","variant","color","max","Math","map","row","value","spacing","direction","sx","alignItems","flex","minWidth","noWrap","label","note","component","height","borderRadius","bgcolor","overflow","title","display","toLocaleString","width","round","opacity","textAlign","key","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SAASA,GAAG,EAAEC,KAAK,EAAEC,UAAU,QAAQ,gBAAe;AAoBtD;;;;;;;;;;CAUC,GACD,OAAO,SAASC,gBAAgBC,KAA2B;IACzD,MAAM,EAAEC,IAAI,EAAEC,SAAS,EAAE,GAAGF;IAC5B,IAAI,CAACC,KAAKE,MAAM,EAAE;QAChB,qBACE,KAACL;YAAWM,SAAQ;YAAQC,OAAM;sBAC/BH;;IAGP;IACA,MAAMI,MAAMC,KAAKD,GAAG,CAAC,MAAML,KAAKO,GAAG,CAAC,CAACC,MAAQA,IAAIC,KAAK;IACtD,qBACE,KAACb;QAAMc,SAAS;kBACbV,KAAKO,GAAG,CAAC,CAACC;gBAgCIA,cAIIA,YASZA;iCA5CL,MAACZ;gBAECe,WAAU;gBACVD,SAAS;gBACTE,IAAI;oBAAEC,YAAY;gBAAS;;kCAE3B,MAAClB;wBAAIiB,IAAI;4BAAEE,MAAM;4BAAWC,UAAU;wBAAE;;0CACtC,KAAClB;gCAAWM,SAAQ;gCAAQa,MAAM;0CAC/BR,IAAIS,KAAK;;4BAEXT,IAAIU,IAAI,iBACP,KAACrB;gCACCM,SAAQ;gCACRC,OAAM;gCACNY,MAAM;gCACNG,WAAU;0CAETX,IAAIU,IAAI;iCAET;;;kCAEN,KAACvB;wBACCiB,IAAI;4BACFE,MAAM;4BACNM,QAAQ;4BACRC,cAAc;4BACdC,SAAS;4BACTC,UAAU;wBACZ;kCAEA,cAAA,KAAC5B;4BACC6B,KAAK,GAAEhB,eAAAA,IAAIiB,OAAO,YAAXjB,eAAeA,IAAIC,KAAK,CAACiB,cAAc;4BAC9Cd,IAAI;gCACFe,OAAO,GAAGrB,KAAKD,GAAG,CAACG,IAAIC,KAAK,GAAG,IAAI,IAAI,GAAGH,KAAKsB,KAAK,CAAC,AAACpB,IAAIC,KAAK,GAAGJ,MAAO,MAAM,CAAC,CAAC;gCACjFe,QAAQ;gCACRE,OAAO,GAAEd,aAAAA,IAAIJ,KAAK,YAATI,aAAa;gCACtBqB,SAAS;4BACX;;;kCAGJ,KAAChC;wBACCM,SAAQ;wBACRS,IAAI;4BAAEE,MAAM;4BAAYC,UAAU;4BAAIe,WAAW;wBAAQ;mCAExDtB,gBAAAA,IAAIiB,OAAO,YAAXjB,gBAAeA,IAAIC,KAAK,CAACiB,cAAc;;;eA3CrClB,IAAIuB,GAAG;;;AAiDtB;AACAjC,gBAAgBkC,WAAW,GAAG;AAE9B,eAAelC,gBAAe"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface ReportExportProps {
|
|
2
|
+
/** The file's name — see `reportFilename`. */
|
|
3
|
+
filename: string;
|
|
4
|
+
/** The header row, in the table's column order. */
|
|
5
|
+
columns: readonly string[];
|
|
6
|
+
/**
|
|
7
|
+
* The rows, one array per line in the header's order, built when the
|
|
8
|
+
* button is pressed rather than on every render: a table of a thousand
|
|
9
|
+
* rows is serialized once, on demand, and never while nobody asked.
|
|
10
|
+
*/
|
|
11
|
+
rows: () => ReadonlyArray<ReadonlyArray<unknown>>;
|
|
12
|
+
/** Nothing to write yet — the window is still reading, or came back empty. */
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* What the table is grouped from, when that is not everything — the
|
|
16
|
+
* card's own truncation notice, drawn beside the button so the file and
|
|
17
|
+
* its limits are read together.
|
|
18
|
+
*/
|
|
19
|
+
caption?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Export CSV for one report table (AGL-2624).
|
|
23
|
+
*
|
|
24
|
+
* Client-side, from the window the card has already loaded: a report table
|
|
25
|
+
* is at most a thousand grouped rows, and the file is those rows exactly as
|
|
26
|
+
* drawn — the same names, the same counts, the same order — so a reader can
|
|
27
|
+
* check the export against the screen. It is NOT a fresh read, so when the
|
|
28
|
+
* card's window was full the caption beside the button says so, the way
|
|
29
|
+
* the card says so beneath the table; an export that quietly wrote a sample
|
|
30
|
+
* as if it were the whole would be the one thing the on-screen caption
|
|
31
|
+
* exists to prevent.
|
|
32
|
+
*/
|
|
33
|
+
export declare function ReportExport(props: ReportExportProps): import("react").JSX.Element;
|
|
34
|
+
export declare namespace ReportExport {
|
|
35
|
+
var displayName: string;
|
|
36
|
+
}
|
|
37
|
+
export default ReportExport;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import { csvDocument } from "@aglyn/aglyn";
|
|
19
|
+
import { mdiDownloadOutline } from "@aglyn/shared-data-mdi";
|
|
20
|
+
import { MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
21
|
+
import { Button, Stack, Typography } from "@mui/material";
|
|
22
|
+
import { downloadTextFile } from "../../model/contacts-csv.js";
|
|
23
|
+
/**
|
|
24
|
+
* Export CSV for one report table (AGL-2624).
|
|
25
|
+
*
|
|
26
|
+
* Client-side, from the window the card has already loaded: a report table
|
|
27
|
+
* is at most a thousand grouped rows, and the file is those rows exactly as
|
|
28
|
+
* drawn — the same names, the same counts, the same order — so a reader can
|
|
29
|
+
* check the export against the screen. It is NOT a fresh read, so when the
|
|
30
|
+
* card's window was full the caption beside the button says so, the way
|
|
31
|
+
* the card says so beneath the table; an export that quietly wrote a sample
|
|
32
|
+
* as if it were the whole would be the one thing the on-screen caption
|
|
33
|
+
* exists to prevent.
|
|
34
|
+
*/ export function ReportExport(props) {
|
|
35
|
+
const { filename, columns, rows, disabled = false, caption } = props;
|
|
36
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
37
|
+
direction: "row",
|
|
38
|
+
spacing: 1.5,
|
|
39
|
+
sx: {
|
|
40
|
+
alignItems: 'center',
|
|
41
|
+
flexWrap: 'wrap',
|
|
42
|
+
rowGap: 0.5
|
|
43
|
+
},
|
|
44
|
+
children: [
|
|
45
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
46
|
+
size: "small",
|
|
47
|
+
startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
48
|
+
path: mdiDownloadOutline.path,
|
|
49
|
+
size: 0.8
|
|
50
|
+
}),
|
|
51
|
+
disabled: disabled,
|
|
52
|
+
onClick: ()=>downloadTextFile(filename, 'text/csv', csvDocument(columns, rows())),
|
|
53
|
+
children: 'Export CSV'
|
|
54
|
+
}),
|
|
55
|
+
caption ? /*#__PURE__*/ _jsx(Typography, {
|
|
56
|
+
variant: "caption",
|
|
57
|
+
color: "text.secondary",
|
|
58
|
+
children: caption
|
|
59
|
+
}) : null
|
|
60
|
+
]
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
ReportExport.displayName = 'ReportExport';
|
|
64
|
+
export default ReportExport;
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=report-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/crm/src/lib/components/reports/report-export.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { csvDocument } from '@aglyn/aglyn'\nimport { mdiDownloadOutline } from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { Button, Stack, Typography } from '@mui/material'\nimport { downloadTextFile } from '../../model/contacts-csv'\n\nexport interface ReportExportProps {\n /** The file's name — see `reportFilename`. */\n filename: string\n /** The header row, in the table's column order. */\n columns: readonly string[]\n /**\n * The rows, one array per line in the header's order, built when the\n * button is pressed rather than on every render: a table of a thousand\n * rows is serialized once, on demand, and never while nobody asked.\n */\n rows: () => ReadonlyArray<ReadonlyArray<unknown>>\n /** Nothing to write yet — the window is still reading, or came back empty. */\n disabled?: boolean\n /**\n * What the table is grouped from, when that is not everything — the\n * card's own truncation notice, drawn beside the button so the file and\n * its limits are read together.\n */\n caption?: string\n}\n\n/**\n * Export CSV for one report table (AGL-2624).\n *\n * Client-side, from the window the card has already loaded: a report table\n * is at most a thousand grouped rows, and the file is those rows exactly as\n * drawn — the same names, the same counts, the same order — so a reader can\n * check the export against the screen. It is NOT a fresh read, so when the\n * card's window was full the caption beside the button says so, the way\n * the card says so beneath the table; an export that quietly wrote a sample\n * as if it were the whole would be the one thing the on-screen caption\n * exists to prevent.\n */\nexport function ReportExport(props: ReportExportProps) {\n const { filename, columns, rows, disabled = false, caption } = props\n return (\n <Stack\n direction=\"row\"\n spacing={1.5}\n sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 0.5 }}\n >\n <Button\n size=\"small\"\n startIcon={<MdiIcon path={mdiDownloadOutline.path} size={0.8} />}\n disabled={disabled}\n onClick={() =>\n downloadTextFile(filename, 'text/csv', csvDocument(columns, rows()))\n }\n >\n {'Export CSV'}\n </Button>\n {caption ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {caption}\n </Typography>\n ) : null}\n </Stack>\n )\n}\nReportExport.displayName = 'ReportExport'\n\nexport default ReportExport\n"],"names":["csvDocument","mdiDownloadOutline","MdiIcon","Button","Stack","Typography","downloadTextFile","ReportExport","props","filename","columns","rows","disabled","caption","direction","spacing","sx","alignItems","flexWrap","rowGap","size","startIcon","path","onClick","variant","color","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SAASA,WAAW,QAAQ,eAAc;AAC1C,SAASC,kBAAkB,QAAQ,yBAAwB;AAC3D,SAASC,OAAO,QAAQ,uBAAsB;AAC9C,SAASC,MAAM,EAAEC,KAAK,EAAEC,UAAU,QAAQ,gBAAe;AACzD,SAASC,gBAAgB,QAAQ,8BAA0B;AAuB3D;;;;;;;;;;;CAWC,GACD,OAAO,SAASC,aAAaC,KAAwB;IACnD,MAAM,EAAEC,QAAQ,EAAEC,OAAO,EAAEC,IAAI,EAAEC,WAAW,KAAK,EAAEC,OAAO,EAAE,GAAGL;IAC/D,qBACE,MAACJ;QACCU,WAAU;QACVC,SAAS;QACTC,IAAI;YAAEC,YAAY;YAAUC,UAAU;YAAQC,QAAQ;QAAI;;0BAE1D,KAAChB;gBACCiB,MAAK;gBACLC,yBAAW,KAACnB;oBAAQoB,MAAMrB,mBAAmBqB,IAAI;oBAAEF,MAAM;;gBACzDR,UAAUA;gBACVW,SAAS,IACPjB,iBAAiBG,UAAU,YAAYT,YAAYU,SAASC;0BAG7D;;YAEFE,wBACC,KAACR;gBAAWmB,SAAQ;gBAAUC,OAAM;0BACjCZ;iBAED;;;AAGV;AACAN,aAAamB,WAAW,GAAG;AAE3B,eAAenB,aAAY"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { CrmReportPeriod } from '@aglyn/aglyn';
|
|
18
|
+
/**
|
|
19
|
+
* The label under one week's bar — the day the week starts, as `Sep 1`.
|
|
20
|
+
*
|
|
21
|
+
* The start alone, because a bar is narrow: "Sep 1 – Sep 7" under thirteen
|
|
22
|
+
* bars truncates to nothing readable, and the reader knows every bar is a
|
|
23
|
+
* week because the chart said so.
|
|
24
|
+
*/
|
|
25
|
+
export declare function weekLabel(startMs: number): string;
|
|
26
|
+
/**
|
|
27
|
+
* The name of a report table's CSV — `crm-activity-30d.csv` — so a folder
|
|
28
|
+
* of downloads says which card and which period each file came from. The
|
|
29
|
+
* cards that describe a stock rather than a flow — the open pipeline, the
|
|
30
|
+
* open tasks — have no period and name none.
|
|
31
|
+
*/
|
|
32
|
+
export declare function reportFilename(card: string, period?: CrmReportPeriod): string;
|
|
33
|
+
/** A date in a table cell, or a dash for none. */
|
|
34
|
+
export declare function shortDate(ms: number | null | undefined): string;
|
|
35
|
+
/** `1 deal`, `2 deals` — a count with its noun. */
|
|
36
|
+
export declare function plural(count: number, singular: string, many?: string): string;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ /**
|
|
17
|
+
* The label under one week's bar — the day the week starts, as `Sep 1`.
|
|
18
|
+
*
|
|
19
|
+
* The start alone, because a bar is narrow: "Sep 1 – Sep 7" under thirteen
|
|
20
|
+
* bars truncates to nothing readable, and the reader knows every bar is a
|
|
21
|
+
* week because the chart said so.
|
|
22
|
+
*/ export function weekLabel(startMs) {
|
|
23
|
+
return new Date(startMs).toLocaleDateString(undefined, {
|
|
24
|
+
month: 'short',
|
|
25
|
+
day: 'numeric'
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The name of a report table's CSV — `crm-activity-30d.csv` — so a folder
|
|
30
|
+
* of downloads says which card and which period each file came from. The
|
|
31
|
+
* cards that describe a stock rather than a flow — the open pipeline, the
|
|
32
|
+
* open tasks — have no period and name none.
|
|
33
|
+
*/ export function reportFilename(card, period) {
|
|
34
|
+
return `crm-${card}${period ? `-${period}` : ''}.csv`;
|
|
35
|
+
}
|
|
36
|
+
/** A date in a table cell, or a dash for none. */ export function shortDate(ms) {
|
|
37
|
+
return typeof ms === 'number' && Number.isFinite(ms) && ms > 0 ? new Date(ms).toLocaleDateString() : '—';
|
|
38
|
+
}
|
|
39
|
+
/** `1 deal`, `2 deals` — a count with its noun. */ export function plural(count, singular, many = `${singular}s`) {
|
|
40
|
+
return `${count.toLocaleString()} ${count === 1 ? singular : many}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=report-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/crm/src/lib/components/reports/report-format.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { CrmReportPeriod } from '@aglyn/aglyn'\n\n/**\n * The label under one week's bar — the day the week starts, as `Sep 1`.\n *\n * The start alone, because a bar is narrow: \"Sep 1 – Sep 7\" under thirteen\n * bars truncates to nothing readable, and the reader knows every bar is a\n * week because the chart said so.\n */\nexport function weekLabel(startMs: number): string {\n return new Date(startMs).toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n })\n}\n\n/**\n * The name of a report table's CSV — `crm-activity-30d.csv` — so a folder\n * of downloads says which card and which period each file came from. The\n * cards that describe a stock rather than a flow — the open pipeline, the\n * open tasks — have no period and name none.\n */\nexport function reportFilename(card: string, period?: CrmReportPeriod): string {\n return `crm-${card}${period ? `-${period}` : ''}.csv`\n}\n\n/** A date in a table cell, or a dash for none. */\nexport function shortDate(ms: number | null | undefined): string {\n return typeof ms === 'number' && Number.isFinite(ms) && ms > 0\n ? new Date(ms).toLocaleDateString()\n : '—'\n}\n\n/** `1 deal`, `2 deals` — a count with its noun. */\nexport function plural(count: number, singular: string, many = `${singular}s`): string {\n return `${count.toLocaleString()} ${count === 1 ? singular : many}`\n}\n"],"names":["weekLabel","startMs","Date","toLocaleDateString","undefined","month","day","reportFilename","card","period","shortDate","ms","Number","isFinite","plural","count","singular","many","toLocaleString"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAID;;;;;;CAMC,GACD,OAAO,SAASA,UAAUC,OAAe;IACvC,OAAO,IAAIC,KAAKD,SAASE,kBAAkB,CAACC,WAAW;QACrDC,OAAO;QACPC,KAAK;IACP;AACF;AAEA;;;;;CAKC,GACD,OAAO,SAASC,eAAeC,IAAY,EAAEC,MAAwB;IACnE,OAAO,CAAC,IAAI,EAAED,OAAOC,SAAS,CAAC,CAAC,EAAEA,QAAQ,GAAG,GAAG,IAAI,CAAC;AACvD;AAEA,gDAAgD,GAChD,OAAO,SAASC,UAAUC,EAA6B;IACrD,OAAO,OAAOA,OAAO,YAAYC,OAAOC,QAAQ,CAACF,OAAOA,KAAK,IACzD,IAAIT,KAAKS,IAAIR,kBAAkB,KAC/B;AACN;AAEA,iDAAiD,GACjD,OAAO,SAASW,OAAOC,KAAa,EAAEC,QAAgB,EAAEC,OAAO,GAAGD,SAAS,CAAC,CAAC;IAC3E,OAAO,GAAGD,MAAMG,cAAc,GAAG,CAAC,EAAEH,UAAU,IAAIC,WAAWC,MAAM;AACrE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { CrmReportPeriod, CrmReportRange } from '@aglyn/aglyn';
|
|
18
|
+
import { type CollectionReference, type Firestore, type QueryConstraint } from 'firebase/firestore';
|
|
19
|
+
import type { CrmRoutes } from '../../model/crm-routes';
|
|
20
|
+
/**
|
|
21
|
+
* What every report card is handed, resolved once by the section (AGL-2604).
|
|
22
|
+
*
|
|
23
|
+
* The cards are independent — each opens its own reads and draws its own
|
|
24
|
+
* figures — but they must agree on four things or the page contradicts
|
|
25
|
+
* itself: WHICH org's collections they read, WHO the reader is (the scope
|
|
26
|
+
* tokens every query filters on), WHICH holder's facet a contact field is
|
|
27
|
+
* read through, and WHEN the period starts and ends. Resolving those in the
|
|
28
|
+
* section and passing them down is what keeps a card from computing its own
|
|
29
|
+
* "now" a second after its neighbor's, or its own token list without the
|
|
30
|
+
* org-wide token.
|
|
31
|
+
*/
|
|
32
|
+
export interface CrmReportScope {
|
|
33
|
+
/** `['orgs', orgId]` — the org-shared data root every CRM collection lives under. */
|
|
34
|
+
scope: readonly ['orgs', string];
|
|
35
|
+
/**
|
|
36
|
+
* The scope tokens this reader may see — the `array-contains-any` operand
|
|
37
|
+
* of every query a card runs, and the same predicate the rules evaluate
|
|
38
|
+
* — or `null` at the ORGANIZATION level (AGL-2630), where an org-wide
|
|
39
|
+
* member's reports carry no clause and total every site at once.
|
|
40
|
+
*/
|
|
41
|
+
tokens: readonly string[] | null;
|
|
42
|
+
/**
|
|
43
|
+
* The consent group whose facet the contact fields are read through, or
|
|
44
|
+
* `null` at the organization level, where each contact's own primary
|
|
45
|
+
* holder is read instead (`contactPrimaryGroup`, from {@link org}).
|
|
46
|
+
*/
|
|
47
|
+
groupId: string | null;
|
|
48
|
+
/** The org document, for the per-contact holder when {@link groupId} is null. */
|
|
49
|
+
org: Record<string, unknown> | null;
|
|
50
|
+
period: CrmReportPeriod;
|
|
51
|
+
range: CrmReportRange;
|
|
52
|
+
/** The moment the period was anchored at, so every card shares one clock. */
|
|
53
|
+
nowMs: number;
|
|
54
|
+
routes: CrmRoutes;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* What every remembered report answer is keyed by: the org, the reader's
|
|
58
|
+
* tokens, the holder's facet and the period — never the clock. A reopened
|
|
59
|
+
* section anchors a new `nowMs`, and the whole point of remembering is that
|
|
60
|
+
* the reopening is the same question; the TTL, not the key, decides when the
|
|
61
|
+
* answer has aged out. `cardKey` names the read within the card so that two
|
|
62
|
+
* counts on one card do not overwrite each other.
|
|
63
|
+
*/
|
|
64
|
+
export declare function reportCacheKey(report: Pick<CrmReportScope, 'scope' | 'tokens' | 'groupId' | 'period'>, cardKey: string): string;
|
|
65
|
+
/** Everything one reader's reports of one org are remembered under — what Refresh forgets. */
|
|
66
|
+
export declare function reportCachePrefix(report: Pick<CrmReportScope, 'scope' | 'tokens' | 'groupId'>): string;
|
|
67
|
+
/** One CRM collection under the report's org. */
|
|
68
|
+
export declare function scopedCollection(firestore: Firestore, scope: CrmReportScope['scope'], name: string): CollectionReference;
|
|
69
|
+
/**
|
|
70
|
+
* The visibility predicate, as the clause every report query starts with —
|
|
71
|
+
* spread into the query, because at the organization level it is NOTHING.
|
|
72
|
+
*
|
|
73
|
+
* A function rather than a convention so that a card cannot forget it: a
|
|
74
|
+
* query on a CRM collection without it is permission-denied rather than a
|
|
75
|
+
* leak, per the rules, but a denied aggregate renders as a dash and a
|
|
76
|
+
* missing clause would be diagnosed as "the count is broken" rather than as
|
|
77
|
+
* what it is. The org level (AGL-2630) drops it on purpose: the rules admit
|
|
78
|
+
* an org-wide member to every row, and a report there is a total over
|
|
79
|
+
* every site.
|
|
80
|
+
*/
|
|
81
|
+
export declare function visibleToClause(tokens: readonly string[] | null): QueryConstraint[];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { collection, where } from "firebase/firestore";
|
|
17
|
+
/**
|
|
18
|
+
* What every remembered report answer is keyed by: the org, the reader's
|
|
19
|
+
* tokens, the holder's facet and the period — never the clock. A reopened
|
|
20
|
+
* section anchors a new `nowMs`, and the whole point of remembering is that
|
|
21
|
+
* the reopening is the same question; the TTL, not the key, decides when the
|
|
22
|
+
* answer has aged out. `cardKey` names the read within the card so that two
|
|
23
|
+
* counts on one card do not overwrite each other.
|
|
24
|
+
*/ export function reportCacheKey(report, cardKey) {
|
|
25
|
+
return `${reportCachePrefix(report)}${report.period}|${cardKey}`;
|
|
26
|
+
}
|
|
27
|
+
/** Everything one reader's reports of one org are remembered under — what Refresh forgets. */ export function reportCachePrefix(report) {
|
|
28
|
+
var _report_groupId;
|
|
29
|
+
// `*` for the org level's "every token" and "every holder": a real token
|
|
30
|
+
// list never contains it, so the two levels cannot share an answer.
|
|
31
|
+
const tokens = report.tokens ? [
|
|
32
|
+
...report.tokens
|
|
33
|
+
].sort().join(',') : '*';
|
|
34
|
+
return `crm-report|${report.scope[1]}|${tokens}|${(_report_groupId = report.groupId) != null ? _report_groupId : '*'}|`;
|
|
35
|
+
}
|
|
36
|
+
/** One CRM collection under the report's org. */ export function scopedCollection(firestore, scope, name) {
|
|
37
|
+
return collection(firestore, scope[0], scope[1], name);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The visibility predicate, as the clause every report query starts with —
|
|
41
|
+
* spread into the query, because at the organization level it is NOTHING.
|
|
42
|
+
*
|
|
43
|
+
* A function rather than a convention so that a card cannot forget it: a
|
|
44
|
+
* query on a CRM collection without it is permission-denied rather than a
|
|
45
|
+
* leak, per the rules, but a denied aggregate renders as a dash and a
|
|
46
|
+
* missing clause would be diagnosed as "the count is broken" rather than as
|
|
47
|
+
* what it is. The org level (AGL-2630) drops it on purpose: the rules admit
|
|
48
|
+
* an org-wide member to every row, and a report there is a total over
|
|
49
|
+
* every site.
|
|
50
|
+
*/ export function visibleToClause(tokens) {
|
|
51
|
+
return tokens ? [
|
|
52
|
+
where('visibleTo', 'array-contains-any', [
|
|
53
|
+
...tokens
|
|
54
|
+
])
|
|
55
|
+
] : [];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=report-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/crm/src/lib/components/reports/report-scope.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { CrmReportPeriod, CrmReportRange } from '@aglyn/aglyn'\nimport {\n collection,\n type CollectionReference,\n type Firestore,\n type QueryConstraint,\n where,\n} from 'firebase/firestore'\nimport type { CrmRoutes } from '../../model/crm-routes'\n\n/**\n * What every report card is handed, resolved once by the section (AGL-2604).\n *\n * The cards are independent — each opens its own reads and draws its own\n * figures — but they must agree on four things or the page contradicts\n * itself: WHICH org's collections they read, WHO the reader is (the scope\n * tokens every query filters on), WHICH holder's facet a contact field is\n * read through, and WHEN the period starts and ends. Resolving those in the\n * section and passing them down is what keeps a card from computing its own\n * \"now\" a second after its neighbor's, or its own token list without the\n * org-wide token.\n */\nexport interface CrmReportScope {\n /** `['orgs', orgId]` — the org-shared data root every CRM collection lives under. */\n scope: readonly ['orgs', string]\n /**\n * The scope tokens this reader may see — the `array-contains-any` operand\n * of every query a card runs, and the same predicate the rules evaluate\n * — or `null` at the ORGANIZATION level (AGL-2630), where an org-wide\n * member's reports carry no clause and total every site at once.\n */\n tokens: readonly string[] | null\n /**\n * The consent group whose facet the contact fields are read through, or\n * `null` at the organization level, where each contact's own primary\n * holder is read instead (`contactPrimaryGroup`, from {@link org}).\n */\n groupId: string | null\n /** The org document, for the per-contact holder when {@link groupId} is null. */\n org: Record<string, unknown> | null\n period: CrmReportPeriod\n range: CrmReportRange\n /** The moment the period was anchored at, so every card shares one clock. */\n nowMs: number\n routes: CrmRoutes\n}\n\n/**\n * What every remembered report answer is keyed by: the org, the reader's\n * tokens, the holder's facet and the period — never the clock. A reopened\n * section anchors a new `nowMs`, and the whole point of remembering is that\n * the reopening is the same question; the TTL, not the key, decides when the\n * answer has aged out. `cardKey` names the read within the card so that two\n * counts on one card do not overwrite each other.\n */\nexport function reportCacheKey(\n report: Pick<CrmReportScope, 'scope' | 'tokens' | 'groupId' | 'period'>,\n cardKey: string,\n): string {\n return `${reportCachePrefix(report)}${report.period}|${cardKey}`\n}\n\n/** Everything one reader's reports of one org are remembered under — what Refresh forgets. */\nexport function reportCachePrefix(\n report: Pick<CrmReportScope, 'scope' | 'tokens' | 'groupId'>,\n): string {\n // `*` for the org level's \"every token\" and \"every holder\": a real token\n // list never contains it, so the two levels cannot share an answer.\n const tokens = report.tokens ? [...report.tokens].sort().join(',') : '*'\n return `crm-report|${report.scope[1]}|${tokens}|${report.groupId ?? '*'}|`\n}\n\n/** One CRM collection under the report's org. */\nexport function scopedCollection(\n firestore: Firestore,\n scope: CrmReportScope['scope'],\n name: string,\n): CollectionReference {\n return collection(firestore, scope[0], scope[1], name)\n}\n\n/**\n * The visibility predicate, as the clause every report query starts with —\n * spread into the query, because at the organization level it is NOTHING.\n *\n * A function rather than a convention so that a card cannot forget it: a\n * query on a CRM collection without it is permission-denied rather than a\n * leak, per the rules, but a denied aggregate renders as a dash and a\n * missing clause would be diagnosed as \"the count is broken\" rather than as\n * what it is. The org level (AGL-2630) drops it on purpose: the rules admit\n * an org-wide member to every row, and a report there is a total over\n * every site.\n */\nexport function visibleToClause(\n tokens: readonly string[] | null,\n): QueryConstraint[] {\n return tokens ? [where('visibleTo', 'array-contains-any', [...tokens])] : []\n}\n"],"names":["collection","where","reportCacheKey","report","cardKey","reportCachePrefix","period","tokens","sort","join","scope","groupId","scopedCollection","firestore","name","visibleToClause"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAGD,SACEA,UAAU,EAIVC,KAAK,QACA,qBAAoB;AAwC3B;;;;;;;CAOC,GACD,OAAO,SAASC,eACdC,MAAuE,EACvEC,OAAe;IAEf,OAAO,GAAGC,kBAAkBF,UAAUA,OAAOG,MAAM,CAAC,CAAC,EAAEF,SAAS;AAClE;AAEA,4FAA4F,GAC5F,OAAO,SAASC,kBACdF,MAA4D;QAKVA;IAHlD,yEAAyE;IACzE,oEAAoE;IACpE,MAAMI,SAASJ,OAAOI,MAAM,GAAG;WAAIJ,OAAOI,MAAM;KAAC,CAACC,IAAI,GAAGC,IAAI,CAAC,OAAO;IACrE,OAAO,CAAC,WAAW,EAAEN,OAAOO,KAAK,CAAC,EAAE,CAAC,CAAC,EAAEH,OAAO,CAAC,GAAEJ,kBAAAA,OAAOQ,OAAO,YAAdR,kBAAkB,IAAI,CAAC,CAAC;AAC5E;AAEA,+CAA+C,GAC/C,OAAO,SAASS,iBACdC,SAAoB,EACpBH,KAA8B,EAC9BI,IAAY;IAEZ,OAAOd,WAAWa,WAAWH,KAAK,CAAC,EAAE,EAAEA,KAAK,CAAC,EAAE,EAAEI;AACnD;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAASC,gBACdR,MAAgC;IAEhC,OAAOA,SAAS;QAACN,MAAM,aAAa,sBAAsB;eAAIM;SAAO;KAAE,GAAG,EAAE;AAC9E"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface ReportStatTileProps {
|
|
2
|
+
/** Caption above the figure, e.g. `New contacts`. */
|
|
3
|
+
label: string;
|
|
4
|
+
/**
|
|
5
|
+
* The figure, already formatted, or `null` when it has not been measured —
|
|
6
|
+
* the read is pending or was refused. `null` draws a dash, never a zero.
|
|
7
|
+
*/
|
|
8
|
+
value: string | null;
|
|
9
|
+
/**
|
|
10
|
+
* Change against the previous period, in percent, or `null` when there is
|
|
11
|
+
* no baseline. `null` renders NOTHING — see below.
|
|
12
|
+
*/
|
|
13
|
+
deltaPct?: number | null;
|
|
14
|
+
/** What the delta is measured against, for the tooltip. */
|
|
15
|
+
deltaCaption?: string;
|
|
16
|
+
/** A line under the figure naming what it counts. */
|
|
17
|
+
note?: string;
|
|
18
|
+
/** Whether a rise is good. A rise in overdue tasks is not. */
|
|
19
|
+
riseIsGood?: boolean;
|
|
20
|
+
/** Where the figure leads — the list it summarizes. */
|
|
21
|
+
href?: string;
|
|
22
|
+
/** Paints the figure, e.g. `error.main` for an overdue count above zero. */
|
|
23
|
+
color?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* One report figure with an optional period-over-period delta, the shape
|
|
27
|
+
* the commerce stat tile draws revenue in.
|
|
28
|
+
*
|
|
29
|
+
* Two rules carried over from there and from the shared `Figure`:
|
|
30
|
+
*
|
|
31
|
+
* - **A `null` value draws a dash, not a zero.** A count that has not
|
|
32
|
+
* arrived, or that the server refused, is not zero of anything, and a
|
|
33
|
+
* zero would be read as a measurement.
|
|
34
|
+
* - **A `null` delta renders nothing — not `+0%`, not `—`.** The delta is
|
|
35
|
+
* `null` exactly when the previous period held nothing, and every way of
|
|
36
|
+
* drawing that is a lie: `+100%` reads as growth, `+0%` reads as flat,
|
|
37
|
+
* and a dash reads as "we could not work it out". A first contact has no
|
|
38
|
+
* growth rate.
|
|
39
|
+
*
|
|
40
|
+
* The tile links to the list it summarizes when it can, because a figure
|
|
41
|
+
* a reader cannot open is a figure they cannot check.
|
|
42
|
+
*/
|
|
43
|
+
export declare function ReportStatTile(props: ReportStatTileProps): import("react").JSX.Element;
|
|
44
|
+
export declare namespace ReportStatTile {
|
|
45
|
+
var displayName: string;
|
|
46
|
+
}
|
|
47
|
+
export default ReportStatTile;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import { AppLink } from "@aglyn/shared-ui-jsx";
|
|
19
|
+
import { Stack, Tooltip, Typography } from "@mui/material";
|
|
20
|
+
/**
|
|
21
|
+
* One report figure with an optional period-over-period delta, the shape
|
|
22
|
+
* the commerce stat tile draws revenue in.
|
|
23
|
+
*
|
|
24
|
+
* Two rules carried over from there and from the shared `Figure`:
|
|
25
|
+
*
|
|
26
|
+
* - **A `null` value draws a dash, not a zero.** A count that has not
|
|
27
|
+
* arrived, or that the server refused, is not zero of anything, and a
|
|
28
|
+
* zero would be read as a measurement.
|
|
29
|
+
* - **A `null` delta renders nothing — not `+0%`, not `—`.** The delta is
|
|
30
|
+
* `null` exactly when the previous period held nothing, and every way of
|
|
31
|
+
* drawing that is a lie: `+100%` reads as growth, `+0%` reads as flat,
|
|
32
|
+
* and a dash reads as "we could not work it out". A first contact has no
|
|
33
|
+
* growth rate.
|
|
34
|
+
*
|
|
35
|
+
* The tile links to the list it summarizes when it can, because a figure
|
|
36
|
+
* a reader cannot open is a figure they cannot check.
|
|
37
|
+
*/ export function ReportStatTile(props) {
|
|
38
|
+
const { label, value, deltaPct = null, deltaCaption = 'vs the previous period', note, riseIsGood = true, href, color } = props;
|
|
39
|
+
const rose = (deltaPct != null ? deltaPct : 0) > 0;
|
|
40
|
+
const flat = deltaPct === 0;
|
|
41
|
+
const deltaColor = flat ? 'text.secondary' : rose === riseIsGood ? 'success.main' : 'error.main';
|
|
42
|
+
const figure = /*#__PURE__*/ _jsx(Typography, {
|
|
43
|
+
variant: "h6",
|
|
44
|
+
sx: color ? {
|
|
45
|
+
color
|
|
46
|
+
} : undefined,
|
|
47
|
+
children: value === null ? '—' : value
|
|
48
|
+
});
|
|
49
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
50
|
+
sx: {
|
|
51
|
+
minWidth: 120
|
|
52
|
+
},
|
|
53
|
+
children: [
|
|
54
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
55
|
+
variant: "caption",
|
|
56
|
+
color: "text.secondary",
|
|
57
|
+
children: label
|
|
58
|
+
}),
|
|
59
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
60
|
+
direction: "row",
|
|
61
|
+
spacing: 0.75,
|
|
62
|
+
sx: {
|
|
63
|
+
alignItems: 'baseline'
|
|
64
|
+
},
|
|
65
|
+
children: [
|
|
66
|
+
href ? /*#__PURE__*/ _jsx(AppLink, {
|
|
67
|
+
href: href,
|
|
68
|
+
underline: "hover",
|
|
69
|
+
color: "inherit",
|
|
70
|
+
children: figure
|
|
71
|
+
}) : figure,
|
|
72
|
+
deltaPct === null || value === null ? null : /*#__PURE__*/ _jsx(Tooltip, {
|
|
73
|
+
title: deltaCaption,
|
|
74
|
+
children: /*#__PURE__*/ _jsx(Typography, {
|
|
75
|
+
variant: "caption",
|
|
76
|
+
sx: {
|
|
77
|
+
color: deltaColor,
|
|
78
|
+
fontWeight: 'fontWeightMedium'
|
|
79
|
+
},
|
|
80
|
+
children: `${deltaPct > 0 ? '+' : ''}${deltaPct}%`
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
]
|
|
84
|
+
}),
|
|
85
|
+
note ? /*#__PURE__*/ _jsx(Typography, {
|
|
86
|
+
variant: "caption",
|
|
87
|
+
color: "text.secondary",
|
|
88
|
+
children: value === null ? 'not measured yet' : note
|
|
89
|
+
}) : null
|
|
90
|
+
]
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
ReportStatTile.displayName = 'ReportStatTile';
|
|
94
|
+
export default ReportStatTile;
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=report-stat-tile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/crm/src/lib/components/reports/report-stat-tile.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { AppLink } from '@aglyn/shared-ui-jsx'\nimport { Stack, Tooltip, Typography } from '@mui/material'\n\nexport interface ReportStatTileProps {\n /** Caption above the figure, e.g. `New contacts`. */\n label: string\n /**\n * The figure, already formatted, or `null` when it has not been measured —\n * the read is pending or was refused. `null` draws a dash, never a zero.\n */\n value: string | null\n /**\n * Change against the previous period, in percent, or `null` when there is\n * no baseline. `null` renders NOTHING — see below.\n */\n deltaPct?: number | null\n /** What the delta is measured against, for the tooltip. */\n deltaCaption?: string\n /** A line under the figure naming what it counts. */\n note?: string\n /** Whether a rise is good. A rise in overdue tasks is not. */\n riseIsGood?: boolean\n /** Where the figure leads — the list it summarizes. */\n href?: string\n /** Paints the figure, e.g. `error.main` for an overdue count above zero. */\n color?: string\n}\n\n/**\n * One report figure with an optional period-over-period delta, the shape\n * the commerce stat tile draws revenue in.\n *\n * Two rules carried over from there and from the shared `Figure`:\n *\n * - **A `null` value draws a dash, not a zero.** A count that has not\n * arrived, or that the server refused, is not zero of anything, and a\n * zero would be read as a measurement.\n * - **A `null` delta renders nothing — not `+0%`, not `—`.** The delta is\n * `null` exactly when the previous period held nothing, and every way of\n * drawing that is a lie: `+100%` reads as growth, `+0%` reads as flat,\n * and a dash reads as \"we could not work it out\". A first contact has no\n * growth rate.\n *\n * The tile links to the list it summarizes when it can, because a figure\n * a reader cannot open is a figure they cannot check.\n */\nexport function ReportStatTile(props: ReportStatTileProps) {\n const {\n label,\n value,\n deltaPct = null,\n deltaCaption = 'vs the previous period',\n note,\n riseIsGood = true,\n href,\n color,\n } = props\n const rose = (deltaPct ?? 0) > 0\n const flat = deltaPct === 0\n const deltaColor = flat\n ? 'text.secondary'\n : rose === riseIsGood\n ? 'success.main'\n : 'error.main'\n const figure = (\n <Typography variant=\"h6\" sx={color ? { color } : undefined}>\n {value === null ? '—' : value}\n </Typography>\n )\n return (\n <Stack sx={{ minWidth: 120 }}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {label}\n </Typography>\n <Stack direction=\"row\" spacing={0.75} sx={{ alignItems: 'baseline' }}>\n {href ? (\n <AppLink href={href} underline=\"hover\" color=\"inherit\">\n {figure}\n </AppLink>\n ) : (\n figure\n )}\n {deltaPct === null || value === null ? null : (\n <Tooltip title={deltaCaption}>\n <Typography\n variant=\"caption\"\n sx={{ color: deltaColor, fontWeight: 'fontWeightMedium' }}\n >\n {`${deltaPct > 0 ? '+' : ''}${deltaPct}%`}\n </Typography>\n </Tooltip>\n )}\n </Stack>\n {note ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {value === null ? 'not measured yet' : note}\n </Typography>\n ) : null}\n </Stack>\n )\n}\nReportStatTile.displayName = 'ReportStatTile'\n\nexport default ReportStatTile\n"],"names":["AppLink","Stack","Tooltip","Typography","ReportStatTile","props","label","value","deltaPct","deltaCaption","note","riseIsGood","href","color","rose","flat","deltaColor","figure","variant","sx","undefined","minWidth","direction","spacing","alignItems","underline","title","fontWeight","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SAASA,OAAO,QAAQ,uBAAsB;AAC9C,SAASC,KAAK,EAAEC,OAAO,EAAEC,UAAU,QAAQ,gBAAe;AA2B1D;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,SAASC,eAAeC,KAA0B;IACvD,MAAM,EACJC,KAAK,EACLC,KAAK,EACLC,WAAW,IAAI,EACfC,eAAe,wBAAwB,EACvCC,IAAI,EACJC,aAAa,IAAI,EACjBC,IAAI,EACJC,KAAK,EACN,GAAGR;IACJ,MAAMS,OAAO,CAACN,mBAAAA,WAAY,KAAK;IAC/B,MAAMO,OAAOP,aAAa;IAC1B,MAAMQ,aAAaD,OACf,mBACAD,SAASH,aACP,iBACA;IACN,MAAMM,uBACJ,KAACd;QAAWe,SAAQ;QAAKC,IAAIN,QAAQ;YAAEA;QAAM,IAAIO;kBAC9Cb,UAAU,OAAO,MAAMA;;IAG5B,qBACE,MAACN;QAAMkB,IAAI;YAAEE,UAAU;QAAI;;0BACzB,KAAClB;gBAAWe,SAAQ;gBAAUL,OAAM;0BACjCP;;0BAEH,MAACL;gBAAMqB,WAAU;gBAAMC,SAAS;gBAAMJ,IAAI;oBAAEK,YAAY;gBAAW;;oBAChEZ,qBACC,KAACZ;wBAAQY,MAAMA;wBAAMa,WAAU;wBAAQZ,OAAM;kCAC1CI;yBAGHA;oBAEDT,aAAa,QAAQD,UAAU,OAAO,qBACrC,KAACL;wBAAQwB,OAAOjB;kCACd,cAAA,KAACN;4BACCe,SAAQ;4BACRC,IAAI;gCAAEN,OAAOG;gCAAYW,YAAY;4BAAmB;sCAEvD,GAAGnB,WAAW,IAAI,MAAM,KAAKA,SAAS,CAAC,CAAC;;;;;YAKhDE,qBACC,KAACP;gBAAWe,SAAQ;gBAAUL,OAAM;0BACjCN,UAAU,OAAO,qBAAqBG;iBAEvC;;;AAGV;AACAN,eAAewB,WAAW,GAAG;AAE7B,eAAexB,eAAc"}
|