@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,255 @@
|
|
|
1
|
+
import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2026 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ /**
|
|
18
|
+
* BRINGING A SPREADSHEET OF LEADS INTO THE CRM — the pure half (AGL-2701).
|
|
19
|
+
*
|
|
20
|
+
* The contact import's three stages (`crm-import.ts`) over the lead
|
|
21
|
+
* vocabulary. A lead is the one CRM record a person does not type: it is
|
|
22
|
+
* what a capture door wrote when somebody signed up, booked or submitted a
|
|
23
|
+
* form, plus the working state the team wrote on top. A file therefore
|
|
24
|
+
* carries HALF a lead — the person, and the team's annotations — and the
|
|
25
|
+
* capture half is the door's to write.
|
|
26
|
+
*
|
|
27
|
+
* ## The address is the identity, because it is the document id
|
|
28
|
+
*
|
|
29
|
+
* A lead lives at `hosts/{hostId}/leads/{personKey}`, and `personKey` is
|
|
30
|
+
* the sha256 of the normalized address. So the address is not merely the
|
|
31
|
+
* one required cell: it is the row's name. A cell the normalizer cannot
|
|
32
|
+
* read is refused as `invalid-email`, and two rows of one file that
|
|
33
|
+
* normalize to the same address are one person — the second is skipped as
|
|
34
|
+
* `duplicate` rather than merged onto the first, for the reason the
|
|
35
|
+
* contacts import gives: one person reported once created and once merged
|
|
36
|
+
* is a number the operator cannot reconcile against the rows they sent.
|
|
37
|
+
*
|
|
38
|
+
* ## What a file may NOT say
|
|
39
|
+
*
|
|
40
|
+
* The export's `Sources`, `First seen`, `Last seen` and `Captures` columns
|
|
41
|
+
* are the capture door's own record of what the visitor did, and
|
|
42
|
+
* `Converted` is stamped by `crm/lead-convert` after the contact exists.
|
|
43
|
+
* None of them is a field here, so the mapping leaves those columns
|
|
44
|
+
* unmapped rather than mis-mapping them — a file that could write
|
|
45
|
+
* "first seen" could rewrite the history it is supposed to describe. The
|
|
46
|
+
* organization-level file's `Site` column is left out for a second reason:
|
|
47
|
+
* the site is the drawer's question and the route's permission is granted
|
|
48
|
+
* for that ONE site, so a cell must not be able to redirect a row to
|
|
49
|
+
* another.
|
|
50
|
+
*
|
|
51
|
+
* ## Qualified is a conversion, not a status a cell can claim
|
|
52
|
+
*
|
|
53
|
+
* `qualified` means a lead BECAME a contact, and `convertedContactId`
|
|
54
|
+
* beside it names the contact that was really created. Only the convert
|
|
55
|
+
* route writes the pair, so the list's own status control offers new,
|
|
56
|
+
* working and unqualified and nothing else. A cell naming `qualified` is
|
|
57
|
+
* dropped and reported here for the same reason: a status claiming a
|
|
58
|
+
* conversion that never happened would show a contact link to nowhere.
|
|
59
|
+
*
|
|
60
|
+
* ## A bad cell is dropped and named; a bad row is skipped and named
|
|
61
|
+
*
|
|
62
|
+
* The address is the only cell that can make a row unstorable. An
|
|
63
|
+
* unreadable status, or an unqualified reason with no unqualified status
|
|
64
|
+
* to belong to, is left off the lead and REPORTED under
|
|
65
|
+
* {@link LeadImportRow.dropped}, so the operator learns that a column went
|
|
66
|
+
* nowhere rather than discovering it weeks later.
|
|
67
|
+
*/ import { normalizeContactEmail } from "@aglyn/aglyn/app-utils/contacts";
|
|
68
|
+
import { CRM_LEAD_STATUS_LABELS, CRM_LEAD_STATUSES, isCrmLeadStatus } from "@aglyn/aglyn/app-utils/crm";
|
|
69
|
+
import { CSV_IMPORT_CHUNK_SIZE, CSV_IMPORT_MAX_BODY_BYTES, CSV_IMPORT_MAX_ROWS, CSV_IMPORT_PREVIEW_ROWS, emptyImportResult, guessImportMapping, importAliasKeys, importSkippedCsv, importTextValue, mapImportRow, mergeImportResults } from "@aglyn/aglyn/app-utils/csv-import";
|
|
70
|
+
/** The shared ceilings, under this collection's names. */ export const LEAD_IMPORT_MAX_ROWS = CSV_IMPORT_MAX_ROWS;
|
|
71
|
+
export const LEAD_IMPORT_CHUNK_SIZE = CSV_IMPORT_CHUNK_SIZE;
|
|
72
|
+
export const LEAD_IMPORT_MAX_BODY_BYTES = CSV_IMPORT_MAX_BODY_BYTES;
|
|
73
|
+
export const LEAD_IMPORT_PREVIEW_ROWS = CSV_IMPORT_PREVIEW_ROWS;
|
|
74
|
+
/** The same caps the lead's own cards hold a typed value to. */ export const LEAD_IMPORT_NOTES_MAX = 4000;
|
|
75
|
+
export const LEAD_IMPORT_REASON_MAX = 500;
|
|
76
|
+
/** A person's name, capped where every other import caps one. */ const NAME_MAX = 120;
|
|
77
|
+
/**
|
|
78
|
+
* The statuses a file may set.
|
|
79
|
+
*
|
|
80
|
+
* The list's own status control offers exactly these three, and for the
|
|
81
|
+
* reason given above: `qualified` is written by the conversion, beside the
|
|
82
|
+
* contact it produced.
|
|
83
|
+
*/ export const LEAD_IMPORT_STATUSES = CRM_LEAD_STATUSES.filter((status)=>status !== 'qualified');
|
|
84
|
+
/** The fields a column may be mapped to, in the order the mapping menu lists them. */ export const LEAD_IMPORT_FIELDS = [
|
|
85
|
+
'email',
|
|
86
|
+
'name',
|
|
87
|
+
'status',
|
|
88
|
+
'ownerEmail',
|
|
89
|
+
'unqualifiedReason',
|
|
90
|
+
'notes'
|
|
91
|
+
];
|
|
92
|
+
/** How each field reads in the mapping menu. Typed so a field cannot ship unlabeled. */ export const LEAD_IMPORT_FIELD_LABELS = {
|
|
93
|
+
email: 'Email (required)',
|
|
94
|
+
name: 'Name',
|
|
95
|
+
status: 'Status (new, working, unqualified)',
|
|
96
|
+
ownerEmail: 'Owner (team member email)',
|
|
97
|
+
unqualifiedReason: 'Unqualified reason',
|
|
98
|
+
notes: 'Notes'
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Header aliases per field, matched after the shared header normalization.
|
|
102
|
+
*
|
|
103
|
+
* First in each list is the header this CRM's own leads export writes, so
|
|
104
|
+
* an export re-imports without a hand mapping; the export's Sources, First
|
|
105
|
+
* seen, Last seen, Captures, Converted and Site columns are deliberately
|
|
106
|
+
* absent from every list, so they land on "Do not import".
|
|
107
|
+
*/ const FIELD_ALIASES = {
|
|
108
|
+
email: [
|
|
109
|
+
'email',
|
|
110
|
+
'email address',
|
|
111
|
+
'e mail',
|
|
112
|
+
'mail',
|
|
113
|
+
'contact email',
|
|
114
|
+
'work email'
|
|
115
|
+
],
|
|
116
|
+
name: [
|
|
117
|
+
'name',
|
|
118
|
+
'full name',
|
|
119
|
+
'lead',
|
|
120
|
+
'lead name',
|
|
121
|
+
'contact',
|
|
122
|
+
'contact name',
|
|
123
|
+
'person'
|
|
124
|
+
],
|
|
125
|
+
status: [
|
|
126
|
+
'status',
|
|
127
|
+
'lead status',
|
|
128
|
+
'stage',
|
|
129
|
+
'lead stage',
|
|
130
|
+
'state'
|
|
131
|
+
],
|
|
132
|
+
ownerEmail: [
|
|
133
|
+
'owner',
|
|
134
|
+
'owner email',
|
|
135
|
+
'assigned to',
|
|
136
|
+
'assignee',
|
|
137
|
+
'rep',
|
|
138
|
+
'sales rep'
|
|
139
|
+
],
|
|
140
|
+
unqualifiedReason: [
|
|
141
|
+
'unqualified reason',
|
|
142
|
+
'reason',
|
|
143
|
+
'disqualified reason',
|
|
144
|
+
'lost reason',
|
|
145
|
+
'reason lost'
|
|
146
|
+
],
|
|
147
|
+
notes: [
|
|
148
|
+
'notes',
|
|
149
|
+
'note',
|
|
150
|
+
'description',
|
|
151
|
+
'comments',
|
|
152
|
+
'details'
|
|
153
|
+
]
|
|
154
|
+
};
|
|
155
|
+
const FIELD_ALIAS_KEYS = importAliasKeys(LEAD_IMPORT_FIELDS, FIELD_ALIASES);
|
|
156
|
+
/** A proposed mapping from a file's header row, each field taken at most once. */ export function guessLeadImportMapping(columns) {
|
|
157
|
+
return guessImportMapping(columns, LEAD_IMPORT_FIELDS, FIELD_ALIAS_KEYS);
|
|
158
|
+
}
|
|
159
|
+
/** One parsed line under the mapping. Empty cells are left absent; a lead has no custom fields. */ export function mapLeadImportRow(cells, mapping) {
|
|
160
|
+
const _mapImportRow = mapImportRow(cells, mapping), { custom: _custom } = _mapImportRow, row = _object_without_properties_loose(_mapImportRow, [
|
|
161
|
+
"custom"
|
|
162
|
+
]);
|
|
163
|
+
return row;
|
|
164
|
+
}
|
|
165
|
+
/** How a skip reason reads on screen and in the downloaded file. */ export const LEAD_IMPORT_SKIP_LABELS = {
|
|
166
|
+
'invalid-email': 'No usable email address',
|
|
167
|
+
duplicate: 'The same address appears earlier in this file',
|
|
168
|
+
'lead-ceiling': 'This site is at the platform lead limit',
|
|
169
|
+
'write-failed': 'Could not be saved'
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* A status cell by id or by label — `working`, `Working` and `WORKING` are
|
|
173
|
+
* one status. `null` for a cell naming no status a file may set, which
|
|
174
|
+
* includes the well-spelled `Qualified` the export writes for a converted
|
|
175
|
+
* lead.
|
|
176
|
+
*/ export function parseImportLeadStatus(value) {
|
|
177
|
+
var _LEAD_IMPORT_STATUSES_find;
|
|
178
|
+
const text = String(value != null ? value : '').trim().toLowerCase();
|
|
179
|
+
if (!text) return null;
|
|
180
|
+
const byId = isCrmLeadStatus(text) ? text : null;
|
|
181
|
+
const byLabel = (_LEAD_IMPORT_STATUSES_find = LEAD_IMPORT_STATUSES.find((status)=>CRM_LEAD_STATUS_LABELS[status].toLowerCase() === text)) != null ? _LEAD_IMPORT_STATUSES_find : null;
|
|
182
|
+
const status = byId != null ? byId : byLabel;
|
|
183
|
+
return status && LEAD_IMPORT_STATUSES.includes(status) ? status : null;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* One raw row as the values that will be written, or the reason it cannot
|
|
187
|
+
* be. Refused here only for an unusable address, because the address is
|
|
188
|
+
* the document id; the owner is refused by the server, which alone can
|
|
189
|
+
* look them up.
|
|
190
|
+
*/ export function normalizeLeadImportRow(raw) {
|
|
191
|
+
var _importTextValue;
|
|
192
|
+
var _importTextValue1;
|
|
193
|
+
const emailText = (_importTextValue = importTextValue(raw.email, 320)) != null ? _importTextValue : '';
|
|
194
|
+
const email = normalizeContactEmail(emailText);
|
|
195
|
+
if (!email) {
|
|
196
|
+
return {
|
|
197
|
+
ok: false,
|
|
198
|
+
reason: 'invalid-email',
|
|
199
|
+
input: emailText
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const dropped = [];
|
|
203
|
+
const drop = (field, value)=>{
|
|
204
|
+
dropped.push({
|
|
205
|
+
field,
|
|
206
|
+
value: String(value != null ? value : '').trim()
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
const row = {
|
|
210
|
+
email,
|
|
211
|
+
dropped
|
|
212
|
+
};
|
|
213
|
+
const name = (_importTextValue1 = importTextValue(raw.name, NAME_MAX)) == null ? void 0 : _importTextValue1.replace(/\s+/g, ' ');
|
|
214
|
+
if (name) row.name = name;
|
|
215
|
+
const statusText = importTextValue(raw.status, 32);
|
|
216
|
+
if (statusText) {
|
|
217
|
+
const status = parseImportLeadStatus(statusText);
|
|
218
|
+
if (status) row.status = status;
|
|
219
|
+
else drop('status', statusText);
|
|
220
|
+
}
|
|
221
|
+
const ownerText = importTextValue(raw.ownerEmail, 320);
|
|
222
|
+
if (ownerText) {
|
|
223
|
+
const owner = normalizeContactEmail(ownerText);
|
|
224
|
+
if (owner) row.ownerEmail = owner;
|
|
225
|
+
else drop('ownerEmail', ownerText);
|
|
226
|
+
}
|
|
227
|
+
/*
|
|
228
|
+
* The reason belongs to the status: it is what an unqualified lead was
|
|
229
|
+
* closed FOR, and on a lead that is not unqualified it describes
|
|
230
|
+
* nothing. A row that carries one without the other keeps the status and
|
|
231
|
+
* reports the reason, so a mis-mapped column is visible rather than
|
|
232
|
+
* stored where nothing reads it.
|
|
233
|
+
*/ const reasonText = importTextValue(raw.unqualifiedReason, LEAD_IMPORT_REASON_MAX);
|
|
234
|
+
if (reasonText) {
|
|
235
|
+
if (row.status === 'unqualified') row.unqualifiedReason = reasonText;
|
|
236
|
+
else drop('unqualifiedReason', reasonText);
|
|
237
|
+
}
|
|
238
|
+
const notes = importTextValue(raw.notes, LEAD_IMPORT_NOTES_MAX);
|
|
239
|
+
if (notes) row.notes = notes;
|
|
240
|
+
return {
|
|
241
|
+
ok: true,
|
|
242
|
+
row
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
export function emptyLeadImportResult() {
|
|
246
|
+
return emptyImportResult();
|
|
247
|
+
}
|
|
248
|
+
export function mergeLeadImportResults(total, chunk, offset = 0) {
|
|
249
|
+
return mergeImportResults(total, chunk, offset);
|
|
250
|
+
}
|
|
251
|
+
/** The skipped rows as a file the operator can fix and re-import. */ export function leadImportSkippedCsv(columns, entries) {
|
|
252
|
+
return importSkippedCsv(columns, entries, LEAD_IMPORT_SKIP_LABELS);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
//# sourceMappingURL=crm-lead-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/crm-lead-import.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\n/**\n * BRINGING A SPREADSHEET OF LEADS INTO THE CRM — the pure half (AGL-2701).\n *\n * The contact import's three stages (`crm-import.ts`) over the lead\n * vocabulary. A lead is the one CRM record a person does not type: it is\n * what a capture door wrote when somebody signed up, booked or submitted a\n * form, plus the working state the team wrote on top. A file therefore\n * carries HALF a lead — the person, and the team's annotations — and the\n * capture half is the door's to write.\n *\n * ## The address is the identity, because it is the document id\n *\n * A lead lives at `hosts/{hostId}/leads/{personKey}`, and `personKey` is\n * the sha256 of the normalized address. So the address is not merely the\n * one required cell: it is the row's name. A cell the normalizer cannot\n * read is refused as `invalid-email`, and two rows of one file that\n * normalize to the same address are one person — the second is skipped as\n * `duplicate` rather than merged onto the first, for the reason the\n * contacts import gives: one person reported once created and once merged\n * is a number the operator cannot reconcile against the rows they sent.\n *\n * ## What a file may NOT say\n *\n * The export's `Sources`, `First seen`, `Last seen` and `Captures` columns\n * are the capture door's own record of what the visitor did, and\n * `Converted` is stamped by `crm/lead-convert` after the contact exists.\n * None of them is a field here, so the mapping leaves those columns\n * unmapped rather than mis-mapping them — a file that could write\n * \"first seen\" could rewrite the history it is supposed to describe. The\n * organization-level file's `Site` column is left out for a second reason:\n * the site is the drawer's question and the route's permission is granted\n * for that ONE site, so a cell must not be able to redirect a row to\n * another.\n *\n * ## Qualified is a conversion, not a status a cell can claim\n *\n * `qualified` means a lead BECAME a contact, and `convertedContactId`\n * beside it names the contact that was really created. Only the convert\n * route writes the pair, so the list's own status control offers new,\n * working and unqualified and nothing else. A cell naming `qualified` is\n * dropped and reported here for the same reason: a status claiming a\n * conversion that never happened would show a contact link to nowhere.\n *\n * ## A bad cell is dropped and named; a bad row is skipped and named\n *\n * The address is the only cell that can make a row unstorable. An\n * unreadable status, or an unqualified reason with no unqualified status\n * to belong to, is left off the lead and REPORTED under\n * {@link LeadImportRow.dropped}, so the operator learns that a column went\n * nowhere rather than discovering it weeks later.\n */\n\nimport { normalizeContactEmail } from '@aglyn/aglyn/app-utils/contacts'\nimport {\n CRM_LEAD_STATUS_LABELS,\n CRM_LEAD_STATUSES,\n type CrmLeadStatus,\n isCrmLeadStatus,\n} from '@aglyn/aglyn/app-utils/crm'\nimport {\n CSV_IMPORT_CHUNK_SIZE,\n CSV_IMPORT_MAX_BODY_BYTES,\n CSV_IMPORT_MAX_ROWS,\n CSV_IMPORT_PREVIEW_ROWS,\n emptyImportResult,\n guessImportMapping,\n importAliasKeys,\n type ImportChunkResult,\n type ImportDroppedValue,\n importSkippedCsv,\n importTextValue,\n mapImportRow,\n mergeImportResults,\n} from '@aglyn/aglyn/app-utils/csv-import'\n\n/** The shared ceilings, under this collection's names. */\nexport const LEAD_IMPORT_MAX_ROWS = CSV_IMPORT_MAX_ROWS\nexport const LEAD_IMPORT_CHUNK_SIZE = CSV_IMPORT_CHUNK_SIZE\nexport const LEAD_IMPORT_MAX_BODY_BYTES = CSV_IMPORT_MAX_BODY_BYTES\nexport const LEAD_IMPORT_PREVIEW_ROWS = CSV_IMPORT_PREVIEW_ROWS\n\n/** The same caps the lead's own cards hold a typed value to. */\nexport const LEAD_IMPORT_NOTES_MAX = 4000\nexport const LEAD_IMPORT_REASON_MAX = 500\n\n/** A person's name, capped where every other import caps one. */\nconst NAME_MAX = 120\n\n/**\n * The statuses a file may set.\n *\n * The list's own status control offers exactly these three, and for the\n * reason given above: `qualified` is written by the conversion, beside the\n * contact it produced.\n */\nexport const LEAD_IMPORT_STATUSES: readonly CrmLeadStatus[] =\n CRM_LEAD_STATUSES.filter((status) => status !== 'qualified')\n\n/** The fields a column may be mapped to, in the order the mapping menu lists them. */\nexport const LEAD_IMPORT_FIELDS = [\n 'email',\n 'name',\n 'status',\n 'ownerEmail',\n 'unqualifiedReason',\n 'notes',\n] as const\n\nexport type LeadImportField = (typeof LEAD_IMPORT_FIELDS)[number]\n\n/** How each field reads in the mapping menu. Typed so a field cannot ship unlabeled. */\nexport const LEAD_IMPORT_FIELD_LABELS: Record<LeadImportField, string> = {\n email: 'Email (required)',\n name: 'Name',\n status: 'Status (new, working, unqualified)',\n ownerEmail: 'Owner (team member email)',\n unqualifiedReason: 'Unqualified reason',\n notes: 'Notes',\n}\n\n/**\n * Header aliases per field, matched after the shared header normalization.\n *\n * First in each list is the header this CRM's own leads export writes, so\n * an export re-imports without a hand mapping; the export's Sources, First\n * seen, Last seen, Captures, Converted and Site columns are deliberately\n * absent from every list, so they land on \"Do not import\".\n */\nconst FIELD_ALIASES: Record<LeadImportField, readonly string[]> = {\n email: ['email', 'email address', 'e mail', 'mail', 'contact email', 'work email'],\n name: ['name', 'full name', 'lead', 'lead name', 'contact', 'contact name', 'person'],\n status: ['status', 'lead status', 'stage', 'lead stage', 'state'],\n ownerEmail: ['owner', 'owner email', 'assigned to', 'assignee', 'rep', 'sales rep'],\n unqualifiedReason: [\n 'unqualified reason',\n 'reason',\n 'disqualified reason',\n 'lost reason',\n 'reason lost',\n ],\n notes: ['notes', 'note', 'description', 'comments', 'details'],\n}\n\nconst FIELD_ALIAS_KEYS = importAliasKeys(LEAD_IMPORT_FIELDS, FIELD_ALIASES)\n\n/** Column index → field. A column absent from the map is not imported. */\nexport type LeadImportMapping = Record<number, LeadImportField>\n\n/** A proposed mapping from a file's header row, each field taken at most once. */\nexport function guessLeadImportMapping(columns: readonly string[]): LeadImportMapping {\n return guessImportMapping(columns, LEAD_IMPORT_FIELDS, FIELD_ALIAS_KEYS)\n}\n\n/**\n * What the browser posts for one line: the cells the mapping selected,\n * under the field they were mapped to, verbatim. `unknown` because the\n * server reads this off an untrusted body.\n */\nexport type LeadImportRawRow = Partial<Record<LeadImportField, unknown>>\n\n/** One parsed line under the mapping. Empty cells are left absent; a lead has no custom fields. */\nexport function mapLeadImportRow(\n cells: readonly string[],\n mapping: Record<number, LeadImportField | `custom:${string}`>,\n): LeadImportRawRow {\n const { custom: _custom, ...row } = mapImportRow(cells, mapping)\n return row\n}\n\nexport type LeadImportSkipReason =\n | 'invalid-email'\n | 'duplicate'\n | 'lead-ceiling'\n | 'write-failed'\n\n/** How a skip reason reads on screen and in the downloaded file. */\nexport const LEAD_IMPORT_SKIP_LABELS: Record<LeadImportSkipReason, string> = {\n 'invalid-email': 'No usable email address',\n duplicate: 'The same address appears earlier in this file',\n 'lead-ceiling': 'This site is at the platform lead limit',\n 'write-failed': 'Could not be saved',\n}\n\n/** One row, ready for the server to resolve and write. */\nexport interface LeadImportRow {\n /** Normalized — the address `personKey` derives the document id from. */\n email: string\n name?: string\n /** Absent leaves an existing lead's status alone and a new one reading as `new`. */\n status?: CrmLeadStatus\n /** Normalized, for the server to resolve against the org's members. */\n ownerEmail?: string\n /** Only ever set beside `status: 'unqualified'` — the pair is one fact. */\n unqualifiedReason?: string\n notes?: string\n dropped: ImportDroppedValue[]\n}\n\nexport type LeadImportRowVerdict =\n | { ok: true; row: LeadImportRow }\n | { ok: false; reason: 'invalid-email'; input: string }\n\n/**\n * A status cell by id or by label — `working`, `Working` and `WORKING` are\n * one status. `null` for a cell naming no status a file may set, which\n * includes the well-spelled `Qualified` the export writes for a converted\n * lead.\n */\nexport function parseImportLeadStatus(value: unknown): CrmLeadStatus | null {\n const text = String(value ?? '')\n .trim()\n .toLowerCase()\n if (!text) return null\n const byId = isCrmLeadStatus(text) ? text : null\n const byLabel =\n LEAD_IMPORT_STATUSES.find(\n (status) => CRM_LEAD_STATUS_LABELS[status].toLowerCase() === text,\n ) ?? null\n const status = byId ?? byLabel\n return status && LEAD_IMPORT_STATUSES.includes(status) ? status : null\n}\n\n/**\n * One raw row as the values that will be written, or the reason it cannot\n * be. Refused here only for an unusable address, because the address is\n * the document id; the owner is refused by the server, which alone can\n * look them up.\n */\nexport function normalizeLeadImportRow(raw: LeadImportRawRow): LeadImportRowVerdict {\n const emailText = importTextValue(raw.email, 320) ?? ''\n const email = normalizeContactEmail(emailText)\n if (!email) {\n return { ok: false, reason: 'invalid-email', input: emailText }\n }\n const dropped: ImportDroppedValue[] = []\n const drop = (field: LeadImportField, value: unknown) => {\n dropped.push({ field, value: String(value ?? '').trim() })\n }\n const row: LeadImportRow = { email, dropped }\n\n const name = importTextValue(raw.name, NAME_MAX)?.replace(/\\s+/g, ' ')\n if (name) row.name = name\n\n const statusText = importTextValue(raw.status, 32)\n if (statusText) {\n const status = parseImportLeadStatus(statusText)\n if (status) row.status = status\n else drop('status', statusText)\n }\n\n const ownerText = importTextValue(raw.ownerEmail, 320)\n if (ownerText) {\n const owner = normalizeContactEmail(ownerText)\n if (owner) row.ownerEmail = owner\n else drop('ownerEmail', ownerText)\n }\n\n /*\n * The reason belongs to the status: it is what an unqualified lead was\n * closed FOR, and on a lead that is not unqualified it describes\n * nothing. A row that carries one without the other keeps the status and\n * reports the reason, so a mis-mapped column is visible rather than\n * stored where nothing reads it.\n */\n const reasonText = importTextValue(raw.unqualifiedReason, LEAD_IMPORT_REASON_MAX)\n if (reasonText) {\n if (row.status === 'unqualified') row.unqualifiedReason = reasonText\n else drop('unqualifiedReason', reasonText)\n }\n\n const notes = importTextValue(raw.notes, LEAD_IMPORT_NOTES_MAX)\n if (notes) row.notes = notes\n\n return { ok: true, row }\n}\n\n/** One row the server did not store, by its index in the request, named by the address. */\nexport interface LeadImportSkippedRow {\n index: number\n email: string\n reason: LeadImportSkipReason\n}\n\n/** What one request did. The drawer sums these across a file. */\nexport type LeadImportChunkResult = ImportChunkResult<LeadImportSkippedRow>\n\nexport function emptyLeadImportResult(): LeadImportChunkResult {\n return emptyImportResult<LeadImportSkippedRow>()\n}\n\nexport function mergeLeadImportResults(\n total: LeadImportChunkResult,\n chunk: LeadImportChunkResult,\n offset = 0,\n): LeadImportChunkResult {\n return mergeImportResults(total, chunk, offset)\n}\n\n/** The skipped rows as a file the operator can fix and re-import. */\nexport function leadImportSkippedCsv(\n columns: readonly string[],\n entries: readonly { cells: readonly string[]; reason: LeadImportSkipReason }[],\n): string {\n return importSkippedCsv(columns, entries, LEAD_IMPORT_SKIP_LABELS)\n}\n"],"names":["normalizeContactEmail","CRM_LEAD_STATUS_LABELS","CRM_LEAD_STATUSES","isCrmLeadStatus","CSV_IMPORT_CHUNK_SIZE","CSV_IMPORT_MAX_BODY_BYTES","CSV_IMPORT_MAX_ROWS","CSV_IMPORT_PREVIEW_ROWS","emptyImportResult","guessImportMapping","importAliasKeys","importSkippedCsv","importTextValue","mapImportRow","mergeImportResults","LEAD_IMPORT_MAX_ROWS","LEAD_IMPORT_CHUNK_SIZE","LEAD_IMPORT_MAX_BODY_BYTES","LEAD_IMPORT_PREVIEW_ROWS","LEAD_IMPORT_NOTES_MAX","LEAD_IMPORT_REASON_MAX","NAME_MAX","LEAD_IMPORT_STATUSES","filter","status","LEAD_IMPORT_FIELDS","LEAD_IMPORT_FIELD_LABELS","email","name","ownerEmail","unqualifiedReason","notes","FIELD_ALIASES","FIELD_ALIAS_KEYS","guessLeadImportMapping","columns","mapLeadImportRow","cells","mapping","custom","_custom","row","LEAD_IMPORT_SKIP_LABELS","duplicate","parseImportLeadStatus","value","text","String","trim","toLowerCase","byId","byLabel","find","includes","normalizeLeadImportRow","raw","emailText","ok","reason","input","dropped","drop","field","push","replace","statusText","ownerText","owner","reasonText","emptyLeadImportResult","mergeLeadImportResults","total","chunk","offset","leadImportSkippedCsv","entries"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDC,GAED,SAASA,qBAAqB,QAAQ,kCAAiC;AACvE,SACEC,sBAAsB,EACtBC,iBAAiB,EAEjBC,eAAe,QACV,6BAA4B;AACnC,SACEC,qBAAqB,EACrBC,yBAAyB,EACzBC,mBAAmB,EACnBC,uBAAuB,EACvBC,iBAAiB,EACjBC,kBAAkB,EAClBC,eAAe,EAGfC,gBAAgB,EAChBC,eAAe,EACfC,YAAY,EACZC,kBAAkB,QACb,oCAAmC;AAE1C,wDAAwD,GACxD,OAAO,MAAMC,uBAAuBT,oBAAmB;AACvD,OAAO,MAAMU,yBAAyBZ,sBAAqB;AAC3D,OAAO,MAAMa,6BAA6BZ,0BAAyB;AACnE,OAAO,MAAMa,2BAA2BX,wBAAuB;AAE/D,8DAA8D,GAC9D,OAAO,MAAMY,wBAAwB,KAAI;AACzC,OAAO,MAAMC,yBAAyB,IAAG;AAEzC,+DAA+D,GAC/D,MAAMC,WAAW;AAEjB;;;;;;CAMC,GACD,OAAO,MAAMC,uBACXpB,kBAAkBqB,MAAM,CAAC,CAACC,SAAWA,WAAW,aAAY;AAE9D,oFAAoF,GACpF,OAAO,MAAMC,qBAAqB;IAChC;IACA;IACA;IACA;IACA;IACA;CACD,CAAS;AAIV,sFAAsF,GACtF,OAAO,MAAMC,2BAA4D;IACvEC,OAAO;IACPC,MAAM;IACNJ,QAAQ;IACRK,YAAY;IACZC,mBAAmB;IACnBC,OAAO;AACT,EAAC;AAED;;;;;;;CAOC,GACD,MAAMC,gBAA4D;IAChEL,OAAO;QAAC;QAAS;QAAiB;QAAU;QAAQ;QAAiB;KAAa;IAClFC,MAAM;QAAC;QAAQ;QAAa;QAAQ;QAAa;QAAW;QAAgB;KAAS;IACrFJ,QAAQ;QAAC;QAAU;QAAe;QAAS;QAAc;KAAQ;IACjEK,YAAY;QAAC;QAAS;QAAe;QAAe;QAAY;QAAO;KAAY;IACnFC,mBAAmB;QACjB;QACA;QACA;QACA;QACA;KACD;IACDC,OAAO;QAAC;QAAS;QAAQ;QAAe;QAAY;KAAU;AAChE;AAEA,MAAME,mBAAmBvB,gBAAgBe,oBAAoBO;AAK7D,gFAAgF,GAChF,OAAO,SAASE,uBAAuBC,OAA0B;IAC/D,OAAO1B,mBAAmB0B,SAASV,oBAAoBQ;AACzD;AASA,iGAAiG,GACjG,OAAO,SAASG,iBACdC,KAAwB,EACxBC,OAA6D;IAE7D,MAAoCzB,gBAAAA,aAAawB,OAAOC,UAAlD,EAAEC,QAAQC,OAAO,EAAU,GAAG3B,eAAR4B,uCAAQ5B;;;IACpC,OAAO4B;AACT;AAQA,kEAAkE,GAClE,OAAO,MAAMC,0BAAgE;IAC3E,iBAAiB;IACjBC,WAAW;IACX,gBAAgB;IAChB,gBAAgB;AAClB,EAAC;AAqBD;;;;;CAKC,GACD,OAAO,SAASC,sBAAsBC,KAAc;QAOhDvB;IANF,MAAMwB,OAAOC,OAAOF,gBAAAA,QAAS,IAC1BG,IAAI,GACJC,WAAW;IACd,IAAI,CAACH,MAAM,OAAO;IAClB,MAAMI,OAAO/C,gBAAgB2C,QAAQA,OAAO;IAC5C,MAAMK,WACJ7B,6BAAAA,qBAAqB8B,IAAI,CACvB,CAAC5B,SAAWvB,sBAAsB,CAACuB,OAAO,CAACyB,WAAW,OAAOH,iBAD/DxB,6BAEK;IACP,MAAME,SAAS0B,eAAAA,OAAQC;IACvB,OAAO3B,UAAUF,qBAAqB+B,QAAQ,CAAC7B,UAAUA,SAAS;AACpE;AAEA;;;;;CAKC,GACD,OAAO,SAAS8B,uBAAuBC,GAAqB;QACxC3C;QAWLA;IAXb,MAAM4C,aAAY5C,mBAAAA,gBAAgB2C,IAAI5B,KAAK,EAAE,gBAA3Bf,mBAAmC;IACrD,MAAMe,QAAQ3B,sBAAsBwD;IACpC,IAAI,CAAC7B,OAAO;QACV,OAAO;YAAE8B,IAAI;YAAOC,QAAQ;YAAiBC,OAAOH;QAAU;IAChE;IACA,MAAMI,UAAgC,EAAE;IACxC,MAAMC,OAAO,CAACC,OAAwBjB;QACpCe,QAAQG,IAAI,CAAC;YAAED;YAAOjB,OAAOE,OAAOF,gBAAAA,QAAS,IAAIG,IAAI;QAAG;IAC1D;IACA,MAAMP,MAAqB;QAAEd;QAAOiC;IAAQ;IAE5C,MAAMhC,QAAOhB,oBAAAA,gBAAgB2C,IAAI3B,IAAI,EAAEP,8BAA1BT,kBAAqCoD,OAAO,CAAC,QAAQ;IAClE,IAAIpC,MAAMa,IAAIb,IAAI,GAAGA;IAErB,MAAMqC,aAAarD,gBAAgB2C,IAAI/B,MAAM,EAAE;IAC/C,IAAIyC,YAAY;QACd,MAAMzC,SAASoB,sBAAsBqB;QACrC,IAAIzC,QAAQiB,IAAIjB,MAAM,GAAGA;aACpBqC,KAAK,UAAUI;IACtB;IAEA,MAAMC,YAAYtD,gBAAgB2C,IAAI1B,UAAU,EAAE;IAClD,IAAIqC,WAAW;QACb,MAAMC,QAAQnE,sBAAsBkE;QACpC,IAAIC,OAAO1B,IAAIZ,UAAU,GAAGsC;aACvBN,KAAK,cAAcK;IAC1B;IAEA;;;;;;GAMC,GACD,MAAME,aAAaxD,gBAAgB2C,IAAIzB,iBAAiB,EAAEV;IAC1D,IAAIgD,YAAY;QACd,IAAI3B,IAAIjB,MAAM,KAAK,eAAeiB,IAAIX,iBAAiB,GAAGsC;aACrDP,KAAK,qBAAqBO;IACjC;IAEA,MAAMrC,QAAQnB,gBAAgB2C,IAAIxB,KAAK,EAAEZ;IACzC,IAAIY,OAAOU,IAAIV,KAAK,GAAGA;IAEvB,OAAO;QAAE0B,IAAI;QAAMhB;IAAI;AACzB;AAYA,OAAO,SAAS4B;IACd,OAAO7D;AACT;AAEA,OAAO,SAAS8D,uBACdC,KAA4B,EAC5BC,KAA4B,EAC5BC,SAAS,CAAC;IAEV,OAAO3D,mBAAmByD,OAAOC,OAAOC;AAC1C;AAEA,mEAAmE,GACnE,OAAO,SAASC,qBACdvC,OAA0B,EAC1BwC,OAA8E;IAE9E,OAAOhE,iBAAiBwB,SAASwC,SAASjC;AAC5C"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
/** The one narrowing the contacts list publishes: the form that captured them. */
|
|
15
|
+
export declare const CRM_CONTACT_FILTER_FORM = "form";
|
|
16
|
+
/**
|
|
17
|
+
* Called from the console registrar. The owner is named rather than read off
|
|
18
|
+
* the loader's marker, so the routes register the same way under a spec that
|
|
19
|
+
* calls the registrar directly.
|
|
20
|
+
*/
|
|
21
|
+
export declare function registerCrmRecordRoutes(): void;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/ import { buildRoute, Route } from "@aglyn/aglyn/app-utils/console-routes";
|
|
14
|
+
import { registerPluginRecordRoute } from "@aglyn/aglyn/plugin-manager/plugin-record-routes";
|
|
15
|
+
import { BUNDLE_ID } from "../constants/bundle-common.js";
|
|
16
|
+
import { crmRoutes } from "./crm-routes.js";
|
|
17
|
+
/**
|
|
18
|
+
* Where the CRM's records are read, published for every other surface.
|
|
19
|
+
*
|
|
20
|
+
* The Inbox links a lead, a submission links its sender, a form links the
|
|
21
|
+
* people it captured. Each used to import {@link crmRoutes} and spell the
|
|
22
|
+
* CRM's nav slug to do it, which made every one of them a reader of this
|
|
23
|
+
* plugin's address table. They ask the record-route registry now, and get
|
|
24
|
+
* `null` — text instead of a link — in a workspace where the CRM is not
|
|
25
|
+
* loaded, which is also the first time that link stopped pointing at a page
|
|
26
|
+
* the workspace cannot open.
|
|
27
|
+
*/ /** The nav slug the shell resolves this plugin's hub by, at either scope. */ const CRM_SLUG = 'crm';
|
|
28
|
+
function hub(context) {
|
|
29
|
+
return crmRoutes(context.host ? buildRoute(Route.HOST_PLUGIN, {
|
|
30
|
+
orgSlug: context.orgSlug,
|
|
31
|
+
host: context.host,
|
|
32
|
+
pluginSlug: CRM_SLUG
|
|
33
|
+
}) : buildRoute(Route.ORG_PLUGIN, {
|
|
34
|
+
orgSlug: context.orgSlug,
|
|
35
|
+
pluginSlug: CRM_SLUG
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
/** The one narrowing the contacts list publishes: the form that captured them. */ export const CRM_CONTACT_FILTER_FORM = 'form';
|
|
39
|
+
/**
|
|
40
|
+
* Called from the console registrar. The owner is named rather than read off
|
|
41
|
+
* the loader's marker, so the routes register the same way under a spec that
|
|
42
|
+
* calls the registrar directly.
|
|
43
|
+
*/ export function registerCrmRecordRoutes() {
|
|
44
|
+
const owner = {
|
|
45
|
+
pluginId: BUNDLE_ID
|
|
46
|
+
};
|
|
47
|
+
registerPluginRecordRoute('contact', {
|
|
48
|
+
list: (context)=>hub(context).section('contacts'),
|
|
49
|
+
record: (context, id)=>hub(context).contact(id),
|
|
50
|
+
byEmail: (context, email)=>hub(context).contactByEmail(email),
|
|
51
|
+
filtered: (context, filter, value)=>filter === CRM_CONTACT_FILTER_FORM ? hub(context).contactsByForm(value) : null
|
|
52
|
+
}, owner);
|
|
53
|
+
registerPluginRecordRoute('lead', {
|
|
54
|
+
list: (context)=>hub(context).section('leads'),
|
|
55
|
+
// A lead is keyed by person under ONE site, so the organization's hub
|
|
56
|
+
// addresses it by site and id; a caller that names no site has no
|
|
57
|
+
// address to be given.
|
|
58
|
+
record: (context, id)=>context.host ? hub(context).lead(id) : null
|
|
59
|
+
}, owner);
|
|
60
|
+
registerPluginRecordRoute('company', {
|
|
61
|
+
list: (context)=>hub(context).section('companies'),
|
|
62
|
+
record: (context, id)=>hub(context).company(id)
|
|
63
|
+
}, owner);
|
|
64
|
+
registerPluginRecordRoute('deal', {
|
|
65
|
+
list: (context)=>hub(context).section('deals'),
|
|
66
|
+
record: (context, id)=>hub(context).deal(id)
|
|
67
|
+
}, owner);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=crm-record-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/crm-record-routes.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\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 * http://www.apache.org/licenses/LICENSE-2.0\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 { buildRoute, Route } from '@aglyn/aglyn/app-utils/console-routes'\nimport {\n registerPluginRecordRoute,\n type PluginRecordRouteContext,\n} from '@aglyn/aglyn/plugin-manager/plugin-record-routes'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { crmRoutes, type CrmRoutes } from './crm-routes'\n\n/**\n * Where the CRM's records are read, published for every other surface.\n *\n * The Inbox links a lead, a submission links its sender, a form links the\n * people it captured. Each used to import {@link crmRoutes} and spell the\n * CRM's nav slug to do it, which made every one of them a reader of this\n * plugin's address table. They ask the record-route registry now, and get\n * `null` — text instead of a link — in a workspace where the CRM is not\n * loaded, which is also the first time that link stopped pointing at a page\n * the workspace cannot open.\n */\n\n/** The nav slug the shell resolves this plugin's hub by, at either scope. */\nconst CRM_SLUG = 'crm'\n\nfunction hub(context: PluginRecordRouteContext): CrmRoutes {\n return crmRoutes(\n context.host\n ? buildRoute(Route.HOST_PLUGIN, {\n orgSlug: context.orgSlug,\n host: context.host,\n pluginSlug: CRM_SLUG,\n })\n : buildRoute(Route.ORG_PLUGIN, {\n orgSlug: context.orgSlug,\n pluginSlug: CRM_SLUG,\n }),\n )\n}\n\n/** The one narrowing the contacts list publishes: the form that captured them. */\nexport const CRM_CONTACT_FILTER_FORM = 'form'\n\n/**\n * Called from the console registrar. The owner is named rather than read off\n * the loader's marker, so the routes register the same way under a spec that\n * calls the registrar directly.\n */\nexport function registerCrmRecordRoutes(): void {\n const owner = { pluginId: BUNDLE_ID }\n registerPluginRecordRoute('contact', {\n list: (context) => hub(context).section('contacts'),\n record: (context, id) => hub(context).contact(id),\n byEmail: (context, email) => hub(context).contactByEmail(email),\n filtered: (context, filter, value) =>\n filter === CRM_CONTACT_FILTER_FORM\n ? hub(context).contactsByForm(value)\n : null,\n }, owner)\n registerPluginRecordRoute('lead', {\n list: (context) => hub(context).section('leads'),\n // A lead is keyed by person under ONE site, so the organization's hub\n // addresses it by site and id; a caller that names no site has no\n // address to be given.\n record: (context, id) => (context.host ? hub(context).lead(id) : null),\n }, owner)\n registerPluginRecordRoute('company', {\n list: (context) => hub(context).section('companies'),\n record: (context, id) => hub(context).company(id),\n }, owner)\n registerPluginRecordRoute('deal', {\n list: (context) => hub(context).section('deals'),\n record: (context, id) => hub(context).deal(id),\n }, owner)\n}\n"],"names":["buildRoute","Route","registerPluginRecordRoute","BUNDLE_ID","crmRoutes","CRM_SLUG","hub","context","host","HOST_PLUGIN","orgSlug","pluginSlug","ORG_PLUGIN","CRM_CONTACT_FILTER_FORM","registerCrmRecordRoutes","owner","pluginId","list","section","record","id","contact","byEmail","email","contactByEmail","filtered","filter","value","contactsByForm","lead","company","deal"],"mappings":"AAAA;;;;;;;;;;;;CAYC,GAED,SAASA,UAAU,EAAEC,KAAK,QAAQ,wCAAuC;AACzE,SACEC,yBAAyB,QAEpB,mDAAkD;AACzD,SAASC,SAAS,QAAQ,gCAA4B;AACtD,SAASC,SAAS,QAAwB,kBAAc;AAExD;;;;;;;;;;CAUC,GAED,2EAA2E,GAC3E,MAAMC,WAAW;AAEjB,SAASC,IAAIC,OAAiC;IAC5C,OAAOH,UACLG,QAAQC,IAAI,GACRR,WAAWC,MAAMQ,WAAW,EAAE;QAC5BC,SAASH,QAAQG,OAAO;QACxBF,MAAMD,QAAQC,IAAI;QAClBG,YAAYN;IACd,KACAL,WAAWC,MAAMW,UAAU,EAAE;QAC3BF,SAASH,QAAQG,OAAO;QACxBC,YAAYN;IACd;AAER;AAEA,gFAAgF,GAChF,OAAO,MAAMQ,0BAA0B,OAAM;AAE7C;;;;CAIC,GACD,OAAO,SAASC;IACd,MAAMC,QAAQ;QAAEC,UAAUb;IAAU;IACpCD,0BAA0B,WAAW;QACnCe,MAAM,CAACV,UAAYD,IAAIC,SAASW,OAAO,CAAC;QACxCC,QAAQ,CAACZ,SAASa,KAAOd,IAAIC,SAASc,OAAO,CAACD;QAC9CE,SAAS,CAACf,SAASgB,QAAUjB,IAAIC,SAASiB,cAAc,CAACD;QACzDE,UAAU,CAAClB,SAASmB,QAAQC,QAC1BD,WAAWb,0BACPP,IAAIC,SAASqB,cAAc,CAACD,SAC5B;IACR,GAAGZ;IACHb,0BAA0B,QAAQ;QAChCe,MAAM,CAACV,UAAYD,IAAIC,SAASW,OAAO,CAAC;QACxC,sEAAsE;QACtE,kEAAkE;QAClE,uBAAuB;QACvBC,QAAQ,CAACZ,SAASa,KAAQb,QAAQC,IAAI,GAAGF,IAAIC,SAASsB,IAAI,CAACT,MAAM;IACnE,GAAGL;IACHb,0BAA0B,WAAW;QACnCe,MAAM,CAACV,UAAYD,IAAIC,SAASW,OAAO,CAAC;QACxCC,QAAQ,CAACZ,SAASa,KAAOd,IAAIC,SAASuB,OAAO,CAACV;IAChD,GAAGL;IACHb,0BAA0B,QAAQ;QAChCe,MAAM,CAACV,UAAYD,IAAIC,SAASW,OAAO,CAAC;QACxCC,QAAQ,CAACZ,SAASa,KAAOd,IAAIC,SAASwB,IAAI,CAACX;IAC7C,GAAGL;AACL"}
|
|
@@ -0,0 +1,101 @@
|
|
|
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 ConsolePluginPageProps } from '@aglyn/aglyn';
|
|
18
|
+
import type { CrmConsoleSectionId } from '../components/crm-console-sections';
|
|
19
|
+
/**
|
|
20
|
+
* Every address inside the Contacts surface, built from the one string the
|
|
21
|
+
* shell hands the page (AGL-2595).
|
|
22
|
+
*
|
|
23
|
+
* The hub owns three kinds of deeper route — `people/{contactId}`,
|
|
24
|
+
* `companies/{companyId}`, `deals/{dealId}` — and eight surfaces link into
|
|
25
|
+
* them: a deal names its contact and company, a task names all three, a
|
|
26
|
+
* report drills into a deal, an activity names whoever it happened with.
|
|
27
|
+
* Eight surfaces each spelling `${basePath}/people/${id}` is eight places
|
|
28
|
+
* for one of them to spell it `contacts/`, and a link that 404s inside the
|
|
29
|
+
* hub is indistinguishable from a record that was deleted.
|
|
30
|
+
*
|
|
31
|
+
* The id is URL-encoded because Firestore ids are opaque: the console mints
|
|
32
|
+
* them, but an import or an API caller may not, and a slash in an id would
|
|
33
|
+
* otherwise read as a further segment.
|
|
34
|
+
*/
|
|
35
|
+
export declare function crmRoutes(basePath: string): {
|
|
36
|
+
section: (id: CrmConsoleSectionId) => string;
|
|
37
|
+
contact: (id: string) => string;
|
|
38
|
+
/**
|
|
39
|
+
* The Contacts list narrowed to the people one form captured (AGL-2612):
|
|
40
|
+
* source `form`, and the `formIds` filter on the form's id. The form's
|
|
41
|
+
* own page links here; the list reads the two keys back through
|
|
42
|
+
* `contactsListSeed`, which is the other half of this address.
|
|
43
|
+
*/
|
|
44
|
+
contactsByForm: (formId: string) => string;
|
|
45
|
+
/**
|
|
46
|
+
* The Contacts list asked to OPEN the one person with this address
|
|
47
|
+
* (AGL-2612). The list is the lookup: a contact's id is minted at
|
|
48
|
+
* capture and nothing outside the CRM holds it, so a surface that has
|
|
49
|
+
* only an email — an Inbox submission row — links here, the list
|
|
50
|
+
* filters on the address (a whole-collection query, under the scope
|
|
51
|
+
* the viewer may read) and moves straight on to the record when exactly
|
|
52
|
+
* one matches. No match leaves the filtered list on screen, which is
|
|
53
|
+
* the honest answer for a submission whose contact the band dropped.
|
|
54
|
+
*/
|
|
55
|
+
contactByEmail: (email: string) => string;
|
|
56
|
+
/**
|
|
57
|
+
* A lead's page — and, at the ORGANIZATION level (AGL-2630), the site
|
|
58
|
+
* it lives under, as a segment before the id: a lead's id is a person
|
|
59
|
+
* key, the same on every site that met the person, and `hosts/{hostId}
|
|
60
|
+
* /leads` is host-scoped by path, so an address that spans sites has to
|
|
61
|
+
* name one. Under a site the address is the id alone, as it always was.
|
|
62
|
+
*/
|
|
63
|
+
lead: (id: string, hostId?: string | null) => string;
|
|
64
|
+
company: (id: string) => string;
|
|
65
|
+
deal: (id: string) => string;
|
|
66
|
+
/**
|
|
67
|
+
* A section opened on one of its saved views (AGL-2617). The list reads
|
|
68
|
+
* the key back through `crmViewIdFromParams`; the same key composes
|
|
69
|
+
* with the Contacts seeds above, which is why it is a query key and not
|
|
70
|
+
* a path segment.
|
|
71
|
+
*/
|
|
72
|
+
sectionView: (id: CrmConsoleSectionId, viewId: string) => string;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* The query keys the Contacts list reads on arrival — written by the two
|
|
76
|
+
* builders above and parsed by `contactsListSeed`, named once so neither
|
|
77
|
+
* side can misspell the other.
|
|
78
|
+
*/
|
|
79
|
+
export declare const CONTACTS_LIST_SOURCE_PARAM = "source";
|
|
80
|
+
export declare const CONTACTS_LIST_FORM_PARAM = "formId";
|
|
81
|
+
/**
|
|
82
|
+
* The email key is the SHARED constant (AGL-2622): the console app — which
|
|
83
|
+
* the module boundaries keep from importing this plugin — builds the same
|
|
84
|
+
* address through `crmContactByEmailHref`, and `crm-routes.spec.ts` pins
|
|
85
|
+
* `contactByEmail` against it so the plugin and the app cannot spell the
|
|
86
|
+
* key two ways.
|
|
87
|
+
*/
|
|
88
|
+
export declare const CONTACTS_LIST_EMAIL_PARAM = "email";
|
|
89
|
+
export type CrmRoutes = ReturnType<typeof crmRoutes>;
|
|
90
|
+
/**
|
|
91
|
+
* What the hub hands a record page: the shell's context, the record's id and
|
|
92
|
+
* the surface's own path so the page can link back to its list.
|
|
93
|
+
*
|
|
94
|
+
* `basePath` is required here where the shell's prop is optional, because a
|
|
95
|
+
* record page is only ever reached THROUGH the hub, which has already refused
|
|
96
|
+
* to render without one.
|
|
97
|
+
*/
|
|
98
|
+
export type CrmDetailPageProps = Pick<ConsolePluginPageProps, 'hostId' | 'org' | 'permissions' | 'releaseFlag' | 'hostRole'> & {
|
|
99
|
+
id: string;
|
|
100
|
+
basePath: string;
|
|
101
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
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_CONTACTS_EMAIL_PARAM } from "@aglyn/aglyn";
|
|
17
|
+
import { CRM_VIEW_PARAM } from "./crm-view-param.js";
|
|
18
|
+
/**
|
|
19
|
+
* Every address inside the Contacts surface, built from the one string the
|
|
20
|
+
* shell hands the page (AGL-2595).
|
|
21
|
+
*
|
|
22
|
+
* The hub owns three kinds of deeper route — `people/{contactId}`,
|
|
23
|
+
* `companies/{companyId}`, `deals/{dealId}` — and eight surfaces link into
|
|
24
|
+
* them: a deal names its contact and company, a task names all three, a
|
|
25
|
+
* report drills into a deal, an activity names whoever it happened with.
|
|
26
|
+
* Eight surfaces each spelling `${basePath}/people/${id}` is eight places
|
|
27
|
+
* for one of them to spell it `contacts/`, and a link that 404s inside the
|
|
28
|
+
* hub is indistinguishable from a record that was deleted.
|
|
29
|
+
*
|
|
30
|
+
* The id is URL-encoded because Firestore ids are opaque: the console mints
|
|
31
|
+
* them, but an import or an API caller may not, and a slash in an id would
|
|
32
|
+
* otherwise read as a further segment.
|
|
33
|
+
*/ export function crmRoutes(basePath) {
|
|
34
|
+
const section = (id)=>`${basePath}/${id}`;
|
|
35
|
+
return {
|
|
36
|
+
section,
|
|
37
|
+
contact: (id)=>`${section('contacts')}/${encodeURIComponent(id)}`,
|
|
38
|
+
/**
|
|
39
|
+
* The Contacts list narrowed to the people one form captured (AGL-2612):
|
|
40
|
+
* source `form`, and the `formIds` filter on the form's id. The form's
|
|
41
|
+
* own page links here; the list reads the two keys back through
|
|
42
|
+
* `contactsListSeed`, which is the other half of this address.
|
|
43
|
+
*/ contactsByForm: (formId)=>`${section('contacts')}?${new URLSearchParams({
|
|
44
|
+
[CONTACTS_LIST_SOURCE_PARAM]: 'form',
|
|
45
|
+
[CONTACTS_LIST_FORM_PARAM]: formId
|
|
46
|
+
}).toString()}`,
|
|
47
|
+
/**
|
|
48
|
+
* The Contacts list asked to OPEN the one person with this address
|
|
49
|
+
* (AGL-2612). The list is the lookup: a contact's id is minted at
|
|
50
|
+
* capture and nothing outside the CRM holds it, so a surface that has
|
|
51
|
+
* only an email — an Inbox submission row — links here, the list
|
|
52
|
+
* filters on the address (a whole-collection query, under the scope
|
|
53
|
+
* the viewer may read) and moves straight on to the record when exactly
|
|
54
|
+
* one matches. No match leaves the filtered list on screen, which is
|
|
55
|
+
* the honest answer for a submission whose contact the band dropped.
|
|
56
|
+
*/ contactByEmail: (email)=>`${section('contacts')}?${new URLSearchParams({
|
|
57
|
+
[CONTACTS_LIST_EMAIL_PARAM]: email
|
|
58
|
+
}).toString()}`,
|
|
59
|
+
/**
|
|
60
|
+
* A lead's page — and, at the ORGANIZATION level (AGL-2630), the site
|
|
61
|
+
* it lives under, as a segment before the id: a lead's id is a person
|
|
62
|
+
* key, the same on every site that met the person, and `hosts/{hostId}
|
|
63
|
+
* /leads` is host-scoped by path, so an address that spans sites has to
|
|
64
|
+
* name one. Under a site the address is the id alone, as it always was.
|
|
65
|
+
*/ lead: (id, hostId)=>hostId ? `${section('leads')}/${encodeURIComponent(hostId)}/${encodeURIComponent(id)}` : `${section('leads')}/${encodeURIComponent(id)}`,
|
|
66
|
+
company: (id)=>`${section('companies')}/${encodeURIComponent(id)}`,
|
|
67
|
+
deal: (id)=>`${section('deals')}/${encodeURIComponent(id)}`,
|
|
68
|
+
/**
|
|
69
|
+
* A section opened on one of its saved views (AGL-2617). The list reads
|
|
70
|
+
* the key back through `crmViewIdFromParams`; the same key composes
|
|
71
|
+
* with the Contacts seeds above, which is why it is a query key and not
|
|
72
|
+
* a path segment.
|
|
73
|
+
*/ sectionView: (id, viewId)=>`${section(id)}?${new URLSearchParams({
|
|
74
|
+
[CRM_VIEW_PARAM]: viewId
|
|
75
|
+
}).toString()}`
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The query keys the Contacts list reads on arrival — written by the two
|
|
80
|
+
* builders above and parsed by `contactsListSeed`, named once so neither
|
|
81
|
+
* side can misspell the other.
|
|
82
|
+
*/ export const CONTACTS_LIST_SOURCE_PARAM = 'source';
|
|
83
|
+
export const CONTACTS_LIST_FORM_PARAM = 'formId';
|
|
84
|
+
/**
|
|
85
|
+
* The email key is the SHARED constant (AGL-2622): the console app — which
|
|
86
|
+
* the module boundaries keep from importing this plugin — builds the same
|
|
87
|
+
* address through `crmContactByEmailHref`, and `crm-routes.spec.ts` pins
|
|
88
|
+
* `contactByEmail` against it so the plugin and the app cannot spell the
|
|
89
|
+
* key two ways.
|
|
90
|
+
*/ export const CONTACTS_LIST_EMAIL_PARAM = CRM_CONTACTS_EMAIL_PARAM;
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=crm-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/crm-routes.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_CONTACTS_EMAIL_PARAM, type ConsolePluginPageProps } from '@aglyn/aglyn'\nimport type { CrmConsoleSectionId } from '../components/crm-console-sections'\nimport { CRM_VIEW_PARAM } from './crm-view-param'\n\n/**\n * Every address inside the Contacts surface, built from the one string the\n * shell hands the page (AGL-2595).\n *\n * The hub owns three kinds of deeper route — `people/{contactId}`,\n * `companies/{companyId}`, `deals/{dealId}` — and eight surfaces link into\n * them: a deal names its contact and company, a task names all three, a\n * report drills into a deal, an activity names whoever it happened with.\n * Eight surfaces each spelling `${basePath}/people/${id}` is eight places\n * for one of them to spell it `contacts/`, and a link that 404s inside the\n * hub is indistinguishable from a record that was deleted.\n *\n * The id is URL-encoded because Firestore ids are opaque: the console mints\n * them, but an import or an API caller may not, and a slash in an id would\n * otherwise read as a further segment.\n */\nexport function crmRoutes(basePath: string) {\n const section = (id: CrmConsoleSectionId) => `${basePath}/${id}`\n return {\n section,\n contact: (id: string) => `${section('contacts')}/${encodeURIComponent(id)}`,\n /**\n * The Contacts list narrowed to the people one form captured (AGL-2612):\n * source `form`, and the `formIds` filter on the form's id. The form's\n * own page links here; the list reads the two keys back through\n * `contactsListSeed`, which is the other half of this address.\n */\n contactsByForm: (formId: string) =>\n `${section('contacts')}?${new URLSearchParams({\n [CONTACTS_LIST_SOURCE_PARAM]: 'form',\n [CONTACTS_LIST_FORM_PARAM]: formId,\n }).toString()}`,\n /**\n * The Contacts list asked to OPEN the one person with this address\n * (AGL-2612). The list is the lookup: a contact's id is minted at\n * capture and nothing outside the CRM holds it, so a surface that has\n * only an email — an Inbox submission row — links here, the list\n * filters on the address (a whole-collection query, under the scope\n * the viewer may read) and moves straight on to the record when exactly\n * one matches. No match leaves the filtered list on screen, which is\n * the honest answer for a submission whose contact the band dropped.\n */\n contactByEmail: (email: string) =>\n `${section('contacts')}?${new URLSearchParams({\n [CONTACTS_LIST_EMAIL_PARAM]: email,\n }).toString()}`,\n /**\n * A lead's page — and, at the ORGANIZATION level (AGL-2630), the site\n * it lives under, as a segment before the id: a lead's id is a person\n * key, the same on every site that met the person, and `hosts/{hostId}\n * /leads` is host-scoped by path, so an address that spans sites has to\n * name one. Under a site the address is the id alone, as it always was.\n */\n lead: (id: string, hostId?: string | null) =>\n hostId\n ? `${section('leads')}/${encodeURIComponent(hostId)}/${encodeURIComponent(id)}`\n : `${section('leads')}/${encodeURIComponent(id)}`,\n company: (id: string) => `${section('companies')}/${encodeURIComponent(id)}`,\n deal: (id: string) => `${section('deals')}/${encodeURIComponent(id)}`,\n /**\n * A section opened on one of its saved views (AGL-2617). The list reads\n * the key back through `crmViewIdFromParams`; the same key composes\n * with the Contacts seeds above, which is why it is a query key and not\n * a path segment.\n */\n sectionView: (id: CrmConsoleSectionId, viewId: string) =>\n `${section(id)}?${new URLSearchParams({\n [CRM_VIEW_PARAM]: viewId,\n }).toString()}`,\n }\n}\n\n/**\n * The query keys the Contacts list reads on arrival — written by the two\n * builders above and parsed by `contactsListSeed`, named once so neither\n * side can misspell the other.\n */\nexport const CONTACTS_LIST_SOURCE_PARAM = 'source'\nexport const CONTACTS_LIST_FORM_PARAM = 'formId'\n/**\n * The email key is the SHARED constant (AGL-2622): the console app — which\n * the module boundaries keep from importing this plugin — builds the same\n * address through `crmContactByEmailHref`, and `crm-routes.spec.ts` pins\n * `contactByEmail` against it so the plugin and the app cannot spell the\n * key two ways.\n */\nexport const CONTACTS_LIST_EMAIL_PARAM = CRM_CONTACTS_EMAIL_PARAM\n\nexport type CrmRoutes = ReturnType<typeof crmRoutes>\n\n/**\n * What the hub hands a record page: the shell's context, the record's id and\n * the surface's own path so the page can link back to its list.\n *\n * `basePath` is required here where the shell's prop is optional, because a\n * record page is only ever reached THROUGH the hub, which has already refused\n * to render without one.\n */\nexport type CrmDetailPageProps = Pick<\n ConsolePluginPageProps,\n 'hostId' | 'org' | 'permissions' | 'releaseFlag' | 'hostRole'\n> & {\n id: string\n basePath: string\n}\n"],"names":["CRM_CONTACTS_EMAIL_PARAM","CRM_VIEW_PARAM","crmRoutes","basePath","section","id","contact","encodeURIComponent","contactsByForm","formId","URLSearchParams","CONTACTS_LIST_SOURCE_PARAM","CONTACTS_LIST_FORM_PARAM","toString","contactByEmail","email","CONTACTS_LIST_EMAIL_PARAM","lead","hostId","company","deal","sectionView","viewId"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,wBAAwB,QAAqC,eAAc;AAEpF,SAASC,cAAc,QAAQ,sBAAkB;AAEjD;;;;;;;;;;;;;;;CAeC,GACD,OAAO,SAASC,UAAUC,QAAgB;IACxC,MAAMC,UAAU,CAACC,KAA4B,GAAGF,SAAS,CAAC,EAAEE,IAAI;IAChE,OAAO;QACLD;QACAE,SAAS,CAACD,KAAe,GAAGD,QAAQ,YAAY,CAAC,EAAEG,mBAAmBF,KAAK;QAC3E;;;;;KAKC,GACDG,gBAAgB,CAACC,SACf,GAAGL,QAAQ,YAAY,CAAC,EAAE,IAAIM,gBAAgB;gBAC5C,CAACC,2BAA2B,EAAE;gBAC9B,CAACC,yBAAyB,EAAEH;YAC9B,GAAGI,QAAQ,IAAI;QACjB;;;;;;;;;KASC,GACDC,gBAAgB,CAACC,QACf,GAAGX,QAAQ,YAAY,CAAC,EAAE,IAAIM,gBAAgB;gBAC5C,CAACM,0BAA0B,EAAED;YAC/B,GAAGF,QAAQ,IAAI;QACjB;;;;;;KAMC,GACDI,MAAM,CAACZ,IAAYa,SACjBA,SACI,GAAGd,QAAQ,SAAS,CAAC,EAAEG,mBAAmBW,QAAQ,CAAC,EAAEX,mBAAmBF,KAAK,GAC7E,GAAGD,QAAQ,SAAS,CAAC,EAAEG,mBAAmBF,KAAK;QACrDc,SAAS,CAACd,KAAe,GAAGD,QAAQ,aAAa,CAAC,EAAEG,mBAAmBF,KAAK;QAC5Ee,MAAM,CAACf,KAAe,GAAGD,QAAQ,SAAS,CAAC,EAAEG,mBAAmBF,KAAK;QACrE;;;;;KAKC,GACDgB,aAAa,CAAChB,IAAyBiB,SACrC,GAAGlB,QAAQC,IAAI,CAAC,EAAE,IAAIK,gBAAgB;gBACpC,CAACT,eAAe,EAAEqB;YACpB,GAAGT,QAAQ,IAAI;IACnB;AACF;AAEA;;;;CAIC,GACD,OAAO,MAAMF,6BAA6B,SAAQ;AAClD,OAAO,MAAMC,2BAA2B,SAAQ;AAChD;;;;;;CAMC,GACD,OAAO,MAAMI,4BAA4BhB,yBAAwB"}
|