@aglyn/plugins-crm 1.0.0 → 1.1.0

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.
Files changed (154) hide show
  1. package/package.json +14 -14
  2. package/src/lib/components/activity-link-fields.d.ts +34 -0
  3. package/src/lib/components/activity-link-fields.js +141 -0
  4. package/src/lib/components/activity-link-fields.js.map +1 -0
  5. package/src/lib/components/activity-list.d.ts +8 -0
  6. package/src/lib/components/activity-list.js +4 -2
  7. package/src/lib/components/activity-list.js.map +1 -1
  8. package/src/lib/components/activity-queries.d.ts +7 -2
  9. package/src/lib/components/activity-queries.js +7 -3
  10. package/src/lib/components/activity-queries.js.map +1 -1
  11. package/src/lib/components/company-contact-roles-card.d.ts +42 -0
  12. package/src/lib/components/company-contact-roles-card.js +135 -0
  13. package/src/lib/components/company-contact-roles-card.js.map +1 -0
  14. package/src/lib/components/company-detail-page.js +12 -1
  15. package/src/lib/components/company-detail-page.js.map +1 -1
  16. package/src/lib/components/company-edit-drawer.js +9 -6
  17. package/src/lib/components/company-edit-drawer.js.map +1 -1
  18. package/src/lib/components/company-picker.js +4 -2
  19. package/src/lib/components/company-picker.js.map +1 -1
  20. package/src/lib/components/contact-associations-card.js +15 -1
  21. package/src/lib/components/contact-associations-card.js.map +1 -1
  22. package/src/lib/components/contact-detail-page.js +13 -14
  23. package/src/lib/components/contact-detail-page.js.map +1 -1
  24. package/src/lib/components/contact-list-columns.js +5 -4
  25. package/src/lib/components/contact-list-columns.js.map +1 -1
  26. package/src/lib/components/contact-properties-card.js +41 -20
  27. package/src/lib/components/contact-properties-card.js.map +1 -1
  28. package/src/lib/components/contact-roles-editor.d.ts +54 -0
  29. package/src/lib/components/contact-roles-editor.js +270 -0
  30. package/src/lib/components/contact-roles-editor.js.map +1 -0
  31. package/src/lib/components/contacts-section.js +6 -4
  32. package/src/lib/components/contacts-section.js.map +1 -1
  33. package/src/lib/components/crm-console-sections.js +1 -1
  34. package/src/lib/components/crm-console-sections.js.map +1 -1
  35. package/src/lib/components/crm-record-picker.d.ts +19 -0
  36. package/src/lib/components/crm-record-picker.js +40 -11
  37. package/src/lib/components/crm-record-picker.js.map +1 -1
  38. package/src/lib/components/crm-related-to-picker.d.ts +33 -0
  39. package/src/lib/components/crm-related-to-picker.js +135 -0
  40. package/src/lib/components/crm-related-to-picker.js.map +1 -0
  41. package/src/lib/components/crm-site-picker.d.ts +13 -1
  42. package/src/lib/components/crm-site-picker.js +15 -6
  43. package/src/lib/components/crm-site-picker.js.map +1 -1
  44. package/src/lib/components/crm-transfer-buttons.d.ts +5 -0
  45. package/src/lib/components/crm-transfer-buttons.js +9 -6
  46. package/src/lib/components/crm-transfer-buttons.js.map +1 -1
  47. package/src/lib/components/deal-contact-roles-card.js +21 -239
  48. package/src/lib/components/deal-contact-roles-card.js.map +1 -1
  49. package/src/lib/components/deal-detail-page.js +2 -1
  50. package/src/lib/components/deal-detail-page.js.map +1 -1
  51. package/src/lib/components/deal-edit-drawer.js +11 -7
  52. package/src/lib/components/deal-edit-drawer.js.map +1 -1
  53. package/src/lib/components/deals-section.js +5 -4
  54. package/src/lib/components/deals-section.js.map +1 -1
  55. package/src/lib/components/log-activity-dialog.d.ts +27 -9
  56. package/src/lib/components/log-activity-dialog.js +96 -32
  57. package/src/lib/components/log-activity-dialog.js.map +1 -1
  58. package/src/lib/components/new-contact-drawer.d.ts +7 -3
  59. package/src/lib/components/new-contact-drawer.js +27 -15
  60. package/src/lib/components/new-contact-drawer.js.map +1 -1
  61. package/src/lib/components/pipeline-stages-dialog.js +5 -1
  62. package/src/lib/components/pipeline-stages-dialog.js.map +1 -1
  63. package/src/lib/components/record-activity-card.d.ts +11 -2
  64. package/src/lib/components/record-activity-card.js +90 -5
  65. package/src/lib/components/record-activity-card.js.map +1 -1
  66. package/src/lib/components/settings-section.d.ts +4 -2
  67. package/src/lib/components/settings-section.js +7 -5
  68. package/src/lib/components/settings-section.js.map +1 -1
  69. package/src/lib/hooks/crm-activity-client-reads.d.ts +8 -0
  70. package/src/lib/hooks/crm-activity-client-reads.js +50 -0
  71. package/src/lib/hooks/crm-activity-client-reads.js.map +1 -0
  72. package/src/lib/hooks/use-campaign-filing-log.d.ts +2 -1
  73. package/src/lib/hooks/use-campaign-filing-log.js +10 -3
  74. package/src/lib/hooks/use-campaign-filing-log.js.map +1 -1
  75. package/src/lib/hooks/use-crm-org-mount.d.ts +8 -6
  76. package/src/lib/hooks/use-crm-org-mount.js +2 -1
  77. package/src/lib/hooks/use-crm-org-mount.js.map +1 -1
  78. package/src/lib/hooks/use-crm-scope.d.ts +17 -5
  79. package/src/lib/hooks/use-crm-scope.js +12 -5
  80. package/src/lib/hooks/use-crm-scope.js.map +1 -1
  81. package/src/lib/model/contact-holder.d.ts +12 -0
  82. package/src/lib/model/contact-holder.js +20 -1
  83. package/src/lib/model/contact-holder.js.map +1 -1
  84. package/src/lib/model/contact-record.d.ts +5 -0
  85. package/src/lib/model/contact-record.js +7 -1
  86. package/src/lib/model/contact-record.js.map +1 -1
  87. package/src/lib/model/contact-update.d.ts +6 -0
  88. package/src/lib/model/contact-update.js +1 -0
  89. package/src/lib/model/contact-update.js.map +1 -1
  90. package/src/lib/model/crm-activity-link.d.ts +117 -0
  91. package/src/lib/model/crm-activity-link.js +113 -0
  92. package/src/lib/model/crm-activity-link.js.map +1 -0
  93. package/src/lib/model/crm-api.d.ts +4 -1
  94. package/src/lib/model/crm-api.js +9 -5
  95. package/src/lib/model/crm-api.js.map +1 -1
  96. package/src/lib/model/deal-board-model.js +5 -3
  97. package/src/lib/model/deal-board-model.js.map +1 -1
  98. package/src/lib/model/deal-contact-roles.d.ts +15 -1
  99. package/src/lib/model/deal-contact-roles.js +17 -3
  100. package/src/lib/model/deal-contact-roles.js.map +1 -1
  101. package/src/lib/model/settle-stage-names.d.ts +25 -0
  102. package/src/lib/model/settle-stage-names.js +29 -0
  103. package/src/lib/model/settle-stage-names.js.map +1 -0
  104. package/src/lib/native-nav.js +1 -1
  105. package/src/lib/native-nav.js.map +1 -1
  106. package/src/lib/server/add-contact-by-hand.d.ts +84 -0
  107. package/src/lib/server/add-contact-by-hand.js +212 -0
  108. package/src/lib/server/add-contact-by-hand.js.map +1 -0
  109. package/src/lib/server/api-v1/contacts.js +61 -23
  110. package/src/lib/server/api-v1/contacts.js.map +1 -1
  111. package/src/lib/server/api-v1/crm-activities.js +13 -3
  112. package/src/lib/server/api-v1/crm-activities.js.map +1 -1
  113. package/src/lib/server/api-v1/crm-pipelines.d.ts +1 -1
  114. package/src/lib/server/api-v1/crm-pipelines.js +8 -2
  115. package/src/lib/server/api-v1/crm-pipelines.js.map +1 -1
  116. package/src/lib/server/api-v1/crm-shared.d.ts +16 -9
  117. package/src/lib/server/api-v1/crm-shared.js +23 -11
  118. package/src/lib/server/api-v1/crm-shared.js.map +1 -1
  119. package/src/lib/server/api-v1/openapi.js +3 -3
  120. package/src/lib/server/api-v1/openapi.js.map +1 -1
  121. package/src/lib/server/automation-steps.js +11 -9
  122. package/src/lib/server/automation-steps.js.map +1 -1
  123. package/src/lib/server/campaign-filing-activity.js +7 -2
  124. package/src/lib/server/campaign-filing-activity.js.map +1 -1
  125. package/src/lib/server/contact-update.d.ts +4 -0
  126. package/src/lib/server/contact-update.js +71 -10
  127. package/src/lib/server/contact-update.js.map +1 -1
  128. package/src/lib/server/convert-host-lead.js +13 -2
  129. package/src/lib/server/convert-host-lead.js.map +1 -1
  130. package/src/lib/server/convert-open-lead.js +8 -1
  131. package/src/lib/server/convert-open-lead.js.map +1 -1
  132. package/src/lib/server/crm-activity-company.d.ts +25 -0
  133. package/src/lib/server/crm-activity-company.js +34 -0
  134. package/src/lib/server/crm-activity-company.js.map +1 -0
  135. package/src/lib/server/crm-inbound-email.js +21 -15
  136. package/src/lib/server/crm-inbound-email.js.map +1 -1
  137. package/src/lib/server/crm-sharing.js +9 -2
  138. package/src/lib/server/crm-sharing.js.map +1 -1
  139. package/src/lib/server/email-send.js +10 -8
  140. package/src/lib/server/email-send.js.map +1 -1
  141. package/src/lib/server/merge-contacts.js +6 -2
  142. package/src/lib/server/merge-contacts.js.map +1 -1
  143. package/src/lib/server/org-caller.d.ts +8 -0
  144. package/src/lib/server/org-caller.js +10 -0
  145. package/src/lib/server/org-caller.js.map +1 -1
  146. package/src/lib/server/record-timeline.d.ts +3 -1
  147. package/src/lib/server/record-timeline.js +11 -3
  148. package/src/lib/server/record-timeline.js.map +1 -1
  149. package/src/lib/server.js +152 -43
  150. package/src/lib/server.js.map +1 -1
  151. package/src/lib/transfer/contacts.js +83 -48
  152. package/src/lib/transfer/contacts.js.map +1 -1
  153. package/src/lib/transfer/fields.js +1 -2
  154. package/src/lib/transfer/fields.js.map +1 -1
