@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,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import * as Aglyn from "@aglyn/aglyn";
|
|
19
|
+
import { mdiAccountGroupOutline, mdiDeleteOutline, mdiDotsHorizontalCircleOutline, mdiEmailOutline, mdiEmailReceiveOutline, mdiNoteTextOutline, mdiPencilOutline, mdiPhoneOutline } from "@aglyn/shared-data-mdi";
|
|
20
|
+
import { MdiIcon, useConfirmationContext } from "@aglyn/shared-ui-jsx";
|
|
21
|
+
import EmptyStateComponent from "@aglyn/shared-ui-jsx/components/empty-state.component";
|
|
22
|
+
import { useSnackbar } from "@aglyn/shared-ui-snackstack";
|
|
23
|
+
import { useUser, useUserName } from "@aglyn/tenant-feature-instance";
|
|
24
|
+
import { Button, Chip, IconButton, Stack, Tooltip, Typography } from "@mui/material";
|
|
25
|
+
import { deleteDoc, doc } from "firebase/firestore";
|
|
26
|
+
import { useCallback } from "react";
|
|
27
|
+
import { useCanEditActivity } from "./activity-queries.js";
|
|
28
|
+
/**
|
|
29
|
+
* One glyph per kind. Typed against the union so a kind added to the list
|
|
30
|
+
* cannot render with no icon — `MdiIcon` would fall back to its default
|
|
31
|
+
* glyph silently, and a log where every note looks like a placeholder is
|
|
32
|
+
* worse than a build error.
|
|
33
|
+
*/ const KIND_ICONS = {
|
|
34
|
+
call: mdiPhoneOutline,
|
|
35
|
+
email: mdiEmailOutline,
|
|
36
|
+
meeting: mdiAccountGroupOutline,
|
|
37
|
+
note: mdiNoteTextOutline,
|
|
38
|
+
other: mdiDotsHorizontalCircleOutline
|
|
39
|
+
};
|
|
40
|
+
/** The icon for a kind — a stored kind outside the union draws as `other`. */ export function ActivityKindIcon(props) {
|
|
41
|
+
const { kind, size = 1 } = props;
|
|
42
|
+
const icon = Aglyn.isCrmActivityKind(kind) ? KIND_ICONS[kind] : KIND_ICONS.other;
|
|
43
|
+
return /*#__PURE__*/ _jsx(MdiIcon, {
|
|
44
|
+
path: icon.path,
|
|
45
|
+
size: size
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
ActivityKindIcon.displayName = 'ActivityKindIcon';
|
|
49
|
+
/**
|
|
50
|
+
* The author's name for a row (AGL-2600).
|
|
51
|
+
*
|
|
52
|
+
* The denormalized `byName` leads: it is the only name a scoped colleague
|
|
53
|
+
* can read, since a member document is readable by its subject and by
|
|
54
|
+
* org-wide members alone. The signed-in user's OWN rows fall back to their
|
|
55
|
+
* live name — the one case where a lookup is possible — and a row that
|
|
56
|
+
* carries neither (written by a door that did not stamp one) reads as a
|
|
57
|
+
* team member rather than as a uid.
|
|
58
|
+
*/ export function useActivityAuthorName() {
|
|
59
|
+
const { data: user } = useUser();
|
|
60
|
+
const ownName = useUserName();
|
|
61
|
+
const uid = user == null ? void 0 : user.uid;
|
|
62
|
+
return useCallback((activity)=>{
|
|
63
|
+
if (activity.byName) return activity.byName;
|
|
64
|
+
if (uid && activity.byUid === uid && ownName) return ownName;
|
|
65
|
+
return 'A team member';
|
|
66
|
+
}, [
|
|
67
|
+
uid,
|
|
68
|
+
ownName
|
|
69
|
+
]);
|
|
70
|
+
}
|
|
71
|
+
/** "45 min" or "2 h 05 min" — a duration a manager reads at a glance. */ function durationLabel(minutes) {
|
|
72
|
+
if (minutes < 60) return `${minutes} min`;
|
|
73
|
+
const hours = Math.floor(minutes / 60);
|
|
74
|
+
const rest = minutes % 60;
|
|
75
|
+
return rest ? `${hours} h ${String(rest).padStart(2, '0')} min` : `${hours} h`;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* One logged activity: the kind's icon and label, what was said, how it
|
|
79
|
+
* went, who logged it and how long ago — with edit and delete for whoever
|
|
80
|
+
* may (AGL-2600).
|
|
81
|
+
*
|
|
82
|
+
* Edit and delete appear only when `editable` says this reader may — the
|
|
83
|
+
* author or an org-wide member. That is the console's verdict and not the
|
|
84
|
+
* rules' — see `useCanEditActivity` for why the rules admit more — so the
|
|
85
|
+
* controls are hidden rather than disabled: a disabled button asks "why
|
|
86
|
+
* not?", and the honest answer would be "you could, through the API".
|
|
87
|
+
*/ export function ActivityRow(props) {
|
|
88
|
+
const { activity, scope, onEdit, subject, nowMs, editable } = props;
|
|
89
|
+
const { firestore, dataScope } = scope;
|
|
90
|
+
const authorName = useActivityAuthorName();
|
|
91
|
+
const { confirm } = useConfirmationContext();
|
|
92
|
+
const { enqueueSnackbar } = useSnackbar();
|
|
93
|
+
const handleDelete = useCallback(async ()=>{
|
|
94
|
+
if (!dataScope) return;
|
|
95
|
+
const confirmed = await confirm({
|
|
96
|
+
title: 'Delete this activity?',
|
|
97
|
+
description: `This ${Aglyn.CRM_ACTIVITY_KIND_LABELS[Aglyn.isCrmActivityKind(activity.kind) ? activity.kind : 'other'].toLowerCase()} is removed from the record it was logged against. ` + 'Nothing the platform captured — a form, an order, a booking — is ' + 'affected.',
|
|
98
|
+
confirmationText: 'Delete activity',
|
|
99
|
+
confirmationButtonProps: {
|
|
100
|
+
color: 'error'
|
|
101
|
+
}
|
|
102
|
+
}).then(()=>true).catch(()=>false);
|
|
103
|
+
if (!confirmed) return;
|
|
104
|
+
try {
|
|
105
|
+
await deleteDoc(doc(firestore, dataScope[0], dataScope[1], Aglyn.CRM_COLLECTIONS.activities, activity.$id));
|
|
106
|
+
enqueueSnackbar('Activity deleted', {
|
|
107
|
+
variant: 'success',
|
|
108
|
+
persist: false
|
|
109
|
+
});
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error(error);
|
|
112
|
+
enqueueSnackbar('An error has occurred', {
|
|
113
|
+
variant: 'error',
|
|
114
|
+
allowDuplicate: true
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}, [
|
|
118
|
+
dataScope,
|
|
119
|
+
confirm,
|
|
120
|
+
activity,
|
|
121
|
+
firestore,
|
|
122
|
+
enqueueSnackbar
|
|
123
|
+
]);
|
|
124
|
+
const label = Aglyn.CRM_ACTIVITY_KIND_LABELS[Aglyn.isCrmActivityKind(activity.kind) ? activity.kind : 'other'];
|
|
125
|
+
/*
|
|
126
|
+
* A message the platform SENT (AGL-2615) carries a subject, an address
|
|
127
|
+
* and a delivery state the webhook advances; the state is the chip beside
|
|
128
|
+
* the kind, red once the message did not land. What was sent is a record
|
|
129
|
+
* of a fact and offers no edit — a rewritten body would misstate what
|
|
130
|
+
* left — though whoever may delete a row may still delete this one.
|
|
131
|
+
*/ const sent = activity.direction === 'outbound';
|
|
132
|
+
/*
|
|
133
|
+
* A message CAPTURED from a mailbox (AGL-2657) carries the provider's
|
|
134
|
+
* Message-ID and, when a correspondent wrote it, the `inbound` direction.
|
|
135
|
+
* It is drawn as its own thing — "Received" beside the kind, the sender
|
|
136
|
+
* where a sent row shows the recipient, no author because nobody on the
|
|
137
|
+
* team logged it — and a member's copied send reads "Sent" without a
|
|
138
|
+
* delivery chip, since the platform did not carry it. Neither takes the
|
|
139
|
+
* caller's "Logged" chip: nobody logged them.
|
|
140
|
+
*/ const received = activity.direction === 'inbound';
|
|
141
|
+
const captured = typeof activity.messageId === 'string' && activity.messageId !== '';
|
|
142
|
+
const deliveryState = Aglyn.isCrmEmailDeliveryState(activity.deliveryState) ? activity.deliveryState : null;
|
|
143
|
+
const when = new Date(activity.atMs);
|
|
144
|
+
const detail = [
|
|
145
|
+
activity.outcome ? activity.outcome : null,
|
|
146
|
+
typeof activity.durationMinutes === 'number' && activity.durationMinutes > 0 ? durationLabel(activity.durationMinutes) : null
|
|
147
|
+
].filter(Boolean);
|
|
148
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
149
|
+
direction: "row",
|
|
150
|
+
spacing: 1.5,
|
|
151
|
+
sx: {
|
|
152
|
+
alignItems: 'flex-start'
|
|
153
|
+
},
|
|
154
|
+
children: [
|
|
155
|
+
/*#__PURE__*/ _jsx(Stack, {
|
|
156
|
+
sx: {
|
|
157
|
+
color: 'text.secondary',
|
|
158
|
+
pt: 0.25,
|
|
159
|
+
fontSize: (theme)=>theme.typography.h6.fontSize
|
|
160
|
+
},
|
|
161
|
+
children: received ? /*#__PURE__*/ _jsx(MdiIcon, {
|
|
162
|
+
path: mdiEmailReceiveOutline.path
|
|
163
|
+
}) : /*#__PURE__*/ _jsx(ActivityKindIcon, {
|
|
164
|
+
kind: activity.kind
|
|
165
|
+
})
|
|
166
|
+
}),
|
|
167
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
168
|
+
spacing: 0.5,
|
|
169
|
+
sx: {
|
|
170
|
+
flex: 1,
|
|
171
|
+
minWidth: 0
|
|
172
|
+
},
|
|
173
|
+
children: [
|
|
174
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
175
|
+
direction: "row",
|
|
176
|
+
spacing: 1,
|
|
177
|
+
sx: {
|
|
178
|
+
alignItems: 'center',
|
|
179
|
+
flexWrap: 'wrap',
|
|
180
|
+
rowGap: 0.5
|
|
181
|
+
},
|
|
182
|
+
children: [
|
|
183
|
+
/*#__PURE__*/ _jsx(Chip, {
|
|
184
|
+
label: label,
|
|
185
|
+
size: "small"
|
|
186
|
+
}),
|
|
187
|
+
received ? /*#__PURE__*/ _jsx(Chip, {
|
|
188
|
+
label: "Received",
|
|
189
|
+
size: "small",
|
|
190
|
+
variant: "outlined",
|
|
191
|
+
color: "info",
|
|
192
|
+
"data-testid": "activity-direction"
|
|
193
|
+
}) : captured ? /*#__PURE__*/ _jsx(Chip, {
|
|
194
|
+
label: "Sent",
|
|
195
|
+
size: "small",
|
|
196
|
+
variant: "outlined",
|
|
197
|
+
"data-testid": "activity-direction"
|
|
198
|
+
}) : null,
|
|
199
|
+
deliveryState ? /*#__PURE__*/ _jsx(Tooltip, {
|
|
200
|
+
title: typeof activity.deliveryAtMs === 'number' ? new Date(activity.deliveryAtMs).toLocaleString() : '',
|
|
201
|
+
children: /*#__PURE__*/ _jsx(Chip, {
|
|
202
|
+
label: Aglyn.CRM_EMAIL_DELIVERY_STATE_LABELS[deliveryState],
|
|
203
|
+
size: "small",
|
|
204
|
+
variant: "outlined",
|
|
205
|
+
color: Aglyn.isCrmEmailDeliveryFailure(deliveryState) ? 'error' : 'default',
|
|
206
|
+
"data-testid": "activity-delivery-state"
|
|
207
|
+
})
|
|
208
|
+
}) : null,
|
|
209
|
+
captured ? null : subject,
|
|
210
|
+
detail.length ? /*#__PURE__*/ _jsx(Typography, {
|
|
211
|
+
variant: "caption",
|
|
212
|
+
color: "text.secondary",
|
|
213
|
+
children: detail.join(' · ')
|
|
214
|
+
}) : null
|
|
215
|
+
]
|
|
216
|
+
}),
|
|
217
|
+
activity.subject ? /*#__PURE__*/ _jsx(Typography, {
|
|
218
|
+
variant: "subtitle2",
|
|
219
|
+
children: activity.subject
|
|
220
|
+
}) : null,
|
|
221
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
222
|
+
variant: "body2",
|
|
223
|
+
sx: {
|
|
224
|
+
whiteSpace: 'pre-wrap'
|
|
225
|
+
},
|
|
226
|
+
children: activity.body
|
|
227
|
+
}),
|
|
228
|
+
/*#__PURE__*/ _jsx(Tooltip, {
|
|
229
|
+
title: when.toLocaleString(),
|
|
230
|
+
children: /*#__PURE__*/ _jsx(Typography, {
|
|
231
|
+
variant: "caption",
|
|
232
|
+
color: "text.secondary",
|
|
233
|
+
sx: {
|
|
234
|
+
alignSelf: 'flex-start'
|
|
235
|
+
},
|
|
236
|
+
children: [
|
|
237
|
+
received ? null : authorName(activity),
|
|
238
|
+
received && activity.from ? `from ${activity.from}` : null,
|
|
239
|
+
sent && activity.to ? `to ${activity.to}` : null,
|
|
240
|
+
Aglyn.activityTimeLabel(activity.atMs, nowMs != null ? nowMs : Date.now())
|
|
241
|
+
].filter(Boolean).join(' · ')
|
|
242
|
+
})
|
|
243
|
+
})
|
|
244
|
+
]
|
|
245
|
+
}),
|
|
246
|
+
editable ? /*#__PURE__*/ _jsxs(Stack, {
|
|
247
|
+
direction: "row",
|
|
248
|
+
spacing: 0.5,
|
|
249
|
+
children: [
|
|
250
|
+
onEdit && !sent && !received ? /*#__PURE__*/ _jsx(IconButton, {
|
|
251
|
+
size: "small",
|
|
252
|
+
"aria-label": "Edit activity",
|
|
253
|
+
onClick: ()=>onEdit(activity),
|
|
254
|
+
children: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
255
|
+
path: mdiPencilOutline.path,
|
|
256
|
+
size: 0.8
|
|
257
|
+
})
|
|
258
|
+
}) : null,
|
|
259
|
+
/*#__PURE__*/ _jsx(IconButton, {
|
|
260
|
+
size: "small",
|
|
261
|
+
"aria-label": "Delete activity",
|
|
262
|
+
onClick: handleDelete,
|
|
263
|
+
children: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
264
|
+
path: mdiDeleteOutline.path,
|
|
265
|
+
size: 0.8
|
|
266
|
+
})
|
|
267
|
+
})
|
|
268
|
+
]
|
|
269
|
+
}) : null
|
|
270
|
+
]
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
ActivityRow.displayName = 'ActivityRow';
|
|
274
|
+
/**
|
|
275
|
+
* A newest-first list of logged activities with a "show more" foot
|
|
276
|
+
* (AGL-2600).
|
|
277
|
+
*
|
|
278
|
+
* The rows arrive ordered — the query is `orderBy('atMs', 'desc')` — and the
|
|
279
|
+
* list does not sort them again; a second sort here is a second place for
|
|
280
|
+
* the order to be defined. The foot appears only while the probe row says
|
|
281
|
+
* more exists, so it never leads nowhere.
|
|
282
|
+
*
|
|
283
|
+
* Who may edit is decided here, once, and handed to every row: the verdict
|
|
284
|
+
* reads the member document, and the list is the one place that can ask
|
|
285
|
+
* for it a single time however many rows it draws.
|
|
286
|
+
*/ export function ActivityList(props) {
|
|
287
|
+
const { rows, scope, onEdit, emptyText = 'Nothing logged yet.', emptyAction, hasMore, onShowMore, subjectFor, readOnly } = props;
|
|
288
|
+
const canEdit = useCanEditActivity(scope.orgId, !readOnly);
|
|
289
|
+
if (!rows.length) {
|
|
290
|
+
return /*#__PURE__*/ _jsx(EmptyStateComponent, {
|
|
291
|
+
compact: true,
|
|
292
|
+
label: 'Nothing logged yet',
|
|
293
|
+
description: emptyText,
|
|
294
|
+
action: emptyAction
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
298
|
+
spacing: 2,
|
|
299
|
+
children: [
|
|
300
|
+
rows.map((activity)=>/*#__PURE__*/ _jsx(ActivityRow, {
|
|
301
|
+
activity: activity,
|
|
302
|
+
scope: scope,
|
|
303
|
+
onEdit: onEdit,
|
|
304
|
+
subject: subjectFor == null ? void 0 : subjectFor(activity),
|
|
305
|
+
editable: canEdit(activity)
|
|
306
|
+
}, activity.$id)),
|
|
307
|
+
hasMore && onShowMore ? /*#__PURE__*/ _jsx(Button, {
|
|
308
|
+
size: "small",
|
|
309
|
+
onClick: onShowMore,
|
|
310
|
+
sx: {
|
|
311
|
+
alignSelf: 'flex-start'
|
|
312
|
+
},
|
|
313
|
+
children: 'Show more'
|
|
314
|
+
}) : null
|
|
315
|
+
]
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
ActivityList.displayName = 'ActivityList';
|
|
319
|
+
export default ActivityList;
|
|
320
|
+
|
|
321
|
+
//# sourceMappingURL=activity-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/activity-list.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport type { CrmActivityKind, CrmActivityRow } from '@aglyn/aglyn'\nimport {\n mdiAccountGroupOutline,\n mdiDeleteOutline,\n mdiDotsHorizontalCircleOutline,\n mdiEmailOutline,\n mdiEmailReceiveOutline,\n mdiNoteTextOutline,\n mdiPencilOutline,\n mdiPhoneOutline,\n} from '@aglyn/shared-data-mdi'\nimport { MdiIcon, useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport EmptyStateComponent from '@aglyn/shared-ui-jsx/components/empty-state.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useUser, useUserName } from '@aglyn/tenant-feature-instance'\nimport {\n Button,\n Chip,\n IconButton,\n Stack,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { deleteDoc, doc } from 'firebase/firestore'\nimport { type ReactNode, useCallback } from 'react'\nimport { type ActivityScope, useCanEditActivity } from './activity-queries'\n\n/**\n * One glyph per kind. Typed against the union so a kind added to the list\n * cannot render with no icon — `MdiIcon` would fall back to its default\n * glyph silently, and a log where every note looks like a placeholder is\n * worse than a build error.\n */\nconst KIND_ICONS: Record<CrmActivityKind, { path: string }> = {\n call: mdiPhoneOutline,\n email: mdiEmailOutline,\n meeting: mdiAccountGroupOutline,\n note: mdiNoteTextOutline,\n other: mdiDotsHorizontalCircleOutline,\n}\n\n/** The icon for a kind — a stored kind outside the union draws as `other`. */\nexport function ActivityKindIcon(props: { kind: string; size?: number }) {\n const { kind, size = 1 } = props\n const icon = Aglyn.isCrmActivityKind(kind) ? KIND_ICONS[kind] : KIND_ICONS.other\n return <MdiIcon path={icon.path} size={size} />\n}\nActivityKindIcon.displayName = 'ActivityKindIcon'\n\n/**\n * The author's name for a row (AGL-2600).\n *\n * The denormalized `byName` leads: it is the only name a scoped colleague\n * can read, since a member document is readable by its subject and by\n * org-wide members alone. The signed-in user's OWN rows fall back to their\n * live name — the one case where a lookup is possible — and a row that\n * carries neither (written by a door that did not stamp one) reads as a\n * team member rather than as a uid.\n */\nexport function useActivityAuthorName(): (\n activity: Pick<CrmActivityRow, 'byUid' | 'byName'>,\n) => string {\n const { data: user } = useUser()\n const ownName = useUserName()\n const uid = user?.uid\n return useCallback(\n (activity) => {\n if (activity.byName) return activity.byName\n if (uid && activity.byUid === uid && ownName) return ownName\n return 'A team member'\n },\n [uid, ownName],\n )\n}\n\n/** \"45 min\" or \"2 h 05 min\" — a duration a manager reads at a glance. */\nfunction durationLabel(minutes: number): string {\n if (minutes < 60) return `${minutes} min`\n const hours = Math.floor(minutes / 60)\n const rest = minutes % 60\n return rest ? `${hours} h ${String(rest).padStart(2, '0')} min` : `${hours} h`\n}\n\nexport interface ActivityRowProps {\n activity: CrmActivityRow\n /** Where the delete is written, from `useActivityScope`. */\n scope: ActivityScope\n /** Opens the dialog on this activity. Absent, the row offers no edit. */\n onEdit?: (activity: CrmActivityRow) => void\n /**\n * What sits after the kind, before the body — a feed puts the record the\n * activity is about here, a record page needs nothing.\n */\n subject?: ReactNode\n /** The clock the relative time is read against; `Date.now()` when absent. */\n nowMs?: number\n /**\n * Whether THIS reader may edit and delete the row — the author, or an\n * org-wide member. Decided by whoever draws the rows, through\n * `useCanEditActivity`, once for the whole list: a row that asked for\n * itself would read the member document once per row.\n */\n editable?: boolean\n}\n\n/**\n * One logged activity: the kind's icon and label, what was said, how it\n * went, who logged it and how long ago — with edit and delete for whoever\n * may (AGL-2600).\n *\n * Edit and delete appear only when `editable` says this reader may — the\n * author or an org-wide member. That is the console's verdict and not the\n * rules' — see `useCanEditActivity` for why the rules admit more — so the\n * controls are hidden rather than disabled: a disabled button asks \"why\n * not?\", and the honest answer would be \"you could, through the API\".\n */\nexport function ActivityRow(props: ActivityRowProps) {\n const { activity, scope, onEdit, subject, nowMs, editable } = props\n const { firestore, dataScope } = scope\n const authorName = useActivityAuthorName()\n const { confirm } = useConfirmationContext()\n const { enqueueSnackbar } = useSnackbar()\n\n const handleDelete = useCallback(async () => {\n if (!dataScope) return\n const confirmed = await confirm({\n title: 'Delete this activity?',\n description:\n `This ${Aglyn.CRM_ACTIVITY_KIND_LABELS[\n Aglyn.isCrmActivityKind(activity.kind) ? activity.kind : 'other'\n ].toLowerCase()} is removed from the record it was logged against. ` +\n 'Nothing the platform captured — a form, an order, a booking — is ' +\n 'affected.',\n confirmationText: 'Delete activity',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n try {\n await deleteDoc(\n doc(\n firestore,\n dataScope[0],\n dataScope[1],\n Aglyn.CRM_COLLECTIONS.activities,\n activity.$id,\n ),\n )\n enqueueSnackbar('Activity deleted', { variant: 'success', persist: false })\n } catch (error) {\n console.error(error)\n enqueueSnackbar('An error has occurred', {\n variant: 'error',\n allowDuplicate: true,\n })\n }\n }, [dataScope, confirm, activity, firestore, enqueueSnackbar])\n\n const label =\n Aglyn.CRM_ACTIVITY_KIND_LABELS[\n Aglyn.isCrmActivityKind(activity.kind) ? activity.kind : 'other'\n ]\n /*\n * A message the platform SENT (AGL-2615) carries a subject, an address\n * and a delivery state the webhook advances; the state is the chip beside\n * the kind, red once the message did not land. What was sent is a record\n * of a fact and offers no edit — a rewritten body would misstate what\n * left — though whoever may delete a row may still delete this one.\n */\n const sent = activity.direction === 'outbound'\n /*\n * A message CAPTURED from a mailbox (AGL-2657) carries the provider's\n * Message-ID and, when a correspondent wrote it, the `inbound` direction.\n * It is drawn as its own thing — \"Received\" beside the kind, the sender\n * where a sent row shows the recipient, no author because nobody on the\n * team logged it — and a member's copied send reads \"Sent\" without a\n * delivery chip, since the platform did not carry it. Neither takes the\n * caller's \"Logged\" chip: nobody logged them.\n */\n const received = activity.direction === 'inbound'\n const captured = typeof activity.messageId === 'string' && activity.messageId !== ''\n const deliveryState = Aglyn.isCrmEmailDeliveryState(activity.deliveryState)\n ? activity.deliveryState\n : null\n const when = new Date(activity.atMs)\n const detail = [\n activity.outcome ? activity.outcome : null,\n typeof activity.durationMinutes === 'number' && activity.durationMinutes > 0\n ? durationLabel(activity.durationMinutes)\n : null,\n ].filter(Boolean)\n\n return (\n <Stack direction=\"row\" spacing={1.5} sx={{ alignItems: 'flex-start' }}>\n <Stack\n sx={{\n color: 'text.secondary',\n pt: 0.25,\n fontSize: (theme) => theme.typography.h6.fontSize,\n }}\n >\n {received ? (\n <MdiIcon path={mdiEmailReceiveOutline.path} />\n ) : (\n <ActivityKindIcon kind={activity.kind} />\n )}\n </Stack>\n <Stack spacing={0.5} sx={{ flex: 1, minWidth: 0 }}>\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 0.5 }}\n >\n <Chip label={label} size=\"small\" />\n {received ? (\n <Chip\n label=\"Received\"\n size=\"small\"\n variant=\"outlined\"\n color=\"info\"\n data-testid=\"activity-direction\"\n />\n ) : captured ? (\n <Chip\n label=\"Sent\"\n size=\"small\"\n variant=\"outlined\"\n data-testid=\"activity-direction\"\n />\n ) : null}\n {deliveryState ? (\n <Tooltip\n title={\n typeof activity.deliveryAtMs === 'number'\n ? new Date(activity.deliveryAtMs).toLocaleString()\n : ''\n }\n >\n <Chip\n label={Aglyn.CRM_EMAIL_DELIVERY_STATE_LABELS[deliveryState]}\n size=\"small\"\n variant=\"outlined\"\n color={Aglyn.isCrmEmailDeliveryFailure(deliveryState) ? 'error' : 'default'}\n data-testid=\"activity-delivery-state\"\n />\n </Tooltip>\n ) : null}\n {captured ? null : subject}\n {detail.length ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {detail.join(' · ')}\n </Typography>\n ) : null}\n </Stack>\n {activity.subject ? (\n <Typography variant=\"subtitle2\">{activity.subject}</Typography>\n ) : null}\n <Typography variant=\"body2\" sx={{ whiteSpace: 'pre-wrap' }}>\n {activity.body}\n </Typography>\n <Tooltip title={when.toLocaleString()}>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ alignSelf: 'flex-start' }}\n >\n {[\n received ? null : authorName(activity),\n received && activity.from ? `from ${activity.from}` : null,\n sent && activity.to ? `to ${activity.to}` : null,\n Aglyn.activityTimeLabel(activity.atMs, nowMs ?? Date.now()),\n ]\n .filter(Boolean)\n .join(' · ')}\n </Typography>\n </Tooltip>\n </Stack>\n {editable ? (\n <Stack direction=\"row\" spacing={0.5}>\n {onEdit && !sent && !received ? (\n <IconButton\n size=\"small\"\n aria-label=\"Edit activity\"\n onClick={() => onEdit(activity)}\n >\n <MdiIcon path={mdiPencilOutline.path} size={0.8} />\n </IconButton>\n ) : null}\n <IconButton\n size=\"small\"\n aria-label=\"Delete activity\"\n onClick={handleDelete}\n >\n <MdiIcon path={mdiDeleteOutline.path} size={0.8} />\n </IconButton>\n </Stack>\n ) : null}\n </Stack>\n )\n}\nActivityRow.displayName = 'ActivityRow'\n\nexport interface ActivityListProps {\n /** Newest-first, as the listener hands them back. */\n rows: readonly CrmActivityRow[]\n scope: ActivityScope\n onEdit?: (activity: CrmActivityRow) => void\n /** What the list says when there is nothing in it. */\n emptyText?: string\n /** The way out of an empty list — the record's \"Log activity\" button. */\n emptyAction?: ReactNode\n /** A further page exists; `onShowMore` widens the window. */\n hasMore?: boolean\n onShowMore?: () => void\n /** The record each row is about, for a list that spans records. */\n subjectFor?: (activity: CrmActivityRow) => ReactNode\n /**\n * No controls on any row, whoever is reading — and no member read to\n * decide them. A feed that spans records is a place to see what happened,\n * not to rewrite it; the record's own page is where an activity is\n * corrected, beside everything else about it.\n */\n readOnly?: boolean\n}\n\n/**\n * A newest-first list of logged activities with a \"show more\" foot\n * (AGL-2600).\n *\n * The rows arrive ordered — the query is `orderBy('atMs', 'desc')` — and the\n * list does not sort them again; a second sort here is a second place for\n * the order to be defined. The foot appears only while the probe row says\n * more exists, so it never leads nowhere.\n *\n * Who may edit is decided here, once, and handed to every row: the verdict\n * reads the member document, and the list is the one place that can ask\n * for it a single time however many rows it draws.\n */\nexport function ActivityList(props: ActivityListProps) {\n const {\n rows,\n scope,\n onEdit,\n emptyText = 'Nothing logged yet.',\n emptyAction,\n hasMore,\n onShowMore,\n subjectFor,\n readOnly,\n } = props\n const canEdit = useCanEditActivity(scope.orgId, !readOnly)\n if (!rows.length) {\n return (\n <EmptyStateComponent\n compact\n label={'Nothing logged yet'}\n description={emptyText}\n action={emptyAction}\n />\n )\n }\n return (\n <Stack spacing={2}>\n {rows.map((activity) => (\n <ActivityRow\n key={activity.$id}\n activity={activity}\n scope={scope}\n onEdit={onEdit}\n subject={subjectFor?.(activity)}\n editable={canEdit(activity)}\n />\n ))}\n {hasMore && onShowMore ? (\n <Button size=\"small\" onClick={onShowMore} sx={{ alignSelf: 'flex-start' }}>\n {'Show more'}\n </Button>\n ) : null}\n </Stack>\n )\n}\nActivityList.displayName = 'ActivityList'\n\nexport default ActivityList\n"],"names":["Aglyn","mdiAccountGroupOutline","mdiDeleteOutline","mdiDotsHorizontalCircleOutline","mdiEmailOutline","mdiEmailReceiveOutline","mdiNoteTextOutline","mdiPencilOutline","mdiPhoneOutline","MdiIcon","useConfirmationContext","EmptyStateComponent","useSnackbar","useUser","useUserName","Button","Chip","IconButton","Stack","Tooltip","Typography","deleteDoc","doc","useCallback","useCanEditActivity","KIND_ICONS","call","email","meeting","note","other","ActivityKindIcon","props","kind","size","icon","isCrmActivityKind","path","displayName","useActivityAuthorName","data","user","ownName","uid","activity","byName","byUid","durationLabel","minutes","hours","Math","floor","rest","String","padStart","ActivityRow","scope","onEdit","subject","nowMs","editable","firestore","dataScope","authorName","confirm","enqueueSnackbar","handleDelete","confirmed","title","description","CRM_ACTIVITY_KIND_LABELS","toLowerCase","confirmationText","confirmationButtonProps","color","then","catch","CRM_COLLECTIONS","activities","$id","variant","persist","error","console","allowDuplicate","label","sent","direction","received","captured","messageId","deliveryState","isCrmEmailDeliveryState","when","Date","atMs","detail","outcome","durationMinutes","filter","Boolean","spacing","sx","alignItems","pt","fontSize","theme","typography","h6","flex","minWidth","flexWrap","rowGap","data-testid","deliveryAtMs","toLocaleString","CRM_EMAIL_DELIVERY_STATE_LABELS","isCrmEmailDeliveryFailure","length","join","whiteSpace","body","alignSelf","from","to","activityTimeLabel","now","aria-label","onClick","ActivityList","rows","emptyText","emptyAction","hasMore","onShowMore","subjectFor","readOnly","canEdit","orgId","compact","action","map"],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as Aglyn from '@aglyn/aglyn';
|
|
2
|
+
import type { AglynOrgBilling, CrmActivityRow } from '@aglyn/aglyn';
|
|
3
|
+
/** The org document as the shell passes it: partial, and possibly absent. */
|
|
4
|
+
export type CrmOrg = Partial<AglynOrgBilling> | null | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* Which record an activity surface is about. Exactly one of the three is set
|
|
7
|
+
* by a record page; a feed across the CRM sets none.
|
|
8
|
+
*/
|
|
9
|
+
export interface ActivityRecordLink {
|
|
10
|
+
contactId?: string;
|
|
11
|
+
companyId?: string;
|
|
12
|
+
dealId?: string;
|
|
13
|
+
/** A lead's own log (AGL-2615) — see `CrmActivityLink.leadId`. */
|
|
14
|
+
leadId?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Everything an activity surface needs to know about WHERE it is reading
|
|
18
|
+
* and writing (AGL-2600), resolved once from the two props the shell hands
|
|
19
|
+
* every CRM page.
|
|
20
|
+
*
|
|
21
|
+
* Four surfaces read activities — a record card, a contact's timeline, the
|
|
22
|
+
* recent feed and the dialog that writes them — and each of them would
|
|
23
|
+
* otherwise resolve the same org, the same consent group and the same token
|
|
24
|
+
* set from the same two inputs. Resolved here so that a surface cannot read
|
|
25
|
+
* with one group and write with another, which is the shape of leak the
|
|
26
|
+
* contacts list closed (a listener with no `where` at all).
|
|
27
|
+
*
|
|
28
|
+
* Pure of Firestore reads: the org document is the one the shell already
|
|
29
|
+
* loaded, so the group and the tokens cost nothing, and the data scope is
|
|
30
|
+
* the memoized `['orgs', orgId]` tuple every host-scoped card builds.
|
|
31
|
+
*/
|
|
32
|
+
export declare function useActivityScope(hostId: string | null, org: CrmOrg): {
|
|
33
|
+
firestore: import("@firebase/firestore").Firestore;
|
|
34
|
+
dataScope: readonly ["orgs", string];
|
|
35
|
+
orgId: string;
|
|
36
|
+
/** The site a NEW activity names as provenance — the mounted site, or the picked one. */
|
|
37
|
+
hostId: string;
|
|
38
|
+
/**
|
|
39
|
+
* The site the surface is MOUNTED under, or `null` at the organization
|
|
40
|
+
* level — what a dialog reads to decide whether to ask which site.
|
|
41
|
+
*/
|
|
42
|
+
mountedHostId: string;
|
|
43
|
+
consentGroup: Aglyn.ConsentGroup;
|
|
44
|
+
readTokens: readonly Aglyn.ScopeToken[];
|
|
45
|
+
writeTokens: readonly Aglyn.ScopeToken[];
|
|
46
|
+
};
|
|
47
|
+
export type ActivityScope = ReturnType<typeof useActivityScope>;
|
|
48
|
+
/**
|
|
49
|
+
* Whether the signed-in user may EDIT or DELETE a given activity (AGL-2600).
|
|
50
|
+
*
|
|
51
|
+
* The author may, and so may an org-wide member — the person who administers
|
|
52
|
+
* the org can correct or remove anything logged in it. Nobody else: a scoped
|
|
53
|
+
* colleague may read a call log they did not write, and may not rewrite it.
|
|
54
|
+
*
|
|
55
|
+
* ⚠️ This is a UI verdict, not an enforced one. The Firestore rules on
|
|
56
|
+
* `crmActivities` admit any member who may write scoped org data, and they
|
|
57
|
+
* do not distinguish the author from anybody else — there is no `byUid`
|
|
58
|
+
* clause in them. The controls are hidden here so that the console does not
|
|
59
|
+
* offer a colleague's log for editing, and a caller who bypasses the console
|
|
60
|
+
* is a caller the rules already admit. Tightening the rules to the author is
|
|
61
|
+
* a decision about what the API permits, not something a card takes on its
|
|
62
|
+
* own.
|
|
63
|
+
*
|
|
64
|
+
* `useScopeTokens` answers org-wide while it loads, so the verdict for a
|
|
65
|
+
* NON-author waits for `loaded` — a scoped colleague must not see edit
|
|
66
|
+
* controls flash on for one paint and then vanish.
|
|
67
|
+
*
|
|
68
|
+
* Called ONCE by the list that draws the rows, never by a row. The verdict
|
|
69
|
+
* costs a read of the member document, and a hundred rows each asking would
|
|
70
|
+
* be a hundred reads of one document on every mount — the shape of cost the
|
|
71
|
+
* console pays nowhere else. `enabled` is for a surface that offers no
|
|
72
|
+
* controls at all, the feed: `useScopeTokens` opens nothing for an undefined
|
|
73
|
+
* org, so a disabled verdict reads nothing and answers no.
|
|
74
|
+
*/
|
|
75
|
+
export declare function useCanEditActivity(orgId: string | undefined, enabled?: boolean): (activity: Pick<CrmActivityRow, "byUid">) => boolean;
|
|
76
|
+
/** How many rows a "show more" step adds, and how many the first paint reads. */
|
|
77
|
+
export declare const ACTIVITY_PAGE_SIZE = 100;
|
|
78
|
+
/**
|
|
79
|
+
* The activities filed against one record, or across the CRM, newest-first
|
|
80
|
+
* and bounded (AGL-2600).
|
|
81
|
+
*
|
|
82
|
+
* The window is the query. `usePagedCollection` widens the listener by one
|
|
83
|
+
* page each time the reader asks for more, so a record with three hundred
|
|
84
|
+
* calls costs a hundred documents until somebody wants the next hundred —
|
|
85
|
+
* and `hasMore` is a fact from the probe row, not a guess from the length.
|
|
86
|
+
* The rows handed back are the WHOLE window so far, not the last page alone,
|
|
87
|
+
* because a log reads as one list that grows at the bottom rather than as
|
|
88
|
+
* numbered pages.
|
|
89
|
+
*
|
|
90
|
+
* Filtered by `array-contains-any` over the reader's tokens, which is the
|
|
91
|
+
* predicate the rules evaluate with `hasAny`: a filtered query is provable
|
|
92
|
+
* per document, and an unfiltered one is refused outright rather than
|
|
93
|
+
* quietly returning everything. The record filter is one equality on top of
|
|
94
|
+
* it — the four indexes `(visibleTo, contactId|companyId|dealId|leadId, atMs
|
|
95
|
+
* DESC)` exist for exactly these queries, and `(visibleTo, atMs DESC)` for the
|
|
96
|
+
* feed that names no record.
|
|
97
|
+
*
|
|
98
|
+
* Each record filter is indexed twice. An organization-level reader has no
|
|
99
|
+
* tokens, so `crmVisibleToClause` contributes no constraint and the query
|
|
100
|
+
* arrives as `(<record>, atMs DESC)` with the array field gone — a different
|
|
101
|
+
* index, not a prefix of the one above it. Adding a record kind here means
|
|
102
|
+
* adding BOTH halves; one of them alone leaves the other audience unserved.
|
|
103
|
+
*
|
|
104
|
+
* These are all DESCENDING because this window asks for `desc` outright. A
|
|
105
|
+
* read over the same rows that names no order is not served by them: Firestore
|
|
106
|
+
* orders such a query by its range field ascending, and an index serves one
|
|
107
|
+
* direction or its exact reverse. That is why the report counts carry their
|
|
108
|
+
* own ascending indexes rather than borrowing these.
|
|
109
|
+
*/
|
|
110
|
+
export declare function useActivityWindow(scope: ActivityScope, link: ActivityRecordLink, pageSize?: number): {
|
|
111
|
+
rows: Aglyn.CrmActivityRow[];
|
|
112
|
+
hasMore: boolean;
|
|
113
|
+
showMore: () => void;
|
|
114
|
+
status: import("@aglyn/tenant-feature-instance").FirestoreCollectionStatus;
|
|
115
|
+
/** Whether the listener has a scope to read at all. */
|
|
116
|
+
ready: boolean;
|
|
117
|
+
};
|