@smooai/chat-widget 0.11.0 → 0.12.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.
- package/dist/chat-widget.global.js +268 -9
- package/dist/chat-widget.global.js.map +1 -1
- package/dist/index.d.ts +262 -236
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +249 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/conversation.ts +112 -2
- package/src/element.ts +178 -5
- package/src/styles.ts +11 -2
|
@@ -11842,7 +11842,7 @@ var SmoothAgentChat = (function(exports) {
|
|
|
11842
11842
|
}) : e[r] = t, e;
|
|
11843
11843
|
}
|
|
11844
11844
|
//#endregion
|
|
11845
|
-
//#region node_modules/.pnpm/@smooai+smooth-operator@1.
|
|
11845
|
+
//#region node_modules/.pnpm/@smooai+smooth-operator@1.21.1/node_modules/@smooai/smooth-operator/dist/transport.js
|
|
11846
11846
|
/**
|
|
11847
11847
|
* Transport abstraction for the client.
|
|
11848
11848
|
*
|
|
@@ -11967,7 +11967,7 @@ var SmoothAgentChat = (function(exports) {
|
|
|
11967
11967
|
}
|
|
11968
11968
|
};
|
|
11969
11969
|
//#endregion
|
|
11970
|
-
//#region node_modules/.pnpm/@smooai+smooth-operator@1.
|
|
11970
|
+
//#region node_modules/.pnpm/@smooai+smooth-operator@1.21.1/node_modules/@smooai/smooth-operator/dist/types.js
|
|
11971
11971
|
/** Every server→client `type` discriminator value. */
|
|
11972
11972
|
const EVENT_TYPES = [
|
|
11973
11973
|
"immediate_response",
|
|
@@ -11980,6 +11980,8 @@ var SmoothAgentChat = (function(exports) {
|
|
|
11980
11980
|
"otp_sent",
|
|
11981
11981
|
"otp_verified",
|
|
11982
11982
|
"otp_invalid",
|
|
11983
|
+
"interaction_required",
|
|
11984
|
+
"interaction_invalid",
|
|
11983
11985
|
"error",
|
|
11984
11986
|
"pong"
|
|
11985
11987
|
];
|
|
@@ -11988,7 +11990,7 @@ var SmoothAgentChat = (function(exports) {
|
|
|
11988
11990
|
return typeof frame === "object" && frame !== null && "type" in frame && typeof frame.type === "string" && EVENT_TYPES.includes(frame.type);
|
|
11989
11991
|
}
|
|
11990
11992
|
//#endregion
|
|
11991
|
-
//#region node_modules/.pnpm/@smooai+smooth-operator@1.
|
|
11993
|
+
//#region node_modules/.pnpm/@smooai+smooth-operator@1.21.1/node_modules/@smooai/smooth-operator/dist/client.js
|
|
11992
11994
|
/**
|
|
11993
11995
|
* SmoothAgentClient — a minimal, idiomatic, transport-agnostic client for the
|
|
11994
11996
|
* smooth-operator WebSocket protocol.
|
|
@@ -12273,6 +12275,20 @@ var SmoothAgentChat = (function(exports) {
|
|
|
12273
12275
|
...req
|
|
12274
12276
|
}));
|
|
12275
12277
|
}
|
|
12278
|
+
/**
|
|
12279
|
+
* Submit (or decline) a Rich Interaction, resuming the turn parked by an
|
|
12280
|
+
* `interaction_required` event. This ONE verb serves every interaction kind
|
|
12281
|
+
* (identity intake, future date pickers, choice chips, …) — adding a kind
|
|
12282
|
+
* needs no new client method. Server-side validation may reply with an
|
|
12283
|
+
* `interaction_invalid` event (the turn stays parked — resubmit); a valid
|
|
12284
|
+
* submit resumes the stream back into the original {@link MessageTurn}.
|
|
12285
|
+
*/
|
|
12286
|
+
submitInteraction(req) {
|
|
12287
|
+
this.transport.send(JSON.stringify({
|
|
12288
|
+
action: "submit_interaction",
|
|
12289
|
+
...req
|
|
12290
|
+
}));
|
|
12291
|
+
}
|
|
12276
12292
|
/** Send an action that expects a single correlated response event. */
|
|
12277
12293
|
request(action) {
|
|
12278
12294
|
const requestId = action.requestId ?? this.generateRequestId();
|
|
@@ -12855,6 +12871,13 @@ var SmoothAgentChat = (function(exports) {
|
|
|
12855
12871
|
return null;
|
|
12856
12872
|
}
|
|
12857
12873
|
}
|
|
12874
|
+
/**
|
|
12875
|
+
* The Rich-Interaction render capabilities this widget declares at session
|
|
12876
|
+
* create (`supports`). Must stay aligned with the card registry in
|
|
12877
|
+
* `element.ts` (`INTERACTION_CARDS`) — registering a card IS declaring its
|
|
12878
|
+
* capability; a test asserts the two match.
|
|
12879
|
+
*/
|
|
12880
|
+
const SUPPORTED_INTERACTION_CAPABILITIES = ["identity_form"];
|
|
12858
12881
|
/** Pull the final assistant text out of an `eventual_response` data payload. */
|
|
12859
12882
|
function extractFinalText(response) {
|
|
12860
12883
|
if (!response || typeof response !== "object") return null;
|
|
@@ -12932,6 +12955,7 @@ var SmoothAgentChat = (function(exports) {
|
|
|
12932
12955
|
_defineProperty(this, "seq", 0);
|
|
12933
12956
|
_defineProperty(this, "activeRequestId", null);
|
|
12934
12957
|
_defineProperty(this, "interrupt", null);
|
|
12958
|
+
_defineProperty(this, "pendingInteractionValues", null);
|
|
12935
12959
|
_defineProperty(this, "identityRestore", { phase: "idle" });
|
|
12936
12960
|
_defineProperty(this, "resumeAttempted", false);
|
|
12937
12961
|
_defineProperty(this, "httpBase", void 0);
|
|
@@ -13010,6 +13034,40 @@ var SmoothAgentChat = (function(exports) {
|
|
|
13010
13034
|
});
|
|
13011
13035
|
this.setInterrupt(null);
|
|
13012
13036
|
}
|
|
13037
|
+
/**
|
|
13038
|
+
* Submit a Rich Interaction card to resume the parked turn. The server
|
|
13039
|
+
* routes to the kind's validator: invalid values come back as an
|
|
13040
|
+
* `interaction_invalid` event (the card re-renders with per-field errors —
|
|
13041
|
+
* the turn stays parked); a valid submit is acked and the turn resumes.
|
|
13042
|
+
* No-op if not awaiting an interaction.
|
|
13043
|
+
*/
|
|
13044
|
+
submitInteraction(values) {
|
|
13045
|
+
if (!this.client || !this.sessionId || !this.activeRequestId || this.interrupt?.kind !== "interaction") return;
|
|
13046
|
+
this.pendingInteractionValues = {
|
|
13047
|
+
kind: this.interrupt.interactionKind,
|
|
13048
|
+
values
|
|
13049
|
+
};
|
|
13050
|
+
this.client.submitInteraction({
|
|
13051
|
+
sessionId: this.sessionId,
|
|
13052
|
+
requestId: this.activeRequestId,
|
|
13053
|
+
interactionId: this.interrupt.interactionId,
|
|
13054
|
+
kind: this.interrupt.interactionKind,
|
|
13055
|
+
values
|
|
13056
|
+
});
|
|
13057
|
+
}
|
|
13058
|
+
/** Decline the pending Rich Interaction; the agent continues without it. */
|
|
13059
|
+
declineInteraction() {
|
|
13060
|
+
if (!this.client || !this.sessionId || !this.activeRequestId || this.interrupt?.kind !== "interaction") return;
|
|
13061
|
+
this.client.submitInteraction({
|
|
13062
|
+
sessionId: this.sessionId,
|
|
13063
|
+
requestId: this.activeRequestId,
|
|
13064
|
+
interactionId: this.interrupt.interactionId,
|
|
13065
|
+
kind: this.interrupt.interactionKind,
|
|
13066
|
+
declined: true
|
|
13067
|
+
});
|
|
13068
|
+
this.pendingInteractionValues = null;
|
|
13069
|
+
this.setInterrupt(null);
|
|
13070
|
+
}
|
|
13013
13071
|
nextId(prefix) {
|
|
13014
13072
|
this.seq += 1;
|
|
13015
13073
|
return `${prefix}-${this.seq}-${Date.now().toString(36)}`;
|
|
@@ -13174,6 +13232,7 @@ var SmoothAgentChat = (function(exports) {
|
|
|
13174
13232
|
userName: state.identity.name,
|
|
13175
13233
|
userEmail: state.identity.email,
|
|
13176
13234
|
browserFingerprint: this.fingerprint(),
|
|
13235
|
+
supports: [...SUPPORTED_INTERACTION_CAPABILITIES],
|
|
13177
13236
|
...metadata ? { metadata } : {}
|
|
13178
13237
|
});
|
|
13179
13238
|
this.sessionId = session.sessionId;
|
|
@@ -13316,6 +13375,55 @@ var SmoothAgentChat = (function(exports) {
|
|
|
13316
13375
|
actionDescription: str(inner.actionDescription)
|
|
13317
13376
|
});
|
|
13318
13377
|
break;
|
|
13378
|
+
case "interaction_required": {
|
|
13379
|
+
const interactionId = str(inner.interactionId);
|
|
13380
|
+
const kind = str(inner.kind);
|
|
13381
|
+
const spec = inner.spec && typeof inner.spec === "object" ? inner.spec : {};
|
|
13382
|
+
if (!interactionId || !kind) break;
|
|
13383
|
+
this.pendingInteractionValues = null;
|
|
13384
|
+
this.setInterrupt({
|
|
13385
|
+
kind: "interaction",
|
|
13386
|
+
interactionId,
|
|
13387
|
+
interactionKind: kind,
|
|
13388
|
+
spec,
|
|
13389
|
+
reason: str(inner.reason)
|
|
13390
|
+
});
|
|
13391
|
+
break;
|
|
13392
|
+
}
|
|
13393
|
+
case "interaction_invalid":
|
|
13394
|
+
if (this.interrupt?.kind === "interaction" && this.interrupt.interactionId === str(inner.interactionId)) {
|
|
13395
|
+
const errors = [];
|
|
13396
|
+
if (Array.isArray(inner.errors)) for (const e of inner.errors) {
|
|
13397
|
+
if (!e || typeof e !== "object") continue;
|
|
13398
|
+
const o = e;
|
|
13399
|
+
const field = str(o.field);
|
|
13400
|
+
if (field) errors.push({
|
|
13401
|
+
field,
|
|
13402
|
+
message: str(o.message) ?? "Invalid value"
|
|
13403
|
+
});
|
|
13404
|
+
}
|
|
13405
|
+
this.pendingInteractionValues = null;
|
|
13406
|
+
this.setInterrupt({
|
|
13407
|
+
...this.interrupt,
|
|
13408
|
+
errors
|
|
13409
|
+
});
|
|
13410
|
+
}
|
|
13411
|
+
break;
|
|
13412
|
+
case "immediate_response":
|
|
13413
|
+
if (this.interrupt?.kind === "interaction") {
|
|
13414
|
+
const pending = this.pendingInteractionValues;
|
|
13415
|
+
if (pending && pending.kind === "identity_intake") {
|
|
13416
|
+
const v = pending.values;
|
|
13417
|
+
this.store.getState().mergeIdentity({
|
|
13418
|
+
name: v.name,
|
|
13419
|
+
email: v.email,
|
|
13420
|
+
phone: v.phone
|
|
13421
|
+
});
|
|
13422
|
+
}
|
|
13423
|
+
this.pendingInteractionValues = null;
|
|
13424
|
+
this.setInterrupt(null);
|
|
13425
|
+
}
|
|
13426
|
+
break;
|
|
13319
13427
|
default: break;
|
|
13320
13428
|
}
|
|
13321
13429
|
}
|
|
@@ -14128,6 +14236,9 @@ ${mode === "fullpage" ? `
|
|
|
14128
14236
|
border-color: color-mix(in srgb, var(--sac-primary) 60%, transparent);
|
|
14129
14237
|
box-shadow: 0 0 0 4px color-mix(in srgb, var(--sac-primary) 14%, transparent);
|
|
14130
14238
|
}
|
|
14239
|
+
.int-form { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
|
|
14240
|
+
.int-form .pc-field input { width: 100%; box-sizing: border-box; }
|
|
14241
|
+
.int-form .int-error { margin-top: 2px; }
|
|
14131
14242
|
.int-btn {
|
|
14132
14243
|
border: 1px solid color-mix(in srgb, var(--sac-border) 80%, transparent);
|
|
14133
14244
|
background: var(--sac-surface-2);
|
|
@@ -14147,8 +14258,14 @@ ${mode === "fullpage" ? `
|
|
|
14147
14258
|
color: var(--sac-primary-text);
|
|
14148
14259
|
box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--sac-primary) 65%, transparent);
|
|
14149
14260
|
}
|
|
14150
|
-
.int-row .int-
|
|
14151
|
-
.int-
|
|
14261
|
+
.int-row .int-form { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
|
|
14262
|
+
.int-form .pc-field input { width: 100%; box-sizing: border-box; }
|
|
14263
|
+
.int-form .int-error { margin-top: 2px; }
|
|
14264
|
+
.int-btn { flex: 1; }
|
|
14265
|
+
.int-row .int-input + .int-form { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
|
|
14266
|
+
.int-form .pc-field input { width: 100%; box-sizing: border-box; }
|
|
14267
|
+
.int-form .int-error { margin-top: 2px; }
|
|
14268
|
+
.int-btn { flex: 0 0 auto; }
|
|
14152
14269
|
.int-error { margin-top: 8px; font-size: 12px; color: #f87171; }
|
|
14153
14270
|
.int-card { position: relative; }
|
|
14154
14271
|
.int-close {
|
|
@@ -14286,9 +14403,139 @@ ${mode === "fullpage" ? `
|
|
|
14286
14403
|
chev: `<svg width="11" height="11" viewBox="0 0 24 24" fill="none"><path d="m9 6 6 6-6 6" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
|
|
14287
14404
|
/** OTP interrupt — a padlock. */
|
|
14288
14405
|
lock: `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="5" y="10.5" width="14" height="9.5" rx="2.2" stroke="currentColor" stroke-width="1.7"/><path d="M8 10.5V8a4 4 0 0 1 8 0v2.5" stroke="currentColor" stroke-width="1.7"/></svg>`,
|
|
14406
|
+
/** Identity-intake interrupt — a person. */
|
|
14407
|
+
user: `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="8.2" r="3.4" stroke="currentColor" stroke-width="1.7"/><path d="M5.5 19.5c.8-3.1 3.4-4.8 6.5-4.8s5.7 1.7 6.5 4.8" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>`,
|
|
14289
14408
|
/** Tool-confirmation interrupt — a shield. */
|
|
14290
14409
|
shield: `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 3 5 6v5c0 4.4 3 7.2 7 8.5 4-1.3 7-4.1 7-8.5V6l-7-3Z" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/><path d="m9 11.5 2 2 4-4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>`
|
|
14291
14410
|
};
|
|
14411
|
+
/**
|
|
14412
|
+
* The identity_intake card: the fields the agent requested (pre-chat form field
|
|
14413
|
+
* pattern — same classes, same phone formatting), per-field server errors, a
|
|
14414
|
+
* submit and a decline affordance. Server-supplied text (reason, labels, error
|
|
14415
|
+
* messages) is set via `textContent` — never innerHTML.
|
|
14416
|
+
*/
|
|
14417
|
+
function buildIdentityIntakeCard(it, ctx) {
|
|
14418
|
+
const form = document.createElement("form");
|
|
14419
|
+
form.className = "int-form";
|
|
14420
|
+
form.noValidate = true;
|
|
14421
|
+
if (it.reason) {
|
|
14422
|
+
const desc = document.createElement("div");
|
|
14423
|
+
desc.className = "int-desc";
|
|
14424
|
+
desc.textContent = it.reason;
|
|
14425
|
+
form.appendChild(desc);
|
|
14426
|
+
}
|
|
14427
|
+
const DEFAULTS = {
|
|
14428
|
+
name: {
|
|
14429
|
+
label: "Name",
|
|
14430
|
+
type: "text",
|
|
14431
|
+
autocomplete: "name"
|
|
14432
|
+
},
|
|
14433
|
+
email: {
|
|
14434
|
+
label: "Email",
|
|
14435
|
+
type: "email",
|
|
14436
|
+
autocomplete: "email"
|
|
14437
|
+
},
|
|
14438
|
+
phone: {
|
|
14439
|
+
label: "Phone",
|
|
14440
|
+
type: "tel",
|
|
14441
|
+
autocomplete: "tel"
|
|
14442
|
+
}
|
|
14443
|
+
};
|
|
14444
|
+
const rawFields = Array.isArray(it.spec.fields) ? it.spec.fields : [];
|
|
14445
|
+
const fields = [];
|
|
14446
|
+
for (const f of rawFields) {
|
|
14447
|
+
if (!f || typeof f !== "object") continue;
|
|
14448
|
+
const o = f;
|
|
14449
|
+
const key = typeof o.key === "string" ? o.key : "";
|
|
14450
|
+
if (key !== "name" && key !== "email" && key !== "phone") continue;
|
|
14451
|
+
fields.push({
|
|
14452
|
+
key,
|
|
14453
|
+
required: o.required === true,
|
|
14454
|
+
label: typeof o.label === "string" ? o.label : void 0
|
|
14455
|
+
});
|
|
14456
|
+
}
|
|
14457
|
+
if (fields.length === 0) fields.push({
|
|
14458
|
+
key: "email",
|
|
14459
|
+
required: true
|
|
14460
|
+
});
|
|
14461
|
+
for (const f of fields) {
|
|
14462
|
+
const d = DEFAULTS[f.key];
|
|
14463
|
+
const label = document.createElement("label");
|
|
14464
|
+
label.className = "pc-field";
|
|
14465
|
+
const caption = document.createElement("span");
|
|
14466
|
+
caption.textContent = f.label ?? d.label;
|
|
14467
|
+
const input = document.createElement("input");
|
|
14468
|
+
input.name = f.key;
|
|
14469
|
+
input.type = d.type;
|
|
14470
|
+
input.setAttribute("autocomplete", d.autocomplete);
|
|
14471
|
+
input.required = f.required;
|
|
14472
|
+
const prefill = ctx.prefill[f.key];
|
|
14473
|
+
if (prefill) input.value = prefill;
|
|
14474
|
+
label.append(caption, input);
|
|
14475
|
+
if (f.key === "phone") {
|
|
14476
|
+
const hint = document.createElement("span");
|
|
14477
|
+
hint.className = "pc-hint";
|
|
14478
|
+
hint.setAttribute("aria-live", "polite");
|
|
14479
|
+
label.appendChild(hint);
|
|
14480
|
+
}
|
|
14481
|
+
const serverError = it.errors?.find((e) => e.field === f.key);
|
|
14482
|
+
if (serverError) {
|
|
14483
|
+
label.classList.add("invalid");
|
|
14484
|
+
const err = document.createElement("span");
|
|
14485
|
+
err.className = "int-error";
|
|
14486
|
+
err.textContent = serverError.message;
|
|
14487
|
+
label.appendChild(err);
|
|
14488
|
+
}
|
|
14489
|
+
form.appendChild(label);
|
|
14490
|
+
}
|
|
14491
|
+
const row = document.createElement("div");
|
|
14492
|
+
row.className = "int-row";
|
|
14493
|
+
const decline = document.createElement("button");
|
|
14494
|
+
decline.className = "int-btn";
|
|
14495
|
+
decline.type = "button";
|
|
14496
|
+
decline.textContent = "No thanks";
|
|
14497
|
+
decline.addEventListener("click", () => ctx.decline());
|
|
14498
|
+
const share = document.createElement("button");
|
|
14499
|
+
share.className = "int-btn primary";
|
|
14500
|
+
share.type = "submit";
|
|
14501
|
+
share.textContent = "Share details";
|
|
14502
|
+
row.append(decline, share);
|
|
14503
|
+
form.appendChild(row);
|
|
14504
|
+
form.addEventListener("submit", (ev) => {
|
|
14505
|
+
ev.preventDefault();
|
|
14506
|
+
if (!form.reportValidity()) return;
|
|
14507
|
+
const data = new FormData(form);
|
|
14508
|
+
const val = (k) => data.get(k)?.trim() || void 0;
|
|
14509
|
+
const rawPhone = val("phone");
|
|
14510
|
+
const phoneInput = form.querySelector("input[name=\"phone\"]");
|
|
14511
|
+
if (rawPhone && phoneInput && !isValidPhoneNumber(rawPhone, PHONE_DEFAULT_REGION)) {
|
|
14512
|
+
const field = phoneInput.closest(".pc-field");
|
|
14513
|
+
field?.classList.add("invalid");
|
|
14514
|
+
const hint = field?.querySelector(".pc-hint");
|
|
14515
|
+
if (hint) hint.textContent = "Enter a valid phone number";
|
|
14516
|
+
if (phoneInput.hasAttribute("required")) {
|
|
14517
|
+
phoneInput.focus();
|
|
14518
|
+
return;
|
|
14519
|
+
}
|
|
14520
|
+
}
|
|
14521
|
+
const phone = rawPhone ? phoneToE164(rawPhone) ?? rawPhone : void 0;
|
|
14522
|
+
ctx.submit({
|
|
14523
|
+
name: val("name"),
|
|
14524
|
+
email: val("email"),
|
|
14525
|
+
phone
|
|
14526
|
+
});
|
|
14527
|
+
});
|
|
14528
|
+
ctx.wirePhoneField(form);
|
|
14529
|
+
queueMicrotask(() => form.querySelector("input")?.focus());
|
|
14530
|
+
return form;
|
|
14531
|
+
}
|
|
14532
|
+
/** Kind → card. See the registry doc above. */
|
|
14533
|
+
const INTERACTION_CARDS = { identity_intake: {
|
|
14534
|
+
capability: "identity_form",
|
|
14535
|
+
title: "Share your details",
|
|
14536
|
+
icon: ICON.user,
|
|
14537
|
+
build: buildIdentityIntakeCard
|
|
14538
|
+
} };
|
|
14292
14539
|
var SmoothAgentChatElement = class extends HTMLElement {
|
|
14293
14540
|
static get observedAttributes() {
|
|
14294
14541
|
return OBSERVED;
|
|
@@ -14571,19 +14818,31 @@ ${mode === "fullpage" ? `
|
|
|
14571
14818
|
head.className = "int-head";
|
|
14572
14819
|
const ico = document.createElement("span");
|
|
14573
14820
|
ico.className = "int-ico";
|
|
14574
|
-
|
|
14821
|
+
const card_meta = it.kind === "interaction" ? INTERACTION_CARDS[it.interactionKind] : void 0;
|
|
14822
|
+
if (it.kind === "interaction" && !card_meta) {
|
|
14823
|
+
this.controller?.declineInteraction();
|
|
14824
|
+
el.classList.add("hidden");
|
|
14825
|
+
return;
|
|
14826
|
+
}
|
|
14827
|
+
ico.innerHTML = it.kind === "otp" ? ICON.lock : it.kind === "interaction" ? card_meta?.icon ?? ICON.user : ICON.shield;
|
|
14575
14828
|
const title = document.createElement("span");
|
|
14576
14829
|
title.className = "int-title";
|
|
14577
|
-
title.textContent = it.kind === "otp" ? "Verification required" : "Confirm this action";
|
|
14830
|
+
title.textContent = it.kind === "otp" ? "Verification required" : it.kind === "interaction" ? card_meta?.title ?? "One more thing" : "Confirm this action";
|
|
14578
14831
|
head.append(ico, title);
|
|
14579
14832
|
card.appendChild(head);
|
|
14580
|
-
if (it.actionDescription) {
|
|
14833
|
+
if (it.kind !== "interaction" && it.actionDescription) {
|
|
14581
14834
|
const desc = document.createElement("div");
|
|
14582
14835
|
desc.className = "int-desc";
|
|
14583
14836
|
desc.textContent = it.actionDescription;
|
|
14584
14837
|
card.appendChild(desc);
|
|
14585
14838
|
}
|
|
14586
|
-
if (it.kind === "
|
|
14839
|
+
if (it.kind === "interaction") card.appendChild(card_meta.build(it, {
|
|
14840
|
+
submit: (values) => this.controller?.submitInteraction(values),
|
|
14841
|
+
decline: () => this.controller?.declineInteraction(),
|
|
14842
|
+
prefill: this.controller?.getStore().getState().identity ?? {},
|
|
14843
|
+
wirePhoneField: (form) => this.wirePhoneField(form)
|
|
14844
|
+
}));
|
|
14845
|
+
else if (it.kind === "otp") {
|
|
14587
14846
|
if (it.sent?.maskedDestination) {
|
|
14588
14847
|
const sent = document.createElement("div");
|
|
14589
14848
|
sent.className = "int-sent";
|