@@ -0,0 +1,135 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { jsx as _jsx } from "react/jsx-runtime";
18
+ import { CRM_COLLECTIONS, dealContactRolesOf, pluginDocsHelp } from "@aglyn/aglyn";
19
+ import { useSnackbar } from "@aglyn/shared-ui-snackstack";
20
+ import { useFirestore, writeGuardedBySeed } from "@aglyn/tenant-feature-instance";
21
+ import { doc, updateDoc } from "firebase/firestore";
22
+ import { useCallback, useMemo, useState } from "react";
23
+ import { useCrmPicklist } from "../hooks/use-crm-picklist.js";
24
+ import { useCrmRecordNames } from "../hooks/use-crm-record-names.js";
25
+ import { useCrmScope } from "../hooks/use-crm-scope.js";
26
+ import { companyContactRolesSave } from "../model/deal-contact-roles.js";
27
+ import { ContactRolesEditor } from "./contact-roles-editor.js";
28
+ /**
29
+ * Salesforce's Account Contact Roles (AGL-4122): who at a company plays which
30
+ * part, and who the Primary is. Separate from the roles on a deal, as there: a
31
+ * person's part in the company is a fact about the account, and their part in
32
+ * one deal can differ. The same list of roles serves both.
33
+ */ export function CompanyContactRolesCard(props) {
34
+ var _ref;
35
+ var _scope_consentGroup;
36
+ const { companyId, company, hostId, org, routes, fromCache, unreadable } = props;
37
+ const firestore = useFirestore();
38
+ const { enqueueSnackbar } = useSnackbar();
39
+ const scope = useCrmScope({
40
+ hostId,
41
+ org
42
+ });
43
+ const groupId = (_ref = (_scope_consentGroup = scope.consentGroup) == null ? void 0 : _scope_consentGroup.groupId) != null ? _ref : null;
44
+ const roles = useMemo(()=>dealContactRolesOf(company), [
45
+ company
46
+ ]);
47
+ const roleList = useCrmPicklist('opportunityContactRole', scope.orgId);
48
+ const nameOf = useCrmRecordNames({
49
+ orgId: scope.orgId,
50
+ groupId,
51
+ org: org != null ? org : null,
52
+ records: roles.map((row)=>({
53
+ kind: 'contact',
54
+ id: row.contactId
55
+ }))
56
+ });
57
+ const [busy, setBusy] = useState(false);
58
+ const [adding, setAdding] = useState(false);
59
+ const save = useCallback(async (next, done)=>{
60
+ if (!scope.orgId) return false;
61
+ const verdict = companyContactRolesSave(company, next, roleList.picklist);
62
+ if (verdict.ok === false) {
63
+ enqueueSnackbar(verdict.error, {
64
+ variant: 'warning',
65
+ persist: false
66
+ });
67
+ return false;
68
+ }
69
+ setBusy(true);
70
+ try {
71
+ const written = await writeGuardedBySeed({
72
+ subject: 'company',
73
+ unreadable,
74
+ fromCache
75
+ }, async ()=>{
76
+ await updateDoc(doc(firestore, 'orgs', scope.orgId, CRM_COLLECTIONS.companies, companyId), {
77
+ contactRoles: verdict.contactRoles,
78
+ updatedAt: new Date()
79
+ });
80
+ });
81
+ if (!written.ok) {
82
+ enqueueSnackbar(written.message, {
83
+ variant: 'warning',
84
+ persist: false
85
+ });
86
+ return false;
87
+ }
88
+ enqueueSnackbar(done, {
89
+ variant: 'success',
90
+ persist: false
91
+ });
92
+ return true;
93
+ } catch (error) {
94
+ console.error(error);
95
+ enqueueSnackbar('An error has occurred', {
96
+ variant: 'error',
97
+ allowDuplicate: true
98
+ });
99
+ return false;
100
+ } finally{
101
+ setBusy(false);
102
+ }
103
+ }, [
104
+ scope.orgId,
105
+ company,
106
+ roleList.picklist,
107
+ unreadable,
108
+ fromCache,
109
+ firestore,
110
+ companyId,
111
+ enqueueSnackbar
112
+ ]);
113
+ return /*#__PURE__*/ _jsx(ContactRolesEditor, {
114
+ noun: "company",
115
+ roles: roles,
116
+ busy: busy,
117
+ adding: adding,
118
+ onAddingChange: setAdding,
119
+ ready: Boolean(scope.orgId),
120
+ hostId: hostId,
121
+ org: org,
122
+ routes: routes,
123
+ picklist: roleList.picklist,
124
+ nameOf: nameOf,
125
+ help: pluginDocsHelp('companies', {
126
+ anchor: '#contact-roles'
127
+ }),
128
+ emptyDescription: "Name who at the company plays which part, one of them Primary.",
129
+ save: save
130
+ });
131
+ }
132
+ CompanyContactRolesCard.displayName = 'CompanyContactRolesCard';
133
+ export default CompanyContactRolesCard;
134
+
135
+ //# sourceMappingURL=company-contact-roles-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/company-contact-roles-card.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport {\n CRM_COLLECTIONS,\n type CrmDealContactRole,\n dealContactRolesOf,\n pluginDocsHelp,\n} from '@aglyn/aglyn'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useFirestore, writeGuardedBySeed } from '@aglyn/tenant-feature-instance'\nimport { doc, updateDoc } from 'firebase/firestore'\nimport { useCallback, useMemo, useState } from 'react'\nimport { useCrmPicklist } from '../hooks/use-crm-picklist'\nimport { useCrmRecordNames } from '../hooks/use-crm-record-names'\nimport { type CrmOrgDoc, useCrmScope } from '../hooks/use-crm-scope'\nimport type { CrmRoutes } from '../model/crm-routes'\nimport { companyContactRolesSave } from '../model/deal-contact-roles'\nimport { ContactRolesEditor } from './contact-roles-editor'\n\nexport interface CompanyContactRolesCardProps {\n companyId: string\n company: { contactRoles?: unknown }\n /** The site the page is read under, or `null` at the organization level. */\n hostId: string | null\n org: CrmOrgDoc\n routes: CrmRoutes\n /** The listener's verdict on the company, for the stale-seed guard. */\n fromCache: boolean\n unreadable: boolean\n}\n\n/**\n * Salesforce's Account Contact Roles (AGL-4122): who at a company plays which\n * part, and who the Primary is. Separate from the roles on a deal, as there: a\n * person's part in the company is a fact about the account, and their part in\n * one deal can differ. The same list of roles serves both.\n */\nexport function CompanyContactRolesCard(props: CompanyContactRolesCardProps) {\n const { companyId, company, hostId, org, routes, fromCache, unreadable } = props\n const firestore = useFirestore()\n const { enqueueSnackbar } = useSnackbar()\n const scope = useCrmScope({ hostId, org })\n const groupId = scope.consentGroup?.groupId ?? null\n const roles = useMemo(() => dealContactRolesOf(company), [company])\n const roleList = useCrmPicklist('opportunityContactRole', scope.orgId)\n const nameOf = useCrmRecordNames({\n orgId: scope.orgId,\n groupId,\n org: (org ?? null) as Record<string, unknown> | null,\n records: roles.map((row) => ({ kind: 'contact' as const, id: row.contactId })),\n })\n const [busy, setBusy] = useState(false)\n const [adding, setAdding] = useState(false)\n\n const save = useCallback(\n async (next: CrmDealContactRole[], done: string) => {\n if (!scope.orgId) return false\n const verdict = companyContactRolesSave(company, next, roleList.picklist)\n if (verdict.ok === false) {\n enqueueSnackbar(verdict.error, { variant: 'warning', persist: false })\n return false\n }\n setBusy(true)\n try {\n const written = await writeGuardedBySeed(\n { subject: 'company', unreadable, fromCache },\n async () => {\n await updateDoc(\n doc(firestore, 'orgs', scope.orgId as string, CRM_COLLECTIONS.companies, companyId),\n { contactRoles: verdict.contactRoles, updatedAt: new Date() },\n )\n },\n )\n if (!written.ok) {\n enqueueSnackbar(written.message, { variant: 'warning', persist: false })\n return false\n }\n enqueueSnackbar(done, { variant: 'success', persist: false })\n return true\n } catch (error) {\n console.error(error)\n enqueueSnackbar('An error has occurred', { variant: 'error', allowDuplicate: true })\n return false\n } finally {\n setBusy(false)\n }\n },\n [scope.orgId, company, roleList.picklist, unreadable, fromCache, firestore, companyId, enqueueSnackbar],\n )\n\n return (\n <ContactRolesEditor\n noun=\"company\"\n roles={roles}\n busy={busy}\n adding={adding}\n onAddingChange={setAdding}\n ready={Boolean(scope.orgId)}\n hostId={hostId}\n org={org}\n routes={routes}\n picklist={roleList.picklist}\n nameOf={nameOf}\n help={pluginDocsHelp('companies', { anchor: '#contact-roles' })}\n emptyDescription=\"Name who at the company plays which part, one of them Primary.\"\n save={save}\n />\n )\n}\nCompanyContactRolesCard.displayName = 'CompanyContactRolesCard'\n\nexport default CompanyContactRolesCard\n"],"names":["CRM_COLLECTIONS","dealContactRolesOf","pluginDocsHelp","useSnackbar","useFirestore","writeGuardedBySeed","doc","updateDoc","useCallback","useMemo","useState","useCrmPicklist","useCrmRecordNames","useCrmScope","companyContactRolesSave","ContactRolesEditor","CompanyContactRolesCard","props","scope","companyId","company","hostId","org","routes","fromCache","unreadable","firestore","enqueueSnackbar","groupId","consentGroup","roles","roleList","orgId","nameOf","records","map","row","kind","id","contactId","busy","setBusy","adding","setAdding","save","next","done","verdict","picklist","ok","error","variant","persist","written","subject","companies","contactRoles","updatedAt","Date","message","console","allowDuplicate","noun","onAddingChange","ready","Boolean","help","anchor","emptyDescription","displayName"],"mappings":"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"}
@@ -26,6 +26,7 @@ import { CrmCreateSiteDefault } from "../hooks/use-crm-org-mount.js";
26
26
  import { useCrmScope } from "../hooks/use-crm-scope.js";
