@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,433 @@
|
|
|
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 { createResourceUid, CRM_COLLECTIONS, CRM_RECORDS_BAND_FULL_MESSAGE, pluginDocsHelp } from "@aglyn/aglyn";
|
|
20
|
+
import { ICON_VARIANT_CLOSE } from "@aglyn/shared-data-enums";
|
|
21
|
+
import { Container, HelpTip, MdiIcon, SrOnly } from "@aglyn/shared-ui-jsx";
|
|
22
|
+
import { NavigationDrawerComponent } from "@aglyn/shared-ui-jsx/components/navigation-drawer.component";
|
|
23
|
+
import { useSnackbar } from "@aglyn/shared-ui-snackstack";
|
|
24
|
+
import { useFirestore, useUser, writeGuardedBySeed } from "@aglyn/tenant-feature-instance";
|
|
25
|
+
import { Alert, Button, IconButton, MenuItem, Stack, TextField, Typography } from "@mui/material";
|
|
26
|
+
import { deleteField, doc, serverTimestamp, setDoc, updateDoc } from "firebase/firestore";
|
|
27
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
28
|
+
import { useContactFieldDefinitions } from "../hooks/use-contact-field-definitions.js";
|
|
29
|
+
import { useCrmActivityLogger } from "../hooks/use-crm-activity-logger.js";
|
|
30
|
+
import { useCrmRecordsQuota } from "../hooks/use-crm-records-quota.js";
|
|
31
|
+
import { useCrmScope } from "../hooks/use-crm-scope.js";
|
|
32
|
+
import { companyDraftFields, companyDraftFrom, EMPTY_COMPANY_DRAFT } from "../model/companies.js";
|
|
33
|
+
import { crmCustomDraftDocument, crmCustomDraftMissingRequired, crmCustomDraftValue, crmCustomDraftWrites } from "../model/crm-custom-draft.js";
|
|
34
|
+
import { CrmCustomFieldControl } from "./crm-custom-field-control.js";
|
|
35
|
+
import { CrmSitePicker } from "./crm-site-picker.js";
|
|
36
|
+
const ADDRESS_FIELDS = [
|
|
37
|
+
{
|
|
38
|
+
key: 'line1',
|
|
39
|
+
label: 'Address line 1'
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
key: 'line2',
|
|
43
|
+
label: 'Address line 2'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: 'city',
|
|
47
|
+
label: 'City'
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
key: 'state',
|
|
51
|
+
label: 'State or region'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
key: 'postalCode',
|
|
55
|
+
label: 'Postal code'
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
key: 'country',
|
|
59
|
+
label: 'Country (two-letter code)'
|
|
60
|
+
}
|
|
61
|
+
];
|
|
62
|
+
/**
|
|
63
|
+
* ONE COMPANY, created or edited (AGL-2597).
|
|
64
|
+
*
|
|
65
|
+
* A drawer rather than a form above the list, and the same drawer for both
|
|
66
|
+
* jobs: a company is eight fields and an address, which is too much to wedge
|
|
67
|
+
* over a table and exactly the same set whether the record exists yet. The
|
|
68
|
+
* list opens it empty; the company's page opens it on the record.
|
|
69
|
+
*
|
|
70
|
+
* Nothing is written per keystroke. The draft is held here and turned into a
|
|
71
|
+
* document by `companyDraftFields` on Save, which is where a domain typed as
|
|
72
|
+
* `acme` or a phone number with no country code is refused — as a message
|
|
73
|
+
* beside the button, with the typed values left where they are.
|
|
74
|
+
*/ export function CompanyEditDrawer(props) {
|
|
75
|
+
var _ref, _members_error;
|
|
76
|
+
const { open, onClose, hostId, org, company, seed, members, onSaved } = props;
|
|
77
|
+
const firestore = useFirestore();
|
|
78
|
+
const { data: user } = useUser();
|
|
79
|
+
const { enqueueSnackbar } = useSnackbar();
|
|
80
|
+
const { scope, createTokens, createHostId } = useCrmScope({
|
|
81
|
+
hostId,
|
|
82
|
+
org
|
|
83
|
+
});
|
|
84
|
+
// The feed the act is logged in is the level it was PERFORMED at
|
|
85
|
+
// (AGL-2738): this site's under a site, the organization's at the org
|
|
86
|
+
// hub. `createHostId` is where the record is STAMPED, which at the hub is
|
|
87
|
+
// a site the reader picked and may hold no role on — a different question
|
|
88
|
+
// from where the line belongs, and a gate the record write never faced.
|
|
89
|
+
const logActivity = useCrmActivityLogger(hostId);
|
|
90
|
+
const [draft, setDraft] = useState(EMPTY_COMPANY_DRAFT);
|
|
91
|
+
const [busy, setBusy] = useState(false);
|
|
92
|
+
const [error, setError] = useState('');
|
|
93
|
+
/*
|
|
94
|
+
* THE CUSTOM FIELDS (AGL-2661): the org's company definitions, and the
|
|
95
|
+
* keys the reader has touched over what the company stores. Saved as the
|
|
96
|
+
* difference — see `crm-custom-draft` — beside the fixed fields, in the
|
|
97
|
+
* same write, so a company is never half-saved.
|
|
98
|
+
*/ const fields = useContactFieldDefinitions((_ref = scope == null ? void 0 : scope[1]) != null ? _ref : null, 'company');
|
|
99
|
+
const storedCustom = useMemo(()=>{
|
|
100
|
+
var _ref;
|
|
101
|
+
return (_ref = company == null ? void 0 : company.custom) != null ? _ref : {};
|
|
102
|
+
}, [
|
|
103
|
+
company == null ? void 0 : company.custom
|
|
104
|
+
]);
|
|
105
|
+
const [custom, setCustom] = useState({});
|
|
106
|
+
/*
|
|
107
|
+
* THE RECORDS BAND (AGL-2611), read only for a CREATE: a company is a
|
|
108
|
+
* record of the band the contacts list is banded by, and on an org at a
|
|
109
|
+
* full hard band this drawer refuses the way `upsertHostContact` refuses a
|
|
110
|
+
* capture — same number, same sentence. An edit is not a record and pays
|
|
111
|
+
* for no aggregate. Only a SETTLED refusal refuses: three reads that have
|
|
112
|
+
* not answered are not a full band.
|
|
113
|
+
*/ const records = useCrmRecordsQuota(open && !company ? scope : null, org);
|
|
114
|
+
const bandFull = !company && records.ready && !records.quota.allowed;
|
|
115
|
+
/*
|
|
116
|
+
* Seeded when the drawer OPENS, and not on every render of the card
|
|
117
|
+
* behind it: the company listen is live, so re-seeding on each snapshot
|
|
118
|
+
* would take a field away from whoever is typing in it — including on the
|
|
119
|
+
* snapshot their own save produces. The create case seeds the owner to the
|
|
120
|
+
* person filing the record, which is the answer nine times in ten and one
|
|
121
|
+
* click to change.
|
|
122
|
+
*/ const companyId = company == null ? void 0 : company.$id;
|
|
123
|
+
useEffect(()=>{
|
|
124
|
+
var _ref;
|
|
125
|
+
if (!open) return;
|
|
126
|
+
setDraft(company ? companyDraftFrom(company) : _extends({}, EMPTY_COMPANY_DRAFT, {
|
|
127
|
+
ownerUid: (_ref = user == null ? void 0 : user.uid) != null ? _ref : ''
|
|
128
|
+
}));
|
|
129
|
+
setCustom({});
|
|
130
|
+
setError('');
|
|
131
|
+
// The stored fields are read once per opening; `company` is a new object
|
|
132
|
+
// on every snapshot and must not re-seed.
|
|
133
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
134
|
+
}, [
|
|
135
|
+
open,
|
|
136
|
+
companyId
|
|
137
|
+
]);
|
|
138
|
+
const patch = useCallback((field, value)=>setDraft((current)=>_extends({}, current, {
|
|
139
|
+
[field]: value
|
|
140
|
+
})), []);
|
|
141
|
+
const patchAddress = useCallback((field, value)=>setDraft((current)=>_extends({}, current, {
|
|
142
|
+
address: _extends({}, current.address, {
|
|
143
|
+
[field]: value
|
|
144
|
+
})
|
|
145
|
+
})), []);
|
|
146
|
+
const handleSave = useCallback(async ()=>{
|
|
147
|
+
if (busy || !scope) return;
|
|
148
|
+
const result = companyDraftFields(draft);
|
|
149
|
+
if (result.ok === false) return setError(result.error);
|
|
150
|
+
const missing = crmCustomDraftMissingRequired(fields.active, storedCustom, custom, company ? 'edit' : 'create');
|
|
151
|
+
if (missing.length) return setError(`${missing.join(', ')} is required.`);
|
|
152
|
+
const customDocument = crmCustomDraftDocument(custom);
|
|
153
|
+
setError('');
|
|
154
|
+
setBusy(true);
|
|
155
|
+
try {
|
|
156
|
+
if (company) {
|
|
157
|
+
var _ref, _ref1;
|
|
158
|
+
const ref = doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.companies, company.$id);
|
|
159
|
+
// The guard WRAPS the write — an early return is a shape you can
|
|
160
|
+
// keep while losing the protection.
|
|
161
|
+
const verdict = await writeGuardedBySeed({
|
|
162
|
+
subject: 'company',
|
|
163
|
+
unreadable: (_ref = seed == null ? void 0 : seed.unreadable) != null ? _ref : false,
|
|
164
|
+
fromCache: (_ref1 = seed == null ? void 0 : seed.fromCache) != null ? _ref1 : false
|
|
165
|
+
}, async ()=>{
|
|
166
|
+
await updateDoc(ref, _extends({}, result.set, Object.fromEntries(result.cleared.map((field)=>[
|
|
167
|
+
field,
|
|
168
|
+
deleteField()
|
|
169
|
+
])), crmCustomDraftWrites(storedCustom, custom), {
|
|
170
|
+
updatedAt: serverTimestamp()
|
|
171
|
+
}));
|
|
172
|
+
});
|
|
173
|
+
if (!verdict.ok) return setError(verdict.message);
|
|
174
|
+
enqueueSnackbar('Company saved', {
|
|
175
|
+
variant: 'success',
|
|
176
|
+
persist: false
|
|
177
|
+
});
|
|
178
|
+
onSaved(company.$id);
|
|
179
|
+
} else {
|
|
180
|
+
var _ref2;
|
|
181
|
+
if (bandFull) return setError(CRM_RECORDS_BAND_FULL_MESSAGE);
|
|
182
|
+
const id = createResourceUid();
|
|
183
|
+
// Held by the button until the capturing site is known; checked
|
|
184
|
+
// again here because a callback can outlive the render that held it.
|
|
185
|
+
if (!createHostId) return;
|
|
186
|
+
await setDoc(doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.companies, id), _extends({}, result.set, customDocument ? {
|
|
187
|
+
custom: customDocument
|
|
188
|
+
} : {}, {
|
|
189
|
+
/*
|
|
190
|
+
* The scope every CRM creator stamps: the whole org when the org
|
|
191
|
+
* shares by default, and otherwise the sites that present as one
|
|
192
|
+
* sender. Without it the record is seen by NOBODY — an absent
|
|
193
|
+
* `visibleTo` matches no reader's predicate — and the rules
|
|
194
|
+
* refuse a scoped member creating outside their own tokens.
|
|
195
|
+
*/ visibleTo: [
|
|
196
|
+
...createTokens
|
|
197
|
+
],
|
|
198
|
+
// Provenance: the site whose console filed it, never rewritten.
|
|
199
|
+
hostId: createHostId,
|
|
200
|
+
createdByUid: (_ref2 = user == null ? void 0 : user.uid) != null ? _ref2 : '',
|
|
201
|
+
createdAt: serverTimestamp(),
|
|
202
|
+
updatedAt: serverTimestamp()
|
|
203
|
+
}));
|
|
204
|
+
// Setup → Activity shows CRM work (AGL-2622): the company is org
|
|
205
|
+
// data, but the act happened in this site's console and belongs in
|
|
206
|
+
// its feed. Creation only — an edit is a save the card reports.
|
|
207
|
+
logActivity('Added company', {
|
|
208
|
+
type: 'company',
|
|
209
|
+
id,
|
|
210
|
+
name: draft.name.trim()
|
|
211
|
+
});
|
|
212
|
+
enqueueSnackbar(`Company "${draft.name.trim()}" created`, {
|
|
213
|
+
variant: 'success',
|
|
214
|
+
persist: false
|
|
215
|
+
});
|
|
216
|
+
onSaved(id);
|
|
217
|
+
}
|
|
218
|
+
onClose();
|
|
219
|
+
} catch (caught) {
|
|
220
|
+
console.error(caught);
|
|
221
|
+
setError('The company could not be saved.');
|
|
222
|
+
} finally{
|
|
223
|
+
setBusy(false);
|
|
224
|
+
}
|
|
225
|
+
}, [
|
|
226
|
+
busy,
|
|
227
|
+
scope,
|
|
228
|
+
draft,
|
|
229
|
+
company,
|
|
230
|
+
bandFull,
|
|
231
|
+
firestore,
|
|
232
|
+
seed,
|
|
233
|
+
createTokens,
|
|
234
|
+
createHostId,
|
|
235
|
+
user,
|
|
236
|
+
logActivity,
|
|
237
|
+
enqueueSnackbar,
|
|
238
|
+
onSaved,
|
|
239
|
+
onClose,
|
|
240
|
+
fields.active,
|
|
241
|
+
storedCustom,
|
|
242
|
+
custom
|
|
243
|
+
]);
|
|
244
|
+
return /*#__PURE__*/ _jsx(NavigationDrawerComponent, {
|
|
245
|
+
open: open,
|
|
246
|
+
anchor: "right",
|
|
247
|
+
variant: "temporary",
|
|
248
|
+
onClose: onClose,
|
|
249
|
+
AppBarProps: {
|
|
250
|
+
color: 'surface'
|
|
251
|
+
},
|
|
252
|
+
appBarLeft: /*#__PURE__*/ _jsxs(_Fragment, {
|
|
253
|
+
children: [
|
|
254
|
+
/*#__PURE__*/ _jsxs(IconButton, {
|
|
255
|
+
color: "inherit",
|
|
256
|
+
edge: "start",
|
|
257
|
+
onClick: onClose,
|
|
258
|
+
sx: {
|
|
259
|
+
mr: 2
|
|
260
|
+
},
|
|
261
|
+
children: [
|
|
262
|
+
/*#__PURE__*/ _jsx(MdiIcon, {
|
|
263
|
+
path: ICON_VARIANT_CLOSE.path
|
|
264
|
+
}),
|
|
265
|
+
/*#__PURE__*/ _jsx(SrOnly, {
|
|
266
|
+
children: 'close drawer'
|
|
267
|
+
})
|
|
268
|
+
]
|
|
269
|
+
}),
|
|
270
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
271
|
+
variant: "h6",
|
|
272
|
+
component: "div",
|
|
273
|
+
children: company ? 'Edit company' : 'New company'
|
|
274
|
+
}),
|
|
275
|
+
/*#__PURE__*/ _jsx(HelpTip, _extends({}, pluginDocsHelp('companies', {
|
|
276
|
+
anchor: '#create-a-company'
|
|
277
|
+
})))
|
|
278
|
+
]
|
|
279
|
+
}),
|
|
280
|
+
children: /*#__PURE__*/ _jsx(Container, {
|
|
281
|
+
gutterY: true,
|
|
282
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
283
|
+
spacing: 2,
|
|
284
|
+
children: [
|
|
285
|
+
company ? null : /*#__PURE__*/ _jsx(CrmSitePicker, {
|
|
286
|
+
hostId: hostId,
|
|
287
|
+
disabled: busy,
|
|
288
|
+
helperText: "The site this company belongs to — it decides which of your sites may see it."
|
|
289
|
+
}),
|
|
290
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
291
|
+
variant: "body2",
|
|
292
|
+
color: "text.secondary",
|
|
293
|
+
children: 'The organization behind one or more of your contacts. The ' + 'domain is what suggests this company for a person from their ' + 'email address, so enter the bare hostname.'
|
|
294
|
+
}),
|
|
295
|
+
bandFull ? /*#__PURE__*/ _jsx(Alert, {
|
|
296
|
+
severity: "warning",
|
|
297
|
+
children: CRM_RECORDS_BAND_FULL_MESSAGE
|
|
298
|
+
}) : null,
|
|
299
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
300
|
+
size: "small",
|
|
301
|
+
label: "Name",
|
|
302
|
+
required: true,
|
|
303
|
+
value: draft.name,
|
|
304
|
+
onChange: (event)=>patch('name', event.target.value),
|
|
305
|
+
autoFocus: true
|
|
306
|
+
}),
|
|
307
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
308
|
+
size: "small",
|
|
309
|
+
label: "Domain",
|
|
310
|
+
placeholder: "example.com",
|
|
311
|
+
value: draft.domain,
|
|
312
|
+
onChange: (event)=>patch('domain', event.target.value)
|
|
313
|
+
}),
|
|
314
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
315
|
+
size: "small",
|
|
316
|
+
label: "Website",
|
|
317
|
+
placeholder: "https://www.example.com",
|
|
318
|
+
value: draft.website,
|
|
319
|
+
onChange: (event)=>patch('website', event.target.value)
|
|
320
|
+
}),
|
|
321
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
322
|
+
size: "small",
|
|
323
|
+
label: "Phone",
|
|
324
|
+
placeholder: "+1 512 555 0123",
|
|
325
|
+
value: draft.phone,
|
|
326
|
+
onChange: (event)=>patch('phone', event.target.value)
|
|
327
|
+
}),
|
|
328
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
329
|
+
size: "small",
|
|
330
|
+
label: "Industry",
|
|
331
|
+
value: draft.industry,
|
|
332
|
+
onChange: (event)=>patch('industry', event.target.value)
|
|
333
|
+
}),
|
|
334
|
+
/*#__PURE__*/ _jsxs(TextField, {
|
|
335
|
+
select: true,
|
|
336
|
+
size: "small",
|
|
337
|
+
label: "Owner",
|
|
338
|
+
value: draft.ownerUid,
|
|
339
|
+
disabled: !members.ready,
|
|
340
|
+
helperText: !members.ready ? 'Loading your team…' : (_members_error = members.error) != null ? _members_error : 'The team member responsible for this account.',
|
|
341
|
+
onChange: (event)=>patch('ownerUid', event.target.value),
|
|
342
|
+
children: [
|
|
343
|
+
/*#__PURE__*/ _jsx(MenuItem, {
|
|
344
|
+
value: "",
|
|
345
|
+
children: 'Nobody yet'
|
|
346
|
+
}),
|
|
347
|
+
draft.ownerUid && !members.options.some((option)=>option.uid === draft.ownerUid) ? /*#__PURE__*/ _jsx(MenuItem, {
|
|
348
|
+
value: draft.ownerUid,
|
|
349
|
+
children: members.labelFor(draft.ownerUid)
|
|
350
|
+
}) : null,
|
|
351
|
+
members.options.map((option)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
352
|
+
value: option.uid,
|
|
353
|
+
children: option.label
|
|
354
|
+
}, option.uid))
|
|
355
|
+
]
|
|
356
|
+
}),
|
|
357
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
358
|
+
size: "small",
|
|
359
|
+
label: "Tags",
|
|
360
|
+
placeholder: "enterprise, west",
|
|
361
|
+
helperText: "Comma-separated, lowercased — the same tags the bulk bar adds",
|
|
362
|
+
value: draft.tags,
|
|
363
|
+
onChange: (event)=>patch('tags', event.target.value)
|
|
364
|
+
}),
|
|
365
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
366
|
+
variant: "subtitle2",
|
|
367
|
+
children: 'Address'
|
|
368
|
+
}),
|
|
369
|
+
ADDRESS_FIELDS.map((field)=>{
|
|
370
|
+
var _draft_address_field_key;
|
|
371
|
+
return /*#__PURE__*/ _jsx(TextField, {
|
|
372
|
+
size: "small",
|
|
373
|
+
label: field.label,
|
|
374
|
+
value: (_draft_address_field_key = draft.address[field.key]) != null ? _draft_address_field_key : '',
|
|
375
|
+
onChange: (event)=>patchAddress(field.key, event.target.value)
|
|
376
|
+
}, field.key);
|
|
377
|
+
}),
|
|
378
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
379
|
+
size: "small",
|
|
380
|
+
label: "Notes",
|
|
381
|
+
value: draft.notes,
|
|
382
|
+
onChange: (event)=>patch('notes', event.target.value),
|
|
383
|
+
multiline: true,
|
|
384
|
+
minRows: 3
|
|
385
|
+
}),
|
|
386
|
+
fields.active.length ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
387
|
+
children: [
|
|
388
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
389
|
+
variant: "subtitle2",
|
|
390
|
+
children: 'Custom fields'
|
|
391
|
+
}),
|
|
392
|
+
fields.active.map((definition)=>/*#__PURE__*/ _jsx(CrmCustomFieldControl, {
|
|
393
|
+
definition: definition,
|
|
394
|
+
value: crmCustomDraftValue(storedCustom, custom, definition.key),
|
|
395
|
+
onChange: (value)=>setCustom((current)=>_extends({}, current, {
|
|
396
|
+
[definition.key]: value
|
|
397
|
+
})),
|
|
398
|
+
disabled: busy
|
|
399
|
+
}, definition.$id))
|
|
400
|
+
]
|
|
401
|
+
}) : null,
|
|
402
|
+
error ? /*#__PURE__*/ _jsx(Alert, {
|
|
403
|
+
severity: "warning",
|
|
404
|
+
children: error
|
|
405
|
+
}) : null,
|
|
406
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
407
|
+
direction: "row",
|
|
408
|
+
spacing: 1,
|
|
409
|
+
children: [
|
|
410
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
411
|
+
variant: "contained",
|
|
412
|
+
color: "primary",
|
|
413
|
+
// A new company waits for its capturing site.
|
|
414
|
+
disabled: busy || !scope || !draft.name.trim() || !company && !createHostId,
|
|
415
|
+
onClick: ()=>void handleSave(),
|
|
416
|
+
children: busy ? 'Saving…' : company ? 'Save company' : 'Create company'
|
|
417
|
+
}),
|
|
418
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
419
|
+
onClick: onClose,
|
|
420
|
+
disabled: busy,
|
|
421
|
+
children: 'Cancel'
|
|
422
|
+
})
|
|
423
|
+
]
|
|
424
|
+
})
|
|
425
|
+
]
|
|
426
|
+
})
|
|
427
|
+
})
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
CompanyEditDrawer.displayName = 'CompanyEditDrawer';
|
|
431
|
+
export default CompanyEditDrawer;
|
|
432
|
+
|
|
433
|
+
//# sourceMappingURL=company-edit-drawer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/company-edit-drawer.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport {\n type AglynOrgBilling,\n type AglynPostalAddress,\n createResourceUid,\n CRM_COLLECTIONS,\n CRM_RECORDS_BAND_FULL_MESSAGE,\n type CrmCompany,\n pluginDocsHelp,\n} from '@aglyn/aglyn'\nimport { ICON_VARIANT_CLOSE } from '@aglyn/shared-data-enums'\nimport { Container, HelpTip, MdiIcon, SrOnly } from '@aglyn/shared-ui-jsx'\nimport { NavigationDrawerComponent } from '@aglyn/shared-ui-jsx/components/navigation-drawer.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n useFirestore,\n useUser,\n writeGuardedBySeed,\n} from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n IconButton,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport {\n deleteField,\n doc,\n serverTimestamp,\n setDoc,\n updateDoc,\n} from 'firebase/firestore'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport { useContactFieldDefinitions } from '../hooks/use-contact-field-definitions'\nimport { useCrmActivityLogger } from '../hooks/use-crm-activity-logger'\nimport { useCrmRecordsQuota } from '../hooks/use-crm-records-quota'\nimport { useCrmScope } from '../hooks/use-crm-scope'\nimport type { OrgMemberOptions } from '../hooks/use-org-member-options'\nimport {\n type CompanyDraft,\n companyDraftFields,\n companyDraftFrom,\n EMPTY_COMPANY_DRAFT,\n} from '../model/companies'\nimport {\n type CrmCustomDraft,\n crmCustomDraftDocument,\n crmCustomDraftMissingRequired,\n crmCustomDraftValue,\n crmCustomDraftWrites,\n} from '../model/crm-custom-draft'\nimport { CrmCustomFieldControl } from './crm-custom-field-control'\nimport { CrmSitePicker } from './crm-site-picker'\n\nexport interface CompanyEditDrawerProps {\n open: boolean\n onClose: () => void\n /**\n * The site the drawer is opened under, or `null` at the organization\n * level (AGL-2630), where a NEW company asks which site captures it and\n * an edit keeps the company's own.\n */\n hostId: string | null\n org?: Partial<AglynOrgBilling> | null\n /**\n * The company being EDITED, or nothing to create one.\n *\n * The two modes differ in what the fields start as and in which write\n * runs: an edit opens on the stored values and updates the document, a\n * create opens empty and stamps the scope, provenance and timestamps a new\n * record must carry.\n */\n company?: (Partial<CrmCompany> & { $id: string }) | null\n /**\n * Whether the stored values the edit opened on can be trusted.\n *\n * Every optional field is written on every save — a blank one is a\n * DELETE — so a form seeded from a cached read would write the cache's\n * blanks over the server's values. The card that holds the listen reports\n * its own `fromCache` and `status`; the drawer refuses to save on a seed\n * the server never confirmed, and says so.\n */\n seed?: { fromCache: boolean; unreadable: boolean }\n /**\n * The team, for the owner picker.\n *\n * Handed in rather than fetched here, because the surface opening this\n * drawer already holds the roster to name owners in its rows, and one\n * fetch per surface is the bargain.\n */\n members: OrgMemberOptions\n /** Called with the record's id after a successful write. */\n onSaved: (companyId: string) => void\n}\n\nconst ADDRESS_FIELDS: ReadonlyArray<{\n key: keyof AglynPostalAddress\n label: string\n}> = [\n { key: 'line1', label: 'Address line 1' },\n { key: 'line2', label: 'Address line 2' },\n { key: 'city', label: 'City' },\n { key: 'state', label: 'State or region' },\n { key: 'postalCode', label: 'Postal code' },\n { key: 'country', label: 'Country (two-letter code)' },\n]\n\n/**\n * ONE COMPANY, created or edited (AGL-2597).\n *\n * A drawer rather than a form above the list, and the same drawer for both\n * jobs: a company is eight fields and an address, which is too much to wedge\n * over a table and exactly the same set whether the record exists yet. The\n * list opens it empty; the company's page opens it on the record.\n *\n * Nothing is written per keystroke. The draft is held here and turned into a\n * document by `companyDraftFields` on Save, which is where a domain typed as\n * `acme` or a phone number with no country code is refused — as a message\n * beside the button, with the typed values left where they are.\n */\nexport function CompanyEditDrawer(props: CompanyEditDrawerProps) {\n const { open, onClose, hostId, org, company, seed, members, onSaved } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const { scope, createTokens, createHostId } = useCrmScope({ hostId, org })\n // The feed the act is logged in is the level it was PERFORMED at\n // (AGL-2738): this site's under a site, the organization's at the org\n // hub. `createHostId` is where the record is STAMPED, which at the hub is\n // a site the reader picked and may hold no role on — a different question\n // from where the line belongs, and a gate the record write never faced.\n const logActivity = useCrmActivityLogger(hostId)\n\n const [draft, setDraft] = useState<CompanyDraft>(EMPTY_COMPANY_DRAFT)\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState('')\n /*\n * THE CUSTOM FIELDS (AGL-2661): the org's company definitions, and the\n * keys the reader has touched over what the company stores. Saved as the\n * difference — see `crm-custom-draft` — beside the fixed fields, in the\n * same write, so a company is never half-saved.\n */\n const fields = useContactFieldDefinitions(scope?.[1] ?? null, 'company')\n const storedCustom = useMemo(() => company?.custom ?? {}, [company?.custom])\n const [custom, setCustom] = useState<CrmCustomDraft>({})\n /*\n * THE RECORDS BAND (AGL-2611), read only for a CREATE: a company is a\n * record of the band the contacts list is banded by, and on an org at a\n * full hard band this drawer refuses the way `upsertHostContact` refuses a\n * capture — same number, same sentence. An edit is not a record and pays\n * for no aggregate. Only a SETTLED refusal refuses: three reads that have\n * not answered are not a full band.\n */\n const records = useCrmRecordsQuota(open && !company ? scope : null, org)\n const bandFull = !company && records.ready && !records.quota.allowed\n\n /*\n * Seeded when the drawer OPENS, and not on every render of the card\n * behind it: the company listen is live, so re-seeding on each snapshot\n * would take a field away from whoever is typing in it — including on the\n * snapshot their own save produces. The create case seeds the owner to the\n * person filing the record, which is the answer nine times in ten and one\n * click to change.\n */\n const companyId = company?.$id\n useEffect(() => {\n if (!open) return\n setDraft(\n company\n ? companyDraftFrom(company)\n : { ...EMPTY_COMPANY_DRAFT, ownerUid: user?.uid ?? '' },\n )\n setCustom({})\n setError('')\n // The stored fields are read once per opening; `company` is a new object\n // on every snapshot and must not re-seed.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, companyId])\n\n const patch = useCallback(\n (field: keyof Omit<CompanyDraft, 'address'>, value: string) =>\n setDraft((current) => ({ ...current, [field]: value })),\n [],\n )\n const patchAddress = useCallback(\n (field: keyof AglynPostalAddress, value: string) =>\n setDraft((current) => ({\n ...current,\n address: { ...current.address, [field]: value },\n })),\n [],\n )\n\n const handleSave = useCallback(async () => {\n if (busy || !scope) return\n const result = companyDraftFields(draft)\n if (result.ok === false) return setError(result.error)\n const missing = crmCustomDraftMissingRequired(\n fields.active,\n storedCustom,\n custom,\n company ? 'edit' : 'create',\n )\n if (missing.length) return setError(`${missing.join(', ')} is required.`)\n const customDocument = crmCustomDraftDocument(custom)\n setError('')\n setBusy(true)\n try {\n if (company) {\n const ref = doc(\n firestore,\n scope[0],\n scope[1],\n CRM_COLLECTIONS.companies,\n company.$id,\n )\n // The guard WRAPS the write — an early return is a shape you can\n // keep while losing the protection.\n const verdict = await writeGuardedBySeed(\n {\n subject: 'company',\n unreadable: seed?.unreadable ?? false,\n fromCache: seed?.fromCache ?? false,\n },\n async () => {\n await updateDoc(ref, {\n ...result.set,\n // A blank optional field is a DELETE on an edit, or the old\n // domain would stay stored and keep matching people by email.\n ...Object.fromEntries(\n result.cleared.map((field) => [field, deleteField()]),\n ),\n // The custom keys that changed, merged into the stored map.\n ...crmCustomDraftWrites(storedCustom, custom),\n updatedAt: serverTimestamp(),\n })\n },\n )\n if (!verdict.ok) return setError(verdict.message)\n enqueueSnackbar('Company saved', { variant: 'success', persist: false })\n onSaved(company.$id)\n } else {\n if (bandFull) return setError(CRM_RECORDS_BAND_FULL_MESSAGE)\n const id = createResourceUid()\n // Held by the button until the capturing site is known; checked\n // again here because a callback can outlive the render that held it.\n if (!createHostId) return\n await setDoc(\n doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.companies, id),\n {\n ...result.set,\n ...(customDocument ? { custom: customDocument } : {}),\n /*\n * The scope every CRM creator stamps: the whole org when the org\n * shares by default, and otherwise the sites that present as one\n * sender. Without it the record is seen by NOBODY — an absent\n * `visibleTo` matches no reader's predicate — and the rules\n * refuse a scoped member creating outside their own tokens.\n */\n visibleTo: [...createTokens],\n // Provenance: the site whose console filed it, never rewritten.\n hostId: createHostId,\n createdByUid: user?.uid ?? '',\n createdAt: serverTimestamp(),\n updatedAt: serverTimestamp(),\n },\n )\n // Setup → Activity shows CRM work (AGL-2622): the company is org\n // data, but the act happened in this site's console and belongs in\n // its feed. Creation only — an edit is a save the card reports.\n logActivity('Added company', { type: 'company', id, name: draft.name.trim() })\n enqueueSnackbar(`Company \"${draft.name.trim()}\" created`, {\n variant: 'success',\n persist: false,\n })\n onSaved(id)\n }\n onClose()\n } catch (caught) {\n console.error(caught)\n setError('The company could not be saved.')\n } finally {\n setBusy(false)\n }\n }, [\n busy,\n scope,\n draft,\n company,\n bandFull,\n firestore,\n seed,\n createTokens,\n createHostId,\n user,\n logActivity,\n enqueueSnackbar,\n onSaved,\n onClose,\n fields.active,\n storedCustom,\n custom,\n ])\n\n return (\n <NavigationDrawerComponent\n open={open}\n anchor=\"right\"\n variant=\"temporary\"\n onClose={onClose}\n AppBarProps={{ color: 'surface' }}\n appBarLeft={\n <>\n <IconButton\n color=\"inherit\"\n edge=\"start\"\n onClick={onClose}\n sx={{ mr: 2 }}\n >\n <MdiIcon path={ICON_VARIANT_CLOSE.path} />\n <SrOnly>{'close drawer'}</SrOnly>\n </IconButton>\n <Typography variant=\"h6\" component=\"div\">\n {company ? 'Edit company' : 'New company'}\n </Typography>\n <HelpTip\n {...pluginDocsHelp('companies', { anchor: '#create-a-company' })}\n />\n </>\n }\n >\n <Container gutterY>\n <Stack spacing={2}>\n {/*\n First, because the scope of everything below follows from it: at\n the organization level a new company names the site that\n captures it. Nothing under a site, and nothing on an edit — a\n company keeps the site it was made on (AGL-2630).\n */}\n {company ? null : (\n <CrmSitePicker\n hostId={hostId}\n disabled={busy}\n helperText=\"The site this company belongs to — it decides which of your sites may see it.\"\n />\n )}\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'The organization behind one or more of your contacts. The ' +\n 'domain is what suggests this company for a person from their ' +\n 'email address, so enter the bare hostname.'}\n </Typography>\n {bandFull ? (\n <Alert severity=\"warning\">{CRM_RECORDS_BAND_FULL_MESSAGE}</Alert>\n ) : null}\n <TextField\n size=\"small\"\n label=\"Name\"\n required\n value={draft.name}\n onChange={(event) => patch('name', event.target.value)}\n autoFocus\n />\n <TextField\n size=\"small\"\n label=\"Domain\"\n placeholder=\"example.com\"\n value={draft.domain}\n onChange={(event) => patch('domain', event.target.value)}\n />\n <TextField\n size=\"small\"\n label=\"Website\"\n placeholder=\"https://www.example.com\"\n value={draft.website}\n onChange={(event) => patch('website', event.target.value)}\n />\n <TextField\n size=\"small\"\n label=\"Phone\"\n placeholder=\"+1 512 555 0123\"\n value={draft.phone}\n onChange={(event) => patch('phone', event.target.value)}\n />\n <TextField\n size=\"small\"\n label=\"Industry\"\n value={draft.industry}\n onChange={(event) => patch('industry', event.target.value)}\n />\n {/*\n The owner is chosen from the team, never typed: the value is a\n uid, and a picker that is still loading says so rather than\n offering an empty list that reads as \"nobody can own this\".\n */}\n <TextField\n select\n size=\"small\"\n label=\"Owner\"\n value={draft.ownerUid}\n disabled={!members.ready}\n helperText={\n !members.ready\n ? 'Loading your team…'\n : (members.error ?? 'The team member responsible for this account.')\n }\n onChange={(event) => patch('ownerUid', event.target.value)}\n >\n <MenuItem value=\"\">{'Nobody yet'}</MenuItem>\n {draft.ownerUid &&\n !members.options.some((option) => option.uid === draft.ownerUid) ? (\n <MenuItem value={draft.ownerUid}>\n {members.labelFor(draft.ownerUid)}\n </MenuItem>\n ) : null}\n {members.options.map((option) => (\n <MenuItem key={option.uid} value={option.uid}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n size=\"small\"\n label=\"Tags\"\n placeholder=\"enterprise, west\"\n helperText=\"Comma-separated, lowercased — the same tags the bulk bar adds\"\n value={draft.tags}\n onChange={(event) => patch('tags', event.target.value)}\n />\n <Typography variant=\"subtitle2\">{'Address'}</Typography>\n {ADDRESS_FIELDS.map((field) => (\n <TextField\n key={field.key}\n size=\"small\"\n label={field.label}\n value={draft.address[field.key] ?? ''}\n onChange={(event) => patchAddress(field.key, event.target.value)}\n />\n ))}\n <TextField\n size=\"small\"\n label=\"Notes\"\n value={draft.notes}\n onChange={(event) => patch('notes', event.target.value)}\n multiline\n minRows={3}\n />\n {fields.active.length ? (\n <>\n <Typography variant=\"subtitle2\">{'Custom fields'}</Typography>\n {fields.active.map((definition) => (\n <CrmCustomFieldControl\n key={definition.$id}\n definition={definition}\n value={crmCustomDraftValue(storedCustom, custom, definition.key)}\n onChange={(value) =>\n setCustom((current) => ({ ...current, [definition.key]: value }))\n }\n disabled={busy}\n />\n ))}\n </>\n ) : null}\n {error ? <Alert severity=\"warning\">{error}</Alert> : null}\n <Stack direction=\"row\" spacing={1}>\n <Button\n variant=\"contained\"\n color=\"primary\"\n // A new company waits for its capturing site.\n disabled={busy || !scope || !draft.name.trim() || (!company && !createHostId)}\n onClick={() => void handleSave()}\n >\n {busy\n ? 'Saving…'\n : company\n ? 'Save company'\n : 'Create company'}\n </Button>\n <Button onClick={onClose} disabled={busy}>\n {'Cancel'}\n </Button>\n </Stack>\n </Stack>\n </Container>\n </NavigationDrawerComponent>\n )\n}\nCompanyEditDrawer.displayName = 'CompanyEditDrawer'\n\nexport default CompanyEditDrawer\n"],"names":["createResourceUid","CRM_COLLECTIONS","CRM_RECORDS_BAND_FULL_MESSAGE","pluginDocsHelp","ICON_VARIANT_CLOSE","Container","HelpTip","MdiIcon","SrOnly","NavigationDrawerComponent","useSnackbar","useFirestore","useUser","writeGuardedBySeed","Alert","Button","IconButton","MenuItem","Stack","TextField","Typography","deleteField","doc","serverTimestamp","setDoc","updateDoc","useCallback","useEffect","useMemo","useState","useContactFieldDefinitions","useCrmActivityLogger","useCrmRecordsQuota","useCrmScope","companyDraftFields","companyDraftFrom","EMPTY_COMPANY_DRAFT","crmCustomDraftDocument","crmCustomDraftMissingRequired","crmCustomDraftValue","crmCustomDraftWrites","CrmCustomFieldControl","CrmSitePicker","ADDRESS_FIELDS","key","label","CompanyEditDrawer","props","members","open","onClose","hostId","org","company","seed","onSaved","firestore","data","user","enqueueSnackbar","scope","createTokens","createHostId","logActivity","draft","setDraft","busy","setBusy","error","setError","fields","storedCustom","custom","setCustom","records","bandFull","ready","quota","allowed","companyId","$id","ownerUid","uid","patch","field","value","current","patchAddress","address","handleSave","result","ok","missing","active","length","join","customDocument","ref","companies","verdict","subject","unreadable","fromCache","set","Object","fromEntries","cleared","map","updatedAt","message","variant","persist","id","visibleTo","createdByUid","createdAt","type","name","trim","caught","console","anchor","AppBarProps","color","appBarLeft","edge","onClick","sx","mr","path","component","gutterY","spacing","disabled","helperText","severity","size","required","onChange","event","target","autoFocus","placeholder","domain","website","phone","industry","select","options","some","option","labelFor","tags","notes","multiline","minRows","definition","direction","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMPORTING A COMPANIES FILE — the company vocabulary over the shared
|
|
3
|
+
* drawer (AGL-2621).
|
|
4
|
+
*
|
|
5
|
+
* The server half is `server/companies-import.ts`. What is particular to
|
|
6
|
+
* companies: the name is the one cell every row needs (a domain is a key,
|
|
7
|
+
* a name is the caption the list cannot do without), the custom fields
|
|
8
|
+
* are the org's COMPANY definitions (AGL-2661), and a row is matched to a
|
|
9
|
+
* company already filed by its domain first and its name second.
|
|
10
|
+
*/
|
|
11
|
+
import { type ConsolePluginPageProps, type ContactFieldDefinition } from '@aglyn/aglyn';
|
|
12
|
+
import { type CompanyImportField, type CompanyImportRawRow, type CompanyImportSkippedRow } from '../model/crm-company-import';
|
|
13
|
+
import { type CsvImportVocabulary } from './csv-import-drawer';
|
|
14
|
+
/** The browser-side address of the route one chunk is posted to. */
|
|
15
|
+
export declare const COMPANIES_IMPORT_URL = "/api/crm/companies-import";
|
|
16
|
+
/** The company vocabulary, over the org's company custom fields (AGL-2661). */
|
|
17
|
+
export declare function companyImportVocabulary(fields: readonly ContactFieldDefinition[]): CsvImportVocabulary<CompanyImportField, CompanyImportRawRow & Record<string, unknown>, CompanyImportSkippedRow>;
|
|
18
|
+
/** The vocabulary with no custom fields — what a surface without an org resolves to. */
|
|
19
|
+
export declare const COMPANY_IMPORT_VOCABULARY: CsvImportVocabulary<"name" | "notes" | "domain" | "website" | "phone" | "industry" | "tags" | "addressLine1" | "addressLine2" | "addressCity" | "addressState" | "addressPostalCode" | "addressCountry" | "ownerEmail", Partial<Record<"name" | "notes" | "domain" | "website" | "phone" | "industry" | "tags" | "addressLine1" | "addressLine2" | "addressCity" | "addressState" | "addressPostalCode" | "addressCountry" | "ownerEmail", unknown>> & {
|
|
20
|
+
custom?: unknown;
|
|
21
|
+
} & Record<string, unknown>, CompanyImportSkippedRow>;
|
|
22
|
+
export interface CompanyImportDrawerProps {
|
|
23
|
+
open: boolean;
|
|
24
|
+
onClose: () => void;
|
|
25
|
+
/** The site the file is filed under, or `null` at the organization level (AGL-2630). */
|
|
26
|
+
hostId: string | null;
|
|
27
|
+
/** The org, for the company field definitions the mapping offers (AGL-2661). */
|
|
28
|
+
org?: ConsolePluginPageProps['org'];
|
|
29
|
+
}
|
|
30
|
+
export declare function CompanyImportDrawer(props: CompanyImportDrawerProps): import("react").JSX.Element;
|
|
31
|
+
export declare namespace CompanyImportDrawer {
|
|
32
|
+
var displayName: string;
|
|
33
|
+
}
|
|
34
|
+
/** The "Import CSV" action on the companies list, with the drawer it opens. */
|
|
35
|
+
export declare function CompanyImportButton(props: {
|
|
36
|
+
hostId: string | null;
|
|
37
|
+
org?: ConsolePluginPageProps['org'];
|
|
38
|
+
}): import("react").JSX.Element;
|
|
39
|
+
export declare namespace CompanyImportButton {
|
|
40
|
+
var displayName: string;
|
|
41
|
+
}
|
|
42
|
+
export default CompanyImportDrawer;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
18
|
+
/**
|
|
19
|
+
* IMPORTING A COMPANIES FILE — the company vocabulary over the shared
|
|
20
|
+
* drawer (AGL-2621).
|
|
21
|
+
*
|
|
22
|
+
* The server half is `server/companies-import.ts`. What is particular to
|
|
23
|
+
* companies: the name is the one cell every row needs (a domain is a key,
|
|
24
|
+
* a name is the caption the list cannot do without), the custom fields
|
|
25
|
+
* are the org's COMPANY definitions (AGL-2661), and a row is matched to a
|
|
26
|
+
* company already filed by its domain first and its name second.
|
|
27
|
+
*/ import { pluginDocsHelp } from "@aglyn/aglyn";
|
|
28
|
+
import { COMPANY_IMPORT_CHUNK_SIZE, COMPANY_IMPORT_FIELD_LABELS, COMPANY_IMPORT_FIELDS, COMPANY_IMPORT_MAX_ROWS, COMPANY_IMPORT_PREVIEW_ROWS, COMPANY_IMPORT_SKIP_LABELS, companyImportSkippedCsv, emptyCompanyImportResult, guessCompanyImportMapping, mapCompanyImportRow, mergeCompanyImportResults } from "../model/crm-company-import.js";
|
|
29
|
+
import { useMemo } from "react";
|
|
30
|
+
import { useContactFieldDefinitions } from "../hooks/use-contact-field-definitions.js";
|
|
31
|
+
import { useCrmScope } from "../hooks/use-crm-scope.js";
|
|
32
|
+
import { companyImportTemplateCsv } from "../model/companies-csv.js";
|
|
33
|
+
import { CsvImportButton, CsvImportDrawer } from "./csv-import-drawer.js";
|
|
34
|
+
/** The browser-side address of the route one chunk is posted to. */ export const COMPANIES_IMPORT_URL = '/api/crm/companies-import';
|
|
35
|
+
/** The company vocabulary, over the org's company custom fields (AGL-2661). */ export function companyImportVocabulary(fields) {
|
|
36
|
+
return {
|
|
37
|
+
title: 'Import companies from CSV',
|
|
38
|
+
collection: 'companies',
|
|
39
|
+
help: pluginDocsHelp('companies', {
|
|
40
|
+
anchor: '#import-from-csv'
|
|
41
|
+
}),
|
|
42
|
+
sitePickerHelperText: 'The site these companies are filed under — it decides which of your ' + 'sites may see them.',
|
|
43
|
+
intro: 'A CSV with a header row. Match its columns to company fields below, ' + 'check the preview, then import. A company already in your list — by ' + 'domain, or failing that by name — is updated rather than added twice. ' + `Up to ${COMPANY_IMPORT_MAX_ROWS.toLocaleString()} rows per file — split ` + 'a larger one.',
|
|
44
|
+
fields: COMPANY_IMPORT_FIELDS,
|
|
45
|
+
fieldLabels: COMPANY_IMPORT_FIELD_LABELS,
|
|
46
|
+
customFields: fields,
|
|
47
|
+
requiredField: 'name',
|
|
48
|
+
requiredWarning: 'Choose which column holds the company name. It is the one field every ' + 'row needs.',
|
|
49
|
+
unusableNotice: (count, total)=>`${count.toLocaleString()} of ${total.toLocaleString()} rows have no ` + 'company name and will be skipped. You can download them after the ' + 'import.',
|
|
50
|
+
guessMapping: (columns)=>guessCompanyImportMapping(columns, fields),
|
|
51
|
+
mapRow: (cells, mapping)=>mapCompanyImportRow(cells, mapping),
|
|
52
|
+
route: COMPANIES_IMPORT_URL,
|
|
53
|
+
maxRows: COMPANY_IMPORT_MAX_ROWS,
|
|
54
|
+
chunkSize: COMPANY_IMPORT_CHUNK_SIZE,
|
|
55
|
+
previewRows: COMPANY_IMPORT_PREVIEW_ROWS,
|
|
56
|
+
emptyResult: emptyCompanyImportResult,
|
|
57
|
+
mergeResults: mergeCompanyImportResults,
|
|
58
|
+
skipLabels: COMPANY_IMPORT_SKIP_LABELS,
|
|
59
|
+
skippedCsv: companyImportSkippedCsv,
|
|
60
|
+
skippedFileName: 'skipped-companies.csv',
|
|
61
|
+
templateCsv: companyImportTemplateCsv,
|
|
62
|
+
templateFileName: 'companies-template.csv'
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** The vocabulary with no custom fields — what a surface without an org resolves to. */ export const COMPANY_IMPORT_VOCABULARY = companyImportVocabulary([]);
|
|
66
|
+
export function CompanyImportDrawer(props) {
|
|
67
|
+
const { open, onClose, hostId, org } = props;
|
|
68
|
+
// The org's company fields, read only while the drawer is open.
|
|
69
|
+
const { orgId } = useCrmScope({
|
|
70
|
+
hostId,
|
|
71
|
+
org
|
|
72
|
+
});
|
|
73
|
+
const { active } = useContactFieldDefinitions(open ? orgId : null, 'company');
|
|
74
|
+
const vocabulary = useMemo(()=>companyImportVocabulary(active), [
|
|
75
|
+
active
|
|
76
|
+
]);
|
|
77
|
+
return /*#__PURE__*/ _jsx(CsvImportDrawer, {
|
|
78
|
+
open: open,
|
|
79
|
+
onClose: onClose,
|
|
80
|
+
hostId: hostId,
|
|
81
|
+
vocabulary: vocabulary
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
CompanyImportDrawer.displayName = 'CompanyImportDrawer';
|
|
85
|
+
/** The "Import CSV" action on the companies list, with the drawer it opens. */ export function CompanyImportButton(props) {
|
|
86
|
+
const { hostId, org } = props;
|
|
87
|
+
return /*#__PURE__*/ _jsx(CsvImportButton, {
|
|
88
|
+
children: (open, onClose)=>/*#__PURE__*/ _jsx(CompanyImportDrawer, {
|
|
89
|
+
open: open,
|
|
90
|
+
onClose: onClose,
|
|
91
|
+
hostId: hostId,
|
|
92
|
+
org: org
|
|
93
|
+
})
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
CompanyImportButton.displayName = 'CompanyImportButton';
|
|
97
|
+
export default CompanyImportDrawer;
|
|
98
|
+
|
|
99
|
+
//# sourceMappingURL=company-import-drawer.js.map
|