@aglyn/plugins-crm 1.0.0-beta.199 → 1.0.0-beta.201
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +13 -13
- package/src/lib/components/activity-list.d.ts +36 -5
- package/src/lib/components/activity-list.js +159 -137
- package/src/lib/components/activity-list.js.map +1 -1
- package/src/lib/components/activity-timeline.d.ts +84 -0
- package/src/lib/components/activity-timeline.js +224 -0
- package/src/lib/components/activity-timeline.js.map +1 -0
- package/src/lib/components/companies-section.d.ts +6 -6
- package/src/lib/components/companies-section.js +54 -84
- package/src/lib/components/companies-section.js.map +1 -1
- package/src/lib/components/company-edit-drawer.js +17 -4
- package/src/lib/components/company-edit-drawer.js.map +1 -1
- package/src/lib/components/company-picker.js +6 -2
- package/src/lib/components/company-picker.js.map +1 -1
- package/src/lib/components/company-properties-card.js +53 -36
- package/src/lib/components/company-properties-card.js.map +1 -1
- package/src/lib/components/contact-associations-card.d.ts +3 -2
- package/src/lib/components/contact-associations-card.js +12 -12
- package/src/lib/components/contact-associations-card.js.map +1 -1
- package/src/lib/components/contact-detail-page.d.ts +4 -3
- package/src/lib/components/contact-detail-page.js +18 -12
- package/src/lib/components/contact-detail-page.js.map +1 -1
- package/src/lib/components/contact-list-columns.d.ts +3 -5
- package/src/lib/components/contact-list-columns.js +6 -8
- package/src/lib/components/contact-list-columns.js.map +1 -1
- package/src/lib/components/contact-properties-card.d.ts +21 -4
- package/src/lib/components/contact-properties-card.js +129 -29
- package/src/lib/components/contact-properties-card.js.map +1 -1
- package/src/lib/components/contact-timeline-card.d.ts +12 -6
- package/src/lib/components/contact-timeline-card.js +132 -174
- package/src/lib/components/contact-timeline-card.js.map +1 -1
- package/src/lib/components/contacts-bulk-bar.js +10 -1
- package/src/lib/components/contacts-bulk-bar.js.map +1 -1
- package/src/lib/components/contacts-section.js +282 -331
- package/src/lib/components/contacts-section.js.map +1 -1
- package/src/lib/components/crm-email-state-chip.js +4 -1
- package/src/lib/components/crm-email-state-chip.js.map +1 -1
- package/src/lib/components/crm-next-activity-column.d.ts +4 -2
- package/src/lib/components/crm-next-activity-column.js +6 -3
- package/src/lib/components/crm-next-activity-column.js.map +1 -1
- package/src/lib/components/deal-edit-drawer.js +8 -4
- package/src/lib/components/deal-edit-drawer.js.map +1 -1
- package/src/lib/components/deal-products-card.js +15 -13
- package/src/lib/components/deal-products-card.js.map +1 -1
- package/src/lib/components/deal-properties-card.js +7 -0
- package/src/lib/components/deal-properties-card.js.map +1 -1
- package/src/lib/components/deal-stage-card.js +31 -29
- package/src/lib/components/deal-stage-card.js.map +1 -1
- package/src/lib/components/deals-section.d.ts +2 -2
- package/src/lib/components/deals-section.js +67 -97
- package/src/lib/components/deals-section.js.map +1 -1
- package/src/lib/components/fields-section.d.ts +4 -0
- package/src/lib/components/fields-section.js +368 -154
- package/src/lib/components/fields-section.js.map +1 -1
- package/src/lib/components/form-contact-fields-card.js +24 -20
- package/src/lib/components/form-contact-fields-card.js.map +1 -1
- package/src/lib/components/lead-campaigns-card.d.ts +1 -1
- package/src/lib/components/lead-campaigns-card.js +43 -38
- package/src/lib/components/lead-campaigns-card.js.map +1 -1
- package/src/lib/components/lead-properties-card.d.ts +14 -6
- package/src/lib/components/lead-properties-card.js +323 -311
- package/src/lib/components/lead-properties-card.js.map +1 -1
- package/src/lib/components/lead-surfaces-note.js +13 -2
- package/src/lib/components/lead-surfaces-note.js.map +1 -1
- package/src/lib/components/leads-bulk-bar.js +16 -3
- package/src/lib/components/leads-bulk-bar.js.map +1 -1
- package/src/lib/components/leads-section.d.ts +2 -1
- package/src/lib/components/leads-section.js +110 -148
- package/src/lib/components/leads-section.js.map +1 -1
- package/src/lib/components/linked-deals-card.js +12 -10
- package/src/lib/components/linked-deals-card.js.map +1 -1
- package/src/lib/components/recent-activity-feed.d.ts +12 -8
- package/src/lib/components/recent-activity-feed.js +54 -29
- package/src/lib/components/recent-activity-feed.js.map +1 -1
- package/src/lib/components/record-activity-card.d.ts +4 -2
- package/src/lib/components/record-activity-card.js +29 -11
- package/src/lib/components/record-activity-card.js.map +1 -1
- package/src/lib/components/reports/activity-card.js +18 -12
- package/src/lib/components/reports/activity-card.js.map +1 -1
- package/src/lib/components/reports/lead-funnel-card.js +47 -37
- package/src/lib/components/reports/lead-funnel-card.js.map +1 -1
- package/src/lib/components/reports/pipeline-card.js +22 -16
- package/src/lib/components/reports/pipeline-card.js.map +1 -1
- package/src/lib/components/reports/report-export.d.ts +4 -11
- package/src/lib/components/reports/report-export.js +16 -33
- package/src/lib/components/reports/report-export.js.map +1 -1
- package/src/lib/components/reports/source-conversion-card.js +18 -12
- package/src/lib/components/reports/source-conversion-card.js.map +1 -1
- package/src/lib/components/reports/tasks-card.js +35 -25
- package/src/lib/components/reports/tasks-card.js.map +1 -1
- package/src/lib/components/tasks-section.js +151 -144
- package/src/lib/components/tasks-section.js.map +1 -1
- package/src/lib/constants/company-filters.d.ts +13 -0
- package/src/lib/constants/company-filters.js +47 -17
- package/src/lib/constants/company-filters.js.map +1 -1
- package/src/lib/constants/contact-filters.d.ts +61 -10
- package/src/lib/constants/contact-filters.js +373 -141
- package/src/lib/constants/contact-filters.js.map +1 -1
- package/src/lib/constants/deal-filters.d.ts +44 -0
- package/src/lib/constants/deal-filters.js +78 -0
- package/src/lib/constants/deal-filters.js.map +1 -0
- package/src/lib/constants/field-list-query.d.ts +23 -0
- package/src/lib/constants/field-list-query.js +80 -0
- package/src/lib/constants/field-list-query.js.map +1 -0
- package/src/lib/hooks/use-crm-list-query.d.ts +68 -0
- package/src/lib/hooks/use-crm-list-query.js +182 -0
- package/src/lib/hooks/use-crm-list-query.js.map +1 -0
- package/src/lib/hooks/use-crm-tasks.d.ts +23 -6
- package/src/lib/hooks/use-crm-tasks.js +44 -42
- package/src/lib/hooks/use-crm-tasks.js.map +1 -1
- package/src/lib/hooks/use-deals.d.ts +2 -34
- package/src/lib/hooks/use-deals.js +3 -62
- package/src/lib/hooks/use-deals.js.map +1 -1
- package/src/lib/model/crm-list-query.d.ts +91 -0
- package/src/lib/model/crm-list-query.js +182 -0
- package/src/lib/model/crm-list-query.js.map +1 -0
- package/src/lib/model/lead-filters.d.ts +50 -44
- package/src/lib/model/lead-filters.js +194 -88
- package/src/lib/model/lead-filters.js.map +1 -1
- package/src/lib/model/list-fields-api.d.ts +26 -0
- package/src/lib/model/list-fields-api.js +47 -0
- package/src/lib/model/list-fields-api.js.map +1 -0
- package/src/lib/model/list-fields.d.ts +47 -0
- package/src/lib/model/list-fields.js +39 -0
- package/src/lib/model/list-fields.js.map +1 -0
- package/src/lib/model/task-views.d.ts +15 -10
- package/src/lib/model/task-views.js +68 -9
- package/src/lib/model/task-views.js.map +1 -1
- package/src/lib/server/capture-contact.js +7 -5
- package/src/lib/server/capture-contact.js.map +1 -1
- package/src/lib/server/companies-import.js +3 -3
- package/src/lib/server/companies-import.js.map +1 -1
- package/src/lib/server/company-delete.js +3 -1
- package/src/lib/server/company-delete.js.map +1 -1
- package/src/lib/server/consent-group-participant.js +4 -0
- package/src/lib/server/consent-group-participant.js.map +1 -1
- package/src/lib/server/contact-update.js +14 -8
- package/src/lib/server/contact-update.js.map +1 -1
- package/src/lib/server/contacts-import.js +4 -2
- package/src/lib/server/contacts-import.js.map +1 -1
- package/src/lib/server/deals-import.js +4 -2
- package/src/lib/server/deals-import.js.map +1 -1
- package/src/lib/server/erase-person.js +2 -1
- package/src/lib/server/erase-person.js.map +1 -1
- package/src/lib/server/lead-create.js +4 -1
- package/src/lib/server/lead-create.js.map +1 -1
- package/src/lib/server/lead-source-values.js +9 -5
- package/src/lib/server/lead-source-values.js.map +1 -1
- package/src/lib/server/leads-import.js +4 -1
- package/src/lib/server/leads-import.js.map +1 -1
- package/src/lib/server/list-fields-routes.d.ts +29 -0
- package/src/lib/server/list-fields-routes.js +85 -0
- package/src/lib/server/list-fields-routes.js.map +1 -0
- package/src/lib/server/record-email-state.js +5 -2
- package/src/lib/server/record-email-state.js.map +1 -1
- package/src/lib/server/record-timeline.js +3 -2
- package/src/lib/server/record-timeline.js.map +1 -1
- package/src/lib/server/task-routes.js +6 -3
- package/src/lib/server/task-routes.js.map +1 -1
- package/src/lib/server/tasks-import.js +5 -2
- package/src/lib/server/tasks-import.js.map +1 -1
- package/src/lib/server.js +10 -1
- package/src/lib/server.js.map +1 -1
- package/src/lib/components/contact-custom-fields-card.d.ts +0 -39
- package/src/lib/components/contact-custom-fields-card.js +0 -204
- package/src/lib/components/contact-custom-fields-card.js.map +0 -1
- package/src/lib/hooks/use-org-leads.d.ts +0 -50
- package/src/lib/hooks/use-org-leads.js +0 -104
- package/src/lib/hooks/use-org-leads.js.map +0 -1
|
@@ -18,7 +18,7 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
|
18
18
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
19
19
|
import * as Aglyn from "@aglyn/aglyn";
|
|
20
20
|
import { mdiAccountCancelOutline } from "@aglyn/shared-data-mdi";
|
|
21
|
-
import { AppLink, MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
21
|
+
import { AppLink, CardDisplay, MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
22
22
|
import { useSnackbar } from "@aglyn/shared-ui-snackstack";
|
|
23
23
|
import { useFirestore, writeGuardedBySeed } from "@aglyn/tenant-feature-instance";
|
|
24
24
|
import { Alert, Button, FormControl, InputLabel, MenuItem, Select, Stack, TextField, Tooltip, Typography } from "@mui/material";
|
|
@@ -37,6 +37,11 @@ import { CrmSendEmailButton } from "./crm-send-email-button.js";
|
|
|
37
37
|
import { LeadOwnerSelect } from "./lead-owner-select.js";
|
|
38
38
|
import { LeadSourceSelect } from "./lead-source-select.js";
|
|
39
39
|
import { LeadStatusChip } from "./lead-status-chip.js";
|
|
40
|
+
import { crmClientListFields, CRM_CLIENT_SEARCH_FIELDS } from "../model/crm-list-query.js";
|
|
41
|
+
/** The Leads list's fields a profile save rewrites; the verdict key is the server's. */ const LEAD_CLIENT_LIST_FIELDS = [
|
|
42
|
+
...CRM_CLIENT_SEARCH_FIELDS,
|
|
43
|
+
'leadSourceKey'
|
|
44
|
+
];
|
|
40
45
|
const NOTES_MAX = Aglyn.CRM_LEAD_NOTES_MAX;
|
|
41
46
|
const TEXT_MAX = Aglyn.CRM_LEAD_TEXT_MAX;
|
|
42
47
|
/** The stored profile as a draft the fields can edit. */ function profileDraftFrom(lead) {
|
|
@@ -84,15 +89,23 @@ const TEXT_MAX = Aglyn.CRM_LEAD_TEXT_MAX;
|
|
|
84
89
|
* What the team knows and decides about a lead: status, owner, notes, and
|
|
85
90
|
* the identity and consent the capture recorded (AGL-2608).
|
|
86
91
|
*
|
|
92
|
+
* Two cards. The record's header carries the identity, the status and owner,
|
|
93
|
+
* the consent the capture recorded and the record's actions. **Details**
|
|
94
|
+
* under it carries the profile, the org's own lead fields under **More
|
|
95
|
+
* fields**, and the notes — one card with one Save in its header, the way
|
|
96
|
+
* Salesforce keeps a record's standard and custom fields in one Details
|
|
97
|
+
* section.
|
|
98
|
+
*
|
|
87
99
|
* Status and owner are single-field client writes — the rules let a site
|
|
88
100
|
* admin, editor or author update `hosts/{hostId}/leads`, and a one-field
|
|
89
|
-
* `update` cannot roll anything else back.
|
|
90
|
-
* from the document, so
|
|
91
|
-
* edited over a cached read would otherwise overwrite a newer note
|
|
92
|
-
*
|
|
101
|
+
* `update` cannot roll anything else back. The details are drafts seeded
|
|
102
|
+
* from the document, so their save goes through `writeGuardedBySeed`: a
|
|
103
|
+
* draft edited over a cached read would otherwise overwrite a newer note or
|
|
104
|
+
* profile with an older one.
|
|
93
105
|
*
|
|
94
|
-
* Converted leads are read-only here. Their status is the
|
|
95
|
-
* the actions become links to what the conversion
|
|
106
|
+
* Converted leads are read-only here, but for the notes. Their status is the
|
|
107
|
+
* conversion, and the header's actions become links to what the conversion
|
|
108
|
+
* made.
|
|
96
109
|
*/ export function LeadPropertiesCard(props) {
|
|
97
110
|
var _lead_phone, _lead_notes, _lead_email, _lead_email1, _lead_name, _lead_leadSource;
|
|
98
111
|
const { hostId, consentGroup, orgId, leadId, lead, leadStatus, fromCache, basePath, roster, onConvert, onUnqualify, extraMenuItems = [], banner, extraChips, erasurePending = false, org } = props;
|
|
@@ -116,16 +129,16 @@ const TEXT_MAX = Aglyn.CRM_LEAD_TEXT_MAX;
|
|
|
116
129
|
// after the status it shows — see `LeadOwnerSelect`.
|
|
117
130
|
const statusLabelId = useId();
|
|
118
131
|
const [notesDirty, setNotesDirty] = useState(false);
|
|
119
|
-
const [savingNotes, setSavingNotes] = useState(false);
|
|
120
132
|
/*
|
|
121
133
|
* THE LEAD'S OWN PROFILE (AGL-3231) — company, title, phone, website,
|
|
122
|
-
* address, tags, lead source — edited
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* not overwrite a newer profile with an
|
|
134
|
+
* address, tags, lead source — edited in the Details card with the notes
|
|
135
|
+
* and the custom fields, under one Save, the way the contact's Properties
|
|
136
|
+
* card saves. Seeded from the document and guarded on save: a draft
|
|
137
|
+
* edited over a cached read must not overwrite a newer profile with an
|
|
138
|
+
* older one.
|
|
126
139
|
*/ const [profile, setProfile] = useState(()=>profileDraftFrom(lead));
|
|
127
140
|
const [profileDirty, setProfileDirty] = useState(false);
|
|
128
|
-
const [
|
|
141
|
+
const [saving, setSaving] = useState(false);
|
|
129
142
|
const [profileErrors, setProfileErrors] = useState({});
|
|
130
143
|
useEffect(()=>{
|
|
131
144
|
if (!profileDirty) setProfile(profileDraftFrom(lead));
|
|
@@ -175,7 +188,7 @@ const TEXT_MAX = Aglyn.CRM_LEAD_TEXT_MAX;
|
|
|
175
188
|
lead.notes,
|
|
176
189
|
notesDirty
|
|
177
190
|
]);
|
|
178
|
-
const write = async (fields, done)=>{
|
|
191
|
+
/** One update of the lead, and whether it landed. */ const write = async (fields, done)=>{
|
|
179
192
|
try {
|
|
180
193
|
const ref = refFor();
|
|
181
194
|
if (!ref) {
|
|
@@ -183,7 +196,7 @@ const TEXT_MAX = Aglyn.CRM_LEAD_TEXT_MAX;
|
|
|
183
196
|
variant: 'warning',
|
|
184
197
|
persist: false
|
|
185
198
|
});
|
|
186
|
-
return;
|
|
199
|
+
return false;
|
|
187
200
|
}
|
|
188
201
|
await updateDoc(ref, _extends({}, fields, {
|
|
189
202
|
updatedAt: serverTimestamp()
|
|
@@ -192,67 +205,76 @@ const TEXT_MAX = Aglyn.CRM_LEAD_TEXT_MAX;
|
|
|
192
205
|
variant: 'success',
|
|
193
206
|
persist: false
|
|
194
207
|
});
|
|
208
|
+
return true;
|
|
195
209
|
} catch (error) {
|
|
196
210
|
enqueueSnackbar(error instanceof Error ? error.message : 'The lead could not be updated.', {
|
|
197
211
|
variant: 'error'
|
|
198
212
|
});
|
|
213
|
+
return false;
|
|
199
214
|
}
|
|
200
215
|
};
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
});
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
216
|
+
/*
|
|
217
|
+
* What Save is offered for: a profile field edited, a custom value that
|
|
218
|
+
* differs from the stored map, or the notes. Touched-and-put-back does
|
|
219
|
+
* not count for a custom value — the draft keeps the key either way, and
|
|
220
|
+
* a Save that wrote nothing would still bump `updatedAt`.
|
|
221
|
+
*/ const customChanged = crmCustomDraftChanges(storedCustom, custom).length > 0;
|
|
222
|
+
const dirty = profileDirty || customChanged || notesDirty;
|
|
223
|
+
/** Every draft back to what the document holds. */ const discard = ()=>{
|
|
224
|
+
var _lead_notes;
|
|
225
|
+
setProfile(profileDraftFrom(lead));
|
|
226
|
+
setProfileDirty(false);
|
|
227
|
+
setProfileErrors({});
|
|
228
|
+
setCustom({});
|
|
229
|
+
setNotes(String((_lead_notes = lead.notes) != null ? _lead_notes : ''));
|
|
218
230
|
setNotesDirty(false);
|
|
219
231
|
};
|
|
220
232
|
/*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
});
|
|
236
|
-
setProfileErrors(errors);
|
|
237
|
-
if (Object.keys(errors).length) return;
|
|
238
|
-
/*
|
|
239
|
-
* A required field the reader CLEARED is refused; one the lead has
|
|
240
|
-
* always lacked is not this save's to demand, or a field added after
|
|
241
|
-
* the lead was captured would block every later edit to its company.
|
|
242
|
-
*/ const missing = crmCustomDraftMissingRequired(fields.active, storedCustom, custom, 'edit');
|
|
243
|
-
if (missing.length) {
|
|
244
|
-
enqueueSnackbar(`${missing.join(', ')} ${missing.length > 1 ? 'are' : 'is'} required.`, {
|
|
245
|
-
variant: 'warning'
|
|
233
|
+
* The Details card's one Save: the profile and the custom values while
|
|
234
|
+
* the lead is open, and the notes, in one update. A converted lead's
|
|
235
|
+
* profile is the contact's now, so only its notes are written.
|
|
236
|
+
*/ const saveDetails = async ()=>{
|
|
237
|
+
const update = {};
|
|
238
|
+
if (!converted && (profileDirty || customChanged)) {
|
|
239
|
+
const { patch, errors } = Aglyn.normalizeCrmLeadProfile({
|
|
240
|
+
company: profile.company,
|
|
241
|
+
jobTitle: profile.jobTitle,
|
|
242
|
+
phone: profile.phone,
|
|
243
|
+
website: profile.website,
|
|
244
|
+
leadSource: profile.leadSource,
|
|
245
|
+
tags: profile.tags,
|
|
246
|
+
address: profile.address
|
|
246
247
|
});
|
|
247
|
-
|
|
248
|
+
setProfileErrors(errors);
|
|
249
|
+
if (Object.keys(errors).length) return;
|
|
250
|
+
/*
|
|
251
|
+
* A required field the reader CLEARED is refused; one the lead has
|
|
252
|
+
* always lacked is not this save's to demand, or a field added after
|
|
253
|
+
* the lead was captured would block every later edit to its company.
|
|
254
|
+
*/ const missing = crmCustomDraftMissingRequired(fields.active, storedCustom, custom, 'edit');
|
|
255
|
+
if (missing.length) {
|
|
256
|
+
enqueueSnackbar(`${missing.join(', ')} ${missing.length > 1 ? 'are' : 'is'} required.`, {
|
|
257
|
+
variant: 'warning'
|
|
258
|
+
});
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const profileFields = profileWrite(patch);
|
|
262
|
+
Object.assign(update, profileFields, crmCustomDraftWrites(storedCustom, custom), // The company, title, tags and lead source are what the Leads list
|
|
263
|
+
// searches and filters by (AGL-3321).
|
|
264
|
+
crmClientListFields('leads', lead, profileFields, LEAD_CLIENT_LIST_FIELDS));
|
|
248
265
|
}
|
|
249
|
-
|
|
266
|
+
if (notesDirty) update['notes'] = notes.trim().slice(0, NOTES_MAX);
|
|
267
|
+
if (!Object.keys(update).length) return;
|
|
268
|
+
setSaving(true);
|
|
269
|
+
let landed = false;
|
|
250
270
|
const verdict = await writeGuardedBySeed({
|
|
251
271
|
subject: 'lead',
|
|
252
272
|
fromCache,
|
|
253
273
|
unreadable: leadStatus === 'error'
|
|
254
|
-
}, ()=>
|
|
255
|
-
|
|
274
|
+
}, async ()=>{
|
|
275
|
+
landed = await write(update, 'Lead saved');
|
|
276
|
+
});
|
|
277
|
+
setSaving(false);
|
|
256
278
|
if (!verdict.ok) {
|
|
257
279
|
var _verdict_message;
|
|
258
280
|
enqueueSnackbar((_verdict_message = verdict.message) != null ? _verdict_message : 'The lead could not be saved.', {
|
|
@@ -260,247 +282,271 @@ const TEXT_MAX = Aglyn.CRM_LEAD_TEXT_MAX;
|
|
|
260
282
|
});
|
|
261
283
|
return;
|
|
262
284
|
}
|
|
285
|
+
if (!landed) return;
|
|
263
286
|
setProfileDirty(false);
|
|
287
|
+
setNotesDirty(false);
|
|
264
288
|
// The draft is spent: what it held is stored, and the controls read
|
|
265
289
|
// the document again.
|
|
266
290
|
setCustom({});
|
|
267
291
|
};
|
|
268
292
|
const consent = Aglyn.readMarketingBasis(lead, consentGroup);
|
|
269
293
|
const consentLine = consent.basis === 'granted' ? `Opted in to marketing${consent.basisAtMs ? ` on ${new Date(consent.basisAtMs).toLocaleDateString()}` : ''}` : consent.basis === 'declined' ? 'Declined marketing' : 'No marketing consent recorded — this lead cannot be emailed marketing';
|
|
270
|
-
return /*#__PURE__*/
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
294
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
295
|
+
children: [
|
|
296
|
+
/*#__PURE__*/ _jsx(CrmRecordHeader, {
|
|
297
|
+
kind: "Lead",
|
|
298
|
+
title: String(lead['name'] || lead['email'] || leadId),
|
|
299
|
+
// The name is the heading; the address is the one line under it,
|
|
300
|
+
// unless the address IS the name, in which case there is no second fact.
|
|
301
|
+
subtitle: lead['name'] ? String((_lead_email = lead['email']) != null ? _lead_email : '') : undefined,
|
|
302
|
+
help: Aglyn.pluginDocsHelp('crmLeads', {
|
|
303
|
+
anchor: '#working-a-lead-from-the-row'
|
|
304
|
+
}),
|
|
305
|
+
backHref: routes.section('leads'),
|
|
306
|
+
backLabel: "Back to leads",
|
|
307
|
+
// The booking door (AGL-2660), while the lead is still the record
|
|
308
|
+
// being worked: once converted, the contact is where a meeting is
|
|
309
|
+
// booked from, and the links below lead there.
|
|
310
|
+
booking: converted ? undefined : {
|
|
311
|
+
hostId,
|
|
312
|
+
org,
|
|
313
|
+
kind: 'lead',
|
|
314
|
+
recordId: leadId
|
|
315
|
+
},
|
|
316
|
+
actions: /*#__PURE__*/ _jsxs(_Fragment, {
|
|
317
|
+
children: [
|
|
318
|
+
converted ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
319
|
+
children: [
|
|
320
|
+
/*#__PURE__*/ _jsx(Button, _extends({
|
|
321
|
+
component: AppLink
|
|
322
|
+
}, {
|
|
323
|
+
componentVariant: 'naked',
|
|
324
|
+
nativeButton: false
|
|
325
|
+
}, {
|
|
326
|
+
href: routes.contact(String(lead.convertedContactId)),
|
|
327
|
+
size: "small",
|
|
328
|
+
variant: "outlined",
|
|
329
|
+
children: 'Open contact'
|
|
330
|
+
})),
|
|
331
|
+
lead.companyId ? /*#__PURE__*/ _jsx(Button, _extends({
|
|
332
|
+
component: AppLink
|
|
333
|
+
}, {
|
|
334
|
+
componentVariant: 'naked',
|
|
335
|
+
nativeButton: false
|
|
336
|
+
}, {
|
|
337
|
+
href: routes.company(lead.companyId),
|
|
338
|
+
size: "small",
|
|
339
|
+
variant: "outlined",
|
|
340
|
+
children: 'Open company'
|
|
341
|
+
})) : null,
|
|
342
|
+
lead.dealId ? /*#__PURE__*/ _jsx(Button, _extends({
|
|
343
|
+
component: AppLink
|
|
344
|
+
}, {
|
|
345
|
+
componentVariant: 'naked',
|
|
346
|
+
nativeButton: false
|
|
347
|
+
}, {
|
|
348
|
+
href: routes.deal(lead.dealId),
|
|
349
|
+
size: "small",
|
|
350
|
+
variant: "outlined",
|
|
351
|
+
children: 'Open deal'
|
|
352
|
+
})) : null
|
|
353
|
+
]
|
|
354
|
+
}) : erasurePending ? /*#__PURE__*/ _jsx(Tooltip, {
|
|
355
|
+
title: CONVERT_PENDING_ERASURE_REASON,
|
|
356
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
357
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
358
|
+
size: "small",
|
|
359
|
+
variant: "contained",
|
|
360
|
+
disabled: true,
|
|
361
|
+
children: 'Convert'
|
|
362
|
+
})
|
|
363
|
+
})
|
|
364
|
+
}) : /*#__PURE__*/ _jsx(Button, {
|
|
296
365
|
size: "small",
|
|
297
366
|
variant: "contained",
|
|
298
|
-
|
|
367
|
+
onClick: onConvert,
|
|
299
368
|
children: 'Convert'
|
|
369
|
+
}),
|
|
370
|
+
/*#__PURE__*/ _jsx(CrmCallButton, {
|
|
371
|
+
hostId: hostId,
|
|
372
|
+
org: org,
|
|
373
|
+
link: {
|
|
374
|
+
leadId
|
|
375
|
+
},
|
|
376
|
+
phone: leadPhone
|
|
377
|
+
}),
|
|
378
|
+
/*#__PURE__*/ _jsx(CrmSendEmailButton, {
|
|
379
|
+
hostId: hostId,
|
|
380
|
+
leadId: leadId,
|
|
381
|
+
email: String((_lead_email1 = lead['email']) != null ? _lead_email1 : ''),
|
|
382
|
+
name: String((_lead_name = lead['name']) != null ? _lead_name : ''),
|
|
383
|
+
emailState: emailState
|
|
300
384
|
})
|
|
301
|
-
|
|
302
|
-
}) : /*#__PURE__*/ _jsx(Button, {
|
|
303
|
-
size: "small",
|
|
304
|
-
variant: "contained",
|
|
305
|
-
onClick: onConvert,
|
|
306
|
-
children: 'Convert'
|
|
307
|
-
}),
|
|
308
|
-
/*#__PURE__*/ _jsx(CrmCallButton, {
|
|
309
|
-
hostId: hostId,
|
|
310
|
-
org: org,
|
|
311
|
-
link: {
|
|
312
|
-
leadId
|
|
313
|
-
},
|
|
314
|
-
phone: leadPhone
|
|
315
|
-
}),
|
|
316
|
-
/*#__PURE__*/ _jsx(CrmSendEmailButton, {
|
|
317
|
-
hostId: hostId,
|
|
318
|
-
leadId: leadId,
|
|
319
|
-
email: String((_lead_email1 = lead['email']) != null ? _lead_email1 : ''),
|
|
320
|
-
name: String((_lead_name = lead['name']) != null ? _lead_name : ''),
|
|
321
|
-
emailState: emailState
|
|
322
|
-
})
|
|
323
|
-
]
|
|
324
|
-
}),
|
|
325
|
-
menuItems: [
|
|
326
|
-
...open ? [
|
|
327
|
-
{
|
|
328
|
-
key: 'unqualify',
|
|
329
|
-
label: 'Unqualify',
|
|
330
|
-
icon: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
331
|
-
path: mdiAccountCancelOutline.path,
|
|
332
|
-
size: 0.8
|
|
333
|
-
}),
|
|
334
|
-
destructive: true,
|
|
335
|
-
onClick: onUnqualify
|
|
336
|
-
}
|
|
337
|
-
] : [],
|
|
338
|
-
...extraMenuItems
|
|
339
|
-
],
|
|
340
|
-
chips: /*#__PURE__*/ _jsxs(_Fragment, {
|
|
341
|
-
children: [
|
|
342
|
-
/*#__PURE__*/ _jsx(LeadStatusChip, {
|
|
343
|
-
lead: lead
|
|
344
|
-
}),
|
|
345
|
-
/*#__PURE__*/ _jsx(CrmEmailStateChip, {
|
|
346
|
-
state: emailState
|
|
347
|
-
}),
|
|
348
|
-
/*#__PURE__*/ _jsx(CrmRecordChip, {
|
|
349
|
-
label: "Owner",
|
|
350
|
-
value: lead.ownerUid ? roster.labelFor(lead.ownerUid) : undefined
|
|
385
|
+
]
|
|
351
386
|
}),
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
387
|
+
menuItems: [
|
|
388
|
+
...open ? [
|
|
389
|
+
{
|
|
390
|
+
key: 'unqualify',
|
|
391
|
+
label: 'Unqualify',
|
|
392
|
+
icon: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
393
|
+
path: mdiAccountCancelOutline.path,
|
|
394
|
+
size: 0.8
|
|
395
|
+
}),
|
|
396
|
+
destructive: true,
|
|
397
|
+
onClick: onUnqualify
|
|
398
|
+
}
|
|
399
|
+
] : [],
|
|
400
|
+
...extraMenuItems
|
|
401
|
+
],
|
|
402
|
+
chips: /*#__PURE__*/ _jsxs(_Fragment, {
|
|
403
|
+
children: [
|
|
404
|
+
/*#__PURE__*/ _jsx(LeadStatusChip, {
|
|
405
|
+
lead: lead
|
|
406
|
+
}),
|
|
407
|
+
/*#__PURE__*/ _jsx(CrmEmailStateChip, {
|
|
408
|
+
state: emailState
|
|
409
|
+
}),
|
|
410
|
+
/*#__PURE__*/ _jsx(CrmRecordChip, {
|
|
411
|
+
label: "Owner",
|
|
412
|
+
value: lead.ownerUid ? roster.labelFor(lead.ownerUid) : undefined
|
|
413
|
+
}),
|
|
414
|
+
extraChips
|
|
415
|
+
]
|
|
368
416
|
}),
|
|
369
|
-
/*#__PURE__*/ _jsxs(Stack, {
|
|
370
|
-
|
|
371
|
-
xs: 'column',
|
|
372
|
-
md: 'row'
|
|
373
|
-
},
|
|
374
|
-
spacing: 2,
|
|
417
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
418
|
+
spacing: 3,
|
|
375
419
|
children: [
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
sx: {
|
|
382
|
-
alignItems: 'center'
|
|
383
|
-
},
|
|
384
|
-
children: [
|
|
385
|
-
/*#__PURE__*/ _jsx(LeadStatusChip, {
|
|
386
|
-
lead: lead
|
|
387
|
-
}),
|
|
388
|
-
/*#__PURE__*/ _jsx(Typography, {
|
|
389
|
-
variant: "body2",
|
|
390
|
-
color: "text.secondary",
|
|
391
|
-
children: lead.convertedAtMs ? `Converted ${new Date(lead.convertedAtMs).toLocaleString()}` : 'Converted'
|
|
392
|
-
})
|
|
393
|
-
]
|
|
420
|
+
banner,
|
|
421
|
+
leadPhone ? /*#__PURE__*/ _jsx(Fact, {
|
|
422
|
+
label: "Phone",
|
|
423
|
+
children: /*#__PURE__*/ _jsx(CrmPhoneLink, {
|
|
424
|
+
phone: leadPhone
|
|
394
425
|
})
|
|
395
|
-
}) :
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
426
|
+
}) : null,
|
|
427
|
+
/*#__PURE__*/ _jsx(Fact, {
|
|
428
|
+
label: "Marketing consent",
|
|
429
|
+
children: consentLine
|
|
430
|
+
}),
|
|
431
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
432
|
+
direction: {
|
|
433
|
+
xs: 'column',
|
|
434
|
+
md: 'row'
|
|
399
435
|
},
|
|
436
|
+
spacing: 2,
|
|
400
437
|
children: [
|
|
401
|
-
/*#__PURE__*/ _jsx(
|
|
402
|
-
id: statusLabelId,
|
|
403
|
-
children: 'Status'
|
|
404
|
-
}),
|
|
405
|
-
/*#__PURE__*/ _jsxs(Select, {
|
|
406
|
-
labelId: statusLabelId,
|
|
438
|
+
converted ? /*#__PURE__*/ _jsx(Fact, {
|
|
407
439
|
label: "Status",
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
440
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
441
|
+
direction: "row",
|
|
442
|
+
spacing: 1,
|
|
443
|
+
sx: {
|
|
444
|
+
alignItems: 'center'
|
|
445
|
+
},
|
|
446
|
+
children: [
|
|
447
|
+
/*#__PURE__*/ _jsx(LeadStatusChip, {
|
|
448
|
+
lead: lead
|
|
449
|
+
}),
|
|
450
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
451
|
+
variant: "body2",
|
|
452
|
+
color: "text.secondary",
|
|
453
|
+
children: lead.convertedAtMs ? `Converted ${new Date(lead.convertedAtMs).toLocaleString()}` : 'Converted'
|
|
454
|
+
})
|
|
455
|
+
]
|
|
456
|
+
})
|
|
457
|
+
}) : /*#__PURE__*/ _jsxs(FormControl, {
|
|
458
|
+
size: "small",
|
|
459
|
+
sx: {
|
|
460
|
+
minWidth: 200
|
|
422
461
|
},
|
|
423
462
|
children: [
|
|
424
|
-
/*#__PURE__*/ _jsx(
|
|
425
|
-
|
|
426
|
-
children:
|
|
427
|
-
}),
|
|
428
|
-
/*#__PURE__*/ _jsx(MenuItem, {
|
|
429
|
-
value: "working",
|
|
430
|
-
children: Aglyn.CRM_LEAD_STATUS_LABELS.working
|
|
463
|
+
/*#__PURE__*/ _jsx(InputLabel, {
|
|
464
|
+
id: statusLabelId,
|
|
465
|
+
children: 'Status'
|
|
431
466
|
}),
|
|
432
|
-
/*#__PURE__*/
|
|
433
|
-
|
|
434
|
-
|
|
467
|
+
/*#__PURE__*/ _jsxs(Select, {
|
|
468
|
+
labelId: statusLabelId,
|
|
469
|
+
label: "Status",
|
|
470
|
+
value: status === 'unqualified' ? 'unqualified' : status,
|
|
471
|
+
onChange: (event)=>{
|
|
472
|
+
const next = String(event.target.value);
|
|
473
|
+
if (next === 'unqualified') {
|
|
474
|
+
onUnqualify();
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
// Reopening drops the reason with the closed state: a lead
|
|
478
|
+
// being worked again is not "unqualified because …".
|
|
479
|
+
void write(_extends({
|
|
480
|
+
status: next
|
|
481
|
+
}, status === 'unqualified' ? {
|
|
482
|
+
unqualifiedReason: deleteField()
|
|
483
|
+
} : {}), 'Status updated');
|
|
484
|
+
},
|
|
485
|
+
children: [
|
|
486
|
+
/*#__PURE__*/ _jsx(MenuItem, {
|
|
487
|
+
value: "new",
|
|
488
|
+
children: Aglyn.CRM_LEAD_STATUS_LABELS.new
|
|
489
|
+
}),
|
|
490
|
+
/*#__PURE__*/ _jsx(MenuItem, {
|
|
491
|
+
value: "working",
|
|
492
|
+
children: Aglyn.CRM_LEAD_STATUS_LABELS.working
|
|
493
|
+
}),
|
|
494
|
+
/*#__PURE__*/ _jsx(MenuItem, {
|
|
495
|
+
value: "unqualified",
|
|
496
|
+
children: `${Aglyn.CRM_LEAD_STATUS_LABELS.unqualified}…`
|
|
497
|
+
})
|
|
498
|
+
]
|
|
435
499
|
})
|
|
436
500
|
]
|
|
501
|
+
}),
|
|
502
|
+
/*#__PURE__*/ _jsx(LeadOwnerSelect, {
|
|
503
|
+
value: lead.ownerUid,
|
|
504
|
+
roster: roster,
|
|
505
|
+
fullWidth: false,
|
|
506
|
+
onChange: (uid)=>void write({
|
|
507
|
+
ownerUid: uid || deleteField()
|
|
508
|
+
}, uid ? 'Owner assigned' : 'Owner cleared')
|
|
437
509
|
})
|
|
438
510
|
]
|
|
439
511
|
}),
|
|
440
|
-
/*#__PURE__*/ _jsx(
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
onChange: (uid)=>void write({
|
|
445
|
-
ownerUid: uid || deleteField()
|
|
446
|
-
}, uid ? 'Owner assigned' : 'Owner cleared')
|
|
447
|
-
})
|
|
512
|
+
status === 'unqualified' && lead.unqualifiedReason ? /*#__PURE__*/ _jsx(Alert, {
|
|
513
|
+
severity: "info",
|
|
514
|
+
children: `Unqualified: ${lead.unqualifiedReason}`
|
|
515
|
+
}) : null
|
|
448
516
|
]
|
|
517
|
+
})
|
|
518
|
+
}),
|
|
519
|
+
/*#__PURE__*/ _jsx(CardDisplay, {
|
|
520
|
+
header: 'Details',
|
|
521
|
+
help: Aglyn.pluginDocsHelp('crmLeads', {
|
|
522
|
+
anchor: '#a-leads-page'
|
|
449
523
|
}),
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
component: AppLink
|
|
475
|
-
}, {
|
|
476
|
-
componentVariant: 'naked',
|
|
477
|
-
nativeButton: false
|
|
478
|
-
}, {
|
|
479
|
-
href: routes.company(lead.companyId),
|
|
480
|
-
size: "small",
|
|
481
|
-
variant: "outlined",
|
|
482
|
-
children: 'Open company'
|
|
483
|
-
})) : null,
|
|
484
|
-
lead.dealId ? /*#__PURE__*/ _jsx(Button, _extends({
|
|
485
|
-
component: AppLink
|
|
486
|
-
}, {
|
|
487
|
-
componentVariant: 'naked',
|
|
488
|
-
nativeButton: false
|
|
489
|
-
}, {
|
|
490
|
-
href: routes.deal(lead.dealId),
|
|
491
|
-
size: "small",
|
|
492
|
-
variant: "outlined",
|
|
493
|
-
children: 'Open deal'
|
|
494
|
-
})) : null
|
|
495
|
-
]
|
|
496
|
-
}) : null,
|
|
497
|
-
/*#__PURE__*/ _jsxs(Stack, {
|
|
524
|
+
contentGutterX: true,
|
|
525
|
+
contentGutterY: true,
|
|
526
|
+
HeaderProps: {
|
|
527
|
+
action: /*#__PURE__*/ _jsxs(Stack, {
|
|
528
|
+
direction: "row",
|
|
529
|
+
spacing: 1,
|
|
530
|
+
children: [
|
|
531
|
+
dirty ? /*#__PURE__*/ _jsx(Button, {
|
|
532
|
+
size: "small",
|
|
533
|
+
disabled: saving,
|
|
534
|
+
onClick: discard,
|
|
535
|
+
children: 'Discard changes'
|
|
536
|
+
}) : null,
|
|
537
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
538
|
+
size: "small",
|
|
539
|
+
variant: "contained",
|
|
540
|
+
onClick: ()=>void saveDetails(),
|
|
541
|
+
disabled: !dirty || saving,
|
|
542
|
+
children: saving ? 'Saving…' : 'Save'
|
|
543
|
+
})
|
|
544
|
+
]
|
|
545
|
+
})
|
|
546
|
+
},
|
|
547
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
498
548
|
spacing: 2,
|
|
499
549
|
children: [
|
|
500
|
-
/*#__PURE__*/ _jsx(Typography, {
|
|
501
|
-
variant: "subtitle2",
|
|
502
|
-
children: 'Profile'
|
|
503
|
-
}),
|
|
504
550
|
/*#__PURE__*/ _jsxs(Stack, {
|
|
505
551
|
direction: {
|
|
506
552
|
xs: 'column',
|
|
@@ -603,9 +649,8 @@ const TEXT_MAX = Aglyn.CRM_LEAD_TEXT_MAX;
|
|
|
603
649
|
fields.active.length ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
604
650
|
children: [
|
|
605
651
|
/*#__PURE__*/ _jsx(Typography, {
|
|
606
|
-
variant: "
|
|
607
|
-
|
|
608
|
-
children: 'Custom fields'
|
|
652
|
+
variant: "subtitle2",
|
|
653
|
+
children: 'More fields'
|
|
609
654
|
}),
|
|
610
655
|
fields.active.map((definition)=>/*#__PURE__*/ _jsx(CrmCustomFieldControl, {
|
|
611
656
|
definition: definition,
|
|
@@ -613,29 +658,10 @@ const TEXT_MAX = Aglyn.CRM_LEAD_TEXT_MAX;
|
|
|
613
658
|
onChange: (value)=>setCustom((current)=>_extends({}, current, {
|
|
614
659
|
[definition.key]: value
|
|
615
660
|
})),
|
|
616
|
-
disabled: converted ||
|
|
661
|
+
disabled: converted || saving
|
|
617
662
|
}, definition.$id))
|
|
618
663
|
]
|
|
619
664
|
}) : null,
|
|
620
|
-
converted ? null : /*#__PURE__*/ _jsx(Stack, {
|
|
621
|
-
direction: "row",
|
|
622
|
-
spacing: 1,
|
|
623
|
-
sx: {
|
|
624
|
-
justifyContent: 'flex-end'
|
|
625
|
-
},
|
|
626
|
-
children: /*#__PURE__*/ _jsx(Button, {
|
|
627
|
-
size: "small",
|
|
628
|
-
variant: "contained",
|
|
629
|
-
onClick: ()=>void saveProfile(),
|
|
630
|
-
disabled: !dirty || savingProfile,
|
|
631
|
-
children: 'Save'
|
|
632
|
-
})
|
|
633
|
-
})
|
|
634
|
-
]
|
|
635
|
-
}),
|
|
636
|
-
/*#__PURE__*/ _jsxs(Stack, {
|
|
637
|
-
spacing: 1,
|
|
638
|
-
children: [
|
|
639
665
|
/*#__PURE__*/ _jsx(TextField, {
|
|
640
666
|
size: "small",
|
|
641
667
|
label: "Notes",
|
|
@@ -652,25 +678,11 @@ const TEXT_MAX = Aglyn.CRM_LEAD_TEXT_MAX;
|
|
|
652
678
|
maxLength: NOTES_MAX
|
|
653
679
|
}
|
|
654
680
|
}
|
|
655
|
-
}),
|
|
656
|
-
/*#__PURE__*/ _jsx(Stack, {
|
|
657
|
-
direction: "row",
|
|
658
|
-
spacing: 1,
|
|
659
|
-
sx: {
|
|
660
|
-
justifyContent: 'flex-end'
|
|
661
|
-
},
|
|
662
|
-
children: /*#__PURE__*/ _jsx(Button, {
|
|
663
|
-
size: "small",
|
|
664
|
-
variant: "contained",
|
|
665
|
-
onClick: ()=>void saveNotes(),
|
|
666
|
-
disabled: !notesDirty || savingNotes,
|
|
667
|
-
children: 'Save notes'
|
|
668
|
-
})
|
|
669
681
|
})
|
|
670
682
|
]
|
|
671
683
|
})
|
|
672
|
-
|
|
673
|
-
|
|
684
|
+
})
|
|
685
|
+
]
|
|
674
686
|
});
|
|
675
687
|
}
|
|
676
688
|
LeadPropertiesCard.displayName = 'LeadPropertiesCard';
|