27
27
  import { useOrgMemberOptions } from "../hooks/use-org-member-options.js";
28
28
  import { crmRoutes } from "../model/crm-routes.js";
29
+ import CompanyContactRolesCard from "./company-contact-roles-card.js";
29
30
  import CompanyContactsCard from "./company-contacts-card.js";
30
31
  import CompanyDealsCard from "./company-deals-card.js";
31
32
  import { CrmRecordHeader } from "./crm-record-header.js";
@@ -130,6 +131,15 @@ import { CrmRecordInsightsZone } from "./crm-record-insights-zone.js";
130
131
  org: org,
131
132
  routes: routes
132
133
  }),
134
+ /*#__PURE__*/ _jsx(CompanyContactRolesCard, {
135
+ companyId: id,
136
+ company: company,
137
+ hostId: hostId,
138
+ org: org,
139
+ routes: routes,
140
+ fromCache: fromCache,
141
+ unreadable: status === 'error'
142
+ }),
133
143
  /*#__PURE__*/ _jsx(CompanyDealsCard, {
134
144
  hostId: hostId,
135
145
  org: org,
@@ -162,7 +172,8 @@ import { CrmRecordInsightsZone } from "./crm-record-insights-zone.js";
162
172
  /*#__PURE__*/ _jsx(RecordActivityCard, {
163
173
  hostId: hostId,
164
174
  org: org,
165
- companyId: id
175
+ companyId: id,
176
+ basePath: basePath
166
177
  })
167
178
  ]
168
179
  })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/company-detail-page.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 { CRM_COLLECTIONS, type CrmCompany } from '@aglyn/aglyn'\nimport { useFirestore, useFirestoreDoc } from '@aglyn/tenant-feature-instance'\nimport { Stack, Typography } from '@mui/material'\nimport { doc } from 'firebase/firestore'\nimport { useRouter } from 'next/navigation'\nimport { useCallback } from 'react'\nimport { CrmCreateSiteDefault } from '../hooks/use-crm-org-mount'\nimport { useCrmScope } from '../hooks/use-crm-scope'\nimport { useOrgMemberOptions } from '../hooks/use-org-member-options'\nimport { type CrmDetailPageProps, crmRoutes } from '../model/crm-routes'\nimport CompanyContactsCard from './company-contacts-card'\nimport CompanyDealsCard from './company-deals-card'\nimport { CrmRecordHeader } from './crm-record-header'\nimport { RecordActivityCard } from './record-activity-card'\nimport RecordFilesCard from './record-files-card'\nimport { RecordTasksCard } from './record-tasks-card'\nimport CompanyPropertiesCard, { COMPANY_PAGE_HELP } from './company-properties-card'\nimport { RecordSharingCard } from './record-sharing-card'\nimport { CrmRecordInsightsZone } from './crm-record-insights-zone'\n\n/**\n * `/crm/companies/{companyId}` — one organization (AGL-2597).\n *\n * The record behind a row of the Companies section: its properties, its\n * people, and — as the rest of the CRM lands — its deals, its open tasks\n * and the activity logged against it. Each of those is a card in a file of\n * its own, so the agent shipping deals replaces one file and touches nothing\n * here; this page reads the ONE document every card is about and hands it\n * down.\n *\n * A route rather than a drawer because a company is what a deal, a task and\n * a contact all point at, and a link that opens a drawer on top of a list is\n * not a link anybody can paste.\n */\nexport function CompanyDetailPage(props: CrmDetailPageProps) {\n const { id, basePath, hostId, org } = props\n const routes = crmRoutes(basePath)\n const router = useRouter()\n const firestore = useFirestore()\n const crmScope = useCrmScope({ hostId, org })\n const { scope, orgId } = crmScope\n const members = useOrgMemberOptions(orgId)\n\n const {\n data: company,\n status,\n fromCache,\n } = useFirestoreDoc<CrmCompany>(\n () =>\n scope\n ? doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.companies, id)\n : null,\n [firestore, scope, id],\n )\n\n const onDeleted = useCallback(\n () => router.push(routes.section('companies')),\n [router, routes],\n )\n\n if (!company) {\n /*\n * Loading and MISSING are different answers. A company that cannot be\n * read is a different situation from an empty one, and reading `status`\n * rather than the absence of data is what stops the refusal being\n * flashed on every arrival, before the org scope has resolved.\n */\n const settled = Boolean(scope) && status !== 'loading'\n return (\n <CrmRecordHeader\n kind=\"Company\"\n title={undefined}\n help={COMPANY_PAGE_HELP}\n backHref={routes.section('companies')}\n backLabel=\"Back to companies\"\n loading={!settled}\n >\n {settled ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'This company could not be loaded. It may have been deleted.'}\n </Typography>\n ) : null}\n </CrmRecordHeader>\n )\n }\n\n return (\n // A create opened from this page — a task, an activity — files under\n // the company's own site unless the reader says otherwise (AGL-2630).\n <CrmCreateSiteDefault hostId={company.hostId ?? null}>\n {/* The properties card is the record's lead card: it publishes the\n page heading and the trail, so the cards under it say what they\n hold rather than repeating the name. */}\n <Stack spacing={2}>\n <CompanyPropertiesCard\n company={{ ...company, $id: id }}\n seed={{ fromCache, unreadable: status === 'error' }}\n hostId={hostId}\n org={org}\n crmScope={crmScope}\n members={members}\n routes={routes}\n onDeleted={onDeleted}\n />\n {/* What an assistant proposes about the company (AGL-2917). */}\n <CrmRecordInsightsZone\n hostId={hostId}\n org={org as Record<string, unknown> | undefined}\n kind=\"company\"\n recordId={id}\n name={String(company.name ?? '')}\n taskLink={{ companyId: id }}\n />\n <CompanyContactsCard\n companyId={id}\n companyName={String(company.name ?? '')}\n crmScope={crmScope}\n org={org as Record<string, unknown> | undefined}\n routes={routes}\n />\n <CompanyDealsCard\n hostId={hostId}\n org={org}\n basePath={basePath}\n companyId={id}\n companyName={String(company.name ?? '')}\n />\n <RecordTasksCard hostId={hostId} org={org} basePath={basePath} companyId={id} />\n <RecordFilesCard\n scope={scope}\n collection={CRM_COLLECTIONS.companies}\n recordId={id}\n mediaIds={company.mediaIds}\n topic=\"companies\"\n />\n {/* Where the company is visible and why, and a manager's share (AGL-3336). */}\n <RecordSharingCard\n object=\"companies\"\n id={id}\n record={company as unknown as Record<string, unknown>}\n hostId={hostId ?? null}\n orgId={orgId}\n org={org}\n viewingHostIds={crmScope.consentGroup?.hostIds}\n />\n <RecordActivityCard hostId={hostId} org={org} companyId={id} />\n </Stack>\n </CrmCreateSiteDefault>\n )\n}\nCompanyDetailPage.displayName = 'CompanyDetailPage'\n\nexport default CompanyDetailPage\n"],"names":["CRM_COLLECTIONS","useFirestore","useFirestoreDoc","Stack","Typography","doc","useRouter","useCallback","CrmCreateSiteDefault","useCrmScope","useOrgMemberOptions","crmRoutes","CompanyContactsCard","CompanyDealsCard","CrmRecordHeader","RecordActivityCard","RecordFilesCard","RecordTasksCard","CompanyPropertiesCard","COMPANY_PAGE_HELP","RecordSharingCard","CrmRecordInsightsZone","CompanyDetailPage","props","company","crmScope","id","basePath","hostId","org","routes","router","firestore","scope","orgId","members","data","status","fromCache","companies","onDeleted","push","section","settled","Boolean","kind","title","undefined","help","backHref","backLabel","loading","variant","color","spacing","$id","seed","unreadable","recordId","name","String","taskLink","companyId","companyName","collection","mediaIds","topic","object","record","viewingHostIds","consentGroup","hostIds","displayName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/company-detail-page.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 { CRM_COLLECTIONS, type CrmCompany } from '@aglyn/aglyn'\nimport { useFirestore, useFirestoreDoc } from '@aglyn/tenant-feature-instance'\nimport { Stack, Typography } from '@mui/material'\nimport { doc } from 'firebase/firestore'\nimport { useRouter } from 'next/navigation'\nimport { useCallback } from 'react'\nimport { CrmCreateSiteDefault } from '../hooks/use-crm-org-mount'\nimport { useCrmScope } from '../hooks/use-crm-scope'\nimport { useOrgMemberOptions } from '../hooks/use-org-member-options'\nimport { type CrmDetailPageProps, crmRoutes } from '../model/crm-routes'\nimport CompanyContactRolesCard from './company-contact-roles-card'\nimport CompanyContactsCard from './company-contacts-card'\nimport CompanyDealsCard from './company-deals-card'\nimport { CrmRecordHeader } from './crm-record-header'\nimport { RecordActivityCard } from './record-activity-card'\nimport RecordFilesCard from './record-files-card'\nimport { RecordTasksCard } from './record-tasks-card'\nimport CompanyPropertiesCard, { COMPANY_PAGE_HELP } from './company-properties-card'\nimport { RecordSharingCard } from './record-sharing-card'\nimport { CrmRecordInsightsZone } from './crm-record-insights-zone'\n\n/**\n * `/crm/companies/{companyId}` — one organization (AGL-2597).\n *\n * The record behind a row of the Companies section: its properties, its\n * people, and — as the rest of the CRM lands — its deals, its open tasks\n * and the activity logged against it. Each of those is a card in a file of\n * its own, so the agent shipping deals replaces one file and touches nothing\n * here; this page reads the ONE document every card is about and hands it\n * down.\n *\n * A route rather than a drawer because a company is what a deal, a task and\n * a contact all point at, and a link that opens a drawer on top of a list is\n * not a link anybody can paste.\n */\nexport function CompanyDetailPage(props: CrmDetailPageProps) {\n const { id, basePath, hostId, org } = props\n const routes = crmRoutes(basePath)\n const router = useRouter()\n const firestore = useFirestore()\n const crmScope = useCrmScope({ hostId, org })\n const { scope, orgId } = crmScope\n const members = useOrgMemberOptions(orgId)\n\n const {\n data: company,\n status,\n fromCache,\n } = useFirestoreDoc<CrmCompany>(\n () =>\n scope\n ? doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.companies, id)\n : null,\n [firestore, scope, id],\n )\n\n const onDeleted = useCallback(\n () => router.push(routes.section('companies')),\n [router, routes],\n )\n\n if (!company) {\n /*\n * Loading and MISSING are different answers. A company that cannot be\n * read is a different situation from an empty one, and reading `status`\n * rather than the absence of data is what stops the refusal being\n * flashed on every arrival, before the org scope has resolved.\n */\n const settled = Boolean(scope) && status !== 'loading'\n return (\n <CrmRecordHeader\n kind=\"Company\"\n title={undefined}\n help={COMPANY_PAGE_HELP}\n backHref={routes.section('companies')}\n backLabel=\"Back to companies\"\n loading={!settled}\n >\n {settled ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'This company could not be loaded. It may have been deleted.'}\n </Typography>\n ) : null}\n </CrmRecordHeader>\n )\n }\n\n return (\n // A create opened from this page — a task, an activity — files under\n // the company's own site unless the reader says otherwise (AGL-2630).\n <CrmCreateSiteDefault hostId={company.hostId ?? null}>\n {/* The properties card is the record's lead card: it publishes the\n page heading and the trail, so the cards under it say what they\n hold rather than repeating the name. */}\n <Stack spacing={2}>\n <CompanyPropertiesCard\n company={{ ...company, $id: id }}\n seed={{ fromCache, unreadable: status === 'error' }}\n hostId={hostId}\n org={org}\n crmScope={crmScope}\n members={members}\n routes={routes}\n onDeleted={onDeleted}\n />\n {/* What an assistant proposes about the company (AGL-2917). */}\n <CrmRecordInsightsZone\n hostId={hostId}\n org={org as Record<string, unknown> | undefined}\n kind=\"company\"\n recordId={id}\n name={String(company.name ?? '')}\n taskLink={{ companyId: id }}\n />\n <CompanyContactsCard\n companyId={id}\n companyName={String(company.name ?? '')}\n crmScope={crmScope}\n org={org as Record<string, unknown> | undefined}\n routes={routes}\n />\n <CompanyContactRolesCard\n companyId={id}\n company={company}\n hostId={hostId}\n org={org}\n routes={routes}\n fromCache={fromCache}\n unreadable={status === 'error'}\n />\n <CompanyDealsCard\n hostId={hostId}\n org={org}\n basePath={basePath}\n companyId={id}\n companyName={String(company.name ?? '')}\n />\n <RecordTasksCard hostId={hostId} org={org} basePath={basePath} companyId={id} />\n <RecordFilesCard\n scope={scope}\n collection={CRM_COLLECTIONS.companies}\n recordId={id}\n mediaIds={company.mediaIds}\n topic=\"companies\"\n />\n {/* Where the company is visible and why, and a manager's share (AGL-3336). */}\n <RecordSharingCard\n object=\"companies\"\n id={id}\n record={company as unknown as Record<string, unknown>}\n hostId={hostId ?? null}\n orgId={orgId}\n org={org}\n viewingHostIds={crmScope.consentGroup?.hostIds}\n />\n <RecordActivityCard hostId={hostId} org={org} companyId={id} basePath={basePath} />\n </Stack>\n </CrmCreateSiteDefault>\n )\n}\nCompanyDetailPage.displayName = 'CompanyDetailPage'\n\nexport default CompanyDetailPage\n"],"names":["CRM_COLLECTIONS","useFirestore","useFirestoreDoc","Stack","Typography","doc","useRouter","useCallback","CrmCreateSiteDefault","useCrmScope","useOrgMemberOptions","crmRoutes","CompanyContactRolesCard","CompanyContactsCard","CompanyDealsCard","CrmRecordHeader","RecordActivityCard","RecordFilesCard","RecordTasksCard","CompanyPropertiesCard","COMPANY_PAGE_HELP","RecordSharingCard","CrmRecordInsightsZone","CompanyDetailPage","props","company","crmScope","id","basePath","hostId","org","routes","router","firestore","scope","orgId","members","data","status","fromCache","companies","onDeleted","push","section","settled","Boolean","kind","title","undefined","help","backHref","backLabel","loading","variant","color","spacing","$id","seed","unreadable","recordId","name","String","taskLink","companyId","companyName","collection","mediaIds","topic","object","record","viewingHostIds","consentGroup","hostIds","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;AAEA,SAASA,eAAe,QAAyB,eAAc;AAC/D,SAASC,YAAY,EAAEC,eAAe,QAAQ,iCAAgC;AAC9E,SAASC,KAAK,EAAEC,UAAU,QAAQ,gBAAe;AACjD,SAASC,GAAG,QAAQ,qBAAoB;AACxC,SAASC,SAAS,QAAQ,kBAAiB;AAC3C,SAASC,WAAW,QAAQ,QAAO;AACnC,SAASC,oBAAoB,QAAQ,gCAA4B;AACjE,SAASC,WAAW,QAAQ,4BAAwB;AACpD,SAASC,mBAAmB,QAAQ,qCAAiC;AACrE,SAAkCC,SAAS,QAAQ,yBAAqB;AACxE,OAAOC,6BAA6B,kCAA8B;AAClE,OAAOC,yBAAyB,6BAAyB;AACzD,OAAOC,sBAAsB,0BAAsB;AACnD,SAASC,eAAe,QAAQ,yBAAqB;AACrD,SAASC,kBAAkB,QAAQ,4BAAwB;AAC3D,OAAOC,qBAAqB,yBAAqB;AACjD,SAASC,eAAe,QAAQ,yBAAqB;AACrD,OAAOC,yBAAyBC,iBAAiB,QAAQ,+BAA2B;AACpF,SAASC,iBAAiB,QAAQ,2BAAuB;AACzD,SAASC,qBAAqB,QAAQ,gCAA4B;AAElE;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASC,kBAAkBC,KAAyB;QAuDzBC,iBAqBXA,eAKOA,gBAmBAA;QAkBJC;IArHxB,MAAM,EAAEC,EAAE,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,GAAG,EAAE,GAAGN;IACtC,MAAMO,SAASpB,UAAUiB;IACzB,MAAMI,SAAS1B;IACf,MAAM2B,YAAYhC;IAClB,MAAMyB,WAAWjB,YAAY;QAAEoB;QAAQC;IAAI;IAC3C,MAAM,EAAEI,KAAK,EAAEC,KAAK,EAAE,GAAGT;IACzB,MAAMU,UAAU1B,oBAAoByB;IAEpC,MAAM,EACJE,MAAMZ,OAAO,EACba,MAAM,EACNC,SAAS,EACV,GAAGrC,gBACF,IACEgC,QACI7B,IAAI4B,WAAWC,KAAK,CAAC,EAAE,EAAEA,KAAK,CAAC,EAAE,EAAElC,gBAAgBwC,SAAS,EAAEb,MAC9D,MACN;QAACM;QAAWC;QAAOP;KAAG;IAGxB,MAAMc,YAAYlC,YAChB,IAAMyB,OAAOU,IAAI,CAACX,OAAOY,OAAO,CAAC,eACjC;QAACX;QAAQD;KAAO;IAGlB,IAAI,CAACN,SAAS;QACZ;;;;;KAKC,GACD,MAAMmB,UAAUC,QAAQX,UAAUI,WAAW;QAC7C,qBACE,KAACvB;YACC+B,MAAK;YACLC,OAAOC;YACPC,MAAM7B;YACN8B,UAAUnB,OAAOY,OAAO,CAAC;YACzBQ,WAAU;YACVC,SAAS,CAACR;sBAETA,wBACC,KAACxC;gBAAWiD,SAAQ;gBAAQC,OAAM;0BAC/B;iBAED;;IAGV;IAEA,OACE,qEAAqE;IACrE,sEAAsE;kBACtE,KAAC9C;QAAqBqB,MAAM,GAAEJ,kBAAAA,QAAQI,MAAM,YAAdJ,kBAAkB;kBAI9C,cAAA,MAACtB;YAAMoD,SAAS;;8BACd,KAACpC;oBACCM,SAAS,aAAKA;wBAAS+B,KAAK7B;;oBAC5B8B,MAAM;wBAAElB;wBAAWmB,YAAYpB,WAAW;oBAAQ;oBAClDT,QAAQA;oBACRC,KAAKA;oBACLJ,UAAUA;oBACVU,SAASA;oBACTL,QAAQA;oBACRU,WAAWA;;8BAGb,KAACnB;oBACCO,QAAQA;oBACRC,KAAKA;oBACLgB,MAAK;oBACLa,UAAUhC;oBACViC,MAAMC,QAAOpC,gBAAAA,QAAQmC,IAAI,YAAZnC,gBAAgB;oBAC7BqC,UAAU;wBAAEC,WAAWpC;oBAAG;;8BAE5B,KAACd;oBACCkD,WAAWpC;oBACXqC,aAAaH,QAAOpC,iBAAAA,QAAQmC,IAAI,YAAZnC,iBAAgB;oBACpCC,UAAUA;oBACVI,KAAKA;oBACLC,QAAQA;;8BAEV,KAACnB;oBACCmD,WAAWpC;oBACXF,SAASA;oBACTI,QAAQA;oBACRC,KAAKA;oBACLC,QAAQA;oBACRQ,WAAWA;oBACXmB,YAAYpB,WAAW;;8BAEzB,KAACxB;oBACCe,QAAQA;oBACRC,KAAKA;oBACLF,UAAUA;oBACVmC,WAAWpC;oBACXqC,aAAaH,QAAOpC,iBAAAA,QAAQmC,IAAI,YAAZnC,iBAAgB;;8BAEtC,KAACP;oBAAgBW,QAAQA;oBAAQC,KAAKA;oBAAKF,UAAUA;oBAAUmC,WAAWpC;;8BAC1E,KAACV;oBACCiB,OAAOA;oBACP+B,YAAYjE,gBAAgBwC,SAAS;oBACrCmB,UAAUhC;oBACVuC,UAAUzC,QAAQyC,QAAQ;oBAC1BC,OAAM;;8BAGR,KAAC9C;oBACC+C,QAAO;oBACPzC,IAAIA;oBACJ0C,QAAQ5C;oBACRI,MAAM,EAAEA,iBAAAA,SAAU;oBAClBM,OAAOA;oBACPL,KAAKA;oBACLwC,cAAc,GAAE5C,yBAAAA,SAAS6C,YAAY,qBAArB7C,uBAAuB8C,OAAO;;8BAEhD,KAACxD;oBAAmBa,QAAQA;oBAAQC,KAAKA;oBAAKiC,WAAWpC;oBAAIC,UAAUA;;;;;AAI/E;AACAL,kBAAkBkD,WAAW,GAAG;AAEhC,eAAelD,kBAAiB"}
@@ -103,7 +103,7 @@ const ADDRESS_FIELDS = [
103
103
  const firestore = useFirestore();
104
104
  const { data: user } = useUser();
105
105
  const { enqueueSnackbar } = useSnackbar();
106
- const { scope, createTokens, createHostId } = useCrmScope({
106
+ const { scope, createTokens, createHostId, createNeedsSite } = useCrmScope({
107
107
  hostId,
108
108
  org
109
109
  });
@@ -279,9 +279,11 @@ const ADDRESS_FIELDS = [
279
279
  var _ref3;
280
280
  if (bandFull) return setError(CRM_RECORDS_BAND_FULL_MESSAGE);
281
281
  const id = createResourceUid();
282
- // Held by the button until the capturing site is known; checked
283
- // again here because a callback can outlive the render that held it.
284
- if (!createHostId) return;
282
+ // Held by the button until it knows who may see the company — the
283
+ // whole org, or a picked site's group where the org keeps its sites
284
+ // apart; checked again here because a callback can outlive the render
285
+ // that held it.
286
+ if (!createTokens.length) return;
285
287
  await setDoc(doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.companies, id), _extends({}, result.set, customDocument ? {
286
288
  custom: customDocument
287
289
  } : {}, crmNewRecordListFields('companies', _extends({}, result.set, {
@@ -394,7 +396,8 @@ const ADDRESS_FIELDS = [
394
396
  company ? null : /*#__PURE__*/ _jsx(CrmSitePicker, {
395
397
  hostId: hostId,
396
398
  disabled: busy,
397
- helperText: "The site this company belongs to — it decides which of your sites may see it."
399
+ optional: !createNeedsSite,
400
+ helperText: createNeedsSite ? 'The site this company belongs to — it decides which of your sites may see it.' : undefined
398
401
  }),
399
402
  /*#__PURE__*/ _jsx(Typography, {
400
403
  variant: "body2",
@@ -697,7 +700,7 @@ const ADDRESS_FIELDS = [
697
700
  variant: "contained",
698
701
  color: "primary",
699
702
  // A new company waits for its capturing site.
700
- disabled: busy || !scope || !draft.name.trim() || !company && !createHostId,
703
+ disabled: busy || !scope || !draft.name.trim() || !company && !createTokens.length,
701
704
  onClick: ()=>void handleSave(),
702
705
  children: busy ? 'Saving…' : company ? 'Save company' : 'Create company'
703
706
  }),
@@ -1 +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 CRM_COMPANY_PICKLIST_FIELDS,\n CRM_COMPANY_TEXT_MAX,\n type CrmCompany,\n type CrmCompanyPicklistField,\n crmCompanyParentId,\n crmCompanyParentRefusal,\n crmNewRecordListFields,\n crmPicklistDefaultLabel,\n pluginDocsHelp,\n crmMemberPickerLabel,\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 getDoc,\n serverTimestamp,\n setDoc,\n updateDoc,\n} from 'firebase/firestore'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useCompanyPicklists } from '../hooks/use-company-picklists'\nimport { DEAL_CURRENCIES } from '../model/deal-board-model'\nimport { CompanyPicker, useCompanyOptions } from './company-picker'\nimport { CrmPicklistSelect } from './picklist-select'\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'\nimport {\n CRM_CLIENT_SEARCH_FIELDS,\n CRM_CLIENT_SORT_FIELDS,\n crmClientListFields,\n} from '../model/crm-list-query'\n\n/**\n * The list fields a client edit of a company rewrites: the search tokens,\n * and the key beside each picklist field the Companies list filters by\n * (AGL-3514).\n */\nconst COMPANY_CLIENT_LIST_FIELDS = [\n ...CRM_CLIENT_SEARCH_FIELDS,\n // Any header sort key the edit's inputs move (AGL-3680).\n ...CRM_CLIENT_SORT_FIELDS,\n ...CRM_COMPANY_PICKLIST_FIELDS.flatMap((entry) => ('keyField' in entry ? [entry.keyField] : [])),\n]\nimport { useCrmSharingFollowUp } from '../hooks/use-crm-sharing'\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\ntype AddressDraftField = 'address' | 'shippingAddress'\n\n/** How each picklist field is labeled on a company. */\nconst COMPANY_PICKLIST_LABELS: Record<CrmCompanyPicklistField, string> = {\n type: 'Type',\n industry: 'Industry',\n rating: 'Rating',\n ownership: 'Ownership',\n accountSource: 'Account source',\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 // A client-direct write owes the org's sharing rules a re-evaluation (AGL-3336).\n const followUpSharing = useCrmSharingFollowUp(hostId, scope?.[1] ?? null)\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 * SALESFORCE'S ACCOUNT FIELDS (AGL-3514): the org's lists behind Type,\n * Industry, Rating, Ownership and Account Source, and the companies a\n * parent may be chosen from — every one the reader can see but this one.\n */\n const picklists = useCompanyPicklists(scope?.[1] ?? null)\n const seededDefaults = useRef(false)\n const companyOptions = useCompanyOptions({ hostId, org, enabled: open })\n const parentOptions = useMemo(\n () => companyOptions.options.filter((option) => option.id !== company?.$id),\n [companyOptions.options, company?.$id],\n )\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 seededDefaults.current = false\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 * A NEW company starts each picklist on the org's default, once the\n * lists have answered — Salesforce's form opens on it too — and only a\n * field nobody has picked a value for yet.\n */\n useEffect(() => {\n if (!open || company || !picklists.ready || seededDefaults.current) return\n seededDefaults.current = true\n setDraft((current) => {\n const next = { ...current }\n for (const { field, picklistId } of CRM_COMPANY_PICKLIST_FIELDS) {\n const list = picklists.lists[picklistId]\n const fallback = list ? crmPicklistDefaultLabel(list) : null\n if (!next[field] && fallback) next[field] = fallback\n }\n return next\n })\n }, [open, company, picklists])\n\n const patch = useCallback(\n (field: keyof Omit<CompanyDraft, AddressDraftField>, value: string) =>\n setDraft((current) => ({ ...current, [field]: value })),\n [],\n )\n const patchAddress = useCallback(\n (which: AddressDraftField, field: keyof AglynPostalAddress, value: string) =>\n setDraft((current) => ({\n ...current,\n [which]: { ...current[which], [field]: value },\n })),\n [],\n )\n /** The parent's own parent, as the cycle guard walks it; `null` for one this reader cannot see. */\n const readParent = useCallback(\n async (id: string) => {\n if (!scope) return null\n try {\n const snapshot = await getDoc(\n doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.companies, id),\n )\n return snapshot.exists()\n ? { parentCompanyId: crmCompanyParentId(snapshot.get('parentCompanyId')) }\n : null\n } catch {\n return null\n }\n },\n [firestore, scope],\n )\n\n const handleSave = useCallback(async () => {\n if (busy || !scope) return\n const result = companyDraftFields(draft, { lists: picklists.lists, current: company })\n if (result.ok === false) return setError(result.error)\n // A parent is never this company, nor one already under it (AGL-3514).\n const parentId = crmCompanyParentId(result.set['parentCompanyId'])\n if (parentId && parentId !== crmCompanyParentId(company?.parentCompanyId)) {\n const refusal = await crmCompanyParentRefusal(company?.$id ?? null, parentId, readParent)\n if (refusal) return setError(refusal)\n }\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 const cleared = Object.fromEntries(\n result.cleared.map((field) => [field, deleteField()]),\n )\n // The stored record the list fields are computed from: the row\n // without the id the listener stamped on it.\n const { $id: _rowId, ...stored } = company\n const searchFields = crmClientListFields(\n 'companies',\n stored,\n { ...result.set, ...cleared },\n COMPANY_CLIENT_LIST_FIELDS,\n )\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 ...cleared,\n // The name and domain are what the Companies list searches\n // (AGL-3321), and the picklist keys what it filters by\n // (AGL-3514), from the listener's row with the edit over it.\n ...searchFields,\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 followUpSharing('companies', [company.$id])\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 // What the Companies list searches and filters by (AGL-3321).\n ...crmNewRecordListFields('companies', {\n ...result.set,\n visibleTo: [...createTokens],\n }),\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 followUpSharing('companies', [id])\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 followUpSharing,\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 picklists.lists,\n readParent,\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 {/*\n Grouped as Salesforce's Account page groups them (AGL-3514):\n what the company is, where it is, and what the team knows.\n */}\n <Typography variant=\"subtitle2\">{'Account information'}</Typography>\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 <CompanyPicker\n label=\"Parent company\"\n options={parentOptions}\n value={draft.parentCompanyId || null}\n onChange={(id) => patch('parentCompanyId', id ?? '')}\n ready={companyOptions.ready}\n truncated={companyOptions.truncated}\n disabled={busy}\n helperText=\"The company this one belongs to, such as a subsidiary's group.\"\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=\"Fax\"\n placeholder=\"+1 512 555 0124\"\n value={draft.fax}\n onChange={(event) => patch('fax', event.target.value)}\n />\n {CRM_COMPANY_PICKLIST_FIELDS.map(({ field, picklistId }) => {\n const list = picklists.lists[picklistId]\n return list ? (\n <CrmPicklistSelect\n key={field}\n picklistId={picklistId}\n picklist={list}\n label={COMPANY_PICKLIST_LABELS[field]}\n value={draft[field]}\n stored={company ? String(company[field] ?? '') : undefined}\n onChange={(label) => patch(field, label)}\n disabled={busy}\n />\n ) : null\n })}\n <TextField\n size=\"small\"\n label=\"Account number\"\n value={draft.accountNumber}\n onChange={(event) => patch('accountNumber', event.target.value)}\n slotProps={{ htmlInput: { maxLength: CRM_COMPANY_TEXT_MAX.accountNumber } }}\n />\n <TextField\n size=\"small\"\n label=\"Account site\"\n placeholder=\"Headquarters\"\n helperText=\"Which of the company's locations this record is.\"\n value={draft.site}\n onChange={(event) => patch('site', event.target.value)}\n slotProps={{ htmlInput: { maxLength: CRM_COMPANY_TEXT_MAX.site } }}\n />\n <Stack direction=\"row\" spacing={1}>\n <TextField\n size=\"small\"\n label=\"Ticker symbol\"\n value={draft.tickerSymbol}\n onChange={(event) => patch('tickerSymbol', event.target.value)}\n slotProps={{ htmlInput: { maxLength: CRM_COMPANY_TEXT_MAX.tickerSymbol } }}\n sx={{ flex: 1 }}\n />\n <TextField\n size=\"small\"\n label=\"SIC code\"\n value={draft.sicCode}\n onChange={(event) => patch('sicCode', event.target.value)}\n slotProps={{ htmlInput: { maxLength: CRM_COMPANY_TEXT_MAX.sicCode } }}\n sx={{ flex: 1 }}\n />\n </Stack>\n <TextField\n size=\"small\"\n label=\"Employees\"\n value={draft.numberOfEmployees}\n onChange={(event) => patch('numberOfEmployees', event.target.value)}\n slotProps={{ htmlInput: { inputMode: 'numeric' } }}\n />\n <Stack direction=\"row\" spacing={1}>\n <TextField\n size=\"small\"\n label=\"Annual revenue\"\n placeholder=\"0.00\"\n value={draft.annualRevenue}\n onChange={(event) => patch('annualRevenue', event.target.value)}\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n sx={{ flex: 1 }}\n />\n <TextField\n select\n size=\"small\"\n label=\"Currency\"\n value={draft.currency}\n onChange={(event) => patch('currency', event.target.value)}\n sx={{ width: 120 }}\n >\n {/* A stored code outside the short list stays selectable as itself. */}\n {[...new Set<string>([...DEAL_CURRENCIES, draft.currency])].map((code) => (\n <MenuItem key={code} value={code}>\n {code.toUpperCase()}\n </MenuItem>\n ))}\n </TextField>\n </Stack>\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 {crmMemberPickerLabel(option)}\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 information'}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Billing address'}\n </Typography>\n {ADDRESS_FIELDS.map((field) => (\n <TextField\n key={`address.${field.key}`}\n size=\"small\"\n label={field.label}\n value={draft.address[field.key] ?? ''}\n onChange={(event) => patchAddress('address', field.key, event.target.value)}\n />\n ))}\n <Stack direction=\"row\" sx={{ alignItems: 'center', justifyContent: 'space-between' }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Shipping address'}\n </Typography>\n <Button\n size=\"small\"\n disabled={busy}\n onClick={() =>\n setDraft((current) => ({ ...current, shippingAddress: { ...current.address } }))\n }\n >\n {'Copy billing address'}\n </Button>\n </Stack>\n {ADDRESS_FIELDS.map((field) => (\n <TextField\n key={`shippingAddress.${field.key}`}\n size=\"small\"\n label={field.label}\n value={draft.shippingAddress[field.key] ?? ''}\n onChange={(event) => patchAddress('shippingAddress', field.key, event.target.value)}\n />\n ))}\n <Typography variant=\"subtitle2\">{'Description information'}</Typography>\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","CRM_COMPANY_PICKLIST_FIELDS","CRM_COMPANY_TEXT_MAX","crmCompanyParentId","crmCompanyParentRefusal","crmNewRecordListFields","crmPicklistDefaultLabel","pluginDocsHelp","crmMemberPickerLabel","ICON_VARIANT_CLOSE","Container","HelpTip","MdiIcon","SrOnly","NavigationDrawerComponent","useSnackbar","useFirestore","useUser","writeGuardedBySeed","Alert","Button","IconButton","MenuItem","Stack","TextField","Typography","deleteField","doc","getDoc","serverTimestamp","setDoc","updateDoc","useCallback","useEffect","useMemo","useRef","useState","useCompanyPicklists","DEAL_CURRENCIES","CompanyPicker","useCompanyOptions","CrmPicklistSelect","useContactFieldDefinitions","useCrmActivityLogger","useCrmRecordsQuota","useCrmScope","companyDraftFields","companyDraftFrom","EMPTY_COMPANY_DRAFT","crmCustomDraftDocument","crmCustomDraftMissingRequired","crmCustomDraftValue","crmCustomDraftWrites","CrmCustomFieldControl","CrmSitePicker","CRM_CLIENT_SEARCH_FIELDS","CRM_CLIENT_SORT_FIELDS","crmClientListFields","COMPANY_CLIENT_LIST_FIELDS","flatMap","entry","keyField","useCrmSharingFollowUp","COMPANY_PICKLIST_LABELS","type","industry","rating","ownership","accountSource","ADDRESS_FIELDS","key","label","CompanyEditDrawer","props","members","open","onClose","hostId","org","company","seed","onSaved","firestore","data","user","enqueueSnackbar","scope","createTokens","createHostId","followUpSharing","logActivity","draft","setDraft","busy","setBusy","error","setError","fields","storedCustom","custom","setCustom","records","bandFull","ready","quota","allowed","picklists","seededDefaults","companyOptions","enabled","parentOptions","options","filter","option","id","$id","companyId","ownerUid","uid","current","next","field","picklistId","list","lists","fallback","patch","value","patchAddress","which","readParent","snapshot","companies","exists","parentCompanyId","get","handleSave","result","ok","parentId","set","refusal","missing","active","length","join","customDocument","ref","verdict","subject","unreadable","fromCache","cleared","Object","fromEntries","map","_rowId","stored","searchFields","updatedAt","message","variant","persist","visibleTo","createdByUid","createdAt","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","truncated","placeholder","domain","website","phone","fax","picklist","String","undefined","accountNumber","slotProps","htmlInput","maxLength","site","direction","tickerSymbol","flex","sicCode","numberOfEmployees","inputMode","annualRevenue","select","currency","width","Set","code","toUpperCase","some","labelFor","tags","address","alignItems","justifyContent","shippingAddress","notes","multiline","minRows","definition","displayName"],"mappings":"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"}
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 CRM_COMPANY_PICKLIST_FIELDS,\n CRM_COMPANY_TEXT_MAX,\n type CrmCompany,\n type CrmCompanyPicklistField,\n crmCompanyParentId,\n crmCompanyParentRefusal,\n crmNewRecordListFields,\n crmPicklistDefaultLabel,\n pluginDocsHelp,\n crmMemberPickerLabel,\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 getDoc,\n serverTimestamp,\n setDoc,\n updateDoc,\n} from 'firebase/firestore'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useCompanyPicklists } from '../hooks/use-company-picklists'\nimport { DEAL_CURRENCIES } from '../model/deal-board-model'\nimport { CompanyPicker, useCompanyOptions } from './company-picker'\nimport { CrmPicklistSelect } from './picklist-select'\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'\nimport {\n CRM_CLIENT_SEARCH_FIELDS,\n CRM_CLIENT_SORT_FIELDS,\n crmClientListFields,\n} from '../model/crm-list-query'\n\n/**\n * The list fields a client edit of a company rewrites: the search tokens,\n * and the key beside each picklist field the Companies list filters by\n * (AGL-3514).\n */\nconst COMPANY_CLIENT_LIST_FIELDS = [\n ...CRM_CLIENT_SEARCH_FIELDS,\n // Any header sort key the edit's inputs move (AGL-3680).\n ...CRM_CLIENT_SORT_FIELDS,\n ...CRM_COMPANY_PICKLIST_FIELDS.flatMap((entry) => ('keyField' in entry ? [entry.keyField] : [])),\n]\nimport { useCrmSharingFollowUp } from '../hooks/use-crm-sharing'\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\ntype AddressDraftField = 'address' | 'shippingAddress'\n\n/** How each picklist field is labeled on a company. */\nconst COMPANY_PICKLIST_LABELS: Record<CrmCompanyPicklistField, string> = {\n type: 'Type',\n industry: 'Industry',\n rating: 'Rating',\n ownership: 'Ownership',\n accountSource: 'Account source',\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, createNeedsSite } = useCrmScope({ hostId, org })\n // A client-direct write owes the org's sharing rules a re-evaluation (AGL-3336).\n const followUpSharing = useCrmSharingFollowUp(hostId, scope?.[1] ?? null)\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 * SALESFORCE'S ACCOUNT FIELDS (AGL-3514): the org's lists behind Type,\n * Industry, Rating, Ownership and Account Source, and the companies a\n * parent may be chosen from — every one the reader can see but this one.\n */\n const picklists = useCompanyPicklists(scope?.[1] ?? null)\n const seededDefaults = useRef(false)\n const companyOptions = useCompanyOptions({ hostId, org, enabled: open })\n const parentOptions = useMemo(\n () => companyOptions.options.filter((option) => option.id !== company?.$id),\n [companyOptions.options, company?.$id],\n )\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 seededDefaults.current = false\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 * A NEW company starts each picklist on the org's default, once the\n * lists have answered — Salesforce's form opens on it too — and only a\n * field nobody has picked a value for yet.\n */\n useEffect(() => {\n if (!open || company || !picklists.ready || seededDefaults.current) return\n seededDefaults.current = true\n setDraft((current) => {\n const next = { ...current }\n for (const { field, picklistId } of CRM_COMPANY_PICKLIST_FIELDS) {\n const list = picklists.lists[picklistId]\n const fallback = list ? crmPicklistDefaultLabel(list) : null\n if (!next[field] && fallback) next[field] = fallback\n }\n return next\n })\n }, [open, company, picklists])\n\n const patch = useCallback(\n (field: keyof Omit<CompanyDraft, AddressDraftField>, value: string) =>\n setDraft((current) => ({ ...current, [field]: value })),\n [],\n )\n const patchAddress = useCallback(\n (which: AddressDraftField, field: keyof AglynPostalAddress, value: string) =>\n setDraft((current) => ({\n ...current,\n [which]: { ...current[which], [field]: value },\n })),\n [],\n )\n /** The parent's own parent, as the cycle guard walks it; `null` for one this reader cannot see. */\n const readParent = useCallback(\n async (id: string) => {\n if (!scope) return null\n try {\n const snapshot = await getDoc(\n doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.companies, id),\n )\n return snapshot.exists()\n ? { parentCompanyId: crmCompanyParentId(snapshot.get('parentCompanyId')) }\n : null\n } catch {\n return null\n }\n },\n [firestore, scope],\n )\n\n const handleSave = useCallback(async () => {\n if (busy || !scope) return\n const result = companyDraftFields(draft, { lists: picklists.lists, current: company })\n if (result.ok === false) return setError(result.error)\n // A parent is never this company, nor one already under it (AGL-3514).\n const parentId = crmCompanyParentId(result.set['parentCompanyId'])\n if (parentId && parentId !== crmCompanyParentId(company?.parentCompanyId)) {\n const refusal = await crmCompanyParentRefusal(company?.$id ?? null, parentId, readParent)\n if (refusal) return setError(refusal)\n }\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 const cleared = Object.fromEntries(\n result.cleared.map((field) => [field, deleteField()]),\n )\n // The stored record the list fields are computed from: the row\n // without the id the listener stamped on it.\n const { $id: _rowId, ...stored } = company\n const searchFields = crmClientListFields(\n 'companies',\n stored,\n { ...result.set, ...cleared },\n COMPANY_CLIENT_LIST_FIELDS,\n )\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 ...cleared,\n // The name and domain are what the Companies list searches\n // (AGL-3321), and the picklist keys what it filters by\n // (AGL-3514), from the listener's row with the edit over it.\n ...searchFields,\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 followUpSharing('companies', [company.$id])\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 it knows who may see the company — the\n // whole org, or a picked site's group where the org keeps its sites\n // apart; checked again here because a callback can outlive the render\n // that held it.\n if (!createTokens.length) return\n await setDoc(\n doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.companies, id),\n {\n ...result.set,\n ...(customDocument ? { custom: customDocument } : {}),\n // What the Companies list searches and filters by (AGL-3321).\n ...crmNewRecordListFields('companies', {\n ...result.set,\n visibleTo: [...createTokens],\n }),\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 followUpSharing('companies', [id])\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 followUpSharing,\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 picklists.lists,\n readParent,\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 it came\n from — required where the org keeps its sites apart, optional\n where every site sees it. Nothing under a site, and nothing on an\n edit — a company keeps the site it was made on (AGL-2630).\n */}\n {company ? null : (\n <CrmSitePicker\n hostId={hostId}\n disabled={busy}\n optional={!createNeedsSite}\n helperText={\n createNeedsSite\n ? 'The site this company belongs to — it decides which of your sites may see it.'\n : undefined\n }\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 {/*\n Grouped as Salesforce's Account page groups them (AGL-3514):\n what the company is, where it is, and what the team knows.\n */}\n <Typography variant=\"subtitle2\">{'Account information'}</Typography>\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 <CompanyPicker\n label=\"Parent company\"\n options={parentOptions}\n value={draft.parentCompanyId || null}\n onChange={(id) => patch('parentCompanyId', id ?? '')}\n ready={companyOptions.ready}\n truncated={companyOptions.truncated}\n disabled={busy}\n helperText=\"The company this one belongs to, such as a subsidiary's group.\"\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=\"Fax\"\n placeholder=\"+1 512 555 0124\"\n value={draft.fax}\n onChange={(event) => patch('fax', event.target.value)}\n />\n {CRM_COMPANY_PICKLIST_FIELDS.map(({ field, picklistId }) => {\n const list = picklists.lists[picklistId]\n return list ? (\n <CrmPicklistSelect\n key={field}\n picklistId={picklistId}\n picklist={list}\n label={COMPANY_PICKLIST_LABELS[field]}\n value={draft[field]}\n stored={company ? String(company[field] ?? '') : undefined}\n onChange={(label) => patch(field, label)}\n disabled={busy}\n />\n ) : null\n })}\n <TextField\n size=\"small\"\n label=\"Account number\"\n value={draft.accountNumber}\n onChange={(event) => patch('accountNumber', event.target.value)}\n slotProps={{ htmlInput: { maxLength: CRM_COMPANY_TEXT_MAX.accountNumber } }}\n />\n <TextField\n size=\"small\"\n label=\"Account site\"\n placeholder=\"Headquarters\"\n helperText=\"Which of the company's locations this record is.\"\n value={draft.site}\n onChange={(event) => patch('site', event.target.value)}\n slotProps={{ htmlInput: { maxLength: CRM_COMPANY_TEXT_MAX.site } }}\n />\n <Stack direction=\"row\" spacing={1}>\n <TextField\n size=\"small\"\n label=\"Ticker symbol\"\n value={draft.tickerSymbol}\n onChange={(event) => patch('tickerSymbol', event.target.value)}\n slotProps={{ htmlInput: { maxLength: CRM_COMPANY_TEXT_MAX.tickerSymbol } }}\n sx={{ flex: 1 }}\n />\n <TextField\n size=\"small\"\n label=\"SIC code\"\n value={draft.sicCode}\n onChange={(event) => patch('sicCode', event.target.value)}\n slotProps={{ htmlInput: { maxLength: CRM_COMPANY_TEXT_MAX.sicCode } }}\n sx={{ flex: 1 }}\n />\n </Stack>\n <TextField\n size=\"small\"\n label=\"Employees\"\n value={draft.numberOfEmployees}\n onChange={(event) => patch('numberOfEmployees', event.target.value)}\n slotProps={{ htmlInput: { inputMode: 'numeric' } }}\n />\n <Stack direction=\"row\" spacing={1}>\n <TextField\n size=\"small\"\n label=\"Annual revenue\"\n placeholder=\"0.00\"\n value={draft.annualRevenue}\n onChange={(event) => patch('annualRevenue', event.target.value)}\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n sx={{ flex: 1 }}\n />\n <TextField\n select\n size=\"small\"\n label=\"Currency\"\n value={draft.currency}\n onChange={(event) => patch('currency', event.target.value)}\n sx={{ width: 120 }}\n >\n {/* A stored code outside the short list stays selectable as itself. */}\n {[...new Set<string>([...DEAL_CURRENCIES, draft.currency])].map((code) => (\n <MenuItem key={code} value={code}>\n {code.toUpperCase()}\n </MenuItem>\n ))}\n </TextField>\n </Stack>\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 {crmMemberPickerLabel(option)}\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 information'}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Billing address'}\n </Typography>\n {ADDRESS_FIELDS.map((field) => (\n <TextField\n key={`address.${field.key}`}\n size=\"small\"\n label={field.label}\n value={draft.address[field.key] ?? ''}\n onChange={(event) => patchAddress('address', field.key, event.target.value)}\n />\n ))}\n <Stack direction=\"row\" sx={{ alignItems: 'center', justifyContent: 'space-between' }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Shipping address'}\n </Typography>\n <Button\n size=\"small\"\n disabled={busy}\n onClick={() =>\n setDraft((current) => ({ ...current, shippingAddress: { ...current.address } }))\n }\n >\n {'Copy billing address'}\n </Button>\n </Stack>\n {ADDRESS_FIELDS.map((field) => (\n <TextField\n key={`shippingAddress.${field.key}`}\n size=\"small\"\n label={field.label}\n value={draft.shippingAddress[field.key] ?? ''}\n onChange={(event) => patchAddress('shippingAddress', field.key, event.target.value)}\n />\n ))}\n <Typography variant=\"subtitle2\">{'Description information'}</Typography>\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 && !createTokens.length)}\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","CRM_COMPANY_PICKLIST_FIELDS","CRM_COMPANY_TEXT_MAX","crmCompanyParentId","crmCompanyParentRefusal","crmNewRecordListFields","crmPicklistDefaultLabel","pluginDocsHelp","crmMemberPickerLabel","ICON_VARIANT_CLOSE","Container","HelpTip","MdiIcon","SrOnly","NavigationDrawerComponent","useSnackbar","useFirestore","useUser","writeGuardedBySeed","Alert","Button","IconButton","MenuItem","Stack","TextField","Typography","deleteField","doc","getDoc","serverTimestamp","setDoc","updateDoc","useCallback","useEffect","useMemo","useRef","useState","useCompanyPicklists","DEAL_CURRENCIES","CompanyPicker","useCompanyOptions","CrmPicklistSelect","useContactFieldDefinitions","useCrmActivityLogger","useCrmRecordsQuota","useCrmScope","companyDraftFields","companyDraftFrom","EMPTY_COMPANY_DRAFT","crmCustomDraftDocument","crmCustomDraftMissingRequired","crmCustomDraftValue","crmCustomDraftWrites","CrmCustomFieldControl","CrmSitePicker","CRM_CLIENT_SEARCH_FIELDS","CRM_CLIENT_SORT_FIELDS","crmClientListFields","COMPANY_CLIENT_LIST_FIELDS","flatMap","entry","keyField","useCrmSharingFollowUp","COMPANY_PICKLIST_LABELS","type","industry","rating","ownership","accountSource","ADDRESS_FIELDS","key","label","CompanyEditDrawer","props","members","open","onClose","hostId","org","company","seed","onSaved","firestore","data","user","enqueueSnackbar","scope","createTokens","createHostId","createNeedsSite","followUpSharing","logActivity","draft","setDraft","busy","setBusy","error","setError","fields","storedCustom","custom","setCustom","records","bandFull","ready","quota","allowed","picklists","seededDefaults","companyOptions","enabled","parentOptions","options","filter","option","id","$id","companyId","ownerUid","uid","current","next","field","picklistId","list","lists","fallback","patch","value","patchAddress","which","readParent","snapshot","companies","exists","parentCompanyId","get","handleSave","result","ok","parentId","set","refusal","missing","active","length","join","customDocument","ref","verdict","subject","unreadable","fromCache","cleared","Object","fromEntries","map","_rowId","stored","searchFields","updatedAt","message","variant","persist","visibleTo","createdByUid","createdAt","name","trim","caught","console","anchor","AppBarProps","color","appBarLeft","edge","onClick","sx","mr","path","component","gutterY","spacing","disabled","optional","helperText","undefined","severity","size","required","onChange","event","target","autoFocus","truncated","placeholder","domain","website","phone","fax","picklist","String","accountNumber","slotProps","htmlInput","maxLength","site","direction","tickerSymbol","flex","sicCode","numberOfEmployees","inputMode","annualRevenue","select","currency","width","Set","code","toUpperCase","some","labelFor","tags","address","alignItems","justifyContent","shippingAddress","notes","multiline","minRows","definition","displayName"],"mappings":"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"}
@@ -104,7 +104,9 @@ export { suggestCompanyForEmail };
104
104
  const { data: user } = useUser();
105
105
  // The provenance and the scope both come from the site the record is
106
106
  // captured by — the mounted one, or at the organization level the one the
107
- // reader picked (AGL-2630). No site picked, no create offered.
107
+ // reader picked (AGL-2630). Where the org keeps its sites apart, no site
108
+ // picked means no create offered; where every site sees its records, a
109
+ // company typed here with no site picked belongs to the whole org.
108
110
  const { scope, createTokens, createHostId } = useCrmScope({
109
111
  hostId,
110
112
  org
@@ -112,7 +114,7 @@ export { suggestCompanyForEmail };
112
114
  const followUpSharing = useCrmSharingFollowUp(hostId, (_ref = scope == null ? void 0 : scope[1]) != null ? _ref : null);
113
115
  const uid = (_ref1 = user == null ? void 0 : user.uid) != null ? _ref1 : '';
114
116
  return useMemo(()=>{
115
- if (!scope || !createHostId) return null;
117
+ if (!scope || !createTokens.length) return null;
116
118
  return async (name)=>{
117
119
  const result = companyDraftFields(_extends({}, EMPTY_COMPANY_DRAFT, {
118
120
  name,