@inploi/plugin-chatbot 14.1.0 → 14.3.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.
@@ -1,5 +1,5 @@
1
1
  import { Flow } from './chatbot.api';
2
- import { ApplicationRecovery, ChatMessage, KeyToSubmissionMap, StartedFlow } from './chatbot.state';
2
+ import { ApplicationRecovery, ChatMessage, KeyToSubmissionMap, StartedFlow, SubmitCooldown } from './chatbot.state';
3
3
  import { ChatInput } from './components/chat-input/chat-input';
4
4
 
5
5
  export declare const idb: {
@@ -7,6 +7,8 @@ export declare const idb: {
7
7
  currentInput: ChatInput | null;
8
8
  nodeHistory: string[];
9
9
  startedWriteNodeIds?: string[];
10
+ unconfirmedAttemptKeys?: string[];
11
+ submitCooldown?: SubmitCooldown;
10
12
  applicationRecovery?: ApplicationRecovery;
11
13
  flowSessionId: string;
12
14
  isFinished: boolean;
@@ -35,7 +35,7 @@ type CurrentFlow = {
35
35
  };
36
36
  export declare const store: {
37
37
  current$: import('@preact/signals').Signal<CurrentFlow>;
38
- viewState$: import('@preact/signals').Signal<"maximised" | "minimised" | "closed">;
38
+ viewState$: import('@preact/signals').Signal<"closed" | "maximised" | "minimised">;
39
39
  prepareFlow: ({ flow, context, flowKeys, title, analytics, job, locationOrigin }: OpenChatbotParams) => Promise<{
40
40
  data: FlowStateData;
41
41
  startedAt: Date;
@@ -401,6 +401,10 @@ export type ApplicationRecovery = {
401
401
  fileQuestionNodeId: string;
402
402
  submitNodeId: string;
403
403
  };
404
+ export type SubmitCooldown = {
405
+ key: string;
406
+ until: number;
407
+ };
404
408
  /** Dynamic part of a flow */
405
409
  export type FlowStateData = {
406
410
  /** History of messages left in the chat */
@@ -417,6 +421,18 @@ export type FlowStateData = {
417
421
  * entry. Caches from before this field infer it conservatively from visited submit nodes.
418
422
  */
419
423
  startedWriteNodeIds?: string[];
424
+ /**
425
+ * Submit node (and job, when known) keys where an earlier attempt in this conversation may have been written without our knowing: an
426
+ * unknown verdict or a failure with no semantics (e.g. a lost response), never a not_submitted or confirmed
427
+ * outcome. A later duplicate is then most likely that attempt landing (PROD-7055). Kept across Restart, which is how a candidate retries after a failure;
428
+ * it is browser-local, like the barrier.
429
+ */
430
+ unconfirmedAttemptKeys?: string[];
431
+ /**
432
+ * When submit becomes available again after an unsuccessful attempt, for the attempt key above (PROD-7112).
433
+ * Kept across Restart so neither Restart nor a reload skips the wait; browser-local, like the barrier.
434
+ */
435
+ submitCooldown?: SubmitCooldown;
420
436
  applicationRecovery?: ApplicationRecovery;
421
437
  /** Needs to be separate because a node can have many inputs */
422
438
  currentInput: ChatInput | null;
@@ -1,4 +1,4 @@
1
- import { Logger } from '@inploi/sdk';
1
+ import { AnalyticsService, Logger } from '@inploi/sdk';
2
2
  import { DistributivePick } from '../../chatbot.utils';
3
3
  import { FlowSubmission } from '../../chatbot.state';
4
4
  import { AddressInputPayload } from './chat-input.address';
@@ -15,9 +15,8 @@ export type ChatInputProps<T extends ChatbotInput> = {
15
15
  onSubmitSuccess: (value: T['submission']) => void;
16
16
  input: Omit<T, 'submission'>;
17
17
  logger: Logger;
18
+ analytics: Pick<AnalyticsService, 'log'>;
18
19
  };
19
20
  export type ChatbotInput = TextPayload | NumberPayload | MultipleChoicePayload | BooleanChoicePayload | FilePayload | SubmitPayload | AddressInputPayload | PhonePayload;
20
21
  export type ChatInput = DistributivePick<ChatbotInput, 'type' | 'config' | 'key'>;
21
- export declare const ChatInput: ({ logger }: {
22
- logger: Logger;
23
- }) => import("preact").JSX.Element;
22
+ export declare const ChatInput: ({ logger, analytics }: Pick<ChatInputProps<ChatbotInput>, "logger" | "analytics">) => import("preact").JSX.Element;
@@ -16,4 +16,4 @@ export type FilePayload = {
16
16
  export declare const FileThumbnail: ({ file, class: className, ...props }: ComponentProps<"div"> & {
17
17
  file: Pick<FileToUpload, "name" | "sizeKb">;
18
18
  }) => import("preact").JSX.Element;
19
- export declare const ChatInputFile: ({ input, onSubmitSuccess }: ChatInputProps<FilePayload>) => import("preact").JSX.Element;
19
+ export declare const ChatInputFile: ({ input, onSubmitSuccess, analytics }: ChatInputProps<FilePayload>) => import("preact").JSX.Element;
@@ -2,8 +2,10 @@ import { ChatInputProps } from './chat-input';
2
2
 
3
3
  export type SubmitPayload = {
4
4
  type: 'submit';
5
+ /** `availableAt` (epoch ms) keeps submit unavailable until then, after an unsuccessful attempt (PROD-7112). */
5
6
  config: {
6
7
  label: string;
8
+ availableAt?: number;
7
9
  };
8
10
  key: string | undefined;
9
11
  submission: null;
package/dist/i18n.d.ts CHANGED
@@ -9,11 +9,17 @@ export declare const TranslationProvider: (props: {
9
9
  readonly skip: "Skip";
10
10
  readonly skipped: "Skipped";
11
11
  readonly submission_closed: "This role is no longer accepting applications.";
12
- readonly submission_duplicate: "It looks like you've already applied for this role.";
12
+ readonly submission_duplicate: "You've already applied for this role, so we haven't submitted a second application. If that doesn't sound right, check your email for a confirmation or try again in a few minutes.";
13
+ readonly submission_duplicate_earlier_attempt: "It looks like your earlier attempt did go through. You don't need to apply again — check your email for confirmation.";
13
14
  readonly submission_retryable: "We couldn't submit your application. Please try again.";
14
15
  readonly submission_failed: "We couldn't submit your application. Choose Restart to try again.";
15
16
  readonly submission_unknown: "We couldn't confirm whether your application was sent. Please check your email for a confirmation. If nothing arrives, choose Restart to apply again.";
16
17
  readonly submission_unreadable_document: "We couldn't read that file. Please upload a different one.";
18
+ readonly submission_cooldown: {
19
+ readonly one: "Submit will be available again in {{count}} second.";
20
+ readonly other: "Submit will be available again in {{count}} seconds.";
21
+ };
22
+ readonly submission_cooldown_ready: "Submit is available again.";
17
23
  readonly submission_still_working: "Still working — the employer's application system is taking a little longer than usual. Please keep this window open.";
18
24
  readonly file_preparing: {
19
25
  readonly one: "Preparing your file…";
@@ -102,11 +108,17 @@ export declare const TranslationProvider: (props: {
102
108
  readonly skip: "Skip";
103
109
  readonly skipped: "Skipped";
104
110
  readonly submission_closed: "This role is no longer accepting applications.";
105
- readonly submission_duplicate: "It looks like you've already applied for this role.";
111
+ readonly submission_duplicate: "You've already applied for this role, so we haven't submitted a second application. If that doesn't sound right, check your email for a confirmation or try again in a few minutes.";
112
+ readonly submission_duplicate_earlier_attempt: "It looks like your earlier attempt did go through. You don't need to apply again — check your email for confirmation.";
106
113
  readonly submission_retryable: "We couldn't submit your application. Please try again.";
107
114
  readonly submission_failed: "We couldn't submit your application. Choose Restart to try again.";
108
115
  readonly submission_unknown: "We couldn't confirm whether your application was sent. Please check your email for a confirmation. If nothing arrives, choose Restart to apply again.";
109
116
  readonly submission_unreadable_document: "We couldn't read that file. Please upload a different one.";
117
+ readonly submission_cooldown: {
118
+ readonly one: "Submit will be available again in {{count}} second.";
119
+ readonly other: "Submit will be available again in {{count}} seconds.";
120
+ };
121
+ readonly submission_cooldown_ready: "Submit is available again.";
110
122
  readonly submission_still_working: "Still working — the employer's application system is taking a little longer than usual. Please keep this window open.";
111
123
  readonly file_preparing: {
112
124
  readonly one: "Preparing your file…";
@@ -192,11 +204,17 @@ export declare const TranslationProvider: (props: {
192
204
  readonly skip: "Skip";
193
205
  readonly skipped: "Skipped";
194
206
  readonly submission_closed: "This role is no longer accepting applications.";
195
- readonly submission_duplicate: "It looks like you've already applied for this role.";
207
+ readonly submission_duplicate: "You've already applied for this role, so we haven't submitted a second application. If that doesn't sound right, check your email for a confirmation or try again in a few minutes.";
208
+ readonly submission_duplicate_earlier_attempt: "It looks like your earlier attempt did go through. You don't need to apply again — check your email for confirmation.";
196
209
  readonly submission_retryable: "We couldn't submit your application. Please try again.";
197
210
  readonly submission_failed: "We couldn't submit your application. Choose Restart to try again.";
198
211
  readonly submission_unknown: "We couldn't confirm whether your application was sent. Please check your email for a confirmation. If nothing arrives, choose Restart to apply again.";
199
212
  readonly submission_unreadable_document: "We couldn't read that file. Please upload a different one.";
213
+ readonly submission_cooldown: {
214
+ readonly one: "Submit will be available again in {{count}} second.";
215
+ readonly other: "Submit will be available again in {{count}} seconds.";
216
+ };
217
+ readonly submission_cooldown_ready: "Submit is available again.";
200
218
  readonly submission_still_working: "Still working — the employer's application system is taking a little longer than usual. Please keep this window open.";
201
219
  readonly file_preparing: {
202
220
  readonly one: "Preparing your file…";
@@ -285,11 +303,17 @@ export declare const TranslationProvider: (props: {
285
303
  readonly skip: "Skip";
286
304
  readonly skipped: "Skipped";
287
305
  readonly submission_closed: "This role is no longer accepting applications.";
288
- readonly submission_duplicate: "It looks like you've already applied for this role.";
306
+ readonly submission_duplicate: "You've already applied for this role, so we haven't submitted a second application. If that doesn't sound right, check your email for a confirmation or try again in a few minutes.";
307
+ readonly submission_duplicate_earlier_attempt: "It looks like your earlier attempt did go through. You don't need to apply again — check your email for confirmation.";
289
308
  readonly submission_retryable: "We couldn't submit your application. Please try again.";
290
309
  readonly submission_failed: "We couldn't submit your application. Choose Restart to try again.";
291
310
  readonly submission_unknown: "We couldn't confirm whether your application was sent. Please check your email for a confirmation. If nothing arrives, choose Restart to apply again.";
292
311
  readonly submission_unreadable_document: "We couldn't read that file. Please upload a different one.";
312
+ readonly submission_cooldown: {
313
+ readonly one: "Submit will be available again in {{count}} second.";
314
+ readonly other: "Submit will be available again in {{count}} seconds.";
315
+ };
316
+ readonly submission_cooldown_ready: "Submit is available again.";
293
317
  readonly submission_still_working: "Still working — the employer's application system is taking a little longer than usual. Please keep this window open.";
294
318
  readonly file_preparing: {
295
319
  readonly one: "Preparing your file…";
@@ -375,11 +399,17 @@ export declare const TranslationProvider: (props: {
375
399
  readonly skip: "Skip";
376
400
  readonly skipped: "Skipped";
377
401
  readonly submission_closed: "This role is no longer accepting applications.";
378
- readonly submission_duplicate: "It looks like you've already applied for this role.";
402
+ readonly submission_duplicate: "You've already applied for this role, so we haven't submitted a second application. If that doesn't sound right, check your email for a confirmation or try again in a few minutes.";
403
+ readonly submission_duplicate_earlier_attempt: "It looks like your earlier attempt did go through. You don't need to apply again — check your email for confirmation.";
379
404
  readonly submission_retryable: "We couldn't submit your application. Please try again.";
380
405
  readonly submission_failed: "We couldn't submit your application. Choose Restart to try again.";
381
406
  readonly submission_unknown: "We couldn't confirm whether your application was sent. Please check your email for a confirmation. If nothing arrives, choose Restart to apply again.";
382
407
  readonly submission_unreadable_document: "We couldn't read that file. Please upload a different one.";
408
+ readonly submission_cooldown: {
409
+ readonly one: "Submit will be available again in {{count}} second.";
410
+ readonly other: "Submit will be available again in {{count}} seconds.";
411
+ };
412
+ readonly submission_cooldown_ready: "Submit is available again.";
383
413
  readonly submission_still_working: "Still working — the employer's application system is taking a little longer than usual. Please keep this window open.";
384
414
  readonly file_preparing: {
385
415
  readonly one: "Preparing your file…";
@@ -466,11 +496,17 @@ export declare const TranslationProvider: (props: {
466
496
  readonly skip: "Skip";
467
497
  readonly skipped: "Skipped";
468
498
  readonly submission_closed: "This role is no longer accepting applications.";
469
- readonly submission_duplicate: "It looks like you've already applied for this role.";
499
+ readonly submission_duplicate: "You've already applied for this role, so we haven't submitted a second application. If that doesn't sound right, check your email for a confirmation or try again in a few minutes.";
500
+ readonly submission_duplicate_earlier_attempt: "It looks like your earlier attempt did go through. You don't need to apply again — check your email for confirmation.";
470
501
  readonly submission_retryable: "We couldn't submit your application. Please try again.";
471
502
  readonly submission_failed: "We couldn't submit your application. Choose Restart to try again.";
472
503
  readonly submission_unknown: "We couldn't confirm whether your application was sent. Please check your email for a confirmation. If nothing arrives, choose Restart to apply again.";
473
504
  readonly submission_unreadable_document: "We couldn't read that file. Please upload a different one.";
505
+ readonly submission_cooldown: {
506
+ readonly one: "Submit will be available again in {{count}} second.";
507
+ readonly other: "Submit will be available again in {{count}} seconds.";
508
+ };
509
+ readonly submission_cooldown_ready: "Submit is available again.";
474
510
  readonly submission_still_working: "Still working — the employer's application system is taking a little longer than usual. Please keep this window open.";
475
511
  readonly file_preparing: {
476
512
  readonly one: "Preparing your file…";