@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,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
18
|
+
/**
|
|
19
|
+
* IMPORTING A CONTACT FILE — the contact vocabulary over the shared drawer
|
|
20
|
+
* (AGL-2602; the drawer itself is `csv-import-drawer.tsx` since AGL-2621).
|
|
21
|
+
*
|
|
22
|
+
* The server half is `server/contacts-import.ts`. What this file adds to
|
|
23
|
+
* the walk the shared drawer makes is what is particular to people: the
|
|
24
|
+
* contact fields and their aliases, the holder's custom fields as further
|
|
25
|
+
* targets, the email as the one cell every row needs — judged here by the
|
|
26
|
+
* same normalizer the route runs, as a courtesy count — and the line in
|
|
27
|
+
* the result that says how many companies the file's company column made.
|
|
28
|
+
*/ import { CRM_COLLECTIONS, normalizeContactEmail, pluginDocsHelp } from "@aglyn/aglyn";
|
|
29
|
+
import { CONTACT_IMPORT_CHUNK_SIZE, CONTACT_IMPORT_FIELD_LABELS, CONTACT_IMPORT_FIELDS, CONTACT_IMPORT_MAX_ROWS, CONTACT_IMPORT_PREVIEW_ROWS, CONTACT_IMPORT_SKIP_LABELS, contactImportSkippedCsv, emptyContactImportResult, guessContactImportMapping, mapContactImportRow, mergeContactImportResults } from "../model/crm-import.js";
|
|
30
|
+
import { useFirestore, useFirestoreCollection } from "@aglyn/tenant-feature-instance";
|
|
31
|
+
import { Typography } from "@mui/material";
|
|
32
|
+
import { collection, limit, query } from "firebase/firestore";
|
|
33
|
+
import { useMemo } from "react";
|
|
34
|
+
import { crmVisibleToClause, useCrmScope } from "../hooks/use-crm-scope.js";
|
|
35
|
+
import { contactImportTemplateCsv } from "../model/contacts-csv.js";
|
|
36
|
+
import { CsvImportButton, CsvImportDrawer } from "./csv-import-drawer.js";
|
|
37
|
+
/**
|
|
38
|
+
* The holder's live custom-field definitions, read only while the drawer
|
|
39
|
+
* is open.
|
|
40
|
+
*
|
|
41
|
+
* A local hook rather than a shared one because the Fields section that
|
|
42
|
+
* will own these definitions is landing beside this drawer; when it ships a
|
|
43
|
+
* `useContactFieldDefinitions`, this is the read to replace with it. Scoped
|
|
44
|
+
* by `visibleTo` the way the contacts listener is, because the rules prove
|
|
45
|
+
* a scoped member's query per document and refuse an unfiltered one.
|
|
46
|
+
*
|
|
47
|
+
* Ordered in memory rather than by the query: `array-contains-any` with an
|
|
48
|
+
* `orderBy` on another field needs a composite index the collection does
|
|
49
|
+
* not have, and a holder's field list fits in one page.
|
|
50
|
+
*/ function useImportFieldDefinitions(options) {
|
|
51
|
+
const { orgId, visibleToTokens, enabled } = options;
|
|
52
|
+
const firestore = useFirestore();
|
|
53
|
+
const { data } = useFirestoreCollection(()=>enabled && orgId ? query(collection(firestore, 'orgs', orgId, CRM_COLLECTIONS.contactFields), ...crmVisibleToClause(visibleToTokens), limit(100)) : null, [
|
|
54
|
+
firestore,
|
|
55
|
+
orgId,
|
|
56
|
+
visibleToTokens,
|
|
57
|
+
enabled
|
|
58
|
+
], {
|
|
59
|
+
idField: '$id'
|
|
60
|
+
});
|
|
61
|
+
return useMemo(()=>(data != null ? data : []).filter((field)=>!!field.key && !field.retiredAt).sort((a, b)=>{
|
|
62
|
+
var _a_order, _b_order;
|
|
63
|
+
return Number((_a_order = a.order) != null ? _a_order : 0) - Number((_b_order = b.order) != null ? _b_order : 0);
|
|
64
|
+
}), [
|
|
65
|
+
data
|
|
66
|
+
]);
|
|
67
|
+
}
|
|
68
|
+
/** The contact vocabulary, over the holder's custom fields. */ function contactImportVocabulary(fields) {
|
|
69
|
+
return {
|
|
70
|
+
title: 'Import contacts from CSV',
|
|
71
|
+
collection: 'contacts',
|
|
72
|
+
help: pluginDocsHelp('contacts', {
|
|
73
|
+
anchor: '#import-from-csv'
|
|
74
|
+
}),
|
|
75
|
+
sitePickerHelperText: 'The site these people are imported into — it decides which of your ' + "sites may see them and whose marketing consent the file's consent " + 'column records.',
|
|
76
|
+
intro: 'A CSV with a header row. Match its columns to contact fields ' + 'below, check the preview, then import. A person already in your ' + 'contacts is updated rather than added twice. Up to ' + `${CONTACT_IMPORT_MAX_ROWS.toLocaleString()} rows per file — split a ` + 'larger one.',
|
|
77
|
+
fields: CONTACT_IMPORT_FIELDS,
|
|
78
|
+
fieldLabels: CONTACT_IMPORT_FIELD_LABELS,
|
|
79
|
+
customFields: fields,
|
|
80
|
+
requiredField: 'email',
|
|
81
|
+
requiredWarning: 'Choose which column holds the email address. It is the one field ' + 'every row needs.',
|
|
82
|
+
unusable: (cell)=>!normalizeContactEmail(cell),
|
|
83
|
+
unusableNotice: (count, total)=>`${count.toLocaleString()} of ${total.toLocaleString()} rows have no ` + 'usable email address and will be skipped. You can download them ' + 'after the import.',
|
|
84
|
+
guessMapping: (columns)=>guessContactImportMapping(columns, fields),
|
|
85
|
+
mapRow: (cells, mapping)=>mapContactImportRow(cells, mapping),
|
|
86
|
+
route: '/api/crm/contacts-import',
|
|
87
|
+
maxRows: CONTACT_IMPORT_MAX_ROWS,
|
|
88
|
+
chunkSize: CONTACT_IMPORT_CHUNK_SIZE,
|
|
89
|
+
previewRows: CONTACT_IMPORT_PREVIEW_ROWS,
|
|
90
|
+
emptyResult: emptyContactImportResult,
|
|
91
|
+
mergeResults: (total, chunk, offset)=>mergeContactImportResults(total, chunk, offset),
|
|
92
|
+
skipLabels: CONTACT_IMPORT_SKIP_LABELS,
|
|
93
|
+
skippedCsv: contactImportSkippedCsv,
|
|
94
|
+
skippedFileName: 'skipped-contacts.csv',
|
|
95
|
+
templateCsv: ()=>contactImportTemplateCsv(fields),
|
|
96
|
+
templateFileName: 'contacts-template.csv',
|
|
97
|
+
resultExtras: (result)=>{
|
|
98
|
+
const created = result.companiesCreated;
|
|
99
|
+
return created ? /*#__PURE__*/ _jsx(Typography, {
|
|
100
|
+
variant: "body2",
|
|
101
|
+
color: "text.secondary",
|
|
102
|
+
children: `${created.toLocaleString()} new ${created === 1 ? 'company' : 'companies'} created from the company column.`
|
|
103
|
+
}) : null;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export function ContactImportDrawer(props) {
|
|
108
|
+
const { open, onClose, hostId, org } = props;
|
|
109
|
+
// The org root and the reader's tokens from the one scope hook (AGL-2614);
|
|
110
|
+
// at the organization level no clause, and the site every row is captured
|
|
111
|
+
// under is the one the drawer's picker names (AGL-2630).
|
|
112
|
+
const { orgId, visibleTo: visibleToTokens } = useCrmScope({
|
|
113
|
+
hostId,
|
|
114
|
+
org
|
|
115
|
+
});
|
|
116
|
+
const fields = useImportFieldDefinitions({
|
|
117
|
+
orgId,
|
|
118
|
+
visibleToTokens,
|
|
119
|
+
enabled: open
|
|
120
|
+
});
|
|
121
|
+
const vocabulary = useMemo(()=>contactImportVocabulary(fields), [
|
|
122
|
+
fields
|
|
123
|
+
]);
|
|
124
|
+
return /*#__PURE__*/ _jsx(CsvImportDrawer, {
|
|
125
|
+
open: open,
|
|
126
|
+
onClose: onClose,
|
|
127
|
+
hostId: hostId,
|
|
128
|
+
vocabulary: vocabulary
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
ContactImportDrawer.displayName = 'ContactImportDrawer';
|
|
132
|
+
/**
|
|
133
|
+
* The "Import CSV" action on the contacts list, with the drawer it opens —
|
|
134
|
+
* mounted only once opened, so the list pays nothing for it until then.
|
|
135
|
+
*/ export function ContactImportButton(props) {
|
|
136
|
+
const { hostId, org } = props;
|
|
137
|
+
return /*#__PURE__*/ _jsx(CsvImportButton, {
|
|
138
|
+
children: (open, onClose)=>/*#__PURE__*/ _jsx(ContactImportDrawer, {
|
|
139
|
+
open: open,
|
|
140
|
+
onClose: onClose,
|
|
141
|
+
hostId: hostId,
|
|
142
|
+
org: org
|
|
143
|
+
})
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
ContactImportButton.displayName = 'ContactImportButton';
|
|
147
|
+
export default ContactImportDrawer;
|
|
148
|
+
|
|
149
|
+
//# sourceMappingURL=contact-import-drawer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/contact-import-drawer.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\n/**\n * IMPORTING A CONTACT FILE — the contact vocabulary over the shared drawer\n * (AGL-2602; the drawer itself is `csv-import-drawer.tsx` since AGL-2621).\n *\n * The server half is `server/contacts-import.ts`. What this file adds to\n * the walk the shared drawer makes is what is particular to people: the\n * contact fields and their aliases, the holder's custom fields as further\n * targets, the email as the one cell every row needs — judged here by the\n * same normalizer the route runs, as a courtesy count — and the line in\n * the result that says how many companies the file's company column made.\n */\n\nimport {\n type ConsolePluginPageProps,\n type ContactFieldDefinition,\n CRM_COLLECTIONS,\n normalizeContactEmail,\n pluginDocsHelp,\n} from '@aglyn/aglyn'\nimport {\n CONTACT_IMPORT_CHUNK_SIZE,\n CONTACT_IMPORT_FIELD_LABELS,\n CONTACT_IMPORT_FIELDS,\n CONTACT_IMPORT_MAX_ROWS,\n CONTACT_IMPORT_PREVIEW_ROWS,\n CONTACT_IMPORT_SKIP_LABELS,\n type ContactImportChunkResult,\n type ContactImportField,\n type ContactImportRawRow,\n type ContactImportSkippedRow,\n contactImportSkippedCsv,\n emptyContactImportResult,\n guessContactImportMapping,\n mapContactImportRow,\n mergeContactImportResults,\n} from '../model/crm-import'\nimport { useFirestore, useFirestoreCollection } from '@aglyn/tenant-feature-instance'\nimport { Typography } from '@mui/material'\nimport { collection, limit, query } from 'firebase/firestore'\nimport { useMemo } from 'react'\nimport { crmVisibleToClause, useCrmScope } from '../hooks/use-crm-scope'\nimport { contactImportTemplateCsv } from '../model/contacts-csv'\nimport {\n CsvImportButton,\n CsvImportDrawer,\n type CsvImportVocabulary,\n} from './csv-import-drawer'\n\nexport interface ContactImportDrawerProps {\n open: boolean\n onClose: () => void\n /**\n * The site the file is imported INTO — what the route captures every row\n * under — or `null` at the organization level (AGL-2630), where the\n * drawer asks which site with a picker and holds the import until one is\n * named.\n */\n hostId: string | null\n /**\n * The org document the shell passed, for the consent group's scope\n * tokens. Typed as the page prop it is forwarded from, so the contacts\n * list mounts the button with the value it already holds and no cast.\n */\n org?: ConsolePluginPageProps['org']\n}\n\n/**\n * The holder's live custom-field definitions, read only while the drawer\n * is open.\n *\n * A local hook rather than a shared one because the Fields section that\n * will own these definitions is landing beside this drawer; when it ships a\n * `useContactFieldDefinitions`, this is the read to replace with it. Scoped\n * by `visibleTo` the way the contacts listener is, because the rules prove\n * a scoped member's query per document and refuse an unfiltered one.\n *\n * Ordered in memory rather than by the query: `array-contains-any` with an\n * `orderBy` on another field needs a composite index the collection does\n * not have, and a holder's field list fits in one page.\n */\nfunction useImportFieldDefinitions(options: {\n orgId: string | null | undefined\n /** The reader's tokens, or `null` at the organization level — no clause. */\n visibleToTokens: readonly string[] | null\n enabled: boolean\n}): ContactFieldDefinition[] {\n const { orgId, visibleToTokens, enabled } = options\n const firestore = useFirestore()\n const { data } = useFirestoreCollection<ContactFieldDefinition & { $id: string }>(\n () =>\n enabled && orgId\n ? query(\n collection(firestore, 'orgs', orgId, CRM_COLLECTIONS.contactFields),\n ...crmVisibleToClause(visibleToTokens),\n limit(100),\n )\n : null,\n [firestore, orgId, visibleToTokens, enabled],\n { idField: '$id' },\n )\n return useMemo(\n () =>\n (data ?? [])\n .filter((field) => !!field.key && !field.retiredAt)\n .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0)),\n [data],\n )\n}\n\n/** The contact vocabulary, over the holder's custom fields. */\nfunction contactImportVocabulary(\n fields: readonly ContactFieldDefinition[],\n): CsvImportVocabulary<\n ContactImportField,\n ContactImportRawRow & Record<string, unknown>,\n ContactImportSkippedRow\n> {\n return {\n title: 'Import contacts from CSV',\n collection: 'contacts',\n help: pluginDocsHelp('contacts', { anchor: '#import-from-csv' }),\n sitePickerHelperText:\n 'The site these people are imported into — it decides which of your ' +\n \"sites may see them and whose marketing consent the file's consent \" +\n 'column records.',\n intro:\n 'A CSV with a header row. Match its columns to contact fields ' +\n 'below, check the preview, then import. A person already in your ' +\n 'contacts is updated rather than added twice. Up to ' +\n `${CONTACT_IMPORT_MAX_ROWS.toLocaleString()} rows per file — split a ` +\n 'larger one.',\n fields: CONTACT_IMPORT_FIELDS,\n fieldLabels: CONTACT_IMPORT_FIELD_LABELS,\n customFields: fields,\n requiredField: 'email',\n requiredWarning:\n 'Choose which column holds the email address. It is the one field ' +\n 'every row needs.',\n unusable: (cell) => !normalizeContactEmail(cell),\n unusableNotice: (count, total) =>\n `${count.toLocaleString()} of ${total.toLocaleString()} rows have no ` +\n 'usable email address and will be skipped. You can download them ' +\n 'after the import.',\n guessMapping: (columns) => guessContactImportMapping(columns, fields),\n mapRow: (cells, mapping) =>\n mapContactImportRow(cells, mapping) as ContactImportRawRow & Record<string, unknown>,\n route: '/api/crm/contacts-import',\n maxRows: CONTACT_IMPORT_MAX_ROWS,\n chunkSize: CONTACT_IMPORT_CHUNK_SIZE,\n previewRows: CONTACT_IMPORT_PREVIEW_ROWS,\n emptyResult: emptyContactImportResult,\n mergeResults: (total, chunk, offset) =>\n mergeContactImportResults(\n total as ContactImportChunkResult,\n chunk as ContactImportChunkResult,\n offset,\n ),\n skipLabels: CONTACT_IMPORT_SKIP_LABELS,\n skippedCsv: contactImportSkippedCsv,\n skippedFileName: 'skipped-contacts.csv',\n templateCsv: () => contactImportTemplateCsv(fields),\n templateFileName: 'contacts-template.csv',\n resultExtras: (result) => {\n const created = (result as ContactImportChunkResult).companiesCreated\n return created ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`${created.toLocaleString()} new ${\n created === 1 ? 'company' : 'companies'\n } created from the company column.`}\n </Typography>\n ) : null\n },\n }\n}\n\nexport function ContactImportDrawer(props: ContactImportDrawerProps) {\n const { open, onClose, hostId, org } = props\n // The org root and the reader's tokens from the one scope hook (AGL-2614);\n // at the organization level no clause, and the site every row is captured\n // under is the one the drawer's picker names (AGL-2630).\n const { orgId, visibleTo: visibleToTokens } = useCrmScope({ hostId, org })\n const fields = useImportFieldDefinitions({\n orgId,\n visibleToTokens,\n enabled: open,\n })\n const vocabulary = useMemo(() => contactImportVocabulary(fields), [fields])\n return (\n <CsvImportDrawer\n open={open}\n onClose={onClose}\n hostId={hostId}\n vocabulary={vocabulary}\n />\n )\n}\nContactImportDrawer.displayName = 'ContactImportDrawer'\n\n/**\n * The \"Import CSV\" action on the contacts list, with the drawer it opens —\n * mounted only once opened, so the list pays nothing for it until then.\n */\nexport function ContactImportButton(props: {\n /** The site the list is read under, or `null` at the organization level. */\n hostId: string | null\n org?: ConsolePluginPageProps['org']\n}) {\n const { hostId, org } = props\n return (\n <CsvImportButton>\n {(open, onClose) => (\n <ContactImportDrawer open={open} onClose={onClose} hostId={hostId} org={org} />\n )}\n </CsvImportButton>\n )\n}\nContactImportButton.displayName = 'ContactImportButton'\n\nexport default ContactImportDrawer\n"],"names":["CRM_COLLECTIONS","normalizeContactEmail","pluginDocsHelp","CONTACT_IMPORT_CHUNK_SIZE","CONTACT_IMPORT_FIELD_LABELS","CONTACT_IMPORT_FIELDS","CONTACT_IMPORT_MAX_ROWS","CONTACT_IMPORT_PREVIEW_ROWS","CONTACT_IMPORT_SKIP_LABELS","contactImportSkippedCsv","emptyContactImportResult","guessContactImportMapping","mapContactImportRow","mergeContactImportResults","useFirestore","useFirestoreCollection","Typography","collection","limit","query","useMemo","crmVisibleToClause","useCrmScope","contactImportTemplateCsv","CsvImportButton","CsvImportDrawer","useImportFieldDefinitions","options","orgId","visibleToTokens","enabled","firestore","data","contactFields","idField","filter","field","key","retiredAt","sort","a","b","Number","order","contactImportVocabulary","fields","title","help","anchor","sitePickerHelperText","intro","toLocaleString","fieldLabels","customFields","requiredField","requiredWarning","unusable","cell","unusableNotice","count","total","guessMapping","columns","mapRow","cells","mapping","route","maxRows","chunkSize","previewRows","emptyResult","mergeResults","chunk","offset","skipLabels","skippedCsv","skippedFileName","templateCsv","templateFileName","resultExtras","result","created","companiesCreated","variant","color","ContactImportDrawer","props","open","onClose","hostId","org","visibleTo","vocabulary","displayName","ContactImportButton"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA;;;;;;;;;;CAUC,GAED,SAGEA,eAAe,EACfC,qBAAqB,EACrBC,cAAc,QACT,eAAc;AACrB,SACEC,yBAAyB,EACzBC,2BAA2B,EAC3BC,qBAAqB,EACrBC,uBAAuB,EACvBC,2BAA2B,EAC3BC,0BAA0B,EAK1BC,uBAAuB,EACvBC,wBAAwB,EACxBC,yBAAyB,EACzBC,mBAAmB,EACnBC,yBAAyB,QACpB,yBAAqB;AAC5B,SAASC,YAAY,EAAEC,sBAAsB,QAAQ,iCAAgC;AACrF,SAASC,UAAU,QAAQ,gBAAe;AAC1C,SAASC,UAAU,EAAEC,KAAK,EAAEC,KAAK,QAAQ,qBAAoB;AAC7D,SAASC,OAAO,QAAQ,QAAO;AAC/B,SAASC,kBAAkB,EAAEC,WAAW,QAAQ,4BAAwB;AACxE,SAASC,wBAAwB,QAAQ,2BAAuB;AAChE,SACEC,eAAe,EACfC,eAAe,QAEV,yBAAqB;AAoB5B;;;;;;;;;;;;;CAaC,GACD,SAASC,0BAA0BC,OAKlC;IACC,MAAM,EAAEC,KAAK,EAAEC,eAAe,EAAEC,OAAO,EAAE,GAAGH;IAC5C,MAAMI,YAAYjB;IAClB,MAAM,EAAEkB,IAAI,EAAE,GAAGjB,uBACf,IACEe,WAAWF,QACPT,MACEF,WAAWc,WAAW,QAAQH,OAAO5B,gBAAgBiC,aAAa,MAC/DZ,mBAAmBQ,kBACtBX,MAAM,QAER,MACN;QAACa;QAAWH;QAAOC;QAAiBC;KAAQ,EAC5C;QAAEI,SAAS;IAAM;IAEnB,OAAOd,QACL,IACE,CAACY,eAAAA,OAAQ,EAAE,EACRG,MAAM,CAAC,CAACC,QAAU,CAAC,CAACA,MAAMC,GAAG,IAAI,CAACD,MAAME,SAAS,EACjDC,IAAI,CAAC,CAACC,GAAGC;gBAAaD,UAAuBC;mBAA9BC,QAAOF,WAAAA,EAAEG,KAAK,YAAPH,WAAW,KAAKE,QAAOD,WAAAA,EAAEE,KAAK,YAAPF,WAAW;YAC7D;QAACT;KAAK;AAEV;AAEA,6DAA6D,GAC7D,SAASY,wBACPC,MAAyC;IAMzC,OAAO;QACLC,OAAO;QACP7B,YAAY;QACZ8B,MAAM7C,eAAe,YAAY;YAAE8C,QAAQ;QAAmB;QAC9DC,sBACE,wEACA,uEACA;QACFC,OACE,kEACA,qEACA,wDACA,GAAG5C,wBAAwB6C,cAAc,GAAG,yBAAyB,CAAC,GACtE;QACFN,QAAQxC;QACR+C,aAAahD;QACbiD,cAAcR;QACdS,eAAe;QACfC,iBACE,sEACA;QACFC,UAAU,CAACC,OAAS,CAACxD,sBAAsBwD;QAC3CC,gBAAgB,CAACC,OAAOC,QACtB,GAAGD,MAAMR,cAAc,GAAG,IAAI,EAAES,MAAMT,cAAc,GAAG,cAAc,CAAC,GACtE,qEACA;QACFU,cAAc,CAACC,UAAYnD,0BAA0BmD,SAASjB;QAC9DkB,QAAQ,CAACC,OAAOC,UACdrD,oBAAoBoD,OAAOC;QAC7BC,OAAO;QACPC,SAAS7D;QACT8D,WAAWjE;QACXkE,aAAa9D;QACb+D,aAAa5D;QACb6D,cAAc,CAACX,OAAOY,OAAOC,SAC3B5D,0BACE+C,OACAY,OACAC;QAEJC,YAAYlE;QACZmE,YAAYlE;QACZmE,iBAAiB;QACjBC,aAAa,IAAMtD,yBAAyBsB;QAC5CiC,kBAAkB;QAClBC,cAAc,CAACC;YACb,MAAMC,UAAU,AAACD,OAAoCE,gBAAgB;YACrE,OAAOD,wBACL,KAACjE;gBAAWmE,SAAQ;gBAAQC,OAAM;0BAC/B,GAAGH,QAAQ9B,cAAc,GAAG,KAAK,EAChC8B,YAAY,IAAI,YAAY,YAC7B,iCAAiC,CAAC;iBAEnC;QACN;IACF;AACF;AAEA,OAAO,SAASI,oBAAoBC,KAA+B;IACjE,MAAM,EAAEC,IAAI,EAAEC,OAAO,EAAEC,MAAM,EAAEC,GAAG,EAAE,GAAGJ;IACvC,2EAA2E;IAC3E,0EAA0E;IAC1E,yDAAyD;IACzD,MAAM,EAAE1D,KAAK,EAAE+D,WAAW9D,eAAe,EAAE,GAAGP,YAAY;QAAEmE;QAAQC;IAAI;IACxE,MAAM7C,SAASnB,0BAA0B;QACvCE;QACAC;QACAC,SAASyD;IACX;IACA,MAAMK,aAAaxE,QAAQ,IAAMwB,wBAAwBC,SAAS;QAACA;KAAO;IAC1E,qBACE,KAACpB;QACC8D,MAAMA;QACNC,SAASA;QACTC,QAAQA;QACRG,YAAYA;;AAGlB;AACAP,oBAAoBQ,WAAW,GAAG;AAElC;;;CAGC,GACD,OAAO,SAASC,oBAAoBR,KAInC;IACC,MAAM,EAAEG,MAAM,EAAEC,GAAG,EAAE,GAAGJ;IACxB,qBACE,KAAC9D;kBACE,CAAC+D,MAAMC,wBACN,KAACH;gBAAoBE,MAAMA;gBAAMC,SAASA;gBAASC,QAAQA;gBAAQC,KAAKA;;;AAIhF;AACAI,oBAAoBD,WAAW,GAAG;AAElC,eAAeR,oBAAmB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CrmOrgDoc } from '../hooks/use-crm-scope';
|
|
2
|
+
export interface ContactKnownByCardProps {
|
|
3
|
+
/** The document as read — the projection below is an allow-list over it. */
|
|
4
|
+
row: Record<string, unknown>;
|
|
5
|
+
contactId: string;
|
|
6
|
+
/** The org document, the only input that can resolve a declared consent group. */
|
|
7
|
+
org: CrmOrgDoc;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* KNOWN BY — the cross-site fact, on the organization-level record
|
|
11
|
+
* (AGL-2630).
|
|
12
|
+
*
|
|
13
|
+
* A contact document is shared by every site that has captured the person:
|
|
14
|
+
* one human who touched two of an org's sites is ONE row, which is the
|
|
15
|
+
* dedupe the shared address book exists for and what makes the billing unit
|
|
16
|
+
* — unique people per org — mean anything. Under a site that fact is
|
|
17
|
+
* invisible on purpose: a site's hub is one holder's view. This card is the
|
|
18
|
+
* one place it is shown, and it shows exactly what the old org-level
|
|
19
|
+
* address book showed and nothing more: which sites know the person, and
|
|
20
|
+
* the person's marketing consent FOR EACH of those sites — one verdict per
|
|
21
|
+
* capturing site, each naming the controller it was read for, because a
|
|
22
|
+
* basis is per (person, controller) and "consented" with nobody attached
|
|
23
|
+
* would be a different and false claim.
|
|
24
|
+
*
|
|
25
|
+
* Notes, tags, activity and commercial figures are each holder's own
|
|
26
|
+
* records and are not projected here: `orgContactRow` is an allow-list for
|
|
27
|
+
* that reason, and the card renders nothing it did not return. The rest of
|
|
28
|
+
* the record page reads through the person's PRIMARY holder; this card is
|
|
29
|
+
* how a reader learns which other sites hold a profile, and the link on
|
|
30
|
+
* each site is how they open it there.
|
|
31
|
+
*
|
|
32
|
+
* Rendered only beneath the org mount — under a site the hook answers
|
|
33
|
+
* `null` and so does the card.
|
|
34
|
+
*/
|
|
35
|
+
export declare function ContactKnownByCard(props: ContactKnownByCardProps): import("react").JSX.Element;
|
|
36
|
+
export declare namespace ContactKnownByCard {
|
|
37
|
+
var displayName: string;
|
|
38
|
+
}
|
|
39
|
+
export default ContactKnownByCard;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import { orgContactConsentLabel, orgContactRow, pluginDocsHelp } from "@aglyn/aglyn";
|
|
19
|
+
import { AppLink, CardDisplay } from "@aglyn/shared-ui-jsx";
|
|
20
|
+
import { Chip, Stack, Typography } from "@mui/material";
|
|
21
|
+
import { useMemo } from "react";
|
|
22
|
+
import { useCrmOrgMount } from "../hooks/use-crm-org-mount.js";
|
|
23
|
+
/**
|
|
24
|
+
* One consent verdict, rendered.
|
|
25
|
+
*
|
|
26
|
+
* The label always names the controller — `orgContactConsentLabel` is what
|
|
27
|
+
* guarantees that — and the color follows the basis rather than replacing
|
|
28
|
+
* it: a green chip with no name on it would be a bare "consented", which is
|
|
29
|
+
* the claim the per-brand model exists to stop anybody making.
|
|
30
|
+
*/ function ConsentChip(props) {
|
|
31
|
+
const { entry, siteName } = props;
|
|
32
|
+
return /*#__PURE__*/ _jsx(Chip, {
|
|
33
|
+
size: "small",
|
|
34
|
+
color: entry.basis === 'granted' ? 'success' : entry.basis === 'declined' ? 'error' : 'default',
|
|
35
|
+
variant: entry.basis === 'unrecorded' ? 'outlined' : 'filled',
|
|
36
|
+
label: orgContactConsentLabel(entry, siteName)
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
ConsentChip.displayName = 'ConsentChip';
|
|
40
|
+
/**
|
|
41
|
+
* KNOWN BY — the cross-site fact, on the organization-level record
|
|
42
|
+
* (AGL-2630).
|
|
43
|
+
*
|
|
44
|
+
* A contact document is shared by every site that has captured the person:
|
|
45
|
+
* one human who touched two of an org's sites is ONE row, which is the
|
|
46
|
+
* dedupe the shared address book exists for and what makes the billing unit
|
|
47
|
+
* — unique people per org — mean anything. Under a site that fact is
|
|
48
|
+
* invisible on purpose: a site's hub is one holder's view. This card is the
|
|
49
|
+
* one place it is shown, and it shows exactly what the old org-level
|
|
50
|
+
* address book showed and nothing more: which sites know the person, and
|
|
51
|
+
* the person's marketing consent FOR EACH of those sites — one verdict per
|
|
52
|
+
* capturing site, each naming the controller it was read for, because a
|
|
53
|
+
* basis is per (person, controller) and "consented" with nobody attached
|
|
54
|
+
* would be a different and false claim.
|
|
55
|
+
*
|
|
56
|
+
* Notes, tags, activity and commercial figures are each holder's own
|
|
57
|
+
* records and are not projected here: `orgContactRow` is an allow-list for
|
|
58
|
+
* that reason, and the card renders nothing it did not return. The rest of
|
|
59
|
+
* the record page reads through the person's PRIMARY holder; this card is
|
|
60
|
+
* how a reader learns which other sites hold a profile, and the link on
|
|
61
|
+
* each site is how they open it there.
|
|
62
|
+
*
|
|
63
|
+
* Rendered only beneath the org mount — under a site the hook answers
|
|
64
|
+
* `null` and so does the card.
|
|
65
|
+
*/ export function ContactKnownByCard(props) {
|
|
66
|
+
const { row, contactId, org } = props;
|
|
67
|
+
const mount = useCrmOrgMount();
|
|
68
|
+
const projected = useMemo(()=>orgContactRow(row, contactId, org != null ? org : null), [
|
|
69
|
+
row,
|
|
70
|
+
contactId,
|
|
71
|
+
org
|
|
72
|
+
]);
|
|
73
|
+
if (!mount) return null;
|
|
74
|
+
const { capturedByHostIds, consent } = projected;
|
|
75
|
+
return /*#__PURE__*/ _jsx(CardDisplay, {
|
|
76
|
+
header: 'Known by',
|
|
77
|
+
help: pluginDocsHelp('contacts', {
|
|
78
|
+
anchor: '#at-the-organization-level'
|
|
79
|
+
}),
|
|
80
|
+
contentGutterX: true,
|
|
81
|
+
contentGutterY: true,
|
|
82
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
83
|
+
spacing: 2,
|
|
84
|
+
children: [
|
|
85
|
+
capturedByHostIds.length ? /*#__PURE__*/ _jsx(Stack, {
|
|
86
|
+
spacing: 1.5,
|
|
87
|
+
children: capturedByHostIds.map((hostId)=>{
|
|
88
|
+
var _entry_groupName;
|
|
89
|
+
const entry = consent.find((verdict)=>verdict.hostId === hostId);
|
|
90
|
+
const href = mount.siteHubHref(hostId);
|
|
91
|
+
const name = mount.siteName(hostId);
|
|
92
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
93
|
+
direction: "row",
|
|
94
|
+
spacing: 1,
|
|
95
|
+
sx: {
|
|
96
|
+
alignItems: 'center',
|
|
97
|
+
flexWrap: 'wrap'
|
|
98
|
+
},
|
|
99
|
+
children: [
|
|
100
|
+
href ? /*#__PURE__*/ _jsx(AppLink, {
|
|
101
|
+
href: `${href}/contacts/${encodeURIComponent(contactId)}`,
|
|
102
|
+
underline: "hover",
|
|
103
|
+
children: name
|
|
104
|
+
}) : /*#__PURE__*/ _jsx(Typography, {
|
|
105
|
+
component: "span",
|
|
106
|
+
variant: "body2",
|
|
107
|
+
children: name
|
|
108
|
+
}),
|
|
109
|
+
entry ? /*#__PURE__*/ _jsx(ConsentChip, {
|
|
110
|
+
entry: entry,
|
|
111
|
+
siteName: name
|
|
112
|
+
}) : null,
|
|
113
|
+
(entry == null ? void 0 : entry.declared) ? /*#__PURE__*/ _jsx(Typography, {
|
|
114
|
+
variant: "caption",
|
|
115
|
+
color: "text.secondary",
|
|
116
|
+
children: `Consent given to ${(_entry_groupName = entry.groupName) != null ? _entry_groupName : entry.groupId}, which ${name} is part of.`
|
|
117
|
+
}) : null
|
|
118
|
+
]
|
|
119
|
+
}, hostId);
|
|
120
|
+
})
|
|
121
|
+
}) : /*
|
|
122
|
+
* Unattributed, not unknown. A row written before the attribution
|
|
123
|
+
* existed names no site, and reading that as "every site" would
|
|
124
|
+
* put a person in front of businesses that never met them.
|
|
125
|
+
*/ /*#__PURE__*/ _jsx(Typography, {
|
|
126
|
+
variant: "body2",
|
|
127
|
+
color: "text.secondary",
|
|
128
|
+
children: 'No site recorded'
|
|
129
|
+
}),
|
|
130
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
131
|
+
variant: "caption",
|
|
132
|
+
color: "text.secondary",
|
|
133
|
+
children: 'The profile, notes, tags and timeline on this page are the first ' + "capturing site's. Open the person in another site to see what " + 'it holds.'
|
|
134
|
+
})
|
|
135
|
+
]
|
|
136
|
+
})
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
ContactKnownByCard.displayName = 'ContactKnownByCard';
|
|
140
|
+
export default ContactKnownByCard;
|
|
141
|
+
|
|
142
|
+
//# sourceMappingURL=contact-known-by-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/contact-known-by-card.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport {\n orgContactConsentLabel,\n orgContactRow,\n pluginDocsHelp,\n type OrgContactHostConsent,\n} from '@aglyn/aglyn'\nimport { AppLink, CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { Chip, Stack, Typography } from '@mui/material'\nimport { useMemo } from 'react'\nimport { useCrmOrgMount } from '../hooks/use-crm-org-mount'\nimport type { CrmOrgDoc } from '../hooks/use-crm-scope'\n\nexport interface ContactKnownByCardProps {\n /** The document as read — the projection below is an allow-list over it. */\n row: Record<string, unknown>\n contactId: string\n /** The org document, the only input that can resolve a declared consent group. */\n org: CrmOrgDoc\n}\n\n/**\n * One consent verdict, rendered.\n *\n * The label always names the controller — `orgContactConsentLabel` is what\n * guarantees that — and the color follows the basis rather than replacing\n * it: a green chip with no name on it would be a bare \"consented\", which is\n * the claim the per-brand model exists to stop anybody making.\n */\nfunction ConsentChip(props: { entry: OrgContactHostConsent; siteName: string }) {\n const { entry, siteName } = props\n return (\n <Chip\n size=\"small\"\n color={\n entry.basis === 'granted'\n ? 'success'\n : entry.basis === 'declined'\n ? 'error'\n : 'default'\n }\n variant={entry.basis === 'unrecorded' ? 'outlined' : 'filled'}\n label={orgContactConsentLabel(entry, siteName)}\n />\n )\n}\nConsentChip.displayName = 'ConsentChip'\n\n/**\n * KNOWN BY — the cross-site fact, on the organization-level record\n * (AGL-2630).\n *\n * A contact document is shared by every site that has captured the person:\n * one human who touched two of an org's sites is ONE row, which is the\n * dedupe the shared address book exists for and what makes the billing unit\n * — unique people per org — mean anything. Under a site that fact is\n * invisible on purpose: a site's hub is one holder's view. This card is the\n * one place it is shown, and it shows exactly what the old org-level\n * address book showed and nothing more: which sites know the person, and\n * the person's marketing consent FOR EACH of those sites — one verdict per\n * capturing site, each naming the controller it was read for, because a\n * basis is per (person, controller) and \"consented\" with nobody attached\n * would be a different and false claim.\n *\n * Notes, tags, activity and commercial figures are each holder's own\n * records and are not projected here: `orgContactRow` is an allow-list for\n * that reason, and the card renders nothing it did not return. The rest of\n * the record page reads through the person's PRIMARY holder; this card is\n * how a reader learns which other sites hold a profile, and the link on\n * each site is how they open it there.\n *\n * Rendered only beneath the org mount — under a site the hook answers\n * `null` and so does the card.\n */\nexport function ContactKnownByCard(props: ContactKnownByCardProps) {\n const { row, contactId, org } = props\n const mount = useCrmOrgMount()\n const projected = useMemo(\n () => orgContactRow(row, contactId, (org ?? null) as Record<string, unknown> | null),\n [row, contactId, org],\n )\n if (!mount) return null\n const { capturedByHostIds, consent } = projected\n return (\n <CardDisplay\n header={'Known by'}\n help={pluginDocsHelp('contacts', { anchor: '#at-the-organization-level' })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n {capturedByHostIds.length ? (\n <Stack spacing={1.5}>\n {capturedByHostIds.map((hostId) => {\n const entry = consent.find((verdict) => verdict.hostId === hostId)\n const href = mount.siteHubHref(hostId)\n const name = mount.siteName(hostId)\n return (\n <Stack\n key={hostId}\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', flexWrap: 'wrap' }}\n >\n {/*\n A site whose subdomain has not resolved must still be\n NAMED — the relationship is real, and hiding it would\n understate who knows this person — but not linked,\n because the route would not exist; a plain span, not an\n anchor to nowhere. Two elements are safe here: the card\n mounts only once the record's listener has answered, so\n there is no server render for a client render to disagree\n with.\n */}\n {href ? (\n <AppLink\n href={`${href}/contacts/${encodeURIComponent(contactId)}`}\n underline=\"hover\"\n >\n {name}\n </AppLink>\n ) : (\n <Typography component=\"span\" variant=\"body2\">\n {name}\n </Typography>\n )}\n {entry ? <ConsentChip entry={entry} siteName={name} /> : null}\n {entry?.declared ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`Consent given to ${entry.groupName ?? entry.groupId}, which ${name} is part of.`}\n </Typography>\n ) : null}\n </Stack>\n )\n })}\n </Stack>\n ) : (\n /*\n * Unattributed, not unknown. A row written before the attribution\n * existed names no site, and reading that as \"every site\" would\n * put a person in front of businesses that never met them.\n */\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'No site recorded'}\n </Typography>\n )}\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'The profile, notes, tags and timeline on this page are the first ' +\n \"capturing site's. Open the person in another site to see what \" +\n 'it holds.'}\n </Typography>\n </Stack>\n </CardDisplay>\n )\n}\nContactKnownByCard.displayName = 'ContactKnownByCard'\n\nexport default ContactKnownByCard\n"],"names":["orgContactConsentLabel","orgContactRow","pluginDocsHelp","AppLink","CardDisplay","Chip","Stack","Typography","useMemo","useCrmOrgMount","ConsentChip","props","entry","siteName","size","color","basis","variant","label","displayName","ContactKnownByCard","row","contactId","org","mount","projected","capturedByHostIds","consent","header","help","anchor","contentGutterX","contentGutterY","spacing","length","map","hostId","find","verdict","href","siteHubHref","name","direction","sx","alignItems","flexWrap","encodeURIComponent","underline","component","declared","groupName","groupId"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SACEA,sBAAsB,EACtBC,aAAa,EACbC,cAAc,QAET,eAAc;AACrB,SAASC,OAAO,EAAEC,WAAW,QAAQ,uBAAsB;AAC3D,SAASC,IAAI,EAAEC,KAAK,EAAEC,UAAU,QAAQ,gBAAe;AACvD,SAASC,OAAO,QAAQ,QAAO;AAC/B,SAASC,cAAc,QAAQ,gCAA4B;AAW3D;;;;;;;CAOC,GACD,SAASC,YAAYC,KAAyD;IAC5E,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGF;IAC5B,qBACE,KAACN;QACCS,MAAK;QACLC,OACEH,MAAMI,KAAK,KAAK,YACZ,YACAJ,MAAMI,KAAK,KAAK,aACd,UACA;QAERC,SAASL,MAAMI,KAAK,KAAK,eAAe,aAAa;QACrDE,OAAOlB,uBAAuBY,OAAOC;;AAG3C;AACAH,YAAYS,WAAW,GAAG;AAE1B;;;;;;;;;;;;;;;;;;;;;;;;;CAyBC,GACD,OAAO,SAASC,mBAAmBT,KAA8B;IAC/D,MAAM,EAAEU,GAAG,EAAEC,SAAS,EAAEC,GAAG,EAAE,GAAGZ;IAChC,MAAMa,QAAQf;IACd,MAAMgB,YAAYjB,QAChB,IAAMP,cAAcoB,KAAKC,WAAYC,cAAAA,MAAO,OAC5C;QAACF;QAAKC;QAAWC;KAAI;IAEvB,IAAI,CAACC,OAAO,OAAO;IACnB,MAAM,EAAEE,iBAAiB,EAAEC,OAAO,EAAE,GAAGF;IACvC,qBACE,KAACrB;QACCwB,QAAQ;QACRC,MAAM3B,eAAe,YAAY;YAAE4B,QAAQ;QAA6B;QACxEC,cAAc;QACdC,cAAc;kBAEd,cAAA,MAAC1B;YAAM2B,SAAS;;gBACbP,kBAAkBQ,MAAM,iBACvB,KAAC5B;oBAAM2B,SAAS;8BACbP,kBAAkBS,GAAG,CAAC,CAACC;4BAoCOxB;wBAnC7B,MAAMA,QAAQe,QAAQU,IAAI,CAAC,CAACC,UAAYA,QAAQF,MAAM,KAAKA;wBAC3D,MAAMG,OAAOf,MAAMgB,WAAW,CAACJ;wBAC/B,MAAMK,OAAOjB,MAAMX,QAAQ,CAACuB;wBAC5B,qBACE,MAAC9B;4BAECoC,WAAU;4BACVT,SAAS;4BACTU,IAAI;gCAAEC,YAAY;gCAAUC,UAAU;4BAAO;;gCAY5CN,qBACC,KAACpC;oCACCoC,MAAM,GAAGA,KAAK,UAAU,EAAEO,mBAAmBxB,YAAY;oCACzDyB,WAAU;8CAETN;mDAGH,KAAClC;oCAAWyC,WAAU;oCAAO/B,SAAQ;8CAClCwB;;gCAGJ7B,sBAAQ,KAACF;oCAAYE,OAAOA;oCAAOC,UAAU4B;qCAAW;gCACxD7B,CAAAA,yBAAAA,MAAOqC,QAAQ,kBACd,KAAC1C;oCAAWU,SAAQ;oCAAUF,OAAM;8CACjC,CAAC,iBAAiB,GAAEH,mBAAAA,MAAMsC,SAAS,YAAftC,mBAAmBA,MAAMuC,OAAO,CAAC,QAAQ,EAAEV,KAAK,YAAY,CAAC;qCAElF;;2BAhCCL;oBAmCX;qBAGF;;;;WAIC,iBACD,KAAC7B;oBAAWU,SAAQ;oBAAQF,OAAM;8BAC/B;;8BAGL,KAACR;oBAAWU,SAAQ;oBAAUF,OAAM;8BACjC,sEACC,mEACA;;;;;AAKZ;AACAK,mBAAmBD,WAAW,GAAG;AAEjC,eAAeC,mBAAkB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { GridColDef } from '@mui/x-data-grid';
|
|
2
|
+
/**
|
|
3
|
+
* The filterable fields that get a column. The rest of
|
|
4
|
+
* `CONTACT_LIST_FILTER_FIELDS` still reaches the filter panel, hidden.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* The declared filter fields that ARE table columns, so the hidden
|
|
8
|
+
* filter-only columns are built for the others alone. Owner and Stage
|
|
9
|
+
* joined it when the grammar learned them (AGL-2617): each is a shown
|
|
10
|
+
* column already, and a second, hidden one under the same field would be
|
|
11
|
+
* a duplicate the grid refuses.
|
|
12
|
+
*/
|
|
13
|
+
export declare const CONTACT_FILTER_COLUMNS: string[];
|
|
14
|
+
/**
|
|
15
|
+
* The columns that ship HIDDEN, for the grid's visibility model (AGL-2616).
|
|
16
|
+
*
|
|
17
|
+
* "Last engaged" is a fact most lists do not need on screen and every list
|
|
18
|
+
* can turn on from the column menu; shipping it visible would widen a
|
|
19
|
+
* table that already carries seven columns for a figure only a marketing
|
|
20
|
+
* reader scans.
|
|
21
|
+
*/
|
|
22
|
+
export declare const CONTACT_OPTIONAL_COLUMNS: string[];
|
|
23
|
+
export interface ContactListColumnOptions {
|
|
24
|
+
/** The owner's name for a uid — the roster's, or the uid itself. */
|
|
25
|
+
memberName: (uid: string) => string;
|
|
26
|
+
/**
|
|
27
|
+
* How a site reads, by document id — handed in at the ORGANIZATION level
|
|
28
|
+
* only (AGL-2630), where it turns on the "Known by" column: the sites
|
|
29
|
+
* that have captured each person. Absent under a site, where every row
|
|
30
|
+
* is known by the site and the column would say so on every line.
|
|
31
|
+
*/
|
|
32
|
+
siteName?: (hostId: string) => string;
|
|
33
|
+
/**
|
|
34
|
+
* One clock for every row of one paint, so two contacts engaged a second
|
|
35
|
+
* apart cannot read "just now" and "1 min ago". Defaults to the paint's
|
|
36
|
+
* own `Date.now()`.
|
|
37
|
+
*/
|
|
38
|
+
nowMs?: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The contacts list's columns (AGL-2596), in their own module so the list
|
|
42
|
+
* file stays about the QUERY and the toolbar while other surfaces — a bulk
|
|
43
|
+
* bar, an import — grow beside it.
|
|
44
|
+
*
|
|
45
|
+
* Owner and Stage read off the flattened row, which is already this
|
|
46
|
+
* holder's facet (`contactRecordFromDoc`), so neither column can show
|
|
47
|
+
* another holder's assignment. Both are `filterable: false` on purpose: the
|
|
48
|
+
* grid's filter panel translates to a Firestore query over the top-level
|
|
49
|
+
* fields in `CONTACT_LIST_FILTER_FIELDS`, and a facet path is not one of
|
|
50
|
+
* them. The toolbar's stage select and "Assigned to me" switch narrow the
|
|
51
|
+
* loaded window instead, and say so.
|
|
52
|
+
*/
|
|
53
|
+
export declare function contactListColumns(options: ContactListColumnOptions): GridColDef[];
|