@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,14 @@
|
|
|
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
|
+
*/ /**
|
|
8
|
+
* The persisted plugin id (AGL-2595). It was `contacts` while the surface was
|
|
9
|
+
* one list; the stored lists were rewritten and the plugin manager's alias for
|
|
10
|
+
* the old value was retired once that backfill reported nothing left
|
|
11
|
+
* (AGL-2614), so `contacts` now reads as an unknown id like any other.
|
|
12
|
+
*/ export const BUNDLE_ID = 'crm';
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=bundle-common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/constants/bundle-common.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 */\n\n/**\n * The persisted plugin id (AGL-2595). It was `contacts` while the surface was\n * one list; the stored lists were rewritten and the plugin manager's alias for\n * the old value was retired once that backfill reported nothing left\n * (AGL-2614), so `contacts` now reads as an unknown id like any other.\n */\nexport const BUNDLE_ID = 'crm'\n"],"names":["BUNDLE_ID"],"mappings":"AAAA;;;;;;CAMC,GAED;;;;;CAKC,GACD,OAAO,MAAMA,YAAY,MAAK"}
|
|
@@ -0,0 +1,18 @@
|
|
|
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 { ListFilterField } from '@aglyn/shared-ui-jsx/const/list-filter';
|
|
18
|
+
export declare const COMPANY_LIST_FILTER_FIELDS: readonly ListFilterField[];
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
* Companies (`orgs/{orgId}/companies`, read scoped to a host).
|
|
18
|
+
*
|
|
19
|
+
* Every predicate here is appended to the listener's `visibleTo
|
|
20
|
+
* array-contains-any`, which is the constraint that decides what a company
|
|
21
|
+
* filter may be. Firestore carries ONE array clause per query, so the
|
|
22
|
+
* word-prefix `contains` search the contact list declares through
|
|
23
|
+
* `nameTokens` cannot run beside the scope predicate — a query with both is
|
|
24
|
+
* refused outright, not served slowly. The name is therefore offered as a
|
|
25
|
+
* PREFIX range and an exact match over `nameLower`, which the
|
|
26
|
+
* `(visibleTo CONTAINS, nameLower ASC)` index serves with the scope in
|
|
27
|
+
* place. No `tokensPath`, deliberately.
|
|
28
|
+
*
|
|
29
|
+
* `ownerUid` is declared so the translator can answer it; the column itself
|
|
30
|
+
* renders a person's name from the roster and offers a single-select
|
|
31
|
+
* operator in the panel, which the section maps onto this field's `equals`.
|
|
32
|
+
* Served by `(visibleTo CONTAINS, ownerUid ASC)`.
|
|
33
|
+
*/ export const COMPANY_LIST_FILTER_FIELDS = [
|
|
34
|
+
{
|
|
35
|
+
column: 'name',
|
|
36
|
+
kind: 'text',
|
|
37
|
+
path: 'name',
|
|
38
|
+
lowerPath: 'nameLower',
|
|
39
|
+
presence: 'always'
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
column: 'ownerUid',
|
|
43
|
+
kind: 'exact',
|
|
44
|
+
path: 'ownerUid',
|
|
45
|
+
operators: [
|
|
46
|
+
'equals'
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=company-filters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/constants/company-filters.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ListFilterField } from '@aglyn/shared-ui-jsx/const/list-filter'\n\n/*\n * Companies (`orgs/{orgId}/companies`, read scoped to a host).\n *\n * Every predicate here is appended to the listener's `visibleTo\n * array-contains-any`, which is the constraint that decides what a company\n * filter may be. Firestore carries ONE array clause per query, so the\n * word-prefix `contains` search the contact list declares through\n * `nameTokens` cannot run beside the scope predicate — a query with both is\n * refused outright, not served slowly. The name is therefore offered as a\n * PREFIX range and an exact match over `nameLower`, which the\n * `(visibleTo CONTAINS, nameLower ASC)` index serves with the scope in\n * place. No `tokensPath`, deliberately.\n *\n * `ownerUid` is declared so the translator can answer it; the column itself\n * renders a person's name from the roster and offers a single-select\n * operator in the panel, which the section maps onto this field's `equals`.\n * Served by `(visibleTo CONTAINS, ownerUid ASC)`.\n */\nexport const COMPANY_LIST_FILTER_FIELDS: readonly ListFilterField[] = [\n {\n column: 'name',\n kind: 'text',\n path: 'name',\n lowerPath: 'nameLower',\n presence: 'always',\n },\n {\n column: 'ownerUid',\n kind: 'exact',\n path: 'ownerUid',\n operators: ['equals'],\n },\n]\n"],"names":["COMPANY_LIST_FILTER_FIELDS","column","kind","path","lowerPath","presence","operators"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAID;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,MAAMA,6BAAyD;IACpE;QACEC,QAAQ;QACRC,MAAM;QACNC,MAAM;QACNC,WAAW;QACXC,UAAU;IACZ;IACA;QACEJ,QAAQ;QACRC,MAAM;QACNC,MAAM;QACNG,WAAW;YAAC;SAAS;IACvB;CACD,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
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 ContactFieldDefinition } from '@aglyn/aglyn';
|
|
18
|
+
import type { ListFilterField } from '@aglyn/shared-ui-jsx/const/list-filter';
|
|
19
|
+
export declare const CONTACT_LIST_FILTER_FIELDS: readonly ListFilterField[];
|
|
20
|
+
/**
|
|
21
|
+
* One filter field per active custom contact field (AGL-2617).
|
|
22
|
+
*
|
|
23
|
+
* A custom value lives under the facet's `custom` map, so every one is
|
|
24
|
+
* window-only for the reason the facet fields above are, and its column is
|
|
25
|
+
* the one the table shows it under — `crmContactCustomColumn(key)` — so a
|
|
26
|
+
* clause and a column agree on the name and a saved view's columns and
|
|
27
|
+
* filters name the same thing. The kind follows the definition's type, and
|
|
28
|
+
* `nullable` is how a cleared value is stored, which is what makes both
|
|
29
|
+
* empty operators honest here.
|
|
30
|
+
*/
|
|
31
|
+
export declare function contactCustomFilterFields(definitions: readonly Pick<ContactFieldDefinition, 'key' | 'type' | 'retiredAt'>[]): ListFilterField[];
|
|
32
|
+
/** The custom fields' headers, keyed by the column each filters as. */
|
|
33
|
+
export declare function contactCustomFilterHeaders(definitions: readonly Pick<ContactFieldDefinition, 'key' | 'label'>[]): Record<string, string>;
|
|
34
|
+
/**
|
|
35
|
+
* How every filterable contact field reads — on a chip, in the add-filter
|
|
36
|
+
* picker, and as the header of a filter-only hidden column.
|
|
37
|
+
*/
|
|
38
|
+
export declare const CONTACT_LIST_FILTER_HEADERS: Readonly<Record<string, string>>;
|
|
@@ -0,0 +1,294 @@
|
|
|
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_CONTACT_VIEW_FIELDS, crmContactCustomColumn } from "@aglyn/aglyn";
|
|
17
|
+
/*
|
|
18
|
+
* Contacts (`orgs/{orgId}/contacts`, read scoped to a host).
|
|
19
|
+
*
|
|
20
|
+
* The card's listener is `limit(1000)` and stays that way — nobody needs
|
|
21
|
+
* forty thousand rows streamed into a table. What that cap must NOT do is
|
|
22
|
+
* decide what a search can find, and it did: an org with 40,000 contacts
|
|
23
|
+
* searched 1,000 of them and answered "no contacts match" for the rest. The
|
|
24
|
+
* head-count already learned this lesson (AGL-1706, a server aggregate); the
|
|
25
|
+
* search is the same mistake one field over.
|
|
26
|
+
*
|
|
27
|
+
* ⛔ `marketingConsent`, `ordersCount` and `ltvCents` are written only when
|
|
28
|
+
* they apply, so a `false`/`0` filter would return nothing rather than
|
|
29
|
+
* everyone else. `isNotEmpty` is exact on them and is what the menu offers.
|
|
30
|
+
*/ export const CONTACT_LIST_FILTER_FIELDS = [
|
|
31
|
+
{
|
|
32
|
+
column: 'name',
|
|
33
|
+
kind: 'text',
|
|
34
|
+
path: 'name',
|
|
35
|
+
lowerPath: 'nameLower',
|
|
36
|
+
tokensPath: 'nameTokens',
|
|
37
|
+
reversedPath: 'nameReversed'
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
// `normalizeContactEmail` lower-cases before every write, so the stored
|
|
41
|
+
// value IS its own normalized key.
|
|
42
|
+
column: 'email',
|
|
43
|
+
kind: 'text',
|
|
44
|
+
path: 'email',
|
|
45
|
+
lowerPath: 'email',
|
|
46
|
+
presence: 'always'
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
/*
|
|
50
|
+
* Already an array of lower-cased tags, so `contains` is a plain
|
|
51
|
+
* `array-contains` — the one place the word-level caveat does not apply,
|
|
52
|
+
* because a tag is matched whole rather than by word prefix.
|
|
53
|
+
*/ column: 'tags',
|
|
54
|
+
kind: 'text',
|
|
55
|
+
path: 'tags',
|
|
56
|
+
tokensPath: 'tags',
|
|
57
|
+
// Ordered by the timestamp the list already sorts on, not by the tag
|
|
58
|
+
// array — `orderBy` on the same field an `array-contains` matches is a
|
|
59
|
+
// composite index nobody wants to explain.
|
|
60
|
+
containsOrderBy: 'updatedAt',
|
|
61
|
+
// `isAnyOf` is a saved segment's "any of these tags" (AGL-2617). The
|
|
62
|
+
// query cannot serve it — `array-contains-any` is the scope clause's
|
|
63
|
+
// — so the translator refuses it and the list matches it over the
|
|
64
|
+
// window, which the caption says.
|
|
65
|
+
operators: [
|
|
66
|
+
'contains',
|
|
67
|
+
'isAnyOf',
|
|
68
|
+
'isNotEmpty'
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
/*
|
|
73
|
+
* The forms a person came in through — the top-level `formIds` mirror
|
|
74
|
+
* of the interactions' `formId` (AGL-2612), matched whole and as typed
|
|
75
|
+
* because a form id is minted with mixed case. The form's own page links
|
|
76
|
+
* here with its id; nobody types one. Ordered by the list's own
|
|
77
|
+
* timestamp for the reason `tags` is, served by the
|
|
78
|
+
* `(formIds CONTAINS, updatedAt DESC)` index.
|
|
79
|
+
*
|
|
80
|
+
* ⚠️ An `array-contains` on the mirror cannot share a query with the
|
|
81
|
+
* `visibleTo` scope clause, so the list drops that clause for this one
|
|
82
|
+
* filter and the rules admit the read to an org-wide member only — the
|
|
83
|
+
* caveat the company contacts card states, stated again on the list.
|
|
84
|
+
*/ column: 'formIds',
|
|
85
|
+
kind: 'text',
|
|
86
|
+
path: 'formIds',
|
|
87
|
+
tokensPath: 'formIds',
|
|
88
|
+
verbatimTokens: true,
|
|
89
|
+
containsOrderBy: 'updatedAt',
|
|
90
|
+
operators: [
|
|
91
|
+
'contains'
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
column: 'hostId',
|
|
96
|
+
kind: 'exact',
|
|
97
|
+
path: 'hostId',
|
|
98
|
+
presence: 'always'
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
column: 'ordersCount',
|
|
102
|
+
kind: 'number',
|
|
103
|
+
path: 'ordersCount'
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
column: 'ltvCents',
|
|
107
|
+
kind: 'number',
|
|
108
|
+
path: 'ltvCents'
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
column: 'createdAt',
|
|
112
|
+
kind: 'date',
|
|
113
|
+
path: 'createdAt',
|
|
114
|
+
presence: 'always'
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
column: 'updatedAt',
|
|
118
|
+
kind: 'date',
|
|
119
|
+
path: 'updatedAt',
|
|
120
|
+
presence: 'always'
|
|
121
|
+
},
|
|
122
|
+
/*
|
|
123
|
+
* When the earliest open task is due (AGL-2661) — window-only, because
|
|
124
|
+
* the value is on the SHARED row but a record written before the field
|
|
125
|
+
* existed has none, and Firestore cannot query for absence. `nullable`
|
|
126
|
+
* is honest: the writer stores `null` for nothing scheduled, and the
|
|
127
|
+
* matcher reads absent the same way, so "is empty" is the "No next
|
|
128
|
+
* activity" filter over the loaded window.
|
|
129
|
+
*/ {
|
|
130
|
+
column: 'nextTaskAtMs',
|
|
131
|
+
kind: 'date',
|
|
132
|
+
path: 'nextTaskAtMs',
|
|
133
|
+
windowOnly: true,
|
|
134
|
+
presence: 'nullable'
|
|
135
|
+
},
|
|
136
|
+
/*
|
|
137
|
+
* THE FACET FIELDS (AGL-2617) — window-only, every one of them.
|
|
138
|
+
*
|
|
139
|
+
* An owner, a stage, a company and the capture sources live on the
|
|
140
|
+
* viewing group's facet of the shared contact row, and a facet path is
|
|
141
|
+
* per group: a `where` on it would need an index per group, and the
|
|
142
|
+
* translator would send a scoped member a query the rules deny. So these
|
|
143
|
+
* are declared for the menu and for a saved view, matched over the loaded
|
|
144
|
+
* window against the flattened row (`ContactRecord` carries each at the
|
|
145
|
+
* top), and never put on a query — `windowOnly` is what holds that line.
|
|
146
|
+
* The paths are the ROW'S, which is what the matcher reads.
|
|
147
|
+
*
|
|
148
|
+
* The values are picked, not typed — a uid from the roster, a stage from
|
|
149
|
+
* the fixed list, a source from its labels, a company from the picker —
|
|
150
|
+
* so `equals` and `isAnyOf` are what they offer; the section supplies
|
|
151
|
+
* the choices. The column names are the contract `CRM_CONTACT_VIEW_FIELDS`
|
|
152
|
+
* states, because the dynamic-list translator reads a view by them.
|
|
153
|
+
*/ {
|
|
154
|
+
column: CRM_CONTACT_VIEW_FIELDS.owner,
|
|
155
|
+
kind: 'exact',
|
|
156
|
+
path: 'ownerUid',
|
|
157
|
+
windowOnly: true,
|
|
158
|
+
operators: [
|
|
159
|
+
'equals',
|
|
160
|
+
'isAnyOf',
|
|
161
|
+
'isNotEmpty'
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
column: CRM_CONTACT_VIEW_FIELDS.stage,
|
|
166
|
+
kind: 'exact',
|
|
167
|
+
path: 'lifecycleStage',
|
|
168
|
+
windowOnly: true,
|
|
169
|
+
operators: [
|
|
170
|
+
'equals',
|
|
171
|
+
'isAnyOf',
|
|
172
|
+
'isNotEmpty'
|
|
173
|
+
]
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
// The `sources` presence map, matched on its keys — see `keysOf`.
|
|
177
|
+
column: CRM_CONTACT_VIEW_FIELDS.source,
|
|
178
|
+
kind: 'exact',
|
|
179
|
+
path: 'sources',
|
|
180
|
+
keysOf: true,
|
|
181
|
+
windowOnly: true,
|
|
182
|
+
operators: [
|
|
183
|
+
'equals',
|
|
184
|
+
'isAnyOf'
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
column: CRM_CONTACT_VIEW_FIELDS.company,
|
|
189
|
+
kind: 'exact',
|
|
190
|
+
path: 'companyId',
|
|
191
|
+
windowOnly: true,
|
|
192
|
+
operators: [
|
|
193
|
+
'equals',
|
|
194
|
+
'isNotEmpty'
|
|
195
|
+
]
|
|
196
|
+
}
|
|
197
|
+
];
|
|
198
|
+
/**
|
|
199
|
+
* One filter field per active custom contact field (AGL-2617).
|
|
200
|
+
*
|
|
201
|
+
* A custom value lives under the facet's `custom` map, so every one is
|
|
202
|
+
* window-only for the reason the facet fields above are, and its column is
|
|
203
|
+
* the one the table shows it under — `crmContactCustomColumn(key)` — so a
|
|
204
|
+
* clause and a column agree on the name and a saved view's columns and
|
|
205
|
+
* filters name the same thing. The kind follows the definition's type, and
|
|
206
|
+
* `nullable` is how a cleared value is stored, which is what makes both
|
|
207
|
+
* empty operators honest here.
|
|
208
|
+
*/ export function contactCustomFilterFields(definitions) {
|
|
209
|
+
return definitions.filter((definition)=>!definition.retiredAt).map((definition)=>{
|
|
210
|
+
const column = crmContactCustomColumn(definition.key);
|
|
211
|
+
const path = `custom.${definition.key}`;
|
|
212
|
+
switch(definition.type){
|
|
213
|
+
case 'number':
|
|
214
|
+
return {
|
|
215
|
+
column,
|
|
216
|
+
kind: 'number',
|
|
217
|
+
path,
|
|
218
|
+
windowOnly: true,
|
|
219
|
+
presence: 'nullable'
|
|
220
|
+
};
|
|
221
|
+
case 'date':
|
|
222
|
+
return {
|
|
223
|
+
column,
|
|
224
|
+
kind: 'date',
|
|
225
|
+
path,
|
|
226
|
+
windowOnly: true,
|
|
227
|
+
presence: 'nullable'
|
|
228
|
+
};
|
|
229
|
+
case 'checkbox':
|
|
230
|
+
return {
|
|
231
|
+
column,
|
|
232
|
+
kind: 'boolean',
|
|
233
|
+
path,
|
|
234
|
+
windowOnly: true
|
|
235
|
+
};
|
|
236
|
+
case 'select':
|
|
237
|
+
return {
|
|
238
|
+
column,
|
|
239
|
+
kind: 'exact',
|
|
240
|
+
path,
|
|
241
|
+
windowOnly: true,
|
|
242
|
+
presence: 'nullable',
|
|
243
|
+
operators: [
|
|
244
|
+
'equals',
|
|
245
|
+
'isAnyOf',
|
|
246
|
+
'isEmpty',
|
|
247
|
+
'isNotEmpty'
|
|
248
|
+
]
|
|
249
|
+
};
|
|
250
|
+
default:
|
|
251
|
+
return {
|
|
252
|
+
column,
|
|
253
|
+
kind: 'text',
|
|
254
|
+
path,
|
|
255
|
+
windowOnly: true,
|
|
256
|
+
presence: 'nullable',
|
|
257
|
+
operators: [
|
|
258
|
+
'contains',
|
|
259
|
+
'equals',
|
|
260
|
+
'startsWith',
|
|
261
|
+
'isEmpty',
|
|
262
|
+
'isNotEmpty'
|
|
263
|
+
]
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/** The custom fields' headers, keyed by the column each filters as. */ export function contactCustomFilterHeaders(definitions) {
|
|
269
|
+
return Object.fromEntries(definitions.map((definition)=>[
|
|
270
|
+
crmContactCustomColumn(definition.key),
|
|
271
|
+
definition.label || definition.key
|
|
272
|
+
]));
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* How every filterable contact field reads — on a chip, in the add-filter
|
|
276
|
+
* picker, and as the header of a filter-only hidden column.
|
|
277
|
+
*/ export const CONTACT_LIST_FILTER_HEADERS = {
|
|
278
|
+
name: 'Contact',
|
|
279
|
+
email: 'Email',
|
|
280
|
+
tags: 'Tags',
|
|
281
|
+
formIds: 'Form ID',
|
|
282
|
+
hostId: 'Site ID',
|
|
283
|
+
ordersCount: 'Orders',
|
|
284
|
+
ltvCents: 'Lifetime value (cents)',
|
|
285
|
+
createdAt: 'Created',
|
|
286
|
+
updatedAt: 'Updated',
|
|
287
|
+
nextTaskAtMs: 'Next activity',
|
|
288
|
+
[CRM_CONTACT_VIEW_FIELDS.owner]: 'Owner',
|
|
289
|
+
[CRM_CONTACT_VIEW_FIELDS.stage]: 'Stage',
|
|
290
|
+
[CRM_CONTACT_VIEW_FIELDS.source]: 'Source',
|
|
291
|
+
[CRM_CONTACT_VIEW_FIELDS.company]: 'Company'
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
//# sourceMappingURL=contact-filters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/constants/contact-filters.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 {\n type ContactFieldDefinition,\n CRM_CONTACT_VIEW_FIELDS,\n crmContactCustomColumn,\n} from '@aglyn/aglyn'\nimport type { ListFilterField } from '@aglyn/shared-ui-jsx/const/list-filter'\n\n/*\n * Contacts (`orgs/{orgId}/contacts`, read scoped to a host).\n *\n * The card's listener is `limit(1000)` and stays that way — nobody needs\n * forty thousand rows streamed into a table. What that cap must NOT do is\n * decide what a search can find, and it did: an org with 40,000 contacts\n * searched 1,000 of them and answered \"no contacts match\" for the rest. The\n * head-count already learned this lesson (AGL-1706, a server aggregate); the\n * search is the same mistake one field over.\n *\n * ⛔ `marketingConsent`, `ordersCount` and `ltvCents` are written only when\n * they apply, so a `false`/`0` filter would return nothing rather than\n * everyone else. `isNotEmpty` is exact on them and is what the menu offers.\n */\nexport const CONTACT_LIST_FILTER_FIELDS: readonly ListFilterField[] = [\n {\n column: 'name',\n kind: 'text',\n path: 'name',\n lowerPath: 'nameLower',\n tokensPath: 'nameTokens',\n reversedPath: 'nameReversed',\n },\n {\n // `normalizeContactEmail` lower-cases before every write, so the stored\n // value IS its own normalized key.\n column: 'email',\n kind: 'text',\n path: 'email',\n lowerPath: 'email',\n presence: 'always',\n },\n {\n /*\n * Already an array of lower-cased tags, so `contains` is a plain\n * `array-contains` — the one place the word-level caveat does not apply,\n * because a tag is matched whole rather than by word prefix.\n */\n column: 'tags',\n kind: 'text',\n path: 'tags',\n tokensPath: 'tags',\n // Ordered by the timestamp the list already sorts on, not by the tag\n // array — `orderBy` on the same field an `array-contains` matches is a\n // composite index nobody wants to explain.\n containsOrderBy: 'updatedAt',\n // `isAnyOf` is a saved segment's \"any of these tags\" (AGL-2617). The\n // query cannot serve it — `array-contains-any` is the scope clause's\n // — so the translator refuses it and the list matches it over the\n // window, which the caption says.\n operators: ['contains', 'isAnyOf', 'isNotEmpty'],\n },\n {\n /*\n * The forms a person came in through — the top-level `formIds` mirror\n * of the interactions' `formId` (AGL-2612), matched whole and as typed\n * because a form id is minted with mixed case. The form's own page links\n * here with its id; nobody types one. Ordered by the list's own\n * timestamp for the reason `tags` is, served by the\n * `(formIds CONTAINS, updatedAt DESC)` index.\n *\n * ⚠️ An `array-contains` on the mirror cannot share a query with the\n * `visibleTo` scope clause, so the list drops that clause for this one\n * filter and the rules admit the read to an org-wide member only — the\n * caveat the company contacts card states, stated again on the list.\n */\n column: 'formIds',\n kind: 'text',\n path: 'formIds',\n tokensPath: 'formIds',\n verbatimTokens: true,\n containsOrderBy: 'updatedAt',\n operators: ['contains'],\n },\n { column: 'hostId', kind: 'exact', path: 'hostId', presence: 'always' },\n { column: 'ordersCount', kind: 'number', path: 'ordersCount' },\n { column: 'ltvCents', kind: 'number', path: 'ltvCents' },\n { column: 'createdAt', kind: 'date', path: 'createdAt', presence: 'always' },\n { column: 'updatedAt', kind: 'date', path: 'updatedAt', presence: 'always' },\n /*\n * When the earliest open task is due (AGL-2661) — window-only, because\n * the value is on the SHARED row but a record written before the field\n * existed has none, and Firestore cannot query for absence. `nullable`\n * is honest: the writer stores `null` for nothing scheduled, and the\n * matcher reads absent the same way, so \"is empty\" is the \"No next\n * activity\" filter over the loaded window.\n */\n {\n column: 'nextTaskAtMs',\n kind: 'date',\n path: 'nextTaskAtMs',\n windowOnly: true,\n presence: 'nullable',\n },\n /*\n * THE FACET FIELDS (AGL-2617) — window-only, every one of them.\n *\n * An owner, a stage, a company and the capture sources live on the\n * viewing group's facet of the shared contact row, and a facet path is\n * per group: a `where` on it would need an index per group, and the\n * translator would send a scoped member a query the rules deny. So these\n * are declared for the menu and for a saved view, matched over the loaded\n * window against the flattened row (`ContactRecord` carries each at the\n * top), and never put on a query — `windowOnly` is what holds that line.\n * The paths are the ROW'S, which is what the matcher reads.\n *\n * The values are picked, not typed — a uid from the roster, a stage from\n * the fixed list, a source from its labels, a company from the picker —\n * so `equals` and `isAnyOf` are what they offer; the section supplies\n * the choices. The column names are the contract `CRM_CONTACT_VIEW_FIELDS`\n * states, because the dynamic-list translator reads a view by them.\n */\n {\n column: CRM_CONTACT_VIEW_FIELDS.owner,\n kind: 'exact',\n path: 'ownerUid',\n windowOnly: true,\n operators: ['equals', 'isAnyOf', 'isNotEmpty'],\n },\n {\n column: CRM_CONTACT_VIEW_FIELDS.stage,\n kind: 'exact',\n path: 'lifecycleStage',\n windowOnly: true,\n operators: ['equals', 'isAnyOf', 'isNotEmpty'],\n },\n {\n // The `sources` presence map, matched on its keys — see `keysOf`.\n column: CRM_CONTACT_VIEW_FIELDS.source,\n kind: 'exact',\n path: 'sources',\n keysOf: true,\n windowOnly: true,\n operators: ['equals', 'isAnyOf'],\n },\n {\n column: CRM_CONTACT_VIEW_FIELDS.company,\n kind: 'exact',\n path: 'companyId',\n windowOnly: true,\n operators: ['equals', 'isNotEmpty'],\n },\n]\n\n/**\n * One filter field per active custom contact field (AGL-2617).\n *\n * A custom value lives under the facet's `custom` map, so every one is\n * window-only for the reason the facet fields above are, and its column is\n * the one the table shows it under — `crmContactCustomColumn(key)` — so a\n * clause and a column agree on the name and a saved view's columns and\n * filters name the same thing. The kind follows the definition's type, and\n * `nullable` is how a cleared value is stored, which is what makes both\n * empty operators honest here.\n */\nexport function contactCustomFilterFields(\n definitions: readonly Pick<ContactFieldDefinition, 'key' | 'type' | 'retiredAt'>[],\n): ListFilterField[] {\n return definitions\n .filter((definition) => !definition.retiredAt)\n .map((definition) => {\n const column = crmContactCustomColumn(definition.key)\n const path = `custom.${definition.key}`\n switch (definition.type) {\n case 'number':\n return { column, kind: 'number', path, windowOnly: true, presence: 'nullable' }\n case 'date':\n return { column, kind: 'date', path, windowOnly: true, presence: 'nullable' }\n case 'checkbox':\n return { column, kind: 'boolean', path, windowOnly: true }\n case 'select':\n return {\n column,\n kind: 'exact',\n path,\n windowOnly: true,\n presence: 'nullable',\n operators: ['equals', 'isAnyOf', 'isEmpty', 'isNotEmpty'],\n }\n default:\n return {\n column,\n kind: 'text',\n path,\n windowOnly: true,\n presence: 'nullable',\n operators: ['contains', 'equals', 'startsWith', 'isEmpty', 'isNotEmpty'],\n }\n }\n })\n}\n\n/** The custom fields' headers, keyed by the column each filters as. */\nexport function contactCustomFilterHeaders(\n definitions: readonly Pick<ContactFieldDefinition, 'key' | 'label'>[],\n): Record<string, string> {\n return Object.fromEntries(\n definitions.map((definition) => [\n crmContactCustomColumn(definition.key),\n definition.label || definition.key,\n ]),\n )\n}\n\n/**\n * How every filterable contact field reads — on a chip, in the add-filter\n * picker, and as the header of a filter-only hidden column.\n */\nexport const CONTACT_LIST_FILTER_HEADERS: Readonly<Record<string, string>> = {\n name: 'Contact',\n email: 'Email',\n tags: 'Tags',\n formIds: 'Form ID',\n hostId: 'Site ID',\n ordersCount: 'Orders',\n ltvCents: 'Lifetime value (cents)',\n createdAt: 'Created',\n updatedAt: 'Updated',\n nextTaskAtMs: 'Next activity',\n [CRM_CONTACT_VIEW_FIELDS.owner]: 'Owner',\n [CRM_CONTACT_VIEW_FIELDS.stage]: 'Stage',\n [CRM_CONTACT_VIEW_FIELDS.source]: 'Source',\n [CRM_CONTACT_VIEW_FIELDS.company]: 'Company',\n}\n"],"names":["CRM_CONTACT_VIEW_FIELDS","crmContactCustomColumn","CONTACT_LIST_FILTER_FIELDS","column","kind","path","lowerPath","tokensPath","reversedPath","presence","containsOrderBy","operators","verbatimTokens","windowOnly","owner","stage","source","keysOf","company","contactCustomFilterFields","definitions","filter","definition","retiredAt","map","key","type","contactCustomFilterHeaders","Object","fromEntries","label","CONTACT_LIST_FILTER_HEADERS","name","email","tags","formIds","hostId","ordersCount","ltvCents","createdAt","updatedAt","nextTaskAtMs"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAEEA,uBAAuB,EACvBC,sBAAsB,QACjB,eAAc;AAGrB;;;;;;;;;;;;;CAaC,GACD,OAAO,MAAMC,6BAAyD;IACpE;QACEC,QAAQ;QACRC,MAAM;QACNC,MAAM;QACNC,WAAW;QACXC,YAAY;QACZC,cAAc;IAChB;IACA;QACE,wEAAwE;QACxE,mCAAmC;QACnCL,QAAQ;QACRC,MAAM;QACNC,MAAM;QACNC,WAAW;QACXG,UAAU;IACZ;IACA;QACE;;;;KAIC,GACDN,QAAQ;QACRC,MAAM;QACNC,MAAM;QACNE,YAAY;QACZ,qEAAqE;QACrE,uEAAuE;QACvE,2CAA2C;QAC3CG,iBAAiB;QACjB,qEAAqE;QACrE,qEAAqE;QACrE,kEAAkE;QAClE,kCAAkC;QAClCC,WAAW;YAAC;YAAY;YAAW;SAAa;IAClD;IACA;QACE;;;;;;;;;;;;KAYC,GACDR,QAAQ;QACRC,MAAM;QACNC,MAAM;QACNE,YAAY;QACZK,gBAAgB;QAChBF,iBAAiB;QACjBC,WAAW;YAAC;SAAW;IACzB;IACA;QAAER,QAAQ;QAAUC,MAAM;QAASC,MAAM;QAAUI,UAAU;IAAS;IACtE;QAAEN,QAAQ;QAAeC,MAAM;QAAUC,MAAM;IAAc;IAC7D;QAAEF,QAAQ;QAAYC,MAAM;QAAUC,MAAM;IAAW;IACvD;QAAEF,QAAQ;QAAaC,MAAM;QAAQC,MAAM;QAAaI,UAAU;IAAS;IAC3E;QAAEN,QAAQ;QAAaC,MAAM;QAAQC,MAAM;QAAaI,UAAU;IAAS;IAC3E;;;;;;;GAOC,GACD;QACEN,QAAQ;QACRC,MAAM;QACNC,MAAM;QACNQ,YAAY;QACZJ,UAAU;IACZ;IACA;;;;;;;;;;;;;;;;;GAiBC,GACD;QACEN,QAAQH,wBAAwBc,KAAK;QACrCV,MAAM;QACNC,MAAM;QACNQ,YAAY;QACZF,WAAW;YAAC;YAAU;YAAW;SAAa;IAChD;IACA;QACER,QAAQH,wBAAwBe,KAAK;QACrCX,MAAM;QACNC,MAAM;QACNQ,YAAY;QACZF,WAAW;YAAC;YAAU;YAAW;SAAa;IAChD;IACA;QACE,kEAAkE;QAClER,QAAQH,wBAAwBgB,MAAM;QACtCZ,MAAM;QACNC,MAAM;QACNY,QAAQ;QACRJ,YAAY;QACZF,WAAW;YAAC;YAAU;SAAU;IAClC;IACA;QACER,QAAQH,wBAAwBkB,OAAO;QACvCd,MAAM;QACNC,MAAM;QACNQ,YAAY;QACZF,WAAW;YAAC;YAAU;SAAa;IACrC;CACD,CAAA;AAED;;;;;;;;;;CAUC,GACD,OAAO,SAASQ,0BACdC,WAAkF;IAElF,OAAOA,YACJC,MAAM,CAAC,CAACC,aAAe,CAACA,WAAWC,SAAS,EAC5CC,GAAG,CAAC,CAACF;QACJ,MAAMnB,SAASF,uBAAuBqB,WAAWG,GAAG;QACpD,MAAMpB,OAAO,CAAC,OAAO,EAAEiB,WAAWG,GAAG,EAAE;QACvC,OAAQH,WAAWI,IAAI;YACrB,KAAK;gBACH,OAAO;oBAAEvB;oBAAQC,MAAM;oBAAUC;oBAAMQ,YAAY;oBAAMJ,UAAU;gBAAW;YAChF,KAAK;gBACH,OAAO;oBAAEN;oBAAQC,MAAM;oBAAQC;oBAAMQ,YAAY;oBAAMJ,UAAU;gBAAW;YAC9E,KAAK;gBACH,OAAO;oBAAEN;oBAAQC,MAAM;oBAAWC;oBAAMQ,YAAY;gBAAK;YAC3D,KAAK;gBACH,OAAO;oBACLV;oBACAC,MAAM;oBACNC;oBACAQ,YAAY;oBACZJ,UAAU;oBACVE,WAAW;wBAAC;wBAAU;wBAAW;wBAAW;qBAAa;gBAC3D;YACF;gBACE,OAAO;oBACLR;oBACAC,MAAM;oBACNC;oBACAQ,YAAY;oBACZJ,UAAU;oBACVE,WAAW;wBAAC;wBAAY;wBAAU;wBAAc;wBAAW;qBAAa;gBAC1E;QACJ;IACF;AACJ;AAEA,qEAAqE,GACrE,OAAO,SAASgB,2BACdP,WAAqE;IAErE,OAAOQ,OAAOC,WAAW,CACvBT,YAAYI,GAAG,CAAC,CAACF,aAAe;YAC9BrB,uBAAuBqB,WAAWG,GAAG;YACrCH,WAAWQ,KAAK,IAAIR,WAAWG,GAAG;SACnC;AAEL;AAEA;;;CAGC,GACD,OAAO,MAAMM,8BAAgE;IAC3EC,MAAM;IACNC,OAAO;IACPC,MAAM;IACNC,SAAS;IACTC,QAAQ;IACRC,aAAa;IACbC,UAAU;IACVC,WAAW;IACXC,WAAW;IACXC,cAAc;IACd,CAACzC,wBAAwBc,KAAK,CAAC,EAAE;IACjC,CAACd,wBAAwBe,KAAK,CAAC,EAAE;IACjC,CAACf,wBAAwBgB,MAAM,CAAC,EAAE;IAClC,CAAChB,wBAAwBkB,OAAO,CAAC,EAAE;AACrC,EAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type ContactFieldDefinition, type CrmFieldObject } from '@aglyn/aglyn';
|
|
2
|
+
/** A stored definition, with the document id every write needs. */
|
|
3
|
+
export interface ContactFieldDefinitionDoc extends ContactFieldDefinition {
|
|
4
|
+
$id: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ContactFieldDefinitionsResult {
|
|
7
|
+
/** Every definition describing the asked-for object, retired ones included, in `order`. */
|
|
8
|
+
definitions: ContactFieldDefinitionDoc[];
|
|
9
|
+
/** The definitions a value may still be written under, in `order`. */
|
|
10
|
+
active: ContactFieldDefinitionDoc[];
|
|
11
|
+
/**
|
|
12
|
+
* Whether the answer above is the server's. False while the listen is
|
|
13
|
+
* settling or while there is no org to ask, so a surface that would draw
|
|
14
|
+
* "no fields yet" waits rather than saying it for one paint.
|
|
15
|
+
*/
|
|
16
|
+
ready: boolean;
|
|
17
|
+
/** The rows have been seen by the server — `writeGuardedBySeed`'s input. */
|
|
18
|
+
fromCache: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The org's custom contact field definitions, sorted, for every surface that
|
|
22
|
+
* needs them (AGL-2601): the Fields list, the contact list's columns, the
|
|
23
|
+
* profile card, the form editor's mapping picker, an import's target list
|
|
24
|
+
* and an audience filter's field menu.
|
|
25
|
+
*
|
|
26
|
+
* ONE bounded read of a small collection. `orgs/{orgId}/contactFields` has
|
|
27
|
+
* no index — it is read whole, ordered by document id so the query needs
|
|
28
|
+
* none, and sorted by `order` here in memory; `CONTACT_FIELDS_MAX_PER_ORG`
|
|
29
|
+
* is the ceiling on that read and the one every reader shares. The listen is
|
|
30
|
+
* cached per org by the Firestore SDK itself: two mounts asking for the same
|
|
31
|
+
* query share one target and one set of documents, so a page with the list
|
|
32
|
+
* and the columns both open pays for the collection once, and a write from
|
|
33
|
+
* the Fields section reaches every reader without an invalidation to forget.
|
|
34
|
+
*
|
|
35
|
+
* `orgId` rather than `hostId` because definitions are ORG-WIDE — the org is
|
|
36
|
+
* what the reader has already resolved through `useOrgDataScope`, and a hook
|
|
37
|
+
* that resolved it again would be a second lookup per surface. Null while
|
|
38
|
+
* that lookup is in flight issues no query at all.
|
|
39
|
+
*/
|
|
40
|
+
export declare function useContactFieldDefinitions(orgId: string | null | undefined,
|
|
41
|
+
/**
|
|
42
|
+
* Which record's definitions to answer with (AGL-2661). Contacts when
|
|
43
|
+
* unsaid, so every reader written before companies and deals carried
|
|
44
|
+
* fields — the form mapping, the contact columns, the audience filter —
|
|
45
|
+
* keeps seeing exactly the definitions it always did.
|
|
46
|
+
*/
|
|
47
|
+
object?: CrmFieldObject): ContactFieldDefinitionsResult;
|
|
48
|
+
export default useContactFieldDefinitions;
|
|
@@ -0,0 +1,72 @@
|
|
|
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 { activeContactFieldDefinitions, CONTACT_FIELDS_MAX_PER_ORG, CRM_COLLECTIONS, fieldDefinitionsForObject } from "@aglyn/aglyn";
|
|
18
|
+
import { useFirestore, useFirestoreCollection } from "@aglyn/tenant-feature-instance";
|
|
19
|
+
import { collection, documentId, limit, orderBy, query } from "firebase/firestore";
|
|
20
|
+
import { useMemo } from "react";
|
|
21
|
+
const EMPTY = [];
|
|
22
|
+
/**
|
|
23
|
+
* The org's custom contact field definitions, sorted, for every surface that
|
|
24
|
+
* needs them (AGL-2601): the Fields list, the contact list's columns, the
|
|
25
|
+
* profile card, the form editor's mapping picker, an import's target list
|
|
26
|
+
* and an audience filter's field menu.
|
|
27
|
+
*
|
|
28
|
+
* ONE bounded read of a small collection. `orgs/{orgId}/contactFields` has
|
|
29
|
+
* no index — it is read whole, ordered by document id so the query needs
|
|
30
|
+
* none, and sorted by `order` here in memory; `CONTACT_FIELDS_MAX_PER_ORG`
|
|
31
|
+
* is the ceiling on that read and the one every reader shares. The listen is
|
|
32
|
+
* cached per org by the Firestore SDK itself: two mounts asking for the same
|
|
33
|
+
* query share one target and one set of documents, so a page with the list
|
|
34
|
+
* and the columns both open pays for the collection once, and a write from
|
|
35
|
+
* the Fields section reaches every reader without an invalidation to forget.
|
|
36
|
+
*
|
|
37
|
+
* `orgId` rather than `hostId` because definitions are ORG-WIDE — the org is
|
|
38
|
+
* what the reader has already resolved through `useOrgDataScope`, and a hook
|
|
39
|
+
* that resolved it again would be a second lookup per surface. Null while
|
|
40
|
+
* that lookup is in flight issues no query at all.
|
|
41
|
+
*/ export function useContactFieldDefinitions(orgId, /**
|
|
42
|
+
* Which record's definitions to answer with (AGL-2661). Contacts when
|
|
43
|
+
* unsaid, so every reader written before companies and deals carried
|
|
44
|
+
* fields — the form mapping, the contact columns, the audience filter —
|
|
45
|
+
* keeps seeing exactly the definitions it always did.
|
|
46
|
+
*/ object = 'contact') {
|
|
47
|
+
const firestore = useFirestore();
|
|
48
|
+
const { data, status, fromCache } = useFirestoreCollection(()=>orgId ? query(collection(firestore, 'orgs', orgId, CRM_COLLECTIONS.contactFields), orderBy(documentId()), limit(CONTACT_FIELDS_MAX_PER_ORG)) : null, [
|
|
49
|
+
firestore,
|
|
50
|
+
orgId
|
|
51
|
+
], {
|
|
52
|
+
idField: '$id'
|
|
53
|
+
});
|
|
54
|
+
// One listen per org, narrowed per reader: the collection is small and
|
|
55
|
+
// shared, and a query per object would be three targets for one list.
|
|
56
|
+
const definitions = useMemo(()=>(data == null ? void 0 : data.length) ? fieldDefinitionsForObject(data, object) : EMPTY, [
|
|
57
|
+
data,
|
|
58
|
+
object
|
|
59
|
+
]);
|
|
60
|
+
const active = useMemo(()=>definitions.length ? activeContactFieldDefinitions(definitions) : EMPTY, [
|
|
61
|
+
definitions
|
|
62
|
+
]);
|
|
63
|
+
return {
|
|
64
|
+
definitions,
|
|
65
|
+
active,
|
|
66
|
+
ready: Boolean(orgId) && status !== 'loading',
|
|
67
|
+
fromCache
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export default useContactFieldDefinitions;
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=use-contact-field-definitions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/hooks/use-contact-field-definitions.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'use client'\n\nimport {\n activeContactFieldDefinitions,\n CONTACT_FIELDS_MAX_PER_ORG,\n type ContactFieldDefinition,\n CRM_COLLECTIONS,\n type CrmFieldObject,\n fieldDefinitionsForObject,\n} from '@aglyn/aglyn'\nimport {\n useFirestore,\n useFirestoreCollection,\n} from '@aglyn/tenant-feature-instance'\nimport {\n collection,\n documentId,\n limit,\n orderBy,\n query,\n} from 'firebase/firestore'\nimport { useMemo } from 'react'\n\n/** A stored definition, with the document id every write needs. */\nexport interface ContactFieldDefinitionDoc extends ContactFieldDefinition {\n $id: string\n}\n\nexport interface ContactFieldDefinitionsResult {\n /** Every definition describing the asked-for object, retired ones included, in `order`. */\n definitions: ContactFieldDefinitionDoc[]\n /** The definitions a value may still be written under, in `order`. */\n active: ContactFieldDefinitionDoc[]\n /**\n * Whether the answer above is the server's. False while the listen is\n * settling or while there is no org to ask, so a surface that would draw\n * \"no fields yet\" waits rather than saying it for one paint.\n */\n ready: boolean\n /** The rows have been seen by the server — `writeGuardedBySeed`'s input. */\n fromCache: boolean\n}\n\nconst EMPTY: ContactFieldDefinitionDoc[] = []\n\n/**\n * The org's custom contact field definitions, sorted, for every surface that\n * needs them (AGL-2601): the Fields list, the contact list's columns, the\n * profile card, the form editor's mapping picker, an import's target list\n * and an audience filter's field menu.\n *\n * ONE bounded read of a small collection. `orgs/{orgId}/contactFields` has\n * no index — it is read whole, ordered by document id so the query needs\n * none, and sorted by `order` here in memory; `CONTACT_FIELDS_MAX_PER_ORG`\n * is the ceiling on that read and the one every reader shares. The listen is\n * cached per org by the Firestore SDK itself: two mounts asking for the same\n * query share one target and one set of documents, so a page with the list\n * and the columns both open pays for the collection once, and a write from\n * the Fields section reaches every reader without an invalidation to forget.\n *\n * `orgId` rather than `hostId` because definitions are ORG-WIDE — the org is\n * what the reader has already resolved through `useOrgDataScope`, and a hook\n * that resolved it again would be a second lookup per surface. Null while\n * that lookup is in flight issues no query at all.\n */\nexport function useContactFieldDefinitions(\n orgId: string | null | undefined,\n /**\n * Which record's definitions to answer with (AGL-2661). Contacts when\n * unsaid, so every reader written before companies and deals carried\n * fields — the form mapping, the contact columns, the audience filter —\n * keeps seeing exactly the definitions it always did.\n */\n object: CrmFieldObject = 'contact',\n): ContactFieldDefinitionsResult {\n const firestore = useFirestore()\n const { data, status, fromCache } =\n useFirestoreCollection<ContactFieldDefinitionDoc>(\n () =>\n orgId\n ? query(\n collection(\n firestore,\n 'orgs',\n orgId,\n CRM_COLLECTIONS.contactFields,\n ),\n orderBy(documentId()),\n limit(CONTACT_FIELDS_MAX_PER_ORG),\n )\n : null,\n [firestore, orgId],\n { idField: '$id' },\n )\n // One listen per org, narrowed per reader: the collection is small and\n // shared, and a query per object would be three targets for one list.\n const definitions = useMemo(\n () => (data?.length ? fieldDefinitionsForObject(data, object) : EMPTY),\n [data, object],\n )\n const active = useMemo(\n () => (definitions.length ? activeContactFieldDefinitions(definitions) : EMPTY),\n [definitions],\n )\n return {\n definitions,\n active,\n ready: Boolean(orgId) && status !== 'loading',\n fromCache,\n }\n}\n\nexport default useContactFieldDefinitions\n"],"names":["activeContactFieldDefinitions","CONTACT_FIELDS_MAX_PER_ORG","CRM_COLLECTIONS","fieldDefinitionsForObject","useFirestore","useFirestoreCollection","collection","documentId","limit","orderBy","query","useMemo","EMPTY","useContactFieldDefinitions","orgId","object","firestore","data","status","fromCache","contactFields","idField","definitions","length","active","ready","Boolean"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;AAEA,SACEA,6BAA6B,EAC7BC,0BAA0B,EAE1BC,eAAe,EAEfC,yBAAyB,QACpB,eAAc;AACrB,SACEC,YAAY,EACZC,sBAAsB,QACjB,iCAAgC;AACvC,SACEC,UAAU,EACVC,UAAU,EACVC,KAAK,EACLC,OAAO,EACPC,KAAK,QACA,qBAAoB;AAC3B,SAASC,OAAO,QAAQ,QAAO;AAsB/B,MAAMC,QAAqC,EAAE;AAE7C;;;;;;;;;;;;;;;;;;;CAmBC,GACD,OAAO,SAASC,2BACdC,KAAgC,EAChC;;;;;GAKC,GACDC,SAAyB,SAAS;IAElC,MAAMC,YAAYZ;IAClB,MAAM,EAAEa,IAAI,EAAEC,MAAM,EAAEC,SAAS,EAAE,GAC/Bd,uBACE,IACES,QACIJ,MACEJ,WACEU,WACA,QACAF,OACAZ,gBAAgBkB,aAAa,GAE/BX,QAAQF,eACRC,MAAMP,+BAER,MACN;QAACe;QAAWF;KAAM,EAClB;QAAEO,SAAS;IAAM;IAErB,uEAAuE;IACvE,sEAAsE;IACtE,MAAMC,cAAcX,QAClB,IAAOM,CAAAA,wBAAAA,KAAMM,MAAM,IAAGpB,0BAA0Bc,MAAMF,UAAUH,OAChE;QAACK;QAAMF;KAAO;IAEhB,MAAMS,SAASb,QACb,IAAOW,YAAYC,MAAM,GAAGvB,8BAA8BsB,eAAeV,OACzE;QAACU;KAAY;IAEf,OAAO;QACLA;QACAE;QACAC,OAAOC,QAAQZ,UAAUI,WAAW;QACpCC;IACF;AACF;AAEA,eAAeN,2BAA0B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ContactUpdateFields } from '../model/contact-update';
|
|
2
|
+
import type { CrmBulkAnswer } from '../model/crm-bulk-writes';
|
|
3
|
+
/**
|
|
4
|
+
* THE CONSOLE'S DOOR TO `crm/contact-update` (AGL-2804).
|
|
5
|
+
*
|
|
6
|
+
* Every surface that edits a contact's facet saves through here rather than
|
|
7
|
+
* writing the document — the record page's profile, custom fields, files and
|
|
8
|
+
* campaign filing, the company page's link, and the contacts bar — because
|
|
9
|
+
* the rules leave a client nothing in a facet but letting a holder go.
|
|
10
|
+
*
|
|
11
|
+
* Built on `useCrmApi`, so beneath the organization hub's mount the request
|
|
12
|
+
* names the org and the route writes each contact through its own primary
|
|
13
|
+
* holder, and under a site it writes the site's.
|
|
14
|
+
*
|
|
15
|
+
* A request refused WHOLE — no session, no permission, a plan without the CRM
|
|
16
|
+
* — throws with the route's sentence.
|
|
17
|
+
* `updateMany` hands a per-contact answer back in the bulk runners' shape;
|
|
18
|
+
* `updateOne` throws that one contact's refusal, which is what a single
|
|
19
|
+
* record's Save shows.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useContactUpdate(hostId: string | null): {
|
|
22
|
+
updateMany: (contactIds: readonly string[], set: ContactUpdateFields) => Promise<CrmBulkAnswer[]>;
|
|
23
|
+
updateOne: (contactId: string, set: ContactUpdateFields) => Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
export default useContactUpdate;
|