@inploi/plugin-chatbot 3.8.0 → 3.10.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/cdn/index.js +25 -25
- package/dist/chatbot.d.ts +0 -1
- package/dist/chatbot.utils.d.ts +1 -2
- package/dist/{index-b616116f.js → index-122b2522.js} +16 -12
- package/dist/{index-efb34443.cjs → index-2d0cac15.cjs} +5 -1
- package/dist/interpreter.d.ts +4 -3
- package/dist/{job-application-content-8b7e62bb.cjs → job-application-content-191ecc14.cjs} +256 -26
- package/dist/{job-application-content-b9799966.js → job-application-content-c89a480d.js} +256 -26
- package/dist/plugin-chatbot.cjs +1 -1
- package/dist/plugin-chatbot.js +2 -2
- package/package.json +5 -4
package/dist/chatbot.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ export type ChatbotPlugin = typeof chatbotPlugin;
|
|
|
6
6
|
export type ChatbotPluginParams = RemoveInternal<Parameters<ChatbotPlugin>[0]>;
|
|
7
7
|
export type Chatbot = ReturnType<ReturnType<ChatbotPlugin>>;
|
|
8
8
|
export declare const chatbotPlugin: ({ _internal_domManager: dom, theme, }: {
|
|
9
|
-
geolocationApiKey?: string | undefined;
|
|
10
9
|
theme: {
|
|
11
10
|
/** Rotation for the hue. Between 0 and 360. */
|
|
12
11
|
hue: number;
|
package/dist/chatbot.utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FlowNode } from '@inploi/core/flows';
|
|
2
2
|
import { ApplicationSubmission, KeyToSubmissionMap } from './chatbot.state';
|
|
3
3
|
export type DistributivePick<T, K extends keyof T> = T extends unknown ? Pick<T, K> : never;
|
|
4
|
+
export declare const kbToReadableSize: (kb: number) => string;
|
|
4
5
|
export declare const getHeadOrThrow: (nodes: FlowNode[]) => {
|
|
5
6
|
id: string;
|
|
6
7
|
data: {
|
|
@@ -20,8 +21,6 @@ export declare const getHeadOrThrow: (nodes: FlowNode[]) => {
|
|
|
20
21
|
} | {
|
|
21
22
|
id: string;
|
|
22
23
|
data: {
|
|
23
|
-
type: "partial" | "full";
|
|
24
|
-
ats: "cornerstone";
|
|
25
24
|
integrationId: string;
|
|
26
25
|
};
|
|
27
26
|
type: "integration-application-submit";
|
|
@@ -1047,6 +1047,9 @@ function invariant$1(condition, message) {
|
|
|
1047
1047
|
}
|
|
1048
1048
|
throw new Error(message);
|
|
1049
1049
|
}
|
|
1050
|
+
function hasProp(data, prop) {
|
|
1051
|
+
return prop in data;
|
|
1052
|
+
}
|
|
1050
1053
|
function _extends() {
|
|
1051
1054
|
_extends = Object.assign ? Object.assign.bind() : function(target) {
|
|
1052
1055
|
for (var i2 = 1; i2 < arguments.length; i2++) {
|
|
@@ -8281,7 +8284,7 @@ const StatusBar = ({
|
|
|
8281
8284
|
})]
|
|
8282
8285
|
});
|
|
8283
8286
|
};
|
|
8284
|
-
const JobApplicationContent = M(() => import("./job-application-content-
|
|
8287
|
+
const JobApplicationContent = M(() => import("./job-application-content-c89a480d.js").then((module) => module.JobApplicationContent));
|
|
8285
8288
|
const MotionProvider = ({
|
|
8286
8289
|
children
|
|
8287
8290
|
}) => {
|
|
@@ -9326,6 +9329,7 @@ const chatbotPlugin = ({
|
|
|
9326
9329
|
});
|
|
9327
9330
|
export {
|
|
9328
9331
|
AnimatePresence as A,
|
|
9332
|
+
chatbotPlugin as B,
|
|
9329
9333
|
Cn as C,
|
|
9330
9334
|
ERROR_MESSAGES as E,
|
|
9331
9335
|
F$1 as F,
|
|
@@ -9338,25 +9342,25 @@ export {
|
|
|
9338
9342
|
clsx as c,
|
|
9339
9343
|
picklist as d,
|
|
9340
9344
|
application as e,
|
|
9341
|
-
|
|
9342
|
-
|
|
9343
|
-
|
|
9345
|
+
h$1 as f,
|
|
9346
|
+
parseAsync as g,
|
|
9347
|
+
hasProp as h,
|
|
9344
9348
|
invariant$1 as i,
|
|
9345
|
-
|
|
9349
|
+
object as j,
|
|
9346
9350
|
k$3 as k,
|
|
9347
|
-
|
|
9351
|
+
minLength as l,
|
|
9348
9352
|
maxLength as m,
|
|
9349
|
-
|
|
9353
|
+
boolean as n,
|
|
9350
9354
|
o,
|
|
9351
9355
|
p$3 as p,
|
|
9352
|
-
|
|
9356
|
+
email as q,
|
|
9353
9357
|
record as r,
|
|
9354
9358
|
string as s,
|
|
9355
9359
|
transform as t,
|
|
9356
9360
|
url as u,
|
|
9357
|
-
|
|
9358
|
-
|
|
9359
|
-
|
|
9361
|
+
regex as v,
|
|
9362
|
+
inputHeight as w,
|
|
9363
|
+
m$1 as x,
|
|
9360
9364
|
y$2 as y,
|
|
9361
|
-
|
|
9365
|
+
viewState as z
|
|
9362
9366
|
};
|
|
@@ -1048,6 +1048,9 @@ function invariant$1(condition, message) {
|
|
|
1048
1048
|
}
|
|
1049
1049
|
throw new Error(message);
|
|
1050
1050
|
}
|
|
1051
|
+
function hasProp(data, prop) {
|
|
1052
|
+
return prop in data;
|
|
1053
|
+
}
|
|
1051
1054
|
function _extends() {
|
|
1052
1055
|
_extends = Object.assign ? Object.assign.bind() : function(target) {
|
|
1053
1056
|
for (var i2 = 1; i2 < arguments.length; i2++) {
|
|
@@ -8282,7 +8285,7 @@ const StatusBar = ({
|
|
|
8282
8285
|
})]
|
|
8283
8286
|
});
|
|
8284
8287
|
};
|
|
8285
|
-
const JobApplicationContent = M(() => Promise.resolve().then(() => require("./job-application-content-
|
|
8288
|
+
const JobApplicationContent = M(() => Promise.resolve().then(() => require("./job-application-content-191ecc14.cjs")).then((module2) => module2.JobApplicationContent));
|
|
8286
8289
|
const MotionProvider = ({
|
|
8287
8290
|
children
|
|
8288
8291
|
}) => {
|
|
@@ -9340,6 +9343,7 @@ exports.chatbotPlugin = chatbotPlugin;
|
|
|
9340
9343
|
exports.clsx = clsx;
|
|
9341
9344
|
exports.email = email;
|
|
9342
9345
|
exports.h = h$1;
|
|
9346
|
+
exports.hasProp = hasProp;
|
|
9343
9347
|
exports.inputHeight = inputHeight;
|
|
9344
9348
|
exports.invariant = invariant$1;
|
|
9345
9349
|
exports.k = k$3;
|
package/dist/interpreter.d.ts
CHANGED
|
@@ -23,11 +23,11 @@ export type ChatService = {
|
|
|
23
23
|
type: TType;
|
|
24
24
|
}>>;
|
|
25
25
|
};
|
|
26
|
-
type ChatbotInterpreterParams = {
|
|
26
|
+
type ChatbotInterpreterParams<TContext extends Record<string, unknown>> = {
|
|
27
27
|
apiClient: ApiClient;
|
|
28
28
|
analytics: AnalyticsService;
|
|
29
29
|
logger: Logger;
|
|
30
|
-
context:
|
|
30
|
+
context: TContext;
|
|
31
31
|
flow: FlowNode[];
|
|
32
32
|
getSubmissions: () => KeyToSubmissionMap | undefined;
|
|
33
33
|
chatService: ChatService;
|
|
@@ -38,8 +38,9 @@ type ChatbotInterpreterParams = {
|
|
|
38
38
|
/** When node is interpreted */
|
|
39
39
|
onInterpret?: (node: FlowNode, prevNode?: FlowNode) => void;
|
|
40
40
|
};
|
|
41
|
-
export declare const createFlowInterpreter: ({ flow, analytics, logger, context, apiClient, getSubmissions, chatService, onFlowEnd, onInterpret, }: ChatbotInterpreterParams) => {
|
|
41
|
+
export declare const createFlowInterpreter: <TContext extends Record<string, unknown>>({ flow, analytics, logger, context, apiClient, getSubmissions, chatService, onFlowEnd, onInterpret, }: ChatbotInterpreterParams<TContext>) => {
|
|
42
42
|
interpret: (startFromNodeId?: string) => Promise<void>;
|
|
43
43
|
abort: () => void;
|
|
44
44
|
};
|
|
45
|
+
export declare const interpolateString: (str: string, context: KeyToSubmissionMap | undefined) => string;
|
|
45
46
|
export {};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const index = require("./index-
|
|
3
|
+
const index = require("./index-2d0cac15.cjs");
|
|
4
4
|
require("@inploi/sdk");
|
|
5
|
+
const kbToReadableSize = (kb) => index.N(kb).with(index._.number.lte(1e3), () => `${Math.round(kb)}KB`).with(index._.number.lt(1e3 * 10), () => `${(kb / 1e3).toFixed(1)}MB`).otherwise(() => `${Math.round(kb / 1e3)}MB`);
|
|
5
6
|
const getHeadOrThrow = (nodes) => {
|
|
6
7
|
const head = nodes.find((n2) => n2.isHead);
|
|
7
8
|
if (!head)
|
|
@@ -231,14 +232,17 @@ async function interpretSubmitNode({
|
|
|
231
232
|
variant: "info",
|
|
232
233
|
text: "Submitting your application…"
|
|
233
234
|
});
|
|
235
|
+
const {
|
|
236
|
+
anonymous_id,
|
|
237
|
+
session_id
|
|
238
|
+
} = analytics.getSessionInfo();
|
|
234
239
|
const response = await apiClient.fetch(`/flow/apply`, {
|
|
235
240
|
method: "POST",
|
|
236
241
|
body: JSON.stringify({
|
|
237
242
|
...context,
|
|
238
|
-
type: node.data.type,
|
|
239
|
-
ats: node.data.ats,
|
|
240
243
|
integration_id: node.data.integrationId,
|
|
241
|
-
anonymous_id
|
|
244
|
+
anonymous_id,
|
|
245
|
+
session_id,
|
|
242
246
|
submissions: getApplicationSubmissionsPayload(submissions || {})
|
|
243
247
|
})
|
|
244
248
|
}).catch((e) => e);
|
|
@@ -252,10 +256,9 @@ async function interpretSubmitNode({
|
|
|
252
256
|
author: "bot",
|
|
253
257
|
text: "Almost there! Please finalise your application on our partner’s website."
|
|
254
258
|
});
|
|
255
|
-
const currentAnonymousId = analytics.getAnonymousId();
|
|
256
259
|
const href = new URL(response2.ats_data.redirect_url);
|
|
257
|
-
if (
|
|
258
|
-
href.searchParams.set("anonymous_id",
|
|
260
|
+
if (anonymous_id && !href.searchParams.has("anonymous_id")) {
|
|
261
|
+
href.searchParams.set("anonymous_id", anonymous_id);
|
|
259
262
|
}
|
|
260
263
|
logApplyComplete();
|
|
261
264
|
await chat.sendMessage({
|
|
@@ -287,12 +290,13 @@ async function interpretSubmitNode({
|
|
|
287
290
|
async function interpretLinkNode({
|
|
288
291
|
chat,
|
|
289
292
|
next,
|
|
290
|
-
node
|
|
293
|
+
node,
|
|
294
|
+
submissions
|
|
291
295
|
}) {
|
|
292
296
|
await chat.sendMessage({
|
|
293
297
|
type: "link",
|
|
294
298
|
href: node.data.href,
|
|
295
|
-
text: node.data.cta
|
|
299
|
+
text: interpolateString(node.data.cta, submissions)
|
|
296
300
|
});
|
|
297
301
|
next(node.nextId);
|
|
298
302
|
}
|
|
@@ -307,12 +311,13 @@ async function interpretIfBlockNode({
|
|
|
307
311
|
async function interpretTextNode({
|
|
308
312
|
chat,
|
|
309
313
|
next,
|
|
310
|
-
node
|
|
314
|
+
node,
|
|
315
|
+
submissions
|
|
311
316
|
}) {
|
|
312
317
|
await chat.sendMessage({
|
|
313
318
|
author: "bot",
|
|
314
319
|
type: "text",
|
|
315
|
-
text: node.data.text
|
|
320
|
+
text: interpolateString(node.data.text, submissions)
|
|
316
321
|
});
|
|
317
322
|
next(node.nextId);
|
|
318
323
|
}
|
|
@@ -333,12 +338,13 @@ async function interpretImageNode({
|
|
|
333
338
|
async function interpretQuestionTextNode({
|
|
334
339
|
chat,
|
|
335
340
|
next,
|
|
336
|
-
node
|
|
341
|
+
node,
|
|
342
|
+
submissions
|
|
337
343
|
}) {
|
|
338
344
|
await chat.sendMessage({
|
|
339
345
|
author: "bot",
|
|
340
346
|
type: "text",
|
|
341
|
-
text: node.data.question
|
|
347
|
+
text: interpolateString(node.data.question, submissions)
|
|
342
348
|
});
|
|
343
349
|
const reply = await chat.userInput({
|
|
344
350
|
key: node.data.key,
|
|
@@ -367,12 +373,13 @@ async function interpretQuestionTextNode({
|
|
|
367
373
|
async function interpretQuestionNumberNode({
|
|
368
374
|
chat,
|
|
369
375
|
next,
|
|
370
|
-
node
|
|
376
|
+
node,
|
|
377
|
+
submissions
|
|
371
378
|
}) {
|
|
372
379
|
await chat.sendMessage({
|
|
373
380
|
author: "bot",
|
|
374
381
|
type: "text",
|
|
375
|
-
text: node.data.question
|
|
382
|
+
text: interpolateString(node.data.question, submissions)
|
|
376
383
|
});
|
|
377
384
|
const reply = await chat.userInput({
|
|
378
385
|
key: node.data.key,
|
|
@@ -401,12 +408,13 @@ async function interpretQuestionNumberNode({
|
|
|
401
408
|
async function interpretQuestionEnumNode({
|
|
402
409
|
chat,
|
|
403
410
|
next,
|
|
404
|
-
node
|
|
411
|
+
node,
|
|
412
|
+
submissions
|
|
405
413
|
}) {
|
|
406
414
|
await chat.sendMessage({
|
|
407
415
|
author: "bot",
|
|
408
416
|
type: "text",
|
|
409
|
-
text: node.data.question
|
|
417
|
+
text: interpolateString(node.data.question, submissions)
|
|
410
418
|
});
|
|
411
419
|
const reply = await chat.userInput({
|
|
412
420
|
key: node.data.key,
|
|
@@ -431,12 +439,13 @@ async function interpretQuestionEnumNode({
|
|
|
431
439
|
async function interpretQuestionBooleanNode({
|
|
432
440
|
chat,
|
|
433
441
|
next,
|
|
434
|
-
node
|
|
442
|
+
node,
|
|
443
|
+
submissions
|
|
435
444
|
}) {
|
|
436
445
|
await chat.sendMessage({
|
|
437
446
|
author: "bot",
|
|
438
447
|
type: "text",
|
|
439
|
-
text: node.data.question
|
|
448
|
+
text: interpolateString(node.data.question, submissions)
|
|
440
449
|
});
|
|
441
450
|
const input = await chat.userInput({
|
|
442
451
|
key: node.data.key,
|
|
@@ -468,27 +477,205 @@ async function interpretQuestionBooleanNode({
|
|
|
468
477
|
}
|
|
469
478
|
next(node.nextId);
|
|
470
479
|
}
|
|
480
|
+
const dummyDivBecauseGoogleRequiresIt = document.createElement("div");
|
|
481
|
+
const keyToAddressComponnents = {
|
|
482
|
+
line1: ["street_number", "floor", "room", "premise"],
|
|
483
|
+
line2: ["subpremise", "street_address", "route"],
|
|
484
|
+
line3: ["sublocality", "neighborhood"],
|
|
485
|
+
city: ["locality", "postal_town"],
|
|
486
|
+
state: ["administrative_area_level_1"],
|
|
487
|
+
postcode: ["postal_code"],
|
|
488
|
+
country: ["country"]
|
|
489
|
+
};
|
|
490
|
+
const fieldMapKeys = Object.keys(keyToAddressComponnents);
|
|
471
491
|
async function interpretQuestionAddressNode({
|
|
472
492
|
chat,
|
|
473
493
|
next,
|
|
474
|
-
node
|
|
494
|
+
node,
|
|
495
|
+
logger
|
|
475
496
|
}) {
|
|
497
|
+
const {
|
|
498
|
+
google
|
|
499
|
+
} = window;
|
|
476
500
|
await chat.sendMessage({
|
|
477
501
|
author: "bot",
|
|
478
502
|
type: "text",
|
|
479
|
-
text:
|
|
503
|
+
text: node.data.question
|
|
480
504
|
});
|
|
481
|
-
|
|
505
|
+
const askForAddress = async (defaultValues) => {
|
|
506
|
+
const addressFields = [{
|
|
507
|
+
label: "Postcode",
|
|
508
|
+
key: node.data.keys.postcode,
|
|
509
|
+
optional: false,
|
|
510
|
+
defaultValue: defaultValues.postcode
|
|
511
|
+
}, {
|
|
512
|
+
label: "Line 1",
|
|
513
|
+
key: node.data.keys.line1,
|
|
514
|
+
optional: false,
|
|
515
|
+
defaultValue: defaultValues.line1
|
|
516
|
+
}, {
|
|
517
|
+
label: "Line 2",
|
|
518
|
+
key: node.data.keys.line2,
|
|
519
|
+
optional: true,
|
|
520
|
+
defaultValue: defaultValues.line2
|
|
521
|
+
}, {
|
|
522
|
+
label: "Line 3",
|
|
523
|
+
key: node.data.keys.line3,
|
|
524
|
+
optional: true,
|
|
525
|
+
defaultValue: defaultValues.line3
|
|
526
|
+
}, {
|
|
527
|
+
label: "City",
|
|
528
|
+
key: node.data.keys.city,
|
|
529
|
+
optional: false,
|
|
530
|
+
defaultValue: defaultValues.city
|
|
531
|
+
}, {
|
|
532
|
+
label: "State/County/Province",
|
|
533
|
+
key: node.data.keys.state,
|
|
534
|
+
optional: true,
|
|
535
|
+
defaultValue: defaultValues.state
|
|
536
|
+
}, {
|
|
537
|
+
label: "Country",
|
|
538
|
+
key: node.data.keys.country,
|
|
539
|
+
optional: false,
|
|
540
|
+
defaultValue: defaultValues.country
|
|
541
|
+
}];
|
|
542
|
+
for (const field of addressFields) {
|
|
543
|
+
await chat.sendMessage({
|
|
544
|
+
author: "bot",
|
|
545
|
+
type: "text",
|
|
546
|
+
text: field.label
|
|
547
|
+
});
|
|
548
|
+
const {
|
|
549
|
+
value
|
|
550
|
+
} = await chat.userInput({
|
|
551
|
+
type: "text",
|
|
552
|
+
key: field.key,
|
|
553
|
+
config: {
|
|
554
|
+
format: "text",
|
|
555
|
+
optional: field.optional,
|
|
556
|
+
defaultValue: field.defaultValue
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
if (value === null) {
|
|
560
|
+
await chat.sendMessage({
|
|
561
|
+
type: "system",
|
|
562
|
+
variant: "info",
|
|
563
|
+
text: "Skipped"
|
|
564
|
+
});
|
|
565
|
+
} else {
|
|
566
|
+
await chat.sendMessage({
|
|
567
|
+
author: "user",
|
|
568
|
+
type: "text",
|
|
569
|
+
text: value
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
if (!index.hasProp(window, "google") || !index.hasProp(window.google, "maps") || !index.hasProp(window.google.maps, "places")) {
|
|
575
|
+
logger.warn("Google maps not available, falling back to manual input.");
|
|
576
|
+
logger.info("If you’d like to use the address autocomplete, please insert the google maps API snippet in your website and make sure it has access to the *places* library.");
|
|
577
|
+
await askForAddress({});
|
|
578
|
+
return next(node.nextId);
|
|
579
|
+
}
|
|
580
|
+
const autocomplete = new google.maps.places.AutocompleteService();
|
|
581
|
+
const places = new google.maps.places.PlacesService(dummyDivBecauseGoogleRequiresIt);
|
|
582
|
+
const {
|
|
583
|
+
value: search
|
|
584
|
+
} = await chat.userInput({
|
|
585
|
+
type: "text",
|
|
586
|
+
key: "_internal-address-search",
|
|
587
|
+
config: {
|
|
588
|
+
format: "text",
|
|
589
|
+
optional: false,
|
|
590
|
+
placeholder: "Search for your address"
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
if (search === null)
|
|
594
|
+
return next(node.id);
|
|
595
|
+
await chat.sendMessage({
|
|
596
|
+
author: "user",
|
|
597
|
+
type: "text",
|
|
598
|
+
text: `Search for “${search}”`
|
|
599
|
+
});
|
|
600
|
+
const {
|
|
601
|
+
predictions
|
|
602
|
+
} = await autocomplete.getPlacePredictions({
|
|
603
|
+
input: search
|
|
604
|
+
});
|
|
605
|
+
const {
|
|
606
|
+
value: [selected]
|
|
607
|
+
} = await chat.userInput({
|
|
608
|
+
type: "multiple-choice",
|
|
609
|
+
key: void 0,
|
|
610
|
+
config: {
|
|
611
|
+
options: predictions.slice(0, 4).map((p) => ({
|
|
612
|
+
label: p.description,
|
|
613
|
+
value: p.place_id
|
|
614
|
+
})).concat({
|
|
615
|
+
label: "None of these",
|
|
616
|
+
value: "none"
|
|
617
|
+
}),
|
|
618
|
+
maxSelected: 1,
|
|
619
|
+
minSelected: 1
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
if (!selected || selected === "none") {
|
|
623
|
+
return next(node.id);
|
|
624
|
+
}
|
|
625
|
+
const result = await new Promise((resolve, reject) => places.getDetails({
|
|
626
|
+
placeId: selected,
|
|
627
|
+
fields: ["address_components"]
|
|
628
|
+
}, (result2, status) => {
|
|
629
|
+
if (status !== google.maps.places.PlacesServiceStatus["OK"])
|
|
630
|
+
return reject(status);
|
|
631
|
+
if (result2 === null)
|
|
632
|
+
return reject("ZERO_RESULTS");
|
|
633
|
+
return resolve({
|
|
634
|
+
ok: true,
|
|
635
|
+
place: result2
|
|
636
|
+
});
|
|
637
|
+
})).catch(async (e) => {
|
|
638
|
+
logger.error("Failed to get address details", e);
|
|
639
|
+
return {
|
|
640
|
+
ok: false
|
|
641
|
+
};
|
|
642
|
+
});
|
|
643
|
+
if (result.ok === false) {
|
|
644
|
+
await chat.sendMessage({
|
|
645
|
+
type: "system",
|
|
646
|
+
variant: "error",
|
|
647
|
+
text: "Failed to get address details"
|
|
648
|
+
});
|
|
649
|
+
await askForAddress({});
|
|
650
|
+
return next(node.id);
|
|
651
|
+
}
|
|
652
|
+
const addressComponents = result.place.address_components;
|
|
653
|
+
const autoFilledInputs = addressComponents ? fieldMapKeys.reduce((acc, key) => {
|
|
654
|
+
const componentTypes = keyToAddressComponnents[key];
|
|
655
|
+
const value = addressComponents.filter((component) => component.types.some((type) => componentTypes.includes(type))).map((component) => component.long_name).join(", ");
|
|
656
|
+
if (value) {
|
|
657
|
+
acc[key] = value;
|
|
658
|
+
}
|
|
659
|
+
return acc;
|
|
660
|
+
}, {}) : {};
|
|
661
|
+
await chat.sendMessage({
|
|
662
|
+
author: "bot",
|
|
663
|
+
type: "text",
|
|
664
|
+
text: "Please confirm or adjust your address:"
|
|
665
|
+
});
|
|
666
|
+
await askForAddress(autoFilledInputs);
|
|
667
|
+
return next(node.nextId);
|
|
482
668
|
}
|
|
483
669
|
async function interpretQuestionFileNode({
|
|
484
670
|
node,
|
|
485
671
|
chat,
|
|
486
|
-
next
|
|
672
|
+
next,
|
|
673
|
+
submissions
|
|
487
674
|
}) {
|
|
488
675
|
await chat.sendMessage({
|
|
489
676
|
author: "bot",
|
|
490
677
|
type: "text",
|
|
491
|
-
text: node.data.question
|
|
678
|
+
text: interpolateString(node.data.question, submissions)
|
|
492
679
|
});
|
|
493
680
|
const files = await chat.userInput({
|
|
494
681
|
key: node.data.key,
|
|
@@ -577,6 +764,27 @@ const isIfBlockConditionMet = (ifBlock, submissions) => {
|
|
|
577
764
|
}
|
|
578
765
|
}, () => false).exhaustive();
|
|
579
766
|
};
|
|
767
|
+
const interpolateString = (str, context) => {
|
|
768
|
+
const regex = /{{\s*([^}]+?)\s*(?:\|\s*([^}]+?)\s*)?}}/g;
|
|
769
|
+
return str.replace(regex, (match2, key, defaultValue = "") => {
|
|
770
|
+
key = key.trim();
|
|
771
|
+
const submission = context == null ? void 0 : context[key];
|
|
772
|
+
if (!submission)
|
|
773
|
+
return defaultValue;
|
|
774
|
+
switch (submission.type) {
|
|
775
|
+
case "boolean":
|
|
776
|
+
return submission.value === "true" ? "true" : "false";
|
|
777
|
+
case "file":
|
|
778
|
+
if (!submission.value)
|
|
779
|
+
return "no files";
|
|
780
|
+
return submission.value.map((file) => `${file.name} (${kbToReadableSize(file.sizeKb)})`).join(", ");
|
|
781
|
+
case "multiple-choice":
|
|
782
|
+
return submission.value.join(", ");
|
|
783
|
+
default:
|
|
784
|
+
return submission.value || defaultValue;
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
};
|
|
580
788
|
const SendButton = ({
|
|
581
789
|
class: className,
|
|
582
790
|
...props
|
|
@@ -741,7 +949,6 @@ const toBase64 = (file) => new Promise((resolve, reject) => {
|
|
|
741
949
|
};
|
|
742
950
|
reader.onerror = reject;
|
|
743
951
|
});
|
|
744
|
-
const kbToReadableSize = (kb) => index.N(kb).with(index._.number.lte(1e3), () => `${Math.round(kb)}KB`).with(index._.number.lt(1e3 * 10), () => `${(kb / 1e3).toFixed(1)}MB`).otherwise(() => `${Math.round(kb / 1e3)}MB`);
|
|
745
952
|
const addFileSizesKb = (files) => files.reduce((acc, cur) => acc + cur.sizeKb, 0);
|
|
746
953
|
const isFileSubmission = isSubmissionOfType("file");
|
|
747
954
|
const FILENAMES_TO_SHOW_QTY = 3;
|
|
@@ -778,6 +985,19 @@ const FilenameBadge = ({
|
|
|
778
985
|
class: index.clsx("outline-neutral-6 text-neutral-11 bg-neutral-1 block rounded-md px-1 py-0.5 text-xs outline outline-1", className),
|
|
779
986
|
...props
|
|
780
987
|
});
|
|
988
|
+
const getFileExtension = (fileName) => {
|
|
989
|
+
const extension = fileName.split(".").pop();
|
|
990
|
+
if (!extension)
|
|
991
|
+
throw new Error("No file extension found");
|
|
992
|
+
return extension ? "." + extension : "";
|
|
993
|
+
};
|
|
994
|
+
const validateExtensions = ({
|
|
995
|
+
allowedExtensions,
|
|
996
|
+
files
|
|
997
|
+
}) => {
|
|
998
|
+
const normalisedExtensions = allowedExtensions.map((ext) => ext.toLowerCase());
|
|
999
|
+
return files.every((file) => normalisedExtensions.includes(getFileExtension(file.name).toLowerCase()));
|
|
1000
|
+
};
|
|
781
1001
|
const ChatInputFile = ({
|
|
782
1002
|
input,
|
|
783
1003
|
onSubmitSuccess,
|
|
@@ -801,6 +1021,15 @@ const ChatInputFile = ({
|
|
|
801
1021
|
message: "Please select a file"
|
|
802
1022
|
});
|
|
803
1023
|
}
|
|
1024
|
+
if (input.config.extensions.length > 0 && !validateExtensions({
|
|
1025
|
+
allowedExtensions: input.config.extensions,
|
|
1026
|
+
files
|
|
1027
|
+
})) {
|
|
1028
|
+
return setError({
|
|
1029
|
+
type: "validate",
|
|
1030
|
+
message: `Please upload ${input.config.extensions.join(", ")} files only`
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
804
1033
|
if (input.config.fileSizeLimitKib && totalSize > input.config.fileSizeLimitKib) {
|
|
805
1034
|
return setError({
|
|
806
1035
|
type: "max",
|
|
@@ -2534,6 +2763,7 @@ const ChatInputText = ({
|
|
|
2534
2763
|
}) => {
|
|
2535
2764
|
var _a;
|
|
2536
2765
|
const submission = input.key ? (_a = index.application.current$.value.application) == null ? void 0 : _a.data.submissions[input.key] : void 0;
|
|
2766
|
+
const defaultValue = input.config.defaultValue;
|
|
2537
2767
|
const {
|
|
2538
2768
|
register,
|
|
2539
2769
|
handleSubmit,
|
|
@@ -2542,7 +2772,7 @@ const ChatInputText = ({
|
|
|
2542
2772
|
}
|
|
2543
2773
|
} = useForm({
|
|
2544
2774
|
defaultValues: {
|
|
2545
|
-
text: isTextSubmission(submission) ? submission.value : ""
|
|
2775
|
+
text: defaultValue ? defaultValue : isTextSubmission(submission) ? submission.value : ""
|
|
2546
2776
|
},
|
|
2547
2777
|
resolver: getResolver(input.config)
|
|
2548
2778
|
});
|