@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,251 @@
|
|
|
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 * as Aglyn from "@aglyn/aglyn";
|
|
19
|
+
import { money } from "@aglyn/shared-ui-email-campaigns/components/report-figures";
|
|
20
|
+
import { CardDisplay } from "@aglyn/shared-ui-jsx";
|
|
21
|
+
import { ScrollTable } from "@aglyn/shared-ui-jsx/components/scroll-table.component";
|
|
22
|
+
import { Box, Stack, TableBody, TableCell, TableHead, TableRow, Typography } from "@mui/material";
|
|
23
|
+
import { limit, orderBy, query, where } from "firebase/firestore";
|
|
24
|
+
import { useMemo } from "react";
|
|
25
|
+
import { useFirestore } from "@aglyn/tenant-feature-instance";
|
|
26
|
+
import { collectionCeiling } from "@aglyn/tenant-feature-instance/hooks/host-collection-queries";
|
|
27
|
+
import { plural } from "./report-format.js";
|
|
28
|
+
import { reportCacheKey, scopedCollection, visibleToClause } from "./report-scope.js";
|
|
29
|
+
import { useWindowRead } from "./use-aggregate-read.js";
|
|
30
|
+
/**
|
|
31
|
+
* The same window the pipeline card reads, under the SAME cache key and
|
|
32
|
+
* the same dependencies, so the two cards cost one read between them —
|
|
33
|
+
* `useAggregateRead` joins a read already in the air for the key. The
|
|
34
|
+
* numbers must match the pipeline card's query exactly or the key would
|
|
35
|
+
* name two different questions.
|
|
36
|
+
*/ const OPEN_DEAL_CEILING = 1000;
|
|
37
|
+
const PIPELINE_CEILING = 20;
|
|
38
|
+
/** `Sep 2026` — the month a column is. */ function monthLabel(startMs) {
|
|
39
|
+
return new Date(startMs).toLocaleDateString(undefined, {
|
|
40
|
+
month: 'short',
|
|
41
|
+
year: 'numeric'
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Forecast by close month (AGL-2620): the open pipeline laid out by the
|
|
46
|
+
* month each deal is expected to close, for the next six, per pipeline,
|
|
47
|
+
* at face value and weighted by the stage.
|
|
48
|
+
*
|
|
49
|
+
* Not period-scoped, like the pipeline card and for the same reason: the
|
|
50
|
+
* forecast is what is open NOW, looked at forward. Deals with no expected
|
|
51
|
+
* close are their own row rather than a footnote — that row is the size
|
|
52
|
+
* of the pipeline nobody has scheduled, which is the number the picker
|
|
53
|
+
* of a close date most needs to see — and deals dated before this month
|
|
54
|
+
* (overdue) or past the sixth (later) are rows too, so the column adds up
|
|
55
|
+
* to the pipeline.
|
|
56
|
+
*/ export function ForecastCard(props) {
|
|
57
|
+
const { report } = props;
|
|
58
|
+
const { scope, tokens, nowMs } = report;
|
|
59
|
+
const firestore = useFirestore();
|
|
60
|
+
const dealWindow = useWindowRead(()=>query(scopedCollection(firestore, scope, 'deals'), ...visibleToClause(tokens), where('status', '==', 'open'), orderBy('updatedAt', 'desc'), limit(OPEN_DEAL_CEILING + 1)), OPEN_DEAL_CEILING, [
|
|
61
|
+
firestore,
|
|
62
|
+
scope,
|
|
63
|
+
tokens,
|
|
64
|
+
nowMs
|
|
65
|
+
], {
|
|
66
|
+
cacheKey: reportCacheKey(report, 'pipeline:deals')
|
|
67
|
+
});
|
|
68
|
+
const pipelineWindow = useWindowRead(()=>collectionCeiling(query(scopedCollection(firestore, scope, 'pipelines'), ...visibleToClause(tokens)), PIPELINE_CEILING), PIPELINE_CEILING, [
|
|
69
|
+
firestore,
|
|
70
|
+
scope,
|
|
71
|
+
tokens,
|
|
72
|
+
nowMs
|
|
73
|
+
], {
|
|
74
|
+
cacheKey: reportCacheKey(report, 'pipeline:pipelines')
|
|
75
|
+
});
|
|
76
|
+
const forecast = useMemo(()=>Aglyn.forecastByCloseMonth(dealWindow.rows, pipelineWindow.rows, nowMs), [
|
|
77
|
+
dealWindow.rows,
|
|
78
|
+
pipelineWindow.rows,
|
|
79
|
+
nowMs
|
|
80
|
+
]);
|
|
81
|
+
const currency = useMemo(()=>Aglyn.currencyOfDeals(dealWindow.rows), [
|
|
82
|
+
dealWindow.rows
|
|
83
|
+
]);
|
|
84
|
+
const read = dealWindow.status === 'success' && pipelineWindow.status === 'success';
|
|
85
|
+
const failed = dealWindow.status === 'error' || pipelineWindow.status === 'error';
|
|
86
|
+
// A pipeline with nothing open is still a column; an unknown pipeline id
|
|
87
|
+
// is a column named for what it is.
|
|
88
|
+
const columns = forecast.pipelines;
|
|
89
|
+
const manyColumns = columns.length > 1;
|
|
90
|
+
const rows = [
|
|
91
|
+
{
|
|
92
|
+
key: 'overdue',
|
|
93
|
+
label: 'Before this month',
|
|
94
|
+
cellOf: (row)=>row.overdue,
|
|
95
|
+
total: forecast.overdue,
|
|
96
|
+
muted: true
|
|
97
|
+
},
|
|
98
|
+
...forecast.buckets.map((bucket, index)=>({
|
|
99
|
+
key: bucket.key,
|
|
100
|
+
label: monthLabel(bucket.start),
|
|
101
|
+
cellOf: (row)=>row.months[index],
|
|
102
|
+
total: forecast.months[index]
|
|
103
|
+
})),
|
|
104
|
+
{
|
|
105
|
+
key: 'later',
|
|
106
|
+
label: 'Later',
|
|
107
|
+
cellOf: (row)=>row.later,
|
|
108
|
+
total: forecast.later,
|
|
109
|
+
muted: true
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
key: 'undated',
|
|
113
|
+
label: 'No expected close',
|
|
114
|
+
cellOf: (row)=>row.undated,
|
|
115
|
+
total: forecast.undated,
|
|
116
|
+
muted: true
|
|
117
|
+
}
|
|
118
|
+
].filter((row)=>row.key !== 'overdue' && row.key !== 'later' ? true : row.total.count > 0);
|
|
119
|
+
const cell = (value, code)=>value.count === 0 ? /*#__PURE__*/ _jsx(Typography, {
|
|
120
|
+
variant: "body2",
|
|
121
|
+
color: "text.disabled",
|
|
122
|
+
children: '—'
|
|
123
|
+
}) : /*#__PURE__*/ _jsxs(Stack, {
|
|
124
|
+
sx: {
|
|
125
|
+
lineHeight: 1.2
|
|
126
|
+
},
|
|
127
|
+
children: [
|
|
128
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
129
|
+
variant: "body2",
|
|
130
|
+
children: money(value.amountCents, code)
|
|
131
|
+
}),
|
|
132
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
133
|
+
variant: "caption",
|
|
134
|
+
color: "text.secondary",
|
|
135
|
+
children: `${money(value.weightedCents, code)} weighted · ${plural(value.count, 'deal')}`
|
|
136
|
+
})
|
|
137
|
+
]
|
|
138
|
+
});
|
|
139
|
+
return /*#__PURE__*/ _jsx(CardDisplay, {
|
|
140
|
+
header: 'Forecast by close month',
|
|
141
|
+
help: Aglyn.pluginDocsHelp('crmReports', {
|
|
142
|
+
anchor: '#forecast-by-close-month',
|
|
143
|
+
excerpt: 'Every open deal by the month it is expected to close, for the ' + 'next six months and per pipeline, at face value and weighted by ' + 'its stage. Deals with no expected close are their own row.'
|
|
144
|
+
}),
|
|
145
|
+
contentGutterX: true,
|
|
146
|
+
contentGutterY: true,
|
|
147
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
148
|
+
spacing: 1.5,
|
|
149
|
+
children: [
|
|
150
|
+
failed ? /*#__PURE__*/ _jsx(Typography, {
|
|
151
|
+
variant: "body2",
|
|
152
|
+
color: "warning.main",
|
|
153
|
+
children: 'The forecast could not be read.'
|
|
154
|
+
}) : !read ? /*#__PURE__*/ _jsx(Typography, {
|
|
155
|
+
variant: "body2",
|
|
156
|
+
color: "text.secondary",
|
|
157
|
+
children: '—'
|
|
158
|
+
}) : forecast.total.count === 0 ? /*#__PURE__*/ _jsx(Typography, {
|
|
159
|
+
variant: "body2",
|
|
160
|
+
color: "text.secondary",
|
|
161
|
+
children: 'No open deals yet.'
|
|
162
|
+
}) : /*#__PURE__*/ _jsx(Box, {
|
|
163
|
+
children: /*#__PURE__*/ _jsxs(ScrollTable, {
|
|
164
|
+
size: "small",
|
|
165
|
+
"aria-label": "Forecast by close month",
|
|
166
|
+
children: [
|
|
167
|
+
/*#__PURE__*/ _jsx(TableHead, {
|
|
168
|
+
children: /*#__PURE__*/ _jsxs(TableRow, {
|
|
169
|
+
children: [
|
|
170
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
171
|
+
children: 'Expected close'
|
|
172
|
+
}),
|
|
173
|
+
columns.map((column)=>/*#__PURE__*/ _jsx(TableCell, {
|
|
174
|
+
align: "right",
|
|
175
|
+
children: column.name || 'Pipeline not visible'
|
|
176
|
+
}, column.pipelineId)),
|
|
177
|
+
manyColumns ? /*#__PURE__*/ _jsx(TableCell, {
|
|
178
|
+
align: "right",
|
|
179
|
+
children: 'All pipelines'
|
|
180
|
+
}) : null
|
|
181
|
+
]
|
|
182
|
+
})
|
|
183
|
+
}),
|
|
184
|
+
/*#__PURE__*/ _jsxs(TableBody, {
|
|
185
|
+
children: [
|
|
186
|
+
rows.map((row)=>/*#__PURE__*/ _jsxs(TableRow, {
|
|
187
|
+
"data-forecast-row": row.key,
|
|
188
|
+
children: [
|
|
189
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
190
|
+
children: /*#__PURE__*/ _jsx(Typography, {
|
|
191
|
+
variant: "body2",
|
|
192
|
+
color: row.muted ? 'text.secondary' : undefined,
|
|
193
|
+
children: row.label
|
|
194
|
+
})
|
|
195
|
+
}),
|
|
196
|
+
columns.map((column)=>/*#__PURE__*/ _jsx(TableCell, {
|
|
197
|
+
align: "right",
|
|
198
|
+
children: cell(row.cellOf(column), currency.currency)
|
|
199
|
+
}, column.pipelineId)),
|
|
200
|
+
manyColumns ? /*#__PURE__*/ _jsx(TableCell, {
|
|
201
|
+
align: "right",
|
|
202
|
+
children: cell(row.total, currency.currency)
|
|
203
|
+
}) : null
|
|
204
|
+
]
|
|
205
|
+
}, row.key)),
|
|
206
|
+
/*#__PURE__*/ _jsxs(TableRow, {
|
|
207
|
+
children: [
|
|
208
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
209
|
+
children: /*#__PURE__*/ _jsx(Typography, {
|
|
210
|
+
variant: "subtitle2",
|
|
211
|
+
children: 'Open pipeline'
|
|
212
|
+
})
|
|
213
|
+
}),
|
|
214
|
+
columns.map((column)=>/*#__PURE__*/ _jsx(TableCell, {
|
|
215
|
+
align: "right",
|
|
216
|
+
children: cell(column.total, currency.currency)
|
|
217
|
+
}, column.pipelineId)),
|
|
218
|
+
manyColumns ? /*#__PURE__*/ _jsx(TableCell, {
|
|
219
|
+
align: "right",
|
|
220
|
+
children: cell(forecast.total, currency.currency)
|
|
221
|
+
}) : null
|
|
222
|
+
]
|
|
223
|
+
})
|
|
224
|
+
]
|
|
225
|
+
})
|
|
226
|
+
]
|
|
227
|
+
})
|
|
228
|
+
}),
|
|
229
|
+
read && currency.mixed ? /*#__PURE__*/ _jsx(Typography, {
|
|
230
|
+
variant: "caption",
|
|
231
|
+
color: "text.secondary",
|
|
232
|
+
children: `Deals are in more than one currency; the figures add them as numbers and show ${currency.currency.toUpperCase()}, the most common.`
|
|
233
|
+
}) : null,
|
|
234
|
+
read && dealWindow.truncated ? /*#__PURE__*/ _jsx(Typography, {
|
|
235
|
+
variant: "caption",
|
|
236
|
+
color: "text.secondary",
|
|
237
|
+
children: `From the ${OPEN_DEAL_CEILING.toLocaleString()} most recently updated open deals.`
|
|
238
|
+
}) : null,
|
|
239
|
+
read && pipelineWindow.truncated ? /*#__PURE__*/ _jsx(Typography, {
|
|
240
|
+
variant: "caption",
|
|
241
|
+
color: "text.secondary",
|
|
242
|
+
children: `Only the first ${PIPELINE_CEILING} pipelines are named.`
|
|
243
|
+
}) : null
|
|
244
|
+
]
|
|
245
|
+
})
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
ForecastCard.displayName = 'ForecastCard';
|
|
249
|
+
export default ForecastCard;
|
|
250
|
+
|
|
251
|
+
//# sourceMappingURL=forecast-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/crm/src/lib/components/reports/forecast-card.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 * as Aglyn from '@aglyn/aglyn'\nimport { money } from '@aglyn/shared-ui-email-campaigns/components/report-figures'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { ScrollTable } from '@aglyn/shared-ui-jsx/components/scroll-table.component'\nimport {\n Box,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n Typography,\n} from '@mui/material'\nimport { limit, orderBy, query, where } from 'firebase/firestore'\nimport { useMemo } from 'react'\nimport { useFirestore } from '@aglyn/tenant-feature-instance'\nimport { collectionCeiling } from '@aglyn/tenant-feature-instance/hooks/host-collection-queries'\nimport { plural } from './report-format'\nimport {\n type CrmReportScope,\n reportCacheKey,\n scopedCollection,\n visibleToClause,\n} from './report-scope'\nimport { useWindowRead } from './use-aggregate-read'\n\n/**\n * The same window the pipeline card reads, under the SAME cache key and\n * the same dependencies, so the two cards cost one read between them —\n * `useAggregateRead` joins a read already in the air for the key. The\n * numbers must match the pipeline card's query exactly or the key would\n * name two different questions.\n */\nconst OPEN_DEAL_CEILING = 1000\nconst PIPELINE_CEILING = 20\n\ntype DealRow = Aglyn.CrmDeal & { $id: string }\ntype PipelineRow = Aglyn.CrmPipeline & { $id: string }\n\nexport interface ForecastCardProps {\n report: CrmReportScope\n}\n\n/** `Sep 2026` — the month a column is. */\nfunction monthLabel(startMs: number): string {\n return new Date(startMs).toLocaleDateString(undefined, { month: 'short', year: 'numeric' })\n}\n\n/**\n * Forecast by close month (AGL-2620): the open pipeline laid out by the\n * month each deal is expected to close, for the next six, per pipeline,\n * at face value and weighted by the stage.\n *\n * Not period-scoped, like the pipeline card and for the same reason: the\n * forecast is what is open NOW, looked at forward. Deals with no expected\n * close are their own row rather than a footnote — that row is the size\n * of the pipeline nobody has scheduled, which is the number the picker\n * of a close date most needs to see — and deals dated before this month\n * (overdue) or past the sixth (later) are rows too, so the column adds up\n * to the pipeline.\n */\nexport function ForecastCard(props: ForecastCardProps) {\n const { report } = props\n const { scope, tokens, nowMs } = report\n const firestore = useFirestore()\n\n const dealWindow = useWindowRead<DealRow>(\n () =>\n query(\n scopedCollection(firestore, scope, 'deals'),\n ...visibleToClause(tokens),\n where('status', '==', 'open'),\n orderBy('updatedAt', 'desc'),\n limit(OPEN_DEAL_CEILING + 1),\n ),\n OPEN_DEAL_CEILING,\n [firestore, scope, tokens, nowMs],\n { cacheKey: reportCacheKey(report, 'pipeline:deals') },\n )\n const pipelineWindow = useWindowRead<PipelineRow>(\n () =>\n collectionCeiling(\n query(scopedCollection(firestore, scope, 'pipelines'), ...visibleToClause(tokens)),\n PIPELINE_CEILING,\n ),\n PIPELINE_CEILING,\n [firestore, scope, tokens, nowMs],\n { cacheKey: reportCacheKey(report, 'pipeline:pipelines') },\n )\n\n const forecast = useMemo(\n () => Aglyn.forecastByCloseMonth(dealWindow.rows, pipelineWindow.rows, nowMs),\n [dealWindow.rows, pipelineWindow.rows, nowMs],\n )\n const currency = useMemo(() => Aglyn.currencyOfDeals(dealWindow.rows), [dealWindow.rows])\n const read = dealWindow.status === 'success' && pipelineWindow.status === 'success'\n const failed = dealWindow.status === 'error' || pipelineWindow.status === 'error'\n\n // A pipeline with nothing open is still a column; an unknown pipeline id\n // is a column named for what it is.\n const columns = forecast.pipelines\n const manyColumns = columns.length > 1\n\n const rows: Array<{ key: string; label: string; cellOf: (row: Aglyn.PipelineForecast) => Aglyn.ForecastCell; total: Aglyn.ForecastCell; muted?: boolean }> = [\n {\n key: 'overdue',\n label: 'Before this month',\n cellOf: (row) => row.overdue,\n total: forecast.overdue,\n muted: true,\n },\n ...forecast.buckets.map((bucket, index) => ({\n key: bucket.key,\n label: monthLabel(bucket.start),\n cellOf: (row: Aglyn.PipelineForecast) => row.months[index],\n total: forecast.months[index],\n })),\n {\n key: 'later',\n label: 'Later',\n cellOf: (row) => row.later,\n total: forecast.later,\n muted: true,\n },\n {\n key: 'undated',\n label: 'No expected close',\n cellOf: (row) => row.undated,\n total: forecast.undated,\n muted: true,\n },\n ].filter((row) => row.key !== 'overdue' && row.key !== 'later' ? true : row.total.count > 0)\n\n const cell = (value: Aglyn.ForecastCell, code: string) =>\n value.count === 0 ? (\n <Typography variant=\"body2\" color=\"text.disabled\">\n {'—'}\n </Typography>\n ) : (\n <Stack sx={{ lineHeight: 1.2 }}>\n <Typography variant=\"body2\">{money(value.amountCents, code)}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${money(value.weightedCents, code)} weighted · ${plural(value.count, 'deal')}`}\n </Typography>\n </Stack>\n )\n\n return (\n <CardDisplay\n header={'Forecast by close month'}\n help={Aglyn.pluginDocsHelp('crmReports', {\n anchor: '#forecast-by-close-month',\n excerpt:\n 'Every open deal by the month it is expected to close, for the ' +\n 'next six months and per pipeline, at face value and weighted by ' +\n 'its stage. Deals with no expected close are their own row.',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={1.5}>\n {failed ? (\n <Typography variant=\"body2\" color=\"warning.main\">\n {'The forecast could not be read.'}\n </Typography>\n ) : !read ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'—'}\n </Typography>\n ) : forecast.total.count === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'No open deals yet.'}\n </Typography>\n ) : (\n <Box>\n <ScrollTable size=\"small\" aria-label=\"Forecast by close month\">\n <TableHead>\n <TableRow>\n <TableCell>{'Expected close'}</TableCell>\n {columns.map((column) => (\n <TableCell key={column.pipelineId} align=\"right\">\n {column.name || 'Pipeline not visible'}\n </TableCell>\n ))}\n {manyColumns ? <TableCell align=\"right\">{'All pipelines'}</TableCell> : null}\n </TableRow>\n </TableHead>\n <TableBody>\n {rows.map((row) => (\n <TableRow key={row.key} data-forecast-row={row.key}>\n <TableCell>\n <Typography variant=\"body2\" color={row.muted ? 'text.secondary' : undefined}>\n {row.label}\n </Typography>\n </TableCell>\n {columns.map((column) => (\n <TableCell key={column.pipelineId} align=\"right\">\n {cell(row.cellOf(column), currency.currency)}\n </TableCell>\n ))}\n {manyColumns ? (\n <TableCell align=\"right\">{cell(row.total, currency.currency)}</TableCell>\n ) : null}\n </TableRow>\n ))}\n <TableRow>\n <TableCell>\n <Typography variant=\"subtitle2\">{'Open pipeline'}</Typography>\n </TableCell>\n {columns.map((column) => (\n <TableCell key={column.pipelineId} align=\"right\">\n {cell(column.total, currency.currency)}\n </TableCell>\n ))}\n {manyColumns ? (\n <TableCell align=\"right\">{cell(forecast.total, currency.currency)}</TableCell>\n ) : null}\n </TableRow>\n </TableBody>\n </ScrollTable>\n </Box>\n )}\n {read && currency.mixed ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`Deals are in more than one currency; the figures add them as numbers and show ${currency.currency.toUpperCase()}, the most common.`}\n </Typography>\n ) : null}\n {read && dealWindow.truncated ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`From the ${OPEN_DEAL_CEILING.toLocaleString()} most recently updated open deals.`}\n </Typography>\n ) : null}\n {read && pipelineWindow.truncated ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`Only the first ${PIPELINE_CEILING} pipelines are named.`}\n </Typography>\n ) : null}\n </Stack>\n </CardDisplay>\n )\n}\nForecastCard.displayName = 'ForecastCard'\n\nexport default ForecastCard\n"],"names":["Aglyn","money","CardDisplay","ScrollTable","Box","Stack","TableBody","TableCell","TableHead","TableRow","Typography","limit","orderBy","query","where","useMemo","useFirestore","collectionCeiling","plural","reportCacheKey","scopedCollection","visibleToClause","useWindowRead","OPEN_DEAL_CEILING","PIPELINE_CEILING","monthLabel","startMs","Date","toLocaleDateString","undefined","month","year","ForecastCard","props","report","scope","tokens","nowMs","firestore","dealWindow","cacheKey","pipelineWindow","forecast","forecastByCloseMonth","rows","currency","currencyOfDeals","read","status","failed","columns","pipelines","manyColumns","length","key","label","cellOf","row","overdue","total","muted","buckets","map","bucket","index","start","months","later","undated","filter","count","cell","value","code","variant","color","sx","lineHeight","amountCents","weightedCents","header","help","pluginDocsHelp","anchor","excerpt","contentGutterX","contentGutterY","spacing","size","aria-label","column","align","name","pipelineId","data-forecast-row","mixed","toUpperCase","truncated","toLocaleString","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
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 Firestore } from 'firebase/firestore';
|
|
18
|
+
/**
|
|
19
|
+
* THE LEADS STILL TO WORK, a site at a time (AGL-2624, across sites since
|
|
20
|
+
* AGL-2634).
|
|
21
|
+
*
|
|
22
|
+
* A lead lives under its site — `hosts/{hostId}/leads`, private by path —
|
|
23
|
+
* so there is no org-level collection to count and no `orgId` on the
|
|
24
|
+
* document to group by. The one figure is two server counts per site and
|
|
25
|
+
* a subtraction: every lead, less the closed ones, because a lead nobody
|
|
26
|
+
* has touched carries no status and Firestore cannot select on a field's
|
|
27
|
+
* absence (`openLeadsFromCounts`). Handed one site this is the glance
|
|
28
|
+
* card's figure as it always was; handed the org's sites it is the org
|
|
29
|
+
* level's total, and the fan-out is bounded by the org's site list rather
|
|
30
|
+
* than by the data.
|
|
31
|
+
*/
|
|
32
|
+
export declare function openLeadsAcrossSites(firestore: Firestore, hostIds: readonly string[]): Promise<number>;
|
|
@@ -0,0 +1,44 @@
|
|
|
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 { CRM_LEAD_CLOSED_STATUSES, openLeadsFromCounts } from "@aglyn/aglyn";
|
|
17
|
+
import { collection, getCountFromServer, query, where } from "firebase/firestore";
|
|
18
|
+
/**
|
|
19
|
+
* THE LEADS STILL TO WORK, a site at a time (AGL-2624, across sites since
|
|
20
|
+
* AGL-2634).
|
|
21
|
+
*
|
|
22
|
+
* A lead lives under its site — `hosts/{hostId}/leads`, private by path —
|
|
23
|
+
* so there is no org-level collection to count and no `orgId` on the
|
|
24
|
+
* document to group by. The one figure is two server counts per site and
|
|
25
|
+
* a subtraction: every lead, less the closed ones, because a lead nobody
|
|
26
|
+
* has touched carries no status and Firestore cannot select on a field's
|
|
27
|
+
* absence (`openLeadsFromCounts`). Handed one site this is the glance
|
|
28
|
+
* card's figure as it always was; handed the org's sites it is the org
|
|
29
|
+
* level's total, and the fan-out is bounded by the org's site list rather
|
|
30
|
+
* than by the data.
|
|
31
|
+
*/ export async function openLeadsAcrossSites(firestore, hostIds) {
|
|
32
|
+
const countOf = (target)=>getCountFromServer(target).then((snapshot)=>snapshot.data().count);
|
|
33
|
+
const perSite = await Promise.all(hostIds.map(async (hostId)=>{
|
|
34
|
+
const leads = collection(firestore, 'hosts', hostId, 'leads');
|
|
35
|
+
const [total, closed] = await Promise.all([
|
|
36
|
+
countOf(query(leads)),
|
|
37
|
+
countOf(query(leads, where('status', 'in', CRM_LEAD_CLOSED_STATUSES)))
|
|
38
|
+
]);
|
|
39
|
+
return openLeadsFromCounts(total, closed);
|
|
40
|
+
}));
|
|
41
|
+
return perSite.reduce((sum, count)=>sum + count, 0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=lead-counts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/crm/src/lib/components/reports/lead-counts.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 { CRM_LEAD_CLOSED_STATUSES, openLeadsFromCounts } from '@aglyn/aglyn'\nimport {\n collection,\n type Firestore,\n getCountFromServer,\n query,\n where,\n} from 'firebase/firestore'\n\n/**\n * THE LEADS STILL TO WORK, a site at a time (AGL-2624, across sites since\n * AGL-2634).\n *\n * A lead lives under its site — `hosts/{hostId}/leads`, private by path —\n * so there is no org-level collection to count and no `orgId` on the\n * document to group by. The one figure is two server counts per site and\n * a subtraction: every lead, less the closed ones, because a lead nobody\n * has touched carries no status and Firestore cannot select on a field's\n * absence (`openLeadsFromCounts`). Handed one site this is the glance\n * card's figure as it always was; handed the org's sites it is the org\n * level's total, and the fan-out is bounded by the org's site list rather\n * than by the data.\n */\nexport async function openLeadsAcrossSites(\n firestore: Firestore,\n hostIds: readonly string[],\n): Promise<number> {\n const countOf = (target: ReturnType<typeof query>) =>\n getCountFromServer(target).then((snapshot) => snapshot.data().count)\n const perSite = await Promise.all(\n hostIds.map(async (hostId) => {\n const leads = collection(firestore, 'hosts', hostId, 'leads')\n const [total, closed] = await Promise.all([\n countOf(query(leads)),\n countOf(query(leads, where('status', 'in', CRM_LEAD_CLOSED_STATUSES))),\n ])\n return openLeadsFromCounts(total, closed)\n }),\n )\n return perSite.reduce((sum, count) => sum + count, 0)\n}\n"],"names":["CRM_LEAD_CLOSED_STATUSES","openLeadsFromCounts","collection","getCountFromServer","query","where","openLeadsAcrossSites","firestore","hostIds","countOf","target","then","snapshot","data","count","perSite","Promise","all","map","hostId","leads","total","closed","reduce","sum"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,wBAAwB,EAAEC,mBAAmB,QAAQ,eAAc;AAC5E,SACEC,UAAU,EAEVC,kBAAkB,EAClBC,KAAK,EACLC,KAAK,QACA,qBAAoB;AAE3B;;;;;;;;;;;;;CAaC,GACD,OAAO,eAAeC,qBACpBC,SAAoB,EACpBC,OAA0B;IAE1B,MAAMC,UAAU,CAACC,SACfP,mBAAmBO,QAAQC,IAAI,CAAC,CAACC,WAAaA,SAASC,IAAI,GAAGC,KAAK;IACrE,MAAMC,UAAU,MAAMC,QAAQC,GAAG,CAC/BT,QAAQU,GAAG,CAAC,OAAOC;QACjB,MAAMC,QAAQlB,WAAWK,WAAW,SAASY,QAAQ;QACrD,MAAM,CAACE,OAAOC,OAAO,GAAG,MAAMN,QAAQC,GAAG,CAAC;YACxCR,QAAQL,MAAMgB;YACdX,QAAQL,MAAMgB,OAAOf,MAAM,UAAU,MAAML;SAC5C;QACD,OAAOC,oBAAoBoB,OAAOC;IACpC;IAEF,OAAOP,QAAQQ,MAAM,CAAC,CAACC,KAAKV,QAAUU,MAAMV,OAAO;AACrD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type CrmReportScope } from './report-scope';
|
|
2
|
+
/**
|
|
3
|
+
* How many of the period's leads the funnel is placed from — the Leads
|
|
4
|
+
* section's own window, over the period rather than over everything.
|
|
5
|
+
*
|
|
6
|
+
* The captured count is a server aggregate and never meets this bound; the
|
|
7
|
+
* funnel needs each lead's status and reason, so it reads the period's
|
|
8
|
+
* newest two hundred and says when there were more. At the organization
|
|
9
|
+
* level the bound is PER SITE (AGL-2634): each site's window is its own,
|
|
10
|
+
* and a site with a thousand leads must not crowd out a site with ten.
|
|
11
|
+
*/
|
|
12
|
+
export declare const LEAD_CEILING = 200;
|
|
13
|
+
export interface LeadFunnelCardProps {
|
|
14
|
+
report: CrmReportScope;
|
|
15
|
+
/**
|
|
16
|
+
* The site whose leads are placed. A lead lives under its host, not the
|
|
17
|
+
* org — `hosts/{hostId}/leads`, private by path, no `visibleTo` — so the
|
|
18
|
+
* report's org scope cannot reach it and the card is told the site. At
|
|
19
|
+
* the organization level `null` (AGL-2630): the card then reads every
|
|
20
|
+
* site the mount lists, one window each (AGL-2634).
|
|
21
|
+
*/
|
|
22
|
+
hostId: string | null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The lead funnel, at whichever level the report is mounted (AGL-2624,
|
|
26
|
+
* AGL-2630, AGL-2634).
|
|
27
|
+
*
|
|
28
|
+
* Under a site: that site. At the organization level: every site the
|
|
29
|
+
* mount lists, one window each, totaled — the org hub's reports total
|
|
30
|
+
* every site, and the leads are no exception now that the fan-out is
|
|
31
|
+
* bounded by the org's site list. With no sites to read the card says so
|
|
32
|
+
* instead of guessing.
|
|
33
|
+
*/
|
|
34
|
+
export declare function LeadFunnelCard(props: LeadFunnelCardProps): import("react").JSX.Element;
|
|
35
|
+
export declare namespace LeadFunnelCard {
|
|
36
|
+
var displayName: string;
|
|
37
|
+
}
|
|
38
|
+
export default LeadFunnelCard;
|