@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,240 @@
|
|
|
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 { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
19
|
+
import { CRM_EMAIL_TEMPLATE_NAME_MAX, CRM_MERGE_FIELDS, crmMergeFieldToken } from "@aglyn/aglyn";
|
|
20
|
+
import { Autocomplete, Button, Dialog, DialogActions, DialogContent, DialogTitle, FormControlLabel, FormHelperText, ListSubheader, Menu, MenuItem, Radio, RadioGroup, TextField } from "@mui/material";
|
|
21
|
+
import { useEffect, useMemo, useState } from "react";
|
|
22
|
+
/** How the picker heads each group; shared first, because it is the team's. */ const visibilityGroup = (template)=>template.visibility === 'personal' ? 'Mine' : 'Shared';
|
|
23
|
+
/**
|
|
24
|
+
* "Template" — the letter to start from, grouped into the team's and the
|
|
25
|
+
* reader's own. An Autocomplete rather than a select because a workspace
|
|
26
|
+
* that keeps forty letters finds one by typing its name. Options are
|
|
27
|
+
* ordered shared-then-personal so the groups render contiguous, which is
|
|
28
|
+
* what the control's grouping needs.
|
|
29
|
+
*/ export function CrmTemplatePicker(props) {
|
|
30
|
+
const { templates, value, onChange, disabled } = props;
|
|
31
|
+
const options = useMemo(()=>[
|
|
32
|
+
...templates
|
|
33
|
+
].sort((a, b)=>a.visibility === b.visibility ? a.name.localeCompare(b.name) : a.visibility === 'personal' ? 1 : -1), [
|
|
34
|
+
templates
|
|
35
|
+
]);
|
|
36
|
+
return /*#__PURE__*/ _jsx(Autocomplete, {
|
|
37
|
+
size: "small",
|
|
38
|
+
options: options,
|
|
39
|
+
groupBy: visibilityGroup,
|
|
40
|
+
getOptionLabel: (option)=>option.name,
|
|
41
|
+
isOptionEqualToValue: (option, selected)=>option.$id === selected.$id,
|
|
42
|
+
value: value,
|
|
43
|
+
onChange: (_event, next)=>onChange(next),
|
|
44
|
+
disabled: disabled,
|
|
45
|
+
noOptionsText: "No templates match",
|
|
46
|
+
renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
|
|
47
|
+
label: "Template",
|
|
48
|
+
helperText: "Fills in the subject and the message. Merge fields such as {{contact.firstName}} are filled from this record when the email is sent."
|
|
49
|
+
}))
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
CrmTemplatePicker.displayName = 'CrmTemplatePicker';
|
|
53
|
+
/**
|
|
54
|
+
* "Insert" — a snippet, or a merge field, at the caret.
|
|
55
|
+
*
|
|
56
|
+
* One menu for both because they are one gesture: put something into the
|
|
57
|
+
* message where I am. The snippets come first, under their own heading,
|
|
58
|
+
* and the fields follow grouped by what they read — only the groups that
|
|
59
|
+
* apply, so a letter to a contact is not offered `{{lead.name}}`. With no
|
|
60
|
+
* snippets the menu is the fields alone, which is what keeps the dialog
|
|
61
|
+
* useful before anyone has saved a snippet.
|
|
62
|
+
*/ export function CrmInsertMenu(props) {
|
|
63
|
+
const { snippets, groups, disabled, onInsert } = props;
|
|
64
|
+
const [anchor, setAnchor] = useState(null);
|
|
65
|
+
const fields = useMemo(()=>{
|
|
66
|
+
const byGroup = new Map();
|
|
67
|
+
for (const field of CRM_MERGE_FIELDS){
|
|
68
|
+
var _byGroup_get;
|
|
69
|
+
if (!groups.includes(field.group)) continue;
|
|
70
|
+
byGroup.set(field.group, [
|
|
71
|
+
...(_byGroup_get = byGroup.get(field.group)) != null ? _byGroup_get : [],
|
|
72
|
+
field
|
|
73
|
+
]);
|
|
74
|
+
}
|
|
75
|
+
return [
|
|
76
|
+
...byGroup.entries()
|
|
77
|
+
];
|
|
78
|
+
}, [
|
|
79
|
+
groups
|
|
80
|
+
]);
|
|
81
|
+
const pick = (text)=>{
|
|
82
|
+
setAnchor(null);
|
|
83
|
+
onInsert(text);
|
|
84
|
+
};
|
|
85
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
86
|
+
children: [
|
|
87
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
88
|
+
size: "small",
|
|
89
|
+
disabled: disabled,
|
|
90
|
+
onClick: (event)=>setAnchor(event.currentTarget),
|
|
91
|
+
"aria-haspopup": "menu",
|
|
92
|
+
children: 'Insert'
|
|
93
|
+
}),
|
|
94
|
+
/*#__PURE__*/ _jsxs(Menu, {
|
|
95
|
+
open: Boolean(anchor),
|
|
96
|
+
anchorEl: anchor,
|
|
97
|
+
onClose: ()=>setAnchor(null),
|
|
98
|
+
children: [
|
|
99
|
+
snippets.length ? /*#__PURE__*/ _jsx(ListSubheader, {
|
|
100
|
+
disableSticky: true,
|
|
101
|
+
children: 'Snippets'
|
|
102
|
+
}) : null,
|
|
103
|
+
snippets.map((snippet)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
104
|
+
onClick: ()=>pick(snippet.body),
|
|
105
|
+
children: snippet.name
|
|
106
|
+
}, snippet.$id)),
|
|
107
|
+
fields.flatMap(([group, entries])=>[
|
|
108
|
+
/*#__PURE__*/ _jsx(ListSubheader, {
|
|
109
|
+
disableSticky: true,
|
|
110
|
+
children: `${group} fields`
|
|
111
|
+
}, `group-${group}`),
|
|
112
|
+
...entries.map((field)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
113
|
+
onClick: ()=>pick(crmMergeFieldToken(field.key)),
|
|
114
|
+
children: field.label
|
|
115
|
+
}, field.key))
|
|
116
|
+
])
|
|
117
|
+
]
|
|
118
|
+
})
|
|
119
|
+
]
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
CrmInsertMenu.displayName = 'CrmInsertMenu';
|
|
123
|
+
/**
|
|
124
|
+
* "Save as template" — a name and whose it is, over the draft as written.
|
|
125
|
+
*
|
|
126
|
+
* The subject and the body are the dialog's own and are not shown again
|
|
127
|
+
* here; this asks only what the draft does not carry. Personal is the
|
|
128
|
+
* default, because a letter one rep wrote is theirs until they hand it to
|
|
129
|
+
* the team, and handing it over is one click.
|
|
130
|
+
*/ export function CrmSaveAsTemplateDialog(props) {
|
|
131
|
+
const { open, onClose, onSave } = props;
|
|
132
|
+
const [name, setName] = useState('');
|
|
133
|
+
const [visibility, setVisibility] = useState('personal');
|
|
134
|
+
const [busy, setBusy] = useState(false);
|
|
135
|
+
const [error, setError] = useState(null);
|
|
136
|
+
useEffect(()=>{
|
|
137
|
+
if (!open) return;
|
|
138
|
+
setName('');
|
|
139
|
+
setVisibility('personal');
|
|
140
|
+
setBusy(false);
|
|
141
|
+
setError(null);
|
|
142
|
+
}, [
|
|
143
|
+
open
|
|
144
|
+
]);
|
|
145
|
+
const canSave = name.trim().length > 0 && !busy;
|
|
146
|
+
const handleSave = async ()=>{
|
|
147
|
+
if (!canSave) return;
|
|
148
|
+
setBusy(true);
|
|
149
|
+
setError(null);
|
|
150
|
+
try {
|
|
151
|
+
await onSave({
|
|
152
|
+
name: name.trim().slice(0, CRM_EMAIL_TEMPLATE_NAME_MAX),
|
|
153
|
+
visibility
|
|
154
|
+
});
|
|
155
|
+
} catch (cause) {
|
|
156
|
+
console.error(cause);
|
|
157
|
+
setError('The template could not be saved. Try again.');
|
|
158
|
+
} finally{
|
|
159
|
+
setBusy(false);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
return /*#__PURE__*/ _jsxs(Dialog, {
|
|
163
|
+
open: open,
|
|
164
|
+
onClose: busy ? undefined : onClose,
|
|
165
|
+
maxWidth: "xs",
|
|
166
|
+
fullWidth: true,
|
|
167
|
+
children: [
|
|
168
|
+
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
169
|
+
children: 'Save as template'
|
|
170
|
+
}),
|
|
171
|
+
/*#__PURE__*/ _jsxs(DialogContent, {
|
|
172
|
+
sx: {
|
|
173
|
+
display: 'flex',
|
|
174
|
+
flexDirection: 'column',
|
|
175
|
+
gap: 2
|
|
176
|
+
},
|
|
177
|
+
children: [
|
|
178
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
179
|
+
size: "small",
|
|
180
|
+
label: "Template name",
|
|
181
|
+
value: name,
|
|
182
|
+
onChange: (event)=>setName(event.target.value),
|
|
183
|
+
autoFocus: true,
|
|
184
|
+
sx: {
|
|
185
|
+
mt: 1
|
|
186
|
+
},
|
|
187
|
+
slotProps: {
|
|
188
|
+
htmlInput: {
|
|
189
|
+
maxLength: CRM_EMAIL_TEMPLATE_NAME_MAX
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}),
|
|
193
|
+
/*#__PURE__*/ _jsxs(RadioGroup, {
|
|
194
|
+
value: visibility,
|
|
195
|
+
onChange: (event)=>setVisibility(event.target.value),
|
|
196
|
+
children: [
|
|
197
|
+
/*#__PURE__*/ _jsx(FormControlLabel, {
|
|
198
|
+
value: "personal",
|
|
199
|
+
control: /*#__PURE__*/ _jsx(Radio, {
|
|
200
|
+
size: "small"
|
|
201
|
+
}),
|
|
202
|
+
label: "Personal — listed for you alone"
|
|
203
|
+
}),
|
|
204
|
+
/*#__PURE__*/ _jsx(FormControlLabel, {
|
|
205
|
+
value: "shared",
|
|
206
|
+
control: /*#__PURE__*/ _jsx(Radio, {
|
|
207
|
+
size: "small"
|
|
208
|
+
}),
|
|
209
|
+
label: "Shared — every CRM editor can use and edit it"
|
|
210
|
+
})
|
|
211
|
+
]
|
|
212
|
+
}),
|
|
213
|
+
error ? /*#__PURE__*/ _jsx(FormHelperText, {
|
|
214
|
+
error: true,
|
|
215
|
+
children: error
|
|
216
|
+
}) : null
|
|
217
|
+
]
|
|
218
|
+
}),
|
|
219
|
+
/*#__PURE__*/ _jsxs(DialogActions, {
|
|
220
|
+
children: [
|
|
221
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
222
|
+
onClick: onClose,
|
|
223
|
+
disabled: busy,
|
|
224
|
+
children: 'Cancel'
|
|
225
|
+
}),
|
|
226
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
227
|
+
variant: "contained",
|
|
228
|
+
color: "primary",
|
|
229
|
+
disabled: !canSave,
|
|
230
|
+
onClick: handleSave,
|
|
231
|
+
children: busy ? 'Saving…' : 'Save template'
|
|
232
|
+
})
|
|
233
|
+
]
|
|
234
|
+
})
|
|
235
|
+
]
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
CrmSaveAsTemplateDialog.displayName = 'CrmSaveAsTemplateDialog';
|
|
239
|
+
|
|
240
|
+
//# sourceMappingURL=crm-email-template-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/crm-email-template-tools.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 CRM_EMAIL_TEMPLATE_NAME_MAX,\n CRM_MERGE_FIELDS,\n type CrmEmailTemplateRow,\n type CrmEmailTemplateVisibility,\n type CrmMergeFieldDefinition,\n type CrmMergeFieldGroup,\n crmMergeFieldToken,\n} from '@aglyn/aglyn'\nimport {\n Autocomplete,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n FormHelperText,\n ListSubheader,\n Menu,\n MenuItem,\n Radio,\n RadioGroup,\n TextField,\n} from '@mui/material'\nimport { type MouseEvent, useEffect, useMemo, useState } from 'react'\n\n/**\n * The pieces the send dialog grows for templates (AGL-2658), each on its\n * own so the dialog's file — which several hands edit — takes three\n * elements and a handful of lines rather than a second component's worth.\n */\n\nexport interface CrmTemplatePickerProps {\n /** Every listed template of kind `template`, shared and personal alike. */\n templates: readonly CrmEmailTemplateRow[]\n /** The one applied to the draft, or `null`. */\n value: CrmEmailTemplateRow | null\n onChange: (template: CrmEmailTemplateRow | null) => void\n disabled?: boolean\n}\n\n/** How the picker heads each group; shared first, because it is the team's. */\nconst visibilityGroup = (template: CrmEmailTemplateRow): string =>\n template.visibility === 'personal' ? 'Mine' : 'Shared'\n\n/**\n * \"Template\" — the letter to start from, grouped into the team's and the\n * reader's own. An Autocomplete rather than a select because a workspace\n * that keeps forty letters finds one by typing its name. Options are\n * ordered shared-then-personal so the groups render contiguous, which is\n * what the control's grouping needs.\n */\nexport function CrmTemplatePicker(props: CrmTemplatePickerProps) {\n const { templates, value, onChange, disabled } = props\n const options = useMemo(\n () =>\n [...templates].sort((a, b) =>\n a.visibility === b.visibility\n ? a.name.localeCompare(b.name)\n : a.visibility === 'personal'\n ? 1\n : -1,\n ),\n [templates],\n )\n return (\n <Autocomplete\n size=\"small\"\n options={options}\n groupBy={visibilityGroup}\n getOptionLabel={(option) => option.name}\n isOptionEqualToValue={(option, selected) => option.$id === selected.$id}\n value={value}\n onChange={(_event, next) => onChange(next)}\n disabled={disabled}\n noOptionsText=\"No templates match\"\n renderInput={(params) => (\n <TextField\n {...params}\n label=\"Template\"\n helperText=\"Fills in the subject and the message. Merge fields such as {{contact.firstName}} are filled from this record when the email is sent.\"\n />\n )}\n />\n )\n}\nCrmTemplatePicker.displayName = 'CrmTemplatePicker'\n\nexport interface CrmInsertMenuProps {\n /** Every listed template of kind `snippet`. */\n snippets: readonly CrmEmailTemplateRow[]\n /** Which merge-field groups apply to the record being written to. */\n groups: readonly CrmMergeFieldGroup[]\n disabled?: boolean\n /** Receives the text to put at the caret. */\n onInsert: (text: string) => void\n}\n\n/**\n * \"Insert\" — a snippet, or a merge field, at the caret.\n *\n * One menu for both because they are one gesture: put something into the\n * message where I am. The snippets come first, under their own heading,\n * and the fields follow grouped by what they read — only the groups that\n * apply, so a letter to a contact is not offered `{{lead.name}}`. With no\n * snippets the menu is the fields alone, which is what keeps the dialog\n * useful before anyone has saved a snippet.\n */\nexport function CrmInsertMenu(props: CrmInsertMenuProps) {\n const { snippets, groups, disabled, onInsert } = props\n const [anchor, setAnchor] = useState<HTMLElement | null>(null)\n const fields = useMemo(() => {\n const byGroup = new Map<CrmMergeFieldGroup, CrmMergeFieldDefinition[]>()\n for (const field of CRM_MERGE_FIELDS) {\n if (!groups.includes(field.group)) continue\n byGroup.set(field.group, [...(byGroup.get(field.group) ?? []), field])\n }\n return [...byGroup.entries()]\n }, [groups])\n const pick = (text: string) => {\n setAnchor(null)\n onInsert(text)\n }\n return (\n <>\n <Button\n size=\"small\"\n disabled={disabled}\n onClick={(event: MouseEvent<HTMLElement>) => setAnchor(event.currentTarget)}\n aria-haspopup=\"menu\"\n >\n {'Insert'}\n </Button>\n <Menu open={Boolean(anchor)} anchorEl={anchor} onClose={() => setAnchor(null)}>\n {snippets.length ? <ListSubheader disableSticky>{'Snippets'}</ListSubheader> : null}\n {snippets.map((snippet) => (\n <MenuItem key={snippet.$id} onClick={() => pick(snippet.body)}>\n {snippet.name}\n </MenuItem>\n ))}\n {fields.flatMap(([group, entries]) => [\n <ListSubheader key={`group-${group}`} disableSticky>\n {`${group} fields`}\n </ListSubheader>,\n ...entries.map((field) => (\n <MenuItem key={field.key} onClick={() => pick(crmMergeFieldToken(field.key))}>\n {field.label}\n </MenuItem>\n )),\n ])}\n </Menu>\n </>\n )\n}\nCrmInsertMenu.displayName = 'CrmInsertMenu'\n\nexport interface CrmSaveAsTemplateDialogProps {\n open: boolean\n onClose: () => void\n /** Writes the template; closing on success is the caller's job. */\n onSave: (draft: {\n name: string\n visibility: CrmEmailTemplateVisibility\n }) => Promise<void>\n}\n\n/**\n * \"Save as template\" — a name and whose it is, over the draft as written.\n *\n * The subject and the body are the dialog's own and are not shown again\n * here; this asks only what the draft does not carry. Personal is the\n * default, because a letter one rep wrote is theirs until they hand it to\n * the team, and handing it over is one click.\n */\nexport function CrmSaveAsTemplateDialog(props: CrmSaveAsTemplateDialogProps) {\n const { open, onClose, onSave } = props\n const [name, setName] = useState('')\n const [visibility, setVisibility] = useState<CrmEmailTemplateVisibility>('personal')\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | null>(null)\n useEffect(() => {\n if (!open) return\n setName('')\n setVisibility('personal')\n setBusy(false)\n setError(null)\n }, [open])\n const canSave = name.trim().length > 0 && !busy\n const handleSave = async () => {\n if (!canSave) return\n setBusy(true)\n setError(null)\n try {\n await onSave({ name: name.trim().slice(0, CRM_EMAIL_TEMPLATE_NAME_MAX), visibility })\n } catch (cause) {\n console.error(cause)\n setError('The template could not be saved. Try again.')\n } finally {\n setBusy(false)\n }\n }\n return (\n <Dialog open={open} onClose={busy ? undefined : onClose} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{'Save as template'}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <TextField\n size=\"small\"\n label=\"Template name\"\n value={name}\n onChange={(event) => setName(event.target.value)}\n autoFocus\n sx={{ mt: 1 }}\n slotProps={{ htmlInput: { maxLength: CRM_EMAIL_TEMPLATE_NAME_MAX } }}\n />\n <RadioGroup\n value={visibility}\n onChange={(event) => setVisibility(event.target.value as CrmEmailTemplateVisibility)}\n >\n <FormControlLabel\n value=\"personal\"\n control={<Radio size=\"small\" />}\n label=\"Personal — listed for you alone\"\n />\n <FormControlLabel\n value=\"shared\"\n control={<Radio size=\"small\" />}\n label=\"Shared — every CRM editor can use and edit it\"\n />\n </RadioGroup>\n {error ? <FormHelperText error>{error}</FormHelperText> : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose} disabled={busy}>\n {'Cancel'}\n </Button>\n <Button variant=\"contained\" color=\"primary\" disabled={!canSave} onClick={handleSave}>\n {busy ? 'Saving…' : 'Save template'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\nCrmSaveAsTemplateDialog.displayName = 'CrmSaveAsTemplateDialog'\n"],"names":["CRM_EMAIL_TEMPLATE_NAME_MAX","CRM_MERGE_FIELDS","crmMergeFieldToken","Autocomplete","Button","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","FormHelperText","ListSubheader","Menu","MenuItem","Radio","RadioGroup","TextField","useEffect","useMemo","useState","visibilityGroup","template","visibility","CrmTemplatePicker","props","templates","value","onChange","disabled","options","sort","a","b","name","localeCompare","size","groupBy","getOptionLabel","option","isOptionEqualToValue","selected","$id","_event","next","noOptionsText","renderInput","params","label","helperText","displayName","CrmInsertMenu","snippets","groups","onInsert","anchor","setAnchor","fields","byGroup","Map","field","includes","group","set","get","entries","pick","text","onClick","event","currentTarget","aria-haspopup","open","Boolean","anchorEl","onClose","length","disableSticky","map","snippet","body","flatMap","key","CrmSaveAsTemplateDialog","onSave","setName","setVisibility","busy","setBusy","error","setError","canSave","trim","handleSave","slice","cause","console","undefined","maxWidth","fullWidth","sx","display","flexDirection","gap","target","autoFocus","mt","slotProps","htmlInput","maxLength","control","variant","color"],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type CrmExportResource } from '@aglyn/aglyn';
|
|
2
|
+
export interface CrmExportAllButtonProps {
|
|
3
|
+
/** Which table to take a complete copy of. */
|
|
4
|
+
resource: CrmExportResource;
|
|
5
|
+
/** The organization whose records these are; null holds the button. */
|
|
6
|
+
orgId: string | null;
|
|
7
|
+
/**
|
|
8
|
+
* The site being read as.
|
|
9
|
+
*
|
|
10
|
+
* Required for contacts — the file is written through one holder's facet
|
|
11
|
+
* and a facet is per site — and for a scoped reader's leads. Null at the
|
|
12
|
+
* organization level, where an org-wide member takes every site's leads
|
|
13
|
+
* in one file.
|
|
14
|
+
*/
|
|
15
|
+
hostId: string | null;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* EXPORT ALL — the whole collection, not the loaded window (AGL-2662).
|
|
20
|
+
*
|
|
21
|
+
* Beside "Export CSV", which writes the rows on screen. The two are
|
|
22
|
+
* deliberately both offered and deliberately named apart: a selection's
|
|
23
|
+
* file is what somebody just picked, and this is the audience.
|
|
24
|
+
*
|
|
25
|
+
* ## The response is checked, not trusted
|
|
26
|
+
*
|
|
27
|
+
* The route reports a `count()` aggregate in `X-Aglyn-Export-Rows`, taken
|
|
28
|
+
* before its first page. A stream that dies halfway produces a perfectly
|
|
29
|
+
* well-formed shorter file, and nothing about the bytes says it is short —
|
|
30
|
+
* which is exactly how the window-sized export stayed invisible for as long
|
|
31
|
+
* as it did. A body with fewer rows than promised is REFUSED rather than
|
|
32
|
+
* saved, because a partial audience saved under a confident name is worse
|
|
33
|
+
* than no file.
|
|
34
|
+
*/
|
|
35
|
+
export declare function CrmExportAllButton(props: CrmExportAllButtonProps): import("react").JSX.Element;
|
|
36
|
+
export declare namespace CrmExportAllButton {
|
|
37
|
+
var displayName: string;
|
|
38
|
+
}
|
|
39
|
+
export default CrmExportAllButton;
|
|
@@ -0,0 +1,98 @@
|
|
|
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
|
+
import { countCsvDataRows } from "@aglyn/aglyn";
|
|
19
|
+
import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
20
|
+
import { useUser } from "@aglyn/tenant-feature-instance";
|
|
21
|
+
import { Button } from "@mui/material";
|
|
22
|
+
import { useSnackbar } from "notistack";
|
|
23
|
+
import { useCallback, useState } from "react";
|
|
24
|
+
import { downloadTextFile } from "../model/contacts-csv.js";
|
|
25
|
+
/** The header the export route promises its row count in. */ const EXPORT_ROWS_HEADER = 'X-Aglyn-Export-Rows';
|
|
26
|
+
/**
|
|
27
|
+
* EXPORT ALL — the whole collection, not the loaded window (AGL-2662).
|
|
28
|
+
*
|
|
29
|
+
* Beside "Export CSV", which writes the rows on screen. The two are
|
|
30
|
+
* deliberately both offered and deliberately named apart: a selection's
|
|
31
|
+
* file is what somebody just picked, and this is the audience.
|
|
32
|
+
*
|
|
33
|
+
* ## The response is checked, not trusted
|
|
34
|
+
*
|
|
35
|
+
* The route reports a `count()` aggregate in `X-Aglyn-Export-Rows`, taken
|
|
36
|
+
* before its first page. A stream that dies halfway produces a perfectly
|
|
37
|
+
* well-formed shorter file, and nothing about the bytes says it is short —
|
|
38
|
+
* which is exactly how the window-sized export stayed invisible for as long
|
|
39
|
+
* as it did. A body with fewer rows than promised is REFUSED rather than
|
|
40
|
+
* saved, because a partial audience saved under a confident name is worse
|
|
41
|
+
* than no file.
|
|
42
|
+
*/ export function CrmExportAllButton(props) {
|
|
43
|
+
const { resource, orgId, hostId, disabled } = props;
|
|
44
|
+
const { data: user } = useUser();
|
|
45
|
+
const { enqueueSnackbar } = useSnackbar();
|
|
46
|
+
const [busy, setBusy] = useState(false);
|
|
47
|
+
const handleExport = useCallback(async ()=>{
|
|
48
|
+
if (!orgId || busy) return;
|
|
49
|
+
setBusy(true);
|
|
50
|
+
try {
|
|
51
|
+
var _response_headers_get;
|
|
52
|
+
const params = new URLSearchParams({
|
|
53
|
+
orgId,
|
|
54
|
+
resource
|
|
55
|
+
});
|
|
56
|
+
if (hostId) params.set('hostId', hostId);
|
|
57
|
+
const response = await authorizedFetch(user, `/api/crm/export?${params.toString()}`);
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
var _ref;
|
|
60
|
+
const failure = await response.json().catch(()=>({}));
|
|
61
|
+
throw new Error((_ref = failure == null ? void 0 : failure.error) != null ? _ref : 'Export failed');
|
|
62
|
+
}
|
|
63
|
+
const text = await response.text();
|
|
64
|
+
const promised = Number((_response_headers_get = response.headers.get(EXPORT_ROWS_HEADER)) != null ? _response_headers_get : '');
|
|
65
|
+
const received = countCsvDataRows(text);
|
|
66
|
+
if (Number.isFinite(promised) && received < promised) {
|
|
67
|
+
enqueueSnackbar(`Export incomplete — ${received} of ${promised} rows arrived. ` + 'Nothing was saved; try again.', {
|
|
68
|
+
variant: 'error'
|
|
69
|
+
});
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
downloadTextFile(`${resource}.csv`, 'text/csv', text);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
enqueueSnackbar(error instanceof Error ? error.message : 'Export failed', {
|
|
75
|
+
variant: 'error'
|
|
76
|
+
});
|
|
77
|
+
} finally{
|
|
78
|
+
setBusy(false);
|
|
79
|
+
}
|
|
80
|
+
}, [
|
|
81
|
+
orgId,
|
|
82
|
+
hostId,
|
|
83
|
+
resource,
|
|
84
|
+
user,
|
|
85
|
+
busy,
|
|
86
|
+
enqueueSnackbar
|
|
87
|
+
]);
|
|
88
|
+
return /*#__PURE__*/ _jsx(Button, {
|
|
89
|
+
size: "small",
|
|
90
|
+
disabled: disabled || busy || !orgId,
|
|
91
|
+
onClick: ()=>void handleExport(),
|
|
92
|
+
children: busy ? 'Exporting…' : 'Export all…'
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
CrmExportAllButton.displayName = 'CrmExportAllButton';
|
|
96
|
+
export default CrmExportAllButton;
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=crm-export-all-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/crm-export-all-button.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 countCsvDataRows,\n type CrmExportResource,\n} from '@aglyn/aglyn'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport { Button } from '@mui/material'\nimport { useSnackbar } from 'notistack'\nimport { useCallback, useState } from 'react'\nimport { downloadTextFile } from '../model/contacts-csv'\n\n/** The header the export route promises its row count in. */\nconst EXPORT_ROWS_HEADER = 'X-Aglyn-Export-Rows'\n\nexport interface CrmExportAllButtonProps {\n /** Which table to take a complete copy of. */\n resource: CrmExportResource\n /** The organization whose records these are; null holds the button. */\n orgId: string | null\n /**\n * The site being read as.\n *\n * Required for contacts — the file is written through one holder's facet\n * and a facet is per site — and for a scoped reader's leads. Null at the\n * organization level, where an org-wide member takes every site's leads\n * in one file.\n */\n hostId: string | null\n disabled?: boolean\n}\n\n/**\n * EXPORT ALL — the whole collection, not the loaded window (AGL-2662).\n *\n * Beside \"Export CSV\", which writes the rows on screen. The two are\n * deliberately both offered and deliberately named apart: a selection's\n * file is what somebody just picked, and this is the audience.\n *\n * ## The response is checked, not trusted\n *\n * The route reports a `count()` aggregate in `X-Aglyn-Export-Rows`, taken\n * before its first page. A stream that dies halfway produces a perfectly\n * well-formed shorter file, and nothing about the bytes says it is short —\n * which is exactly how the window-sized export stayed invisible for as long\n * as it did. A body with fewer rows than promised is REFUSED rather than\n * saved, because a partial audience saved under a confident name is worse\n * than no file.\n */\nexport function CrmExportAllButton(props: CrmExportAllButtonProps) {\n const { resource, orgId, hostId, disabled } = props\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const [busy, setBusy] = useState(false)\n\n const handleExport = useCallback(async () => {\n if (!orgId || busy) return\n setBusy(true)\n try {\n const params = new URLSearchParams({ orgId, resource })\n if (hostId) params.set('hostId', hostId)\n const response = await authorizedFetch(\n user,\n `/api/crm/export?${params.toString()}`,\n )\n if (!response.ok) {\n const failure = await response.json().catch(() => ({}))\n throw new Error(failure?.error ?? 'Export failed')\n }\n const text = await response.text()\n const promised = Number(response.headers.get(EXPORT_ROWS_HEADER) ?? '')\n const received = countCsvDataRows(text)\n if (Number.isFinite(promised) && received < promised) {\n enqueueSnackbar(\n `Export incomplete — ${received} of ${promised} rows arrived. ` +\n 'Nothing was saved; try again.',\n { variant: 'error' },\n )\n return\n }\n downloadTextFile(`${resource}.csv`, 'text/csv', text)\n } catch (error) {\n enqueueSnackbar(\n error instanceof Error ? error.message : 'Export failed',\n { variant: 'error' },\n )\n } finally {\n setBusy(false)\n }\n }, [orgId, hostId, resource, user, busy, enqueueSnackbar])\n\n return (\n <Button\n size=\"small\"\n disabled={disabled || busy || !orgId}\n onClick={() => void handleExport()}\n >\n {busy ? 'Exporting…' : 'Export all…'}\n </Button>\n )\n}\nCrmExportAllButton.displayName = 'CrmExportAllButton'\n\nexport default CrmExportAllButton\n"],"names":["countCsvDataRows","authorizedFetch","useUser","Button","useSnackbar","useCallback","useState","downloadTextFile","EXPORT_ROWS_HEADER","CrmExportAllButton","props","resource","orgId","hostId","disabled","data","user","enqueueSnackbar","busy","setBusy","handleExport","response","params","URLSearchParams","set","toString","ok","failure","json","catch","Error","error","text","promised","Number","headers","get","received","isFinite","variant","message","size","onClick","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SACEA,gBAAgB,QAEX,eAAc;AACrB,SAASC,eAAe,QAAQ,2CAA0C;AAC1E,SAASC,OAAO,QAAQ,iCAAgC;AACxD,SAASC,MAAM,QAAQ,gBAAe;AACtC,SAASC,WAAW,QAAQ,YAAW;AACvC,SAASC,WAAW,EAAEC,QAAQ,QAAQ,QAAO;AAC7C,SAASC,gBAAgB,QAAQ,2BAAuB;AAExD,2DAA2D,GAC3D,MAAMC,qBAAqB;AAmB3B;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,SAASC,mBAAmBC,KAA8B;IAC/D,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,QAAQ,EAAE,GAAGJ;IAC9C,MAAM,EAAEK,MAAMC,IAAI,EAAE,GAAGd;IACvB,MAAM,EAAEe,eAAe,EAAE,GAAGb;IAC5B,MAAM,CAACc,MAAMC,QAAQ,GAAGb,SAAS;IAEjC,MAAMc,eAAef,YAAY;QAC/B,IAAI,CAACO,SAASM,MAAM;QACpBC,QAAQ;QACR,IAAI;gBAYsBE;YAXxB,MAAMC,SAAS,IAAIC,gBAAgB;gBAAEX;gBAAOD;YAAS;YACrD,IAAIE,QAAQS,OAAOE,GAAG,CAAC,UAAUX;YACjC,MAAMQ,WAAW,MAAMpB,gBACrBe,MACA,CAAC,gBAAgB,EAAEM,OAAOG,QAAQ,IAAI;YAExC,IAAI,CAACJ,SAASK,EAAE,EAAE;;gBAChB,MAAMC,UAAU,MAAMN,SAASO,IAAI,GAAGC,KAAK,CAAC,IAAO,CAAA,CAAC,CAAA;gBACpD,MAAM,IAAIC,cAAMH,2BAAAA,QAASI,KAAK,mBAAI;YACpC;YACA,MAAMC,OAAO,MAAMX,SAASW,IAAI;YAChC,MAAMC,WAAWC,QAAOb,wBAAAA,SAASc,OAAO,CAACC,GAAG,CAAC5B,+BAArBa,wBAA4C;YACpE,MAAMgB,WAAWrC,iBAAiBgC;YAClC,IAAIE,OAAOI,QAAQ,CAACL,aAAaI,WAAWJ,UAAU;gBACpDhB,gBACE,CAAC,oBAAoB,EAAEoB,SAAS,IAAI,EAAEJ,SAAS,eAAe,CAAC,GAC7D,iCACF;oBAAEM,SAAS;gBAAQ;gBAErB;YACF;YACAhC,iBAAiB,GAAGI,SAAS,IAAI,CAAC,EAAE,YAAYqB;QAClD,EAAE,OAAOD,OAAO;YACdd,gBACEc,iBAAiBD,QAAQC,MAAMS,OAAO,GAAG,iBACzC;gBAAED,SAAS;YAAQ;QAEvB,SAAU;YACRpB,QAAQ;QACV;IACF,GAAG;QAACP;QAAOC;QAAQF;QAAUK;QAAME;QAAMD;KAAgB;IAEzD,qBACE,KAACd;QACCsC,MAAK;QACL3B,UAAUA,YAAYI,QAAQ,CAACN;QAC/B8B,SAAS,IAAM,KAAKtB;kBAEnBF,OAAO,eAAe;;AAG7B;AACAT,mBAAmBkC,WAAW,GAAG;AAEjC,eAAelC,mBAAkB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type CrmViewFilterClause } from '@aglyn/aglyn';
|
|
2
|
+
import { type ListFilterField } from '@aglyn/shared-ui-jsx/const/list-filter';
|
|
3
|
+
/** A choice for a field whose value is picked rather than typed. */
|
|
4
|
+
export interface CrmFilterOption {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CrmFilterBarProps {
|
|
9
|
+
/** The list's grammar — every field a clause may name. */
|
|
10
|
+
fields: readonly ListFilterField[];
|
|
11
|
+
/** How a field reads on a chip; a field without one reads as its column. */
|
|
12
|
+
headers: Readonly<Record<string, string>>;
|
|
13
|
+
clauses: readonly CrmViewFilterClause[];
|
|
14
|
+
onChange: (clauses: CrmViewFilterClause[]) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Choices per field — an owner from the roster, a stage from the fixed
|
|
17
|
+
* list, a source from its labels. A field with choices gets a picker
|
|
18
|
+
* and its chip shows the label; without them a value is typed.
|
|
19
|
+
*/
|
|
20
|
+
options?: Readonly<Record<string, readonly CrmFilterOption[]>>;
|
|
21
|
+
/** The field the query is serving, marked so the reader knows which reached everything. */
|
|
22
|
+
servedField?: string | null;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The reader reached for a filter. A section that reads its pickers'
|
|
26
|
+
* choices lazily — the roster, the companies — starts those reads here,
|
|
27
|
+
* so a list nobody is narrowing pays for neither.
|
|
28
|
+
*/
|
|
29
|
+
onOpen?: () => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The chips above a CRM list: every clause the list is narrowed by, and
|
|
33
|
+
* the one control that adds another (AGL-2617).
|
|
34
|
+
*
|
|
35
|
+
* A saved view carries several clauses and the data grid's own filter panel
|
|
36
|
+
* holds one, so the list needs an editor of its own for the set. Each
|
|
37
|
+
* clause is a chip that reads as a sentence — "Owner is Dana", "Created on
|
|
38
|
+
* or after 1 Jan" — with the clause the query serves marked, because that
|
|
39
|
+
* is the one that reached every contact and the others narrowed the loaded
|
|
40
|
+
* window; the list's caption says the same thing in prose.
|
|
41
|
+
*
|
|
42
|
+
* Adding one is a popover, not a row of controls: field, operator, value,
|
|
43
|
+
* Add. The value control follows the field — a picker where the section
|
|
44
|
+
* supplied choices, a date box for a date, a number box for a number, a
|
|
45
|
+
* text box otherwise — and the operators offered are exactly the ones the
|
|
46
|
+
* grammar declares for the field, so a clause cannot be built that nothing
|
|
47
|
+
* answers.
|
|
48
|
+
*/
|
|
49
|
+
export declare function CrmFilterBar(props: CrmFilterBarProps): import("react").JSX.Element;
|
|
50
|
+
export declare namespace CrmFilterBar {
|
|
51
|
+
var displayName: string;
|
|
52
|
+
}
|
|
53
|
+
export default CrmFilterBar;
|