@wise/dynamic-flow-client 0.2.1 → 0.3.0-beta-ec09e7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +47 -25
  2. package/build/common/contexts/events/EventsContext.d.ts +15 -0
  3. package/build/common/contexts/events/EventsContext.js +33 -0
  4. package/build/common/contexts/events/index.d.ts +1 -0
  5. package/build/common/contexts/events/index.js +1 -0
  6. package/build/flow/DynamicFlow.d.ts +0 -1
  7. package/build/flow/DynamicFlow.js +21 -22
  8. package/build/flow/DynamicFlowStep.d.ts +0 -1
  9. package/build/flow/errorBoundary/ErrorBoundaryAlert.d.ts +0 -1
  10. package/build/flow/response-parsers/index.d.ts +2 -2
  11. package/build/flow/response-parsers/index.js +16 -3
  12. package/build/flow/stories/DynamicFlow.story.js +1 -1
  13. package/build/flow/stories/EditableDynamicFlow.d.ts +0 -1
  14. package/build/flow/stories/EditableDynamicFlow.js +1 -1
  15. package/build/flow/types.d.ts +6 -31
  16. package/build/i18n/de.json +5 -1
  17. package/build/i18n/es.json +7 -3
  18. package/build/i18n/fr.json +9 -5
  19. package/build/i18n/hu.json +5 -1
  20. package/build/i18n/id.json +7 -3
  21. package/build/i18n/it.json +4 -0
  22. package/build/i18n/ja.json +15 -11
  23. package/build/i18n/pl.json +30 -3
  24. package/build/i18n/pt.json +4 -0
  25. package/build/i18n/ro.json +5 -1
  26. package/build/i18n/ru.json +10 -6
  27. package/build/i18n/th.json +6 -2
  28. package/build/i18n/tr.json +30 -3
  29. package/build/i18n/zh-CN.json +8 -4
  30. package/build/i18n/zh.json +4 -0
  31. package/build/index.d.ts +0 -2
  32. package/build/index.js +0 -2
  33. package/build/jsonSchemaForm/JsonSchemaForm.d.ts +2 -3
  34. package/build/jsonSchemaForm/JsonSchemaForm.js +4 -4
  35. package/build/jsonSchemaForm/allOfSchema/AllOfSchema.d.ts +0 -1
  36. package/build/jsonSchemaForm/arrayTypeSchema/ArraySchema.d.ts +0 -1
  37. package/build/jsonSchemaForm/arrayTypeSchema/arrayListSchema/ArrayListSchema.d.ts +0 -1
  38. package/build/jsonSchemaForm/arrayTypeSchema/arrayListSchema/multipleFileUploadSchema/MultipleFileUploadSchema.d.ts +0 -1
  39. package/build/jsonSchemaForm/arrayTypeSchema/arrayListSchema/multipleFileUploadSchema/MultipleFileUploadSchema.js +5 -5
  40. package/build/jsonSchemaForm/basicTypeSchema/BasicTypeSchema.d.ts +0 -1
  41. package/build/jsonSchemaForm/controlFeedback/ControlFeedback.d.ts +0 -1
  42. package/build/jsonSchemaForm/genericSchema/GenericSchema.d.ts +0 -1
  43. package/build/jsonSchemaForm/help/Help.d.ts +0 -1
  44. package/build/jsonSchemaForm/objectSchema/ObjectSchema.d.ts +0 -1
  45. package/build/jsonSchemaForm/oneOfSchema/OneOfSchema.d.ts +0 -1
  46. package/build/jsonSchemaForm/oneOfSchema/OneOfSchema.js +4 -4
  47. package/build/jsonSchemaForm/persistAsyncSchema/PersistAsyncSchema.d.ts +0 -1
  48. package/build/jsonSchemaForm/persistAsyncSchema/basic/PersistAsyncBasicSchema.d.ts +0 -1
  49. package/build/jsonSchemaForm/persistAsyncSchema/basic/PersistAsyncBasicSchema.js +5 -5
  50. package/build/jsonSchemaForm/persistAsyncSchema/blob/PersistAsyncBlobSchema.d.ts +0 -1
  51. package/build/jsonSchemaForm/persistAsyncSchema/blob/PersistAsyncBlobSchema.js +4 -4
  52. package/build/jsonSchemaForm/persistAsyncSchema/blob/UploadInputAdapter.d.ts +0 -1
  53. package/build/jsonSchemaForm/persistAsyncSchema/blob/UploadInputAdapter.js +3 -3
  54. package/build/jsonSchemaForm/promotedOneOfSchema/PromotedOneOfSchema.d.ts +0 -1
  55. package/build/jsonSchemaForm/promotedOneOfSchema/control/PromotedOneOfCheckboxControl.d.ts +0 -1
  56. package/build/jsonSchemaForm/promotedOneOfSchema/control/PromotedOneOfRadioControl.d.ts +0 -1
  57. package/build/jsonSchemaForm/readOnlySchema/ReadOnlySchema.d.ts +0 -1
  58. package/build/jsonSchemaForm/schemaFormControl/SchemaFormControl.d.ts +0 -1
  59. package/build/jsonSchemaForm/schemaFormControl/optionMapper.d.ts +0 -1
  60. package/build/jsonSchemaForm/validationAsyncSchema/ValidationAsyncSchema.d.ts +0 -1
  61. package/build/jsonSchemaForm/validationAsyncSchema/ValidationAsyncSchema.js +5 -5
  62. package/build/layout/DynamicLayout.d.ts +0 -1
  63. package/build/layout/alert/index.d.ts +0 -1
  64. package/build/layout/box/index.d.ts +0 -1
  65. package/build/layout/button/index.d.ts +0 -1
  66. package/build/layout/columns/index.d.ts +0 -1
  67. package/build/layout/decision/index.d.ts +0 -1
  68. package/build/layout/divider/index.d.ts +0 -1
  69. package/build/layout/external/DynamicExternal.d.ts +0 -1
  70. package/build/layout/form/index.d.ts +0 -1
  71. package/build/layout/heading/index.d.ts +0 -1
  72. package/build/layout/icon/index.d.ts +1 -2
  73. package/build/layout/icon/index.js +3 -2
  74. package/build/layout/image/index.d.ts +0 -1
  75. package/build/layout/image/index.js +7 -2
  76. package/build/layout/info/index.d.ts +0 -1
  77. package/build/layout/list/index.d.ts +0 -1
  78. package/build/layout/loading-indicator/index.d.ts +0 -1
  79. package/build/layout/paragraph/DynamicParagraph.d.ts +0 -1
  80. package/build/layout/review/index.d.ts +0 -1
  81. package/build/main.css +3 -6
  82. package/build/step/cameraStep/CameraStep.d.ts +0 -1
  83. package/build/step/cameraStep/CameraStep.js +3 -3
  84. package/build/step/cameraStep/cameraCapture/CameraCapture.d.ts +3 -4
  85. package/build/step/cameraStep/cameraCapture/CameraCapture.js +6 -6
  86. package/build/step/cameraStep/cameraCapture/components/index.d.ts +0 -1
  87. package/build/step/cameraStep/cameraCapture/overlay/Overlay.d.ts +0 -1
  88. package/build/step/cameraStep/cameraCapture/screens/CameraNotSupported/CameraNotSupported.d.ts +0 -1
  89. package/build/step/cameraStep/cameraCapture/screens/NoCameraAccess/NoCameraAccess.d.ts +0 -1
  90. package/build/step/cameraStep/cameraCapture/tracking/index.d.ts +4 -4
  91. package/build/step/cameraStep/cameraCapture/tracking/index.js +19 -22
  92. package/build/step/externalConfirmationStep/ExternalConfirmationStep.d.ts +0 -1
  93. package/build/step/layoutStep/LayoutStep.d.ts +0 -1
  94. package/build/step/layoutStep/LayoutStep.js +3 -3
  95. package/package.json +44 -51
  96. package/build/common/requirements.d.ts +0 -10
  97. package/build/common/requirements.js +0 -50
  98. package/build/common/tracking/index.d.ts +0 -15
  99. package/build/common/tracking/index.js +0 -33
  100. package/build/field/Field.d.ts +0 -69
  101. package/build/field/Field.js +0 -311
  102. package/build/field/index.d.ts +0 -2
  103. package/build/field/index.js +0 -2
package/README.md CHANGED
@@ -23,17 +23,18 @@ pnpm install @wise/dynamic-flow-client
23
23
 
24
24
  ```
25
25
  # yarn
26
- yarn add prop-types react react-dom react-intl
26
+ yarn add react react-dom react-intl
27
27
  yarn add @transferwise/components @transferwise/formatting @transferwise/icons @transferwise/neptune-css @transferwise/neptune-validation
28
28
 
29
29
  # npm
30
- npm install prop-types react react-dom react-intl
30
+ npm install react react-dom react-intl
31
31
  npm install @transferwise/components @transferwise/formatting @transferwise/icons @transferwise/neptune-css @transferwise/neptune-validation
32
32
 
33
33
  # pnpm
34
- pnpm install prop-types react react-dom react-intl
34
+ pnpm install react react-dom react-intl
35
35
  pnpm install @transferwise/components @transferwise/formatting @transferwise/icons @transferwise/neptune-css @transferwise/neptune-validation
36
36
  ```
37
+ **Note:** Keep in mind that some of these dependencies have their own peer dependencies. Don't forget to install those, for instance: `@transferwise/components` needs `@wise/art` and `@wise/components-theming`.
37
38
 
38
39
  ```js
39
40
  // Should be imported once in your application
@@ -50,10 +51,7 @@ import {
50
51
  getLangFromLocale,
51
52
  DEFAULT_LANG,
52
53
  } from '@transferwise/components';
53
- import {
54
- DynamicFlow,
55
- translations as dynamicFlowsTranslations,
56
- } from '@wise/dynamic-flow-client/';
54
+ import { DynamicFlow, translations as dynamicFlowsTranslations } from '@wise/dynamic-flow-client/';
57
55
 
58
56
  const lang = getLangFromLocale(locale) || DEFAULT_LANG;
59
57
  const i18n = {
@@ -88,7 +86,7 @@ We recommend using a `initialAction` and a `fetcher` function.
88
86
  <DynamicFlow
89
87
  initialAction={{ method: 'GET', url: '/my-amazing-new-flow' }}
90
88
  fetcher={(...args) => fetch(...args)}
91
- onClose={(result) => {
89
+ onComplete={(result) => {
92
90
  console.log('Flow exited with', result);
93
91
  }}
94
92
  onError={(error, statusCode) => {
@@ -105,44 +103,70 @@ In some cases you may want to obtain the initial step yourself, and then pass it
105
103
  <DynamicFlow
106
104
  initialStep={someInitialStepIfoundLayingAroundHere}
107
105
  fetcher={...}
108
- onClose={...}
106
+ onComplete={...}
109
107
  onError={...}
110
108
  />
111
109
  ```
112
110
 
113
- ### `baseUrl` vs `fetcher`
111
+ ### The `fetcher` function prop
114
112
 
115
- We recommend passing a fetcher function. This can be `window.fetch` itself or some wrapper function where you inject auth headers and anything else you many need.
113
+ You must pass a fetcher function. This can be `window.fetch` itself or some wrapper function where you inject authorisation headers and anything else you many need.
116
114
 
117
- You can take advantage of the `makeFetcher` utility function. This function takes a `baseUrl` and `additionalHeaders` arguments. The `baseUrl` will be prefixed to any relative request URLs. Absolute URLs will not be altered. The `additionalHeaders` parameter can be used to add any request headers you need in all requests, such as `{ 'X-Access-Token': 'Tr4n5f3rw153' }`:
115
+ You can take advantage of the provided `makeFetcher` utility function. This function takes `baseUrl` and `additionalHeaders` arguments. The `baseUrl` will be prefixed to any relative request URLs. Absolute URLs will not be altered. The `additionalHeaders` parameter can be used to add any request headers you need in all requests.
118
116
 
119
117
  ```tsx
120
118
  import { makeFetcher, DynamicFlow } from '@wise/dynamic-flow-client';
121
119
 
122
- const myFetcher = makeFetcher('/my-base-url', { 'X-Access-Token': 'Tr4n5f3rw153' });
123
-
124
- ...
120
+ const myFetcher = makeFetcher('/my-base-url', { 'X-Access-Token': 'an-access-token' });
125
121
 
126
122
  <DynamicFlow
127
- initialAction={{ method: 'GET', url: '/my-amazing-new-flow' }}
123
+ initialAction={{ method: 'GET', url: '/flow-starting-url' }}
128
124
  fetcher={myFetcher}
129
- // baseUrl="/my-base-url"
130
- onClose={...}
125
+ onComplete={...}
131
126
  onError={...}
132
127
  />
133
128
  ```
134
129
 
135
- **Important**: You must not throw from your fetcher function. Errors should result in a response with an error status code and potentially a body with an error message.
130
+ #### Custom `fetcher` functions
136
131
 
137
- ### Logging and Tracking
132
+ If you want to write your own fetcher function (or if you're writing mocks), it's important that you return proper `Response` objects, and that you **do not throw**. Errors should result in a response with an error status code and potentially a body with an error message. For example:
138
133
 
139
- The `DynamicFlow` component accepts two optional props: `onTrackableEvent` and `onLog` which can be used to track and log.
134
+ ```tsx
135
+ const mockFetcher = (input, init) => {
136
+ switch (input) {
137
+ case '/standard':
138
+ return Promise.resolve(new Response(init.body));
139
+ case '/exit':
140
+ return Promise.resolve(new Response(init.body, { headers: { 'x-df-exit': true } }));
141
+ case '/error':
142
+ default:
143
+ return Promise.resolve(new Response('An error has occurred.', { status: 500 }));
144
+ }
145
+ };
146
+ ```
147
+
148
+ Also, please make sure your mocks return a new `Response` instace every time. This is because responses are mutated when we parse their body, and they cannot be parsed a second time.
149
+
150
+ ```ts
151
+ const initialResponse = new Response(JSON.stringify(initialStep));
152
+ // ❌ wrong - the same instance is returned on each request
153
+ const mockFetcher = (input, init) => Promise.resolve(initialResponse);
154
+ ```
155
+
156
+ ```ts
157
+ // ✅ correct - a new instance is returned on each request
158
+ const mockFetcher = (input, init) => Promise.resolve(new Response(JSON.stringify(initialStep)));
159
+ ```
160
+
161
+ ### Telemetry
162
+
163
+ The `DynamicFlow` component accepts two optional props: `onEvent` and `onLog` which can be used to track and log.
140
164
 
141
165
  In the example below we send tracking events to Mixpanel and logging events to Rollbar.
142
166
 
143
167
  ```tsx
144
168
  <DynamicFlow
145
- onTrackableEvent={(event, props) => mixpanel.track(event, props)}
169
+ onEvent={(event, props) => mixpanel.track(event, props)}
146
170
  onLog={(level, message, extra) => Rollbar[level](message, extra)}
147
171
  />
148
172
  ```
@@ -150,7 +174,7 @@ In the example below we send tracking events to Mixpanel and logging events to R
150
174
  Alternatively, you can log to the browser console:
151
175
 
152
176
  ```ts
153
- onTrackableEvent={(event, props) => console.log(event, props)}
177
+ onEvent={(event, props) => console.log(event, props)}
154
178
  onLog={(level, message, extra) => {
155
179
  const levelToConsole = {
156
180
  critical: console.error,
@@ -183,8 +207,6 @@ type LoaderConfig = {
183
207
  | `initial` | boolean | Whether or not to display the Loader component while loading the initial step. | true |
184
208
  | `submission` | boolean | Whether or not to display the Loader component during form submissions. | false |
185
209
 
186
-
187
210
  ## Contributing
188
211
 
189
212
  We love contributions! Check out `CONTRIBUTING.md` for more information.
190
-
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export type EventName = 'Dynamic Flow - Flow Started' | 'Dynamic Flow - Flow Finished' | 'Dynamic Flow - Step Started' | 'Dynamic Flow - Step Submitted' | 'Dynamic Flow - Step Refreshed' | 'Dynamic Flow - OneOf Selected' | 'Dynamic Flow - PersistAsync' | 'Dynamic Flow - ValidationAsync' | 'Dynamic Flow - Camera Permission Denied' | 'Dynamic Flow - Camera Feed Started' | 'Dynamic Flow - Camera Not Supported' | 'Dynamic Flow - invalid submission response' | 'Dynamic Flow - onAction supressed' | 'Dynamic Flow - OneOf Searched';
3
+ export type EventHandler = (eventName: EventName, properties: Record<string, unknown>) => void;
4
+ type Props = {
5
+ metadata?: Record<string, unknown> & {
6
+ flowId?: string;
7
+ stepId?: string;
8
+ };
9
+ children: React.ReactNode;
10
+ onEvent: EventHandler;
11
+ };
12
+ export declare const EventsContextProvider: ({ metadata, children, onEvent }: Props) => JSX.Element;
13
+ export declare function useEventDispatcher(): EventHandler;
14
+ export declare const getEventDispatcher: (onEvent: EventHandler, metadata?: Record<string, unknown>) => EventHandler;
15
+ export {};
@@ -0,0 +1,33 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { createContext, useContext, useMemo } from 'react';
14
+ var EventsContext = createContext({
15
+ triggerEvent: function () {
16
+ // noop
17
+ }
18
+ });
19
+ export var EventsContextProvider = function (_a) {
20
+ var metadata = _a.metadata, children = _a.children, onEvent = _a.onEvent;
21
+ var value = useMemo(function () { return ({ triggerEvent: getEventDispatcher(onEvent, metadata) }); }, [onEvent, metadata]);
22
+ return _jsx(EventsContext.Provider, __assign({ value: value }, { children: children }));
23
+ };
24
+ export function useEventDispatcher() {
25
+ var triggerEvent = useContext(EventsContext).triggerEvent;
26
+ return triggerEvent;
27
+ }
28
+ export var getEventDispatcher = function (onEvent, metadata) {
29
+ return function (eventName, properties) {
30
+ if (properties === void 0) { properties = {}; }
31
+ return onEvent(eventName, __assign(__assign({}, metadata), properties));
32
+ };
33
+ };
@@ -0,0 +1 @@
1
+ export * from './EventsContext';
@@ -0,0 +1 @@
1
+ export * from './EventsContext';
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import { DynamicFlowProps } from './types';
3
2
  declare const DynamicFlow: (props: DynamicFlowProps) => JSX.Element;
4
3
  export default DynamicFlow;
@@ -49,9 +49,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
49
49
  import { useCallback, useEffect, useMemo, useState } from 'react';
50
50
  import { useIntl } from 'react-intl';
51
51
  import { DynamicFlowProvider } from '../common/contexts/dynamicFlowContext/dynamicFlowContext';
52
- import { FetcherProvider, makeFetcher } from '../common/contexts/fetcherContext';
52
+ import { getEventDispatcher, EventsContextProvider } from '../common/contexts/events';
53
+ import { FetcherProvider } from '../common/contexts/fetcherContext';
53
54
  import { LogProvider, getLogger } from '../common/logging';
54
- import { getTracker, TrackingContextProvider } from '../common/tracking';
55
55
  import { isValidSchema } from '../common/validation/schema-validators';
56
56
  import { isObjectModel } from '../dynamic-flow-types';
57
57
  import { DynamicFlowStep } from './DynamicFlowStep';
@@ -72,7 +72,7 @@ var noop = function () { };
72
72
  *
73
73
  */
74
74
  var DynamicFlowComponent = function (_a) {
75
- var flowId = _a.id, baseUrl = _a.baseUrl, propsFetcher = _a.fetcher, flowUrl = _a.flowUrl, initialAction = _a.initialAction, initialStep = _a.initialStep, loaderConfig = _a.loaderConfig, _b = _a.displayStepTitle, displayStepTitle = _b === void 0 ? true : _b, onClose = _a.onClose, _c = _a.onStepChange, onStepChange = _c === void 0 ? noop : _c, onError = _a.onError, _d = _a.onTrackableEvent, onTrackableEvent = _d === void 0 ? noop : _d, _e = _a.onLog, onLog = _e === void 0 ? noop : _e;
75
+ var flowId = _a.flowId, fetcher = _a.fetcher, flowUrl = _a.flowUrl, initialAction = _a.initialAction, initialStep = _a.initialStep, loaderConfig = _a.loaderConfig, _b = _a.displayStepTitle, displayStepTitle = _b === void 0 ? true : _b, onComplete = _a.onComplete, _c = _a.onStepChange, onStepChange = _c === void 0 ? noop : _c, onError = _a.onError, _d = _a.onEvent, onEvent = _d === void 0 ? noop : _d, _e = _a.onLog, onLog = _e === void 0 ? noop : _e;
76
76
  var locale = useIntl().locale;
77
77
  var _f = useDynamicFlowState(initialStep), formErrors = _f.formErrors, globalError = _f.globalError, step = _f.step, models = _f.models, etag = _f.etag, modelIsValid = _f.modelIsValid, setFormErrors = _f.setFormErrors, setGlobalError = _f.setGlobalError, setStepAndEtag = _f.setStepAndEtag, setSchemaModel = _f.setSchemaModel;
78
78
  var _g = useState(false), submitted = _g[0], setSubmitted = _g[1];
@@ -81,8 +81,7 @@ var DynamicFlowComponent = function (_a) {
81
81
  var logError = getLogger('error', onLog, flowId, step === null || step === void 0 ? void 0 : step.key);
82
82
  var logCritical = getLogger('critical', onLog, flowId, step === null || step === void 0 ? void 0 : step.key);
83
83
  var analyticsMetadata = useMemo(function () { var _a; return (__assign({ flowId: flowId, stepId: step === null || step === void 0 ? void 0 : step.key }, ((_a = step === null || step === void 0 ? void 0 : step.analytics) !== null && _a !== void 0 ? _a : {}))); }, [flowId, step]);
84
- var trackEvent = useMemo(function () { return getTracker(onTrackableEvent, analyticsMetadata); }, [onTrackableEvent, analyticsMetadata]);
85
- var fetcher = useMemo(function () { return propsFetcher || makeFetcher(baseUrl); }, [propsFetcher, baseUrl]);
84
+ var dispatchEvent = useMemo(function () { return getEventDispatcher(onEvent, analyticsMetadata); }, [onEvent, analyticsMetadata]);
86
85
  var triggerActionRequest = useCallback(function (_a) {
87
86
  var action = _a.action, data = _a.data, etag = _a.etag;
88
87
  var url = action.url, _b = action.method, method = _b === void 0 ? 'POST' : _b;
@@ -104,7 +103,7 @@ var DynamicFlowComponent = function (_a) {
104
103
  _a.label = 1;
105
104
  case 1:
106
105
  _a.trys.push([1, 3, , 4]);
107
- trackEvent('Dynamic Flow - Step Submitted', { actionId: action.$id });
106
+ dispatchEvent('Dynamic Flow - Step Submitted', { actionId: action.$id });
108
107
  return [4 /*yield*/, triggerActionRequest({ action: action, data: data })];
109
108
  case 2:
110
109
  response = _a.sent();
@@ -127,7 +126,7 @@ var DynamicFlowComponent = function (_a) {
127
126
  _a.label = 1;
128
127
  case 1:
129
128
  _a.trys.push([1, 4, , 5]);
130
- trackEvent('Dynamic Flow - Step Refreshed', { status: 'pending' });
129
+ dispatchEvent('Dynamic Flow - Step Refreshed', { status: 'pending' });
131
130
  return [4 /*yield*/, triggerActionRequest({ action: action, data: data, etag: etag })];
132
131
  case 2:
133
132
  response = _a.sent();
@@ -156,7 +155,7 @@ var DynamicFlowComponent = function (_a) {
156
155
  return [4 /*yield*/, parseExitResponse(response)];
157
156
  case 2:
158
157
  exitResult = _a.sent();
159
- onCloseWithTracking(__assign(__assign({}, exitResult), action.result));
158
+ onCloseWithEvent(__assign(__assign({}, exitResult), action.result));
160
159
  return [3 /*break*/, 4];
161
160
  case 3:
162
161
  error_3 = _a.sent();
@@ -167,16 +166,16 @@ var DynamicFlowComponent = function (_a) {
167
166
  });
168
167
  }); };
169
168
  var debouncedFetchRefresh = useDebouncedRefresh(fetchRefreshStep);
170
- var onCloseWithTracking = useCallback(function (result) {
171
- trackEvent('Dynamic Flow - Flow Finished', { result: 'success' });
172
- onClose(result);
173
- }, [onClose, trackEvent]);
169
+ var onCloseWithEvent = useCallback(function (result) {
170
+ dispatchEvent('Dynamic Flow - Flow Finished', { result: 'success' });
171
+ onComplete(result);
172
+ }, [onComplete, dispatchEvent]);
174
173
  useEffect(function () {
175
- trackEvent('Dynamic Flow - Flow Started', {});
174
+ dispatchEvent('Dynamic Flow - Flow Started', {});
176
175
  }, []);
177
176
  useEffect(function () {
178
177
  if (!initialStep) {
179
- var action = __assign({ $id: '#initial-step-request', method: 'GET', url: flowUrl }, initialAction);
178
+ var action = __assign({ $id: '#initial-step-request', method: 'GET' }, initialAction);
180
179
  void fetchNextStep(action, action.data);
181
180
  }
182
181
  }, [flowUrl, fetcher, locale, JSON.stringify(initialStep), JSON.stringify(initialAction)]);
@@ -197,7 +196,7 @@ var DynamicFlowComponent = function (_a) {
197
196
  void fetchNextStep(parsedResponse.action, parsedResponse.action.data);
198
197
  return [2 /*return*/];
199
198
  case 'exit':
200
- return [2 /*return*/, onCloseWithTracking(parsedResponse.result)];
199
+ return [2 /*return*/, onCloseWithEvent(parsedResponse.result)];
201
200
  case 'step':
202
201
  default: {
203
202
  step_1 = parsedResponse.step, etag_1 = parsedResponse.etag;
@@ -220,12 +219,12 @@ var DynamicFlowComponent = function (_a) {
220
219
  onStepChange(newStep, previousStep);
221
220
  setSubmitted(false);
222
221
  setLoadingState('idle');
223
- trackEvent('Dynamic Flow - Step Started', __assign({ stepId: newStep.key }, newStep === null || newStep === void 0 ? void 0 : newStep.analytics));
222
+ dispatchEvent('Dynamic Flow - Step Started', __assign({ stepId: newStep.key }, newStep === null || newStep === void 0 ? void 0 : newStep.analytics));
224
223
  };
225
224
  var updateStepAfterRefresh = function (step, etag) {
226
225
  setStepAndEtag(step, etag);
227
226
  setLoadingState('idle');
228
- trackEvent('Dynamic Flow - Step Refreshed', { status: 'success' });
227
+ dispatchEvent('Dynamic Flow - Step Refreshed', { status: 'success' });
229
228
  };
230
229
  var handleErrorResponse = function (response, fetchType) { return __awaiter(void 0, void 0, void 0, function () {
231
230
  var errorBody, action, error_5;
@@ -263,9 +262,9 @@ var DynamicFlowComponent = function (_a) {
263
262
  case 5:
264
263
  error_5 = _a.sent();
265
264
  if (fetchType === 'refresh') {
266
- trackEvent('Dynamic Flow - Step Refreshed', { status: 'failure' });
265
+ dispatchEvent('Dynamic Flow - Step Refreshed', { status: 'failure' });
267
266
  }
268
- trackEvent('Dynamic Flow - Flow Finished', { status: 'failure' });
267
+ dispatchEvent('Dynamic Flow - Flow Finished', { status: 'failure' });
269
268
  onError(error_5, response.status);
270
269
  logError('Invalid response', 'Error response body must be an object.');
271
270
  return [3 /*break*/, 6];
@@ -337,7 +336,7 @@ var DynamicFlowComponent = function (_a) {
337
336
  _a.label = 5;
338
337
  case 5: return [2 /*return*/];
339
338
  case 6:
340
- onCloseWithTracking(result);
339
+ onCloseWithEvent(result);
341
340
  return [2 /*return*/];
342
341
  case 7:
343
342
  if (isSubmissionMethod(method)) {
@@ -347,7 +346,7 @@ var DynamicFlowComponent = function (_a) {
347
346
  void fetchNextStep(action, submissionData);
348
347
  }
349
348
  else {
350
- trackEvent('Dynamic Flow - onAction supressed', __assign({ reason: 'invalid model' }, extraLoggingProps));
349
+ dispatchEvent('Dynamic Flow - onAction supressed', __assign({ reason: 'invalid model' }, extraLoggingProps));
351
350
  }
352
351
  return [2 /*return*/];
353
352
  }
@@ -356,7 +355,7 @@ var DynamicFlowComponent = function (_a) {
356
355
  }
357
356
  });
358
357
  }); };
359
- return (_jsx(LogProvider, __assign({ flowId: flowId, stepId: step === null || step === void 0 ? void 0 : step.key, onLog: onLog }, { children: _jsx(TrackingContextProvider, __assign({ metadata: analyticsMetadata, onTrackableEvent: onTrackableEvent }, { children: _jsx(DynamicFlowProvider, __assign({ loading: loadingState !== 'idle' }, { children: _jsx(FetcherProvider, __assign({ fetcher: fetcher }, { children: loader !== null ? (loader) : (_jsx(DynamicFlowStep, { step: step, model: combineModels(models), submitted: submitted, globalError: globalError, formErrors: formErrors, stepLayoutOptions: { displayStepTitle: displayStepTitle }, onAction: function (action) {
358
+ return (_jsx(LogProvider, __assign({ flowId: flowId, stepId: step === null || step === void 0 ? void 0 : step.key, onLog: onLog }, { children: _jsx(EventsContextProvider, __assign({ metadata: analyticsMetadata, onEvent: onEvent }, { children: _jsx(DynamicFlowProvider, __assign({ loading: loadingState !== 'idle' }, { children: _jsx(FetcherProvider, __assign({ fetcher: fetcher }, { children: loader !== null ? (loader) : (_jsx(DynamicFlowStep, { step: step, model: combineModels(models), submitted: submitted, globalError: globalError, formErrors: formErrors, stepLayoutOptions: { displayStepTitle: displayStepTitle }, onAction: function (action) {
360
359
  void onAction(action);
361
360
  }, onModelChange: onModelChange })) })) })) })) })));
362
361
  };
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import { GlobalError, Step } from '../dynamic-flow-types';
3
2
  import { LayoutStepProps } from '../step/layoutStep/LayoutStep';
4
3
  type DynamicFlowStepProps = Omit<LayoutStepProps, 'stepSpecification'> & {
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  type Props = {
3
2
  onDismiss: () => void;
4
3
  };
@@ -2,7 +2,7 @@ import { ActionResponseBody, ErrorResponseBody, Step } from '../../dynamic-flow-
2
2
  import { DynamicFlowProps } from '../types';
3
3
  type ParsedBody = {
4
4
  type: 'exit';
5
- result: Parameters<DynamicFlowProps['onClose']>[0];
5
+ result: Parameters<DynamicFlowProps['onComplete']>[0];
6
6
  } | {
7
7
  type: 'action';
8
8
  action: ActionResponseBody['action'];
@@ -13,5 +13,5 @@ type ParsedBody = {
13
13
  };
14
14
  export declare const parseFetchResponse: (response: Response) => Promise<ParsedBody>;
15
15
  export declare const parseErrorResponse: (response: Response) => Promise<ErrorResponseBody>;
16
- export declare const parseExitResponse: (response: Response) => Promise<Parameters<DynamicFlowProps['onClose']>[0]>;
16
+ export declare const parseExitResponse: (response: Response) => Promise<Parameters<DynamicFlowProps['onComplete']>[0]>;
17
17
  export {};
@@ -42,11 +42,12 @@ export var parseFetchResponse = function (response) { return __awaiter(void 0, v
42
42
  return __generator(this, function (_c) {
43
43
  switch (_c.label) {
44
44
  case 0:
45
+ assertResponseIsValid(response);
45
46
  if (!((_b = response.headers) === null || _b === void 0 ? void 0 : _b.has('X-Df-Exit'))) return [3 /*break*/, 2];
46
47
  _a = { type: 'exit' };
47
48
  return [4 /*yield*/, parseExitResponse(response)];
48
49
  case 1: return [2 /*return*/, (_a.result = _c.sent(), _a)];
49
- case 2: return [4 /*yield*/, parseResponseJson(response.clone())];
50
+ case 2: return [4 /*yield*/, parseResponseJson(response)];
50
51
  case 3:
51
52
  jsonBody = _c.sent();
52
53
  if (!isObject(jsonBody)) {
@@ -71,7 +72,9 @@ export var parseErrorResponse = function (response) { return __awaiter(void 0, v
71
72
  var jsonBody;
72
73
  return __generator(this, function (_a) {
73
74
  switch (_a.label) {
74
- case 0: return [4 /*yield*/, parseResponseJson(response.clone())];
75
+ case 0:
76
+ assertResponseIsValid(response);
77
+ return [4 /*yield*/, parseResponseJson(response)];
75
78
  case 1:
76
79
  jsonBody = _a.sent();
77
80
  if (!isObject(jsonBody)) {
@@ -85,7 +88,9 @@ export var parseExitResponse = function (response) { return __awaiter(void 0, vo
85
88
  var result;
86
89
  return __generator(this, function (_a) {
87
90
  switch (_a.label) {
88
- case 0: return [4 /*yield*/, parseResponseJson(response.clone())];
91
+ case 0:
92
+ assertResponseIsValid(response);
93
+ return [4 /*yield*/, parseResponseJson(response)];
89
94
  case 1:
90
95
  result = _a.sent();
91
96
  if (isObject(result) || result === null) {
@@ -110,3 +115,11 @@ var parseResponseJson = function (response) { return __awaiter(void 0, void 0, v
110
115
  }
111
116
  });
112
117
  }); };
118
+ var assertResponseIsValid = function (response) {
119
+ if (!(response instanceof Response)) {
120
+ throw new Error('Incorrect type of response from fetch. Expected object of type Response.');
121
+ }
122
+ if (response.bodyUsed) {
123
+ throw new Error('The body of the provided Response object has already been used. Every request must respond with a new Response object.');
124
+ }
125
+ };
@@ -15,7 +15,7 @@ allStepNames.forEach(function (stepName) {
15
15
  if (!storyMap[group]) {
16
16
  storyMap[group] = storiesOf("Dynamic Flow/".concat(group), module);
17
17
  }
18
- storyMap[group].add(name, function () { return (_jsx(DynamicFlow, { id: "storybook", initialAction: { method: 'GET', url: "/steps/".concat(stepName) }, fetcher: fixtureFetcher, loaderConfig: { size: 'xl', initial: true, submission: false }, onClose: action('onClose'), onStepChange: action('onStepChange'), onError: action('onError'), onTrackableEvent: action('onTrackableEvent'), onLog: action('onLog') }, stepName)); });
18
+ storyMap[group].add(name, function () { return (_jsx(DynamicFlow, { flowId: "storybook", initialAction: { method: 'GET', url: "/steps/".concat(stepName) }, fetcher: fixtureFetcher, loaderConfig: { size: 'xl', initial: true, submission: false }, onComplete: action('onComplete'), onStepChange: action('onStepChange'), onError: action('onError'), onEvent: action('onEvent'), onLog: action('onLog') }, stepName)); });
19
19
  });
20
20
  var editable = storiesOf("Dynamic Flow/Editable", module);
21
21
  editable.add('Dynamic Flow', EditableDynamicFlow, {
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  declare const EditableDynamicFlow: ({ initialStepName }: {
3
2
  initialStepName?: string | undefined;
4
3
  }) => JSX.Element;
@@ -28,7 +28,7 @@ var InteractiveDemo = function (_a) {
28
28
  var onTextAreaChange = function (event) {
29
29
  setInitialStep(event.target.value);
30
30
  };
31
- return (_jsxs("div", __assign({ style: { display: 'flex', gap: '1em' } }, { children: [_jsxs("div", __assign({ style: { flexBasis: '50%' } }, { children: [_jsx("h3", { children: "Editable Demo" }), _jsxs("p", { children: ["You can select an initial step from the drop down in the controls panel.", _jsx("br", {}), "You can edit the JSON below and see the result on the right."] }), _jsx("textarea", { wrap: "off", rows: 40, style: { fontFamily: 'monospace', fontSize: '0.9em', width: '100%' }, value: initialStep, onChange: onTextAreaChange })] })), _jsx("div", __assign({ style: { flexBasis: '50%' } }, { children: _jsx(DynamicFlow, { initialStep: safeParseStepJson(initialStep), fetcher: fixtureFetcher, onClose: action('onClose'), onStepChange: action('onStepChange'), onError: action('onError'), onTrackableEvent: action('onTrackableEvent'), onLog: action('onLog') }, initialStep) }))] })));
31
+ return (_jsxs("div", __assign({ style: { display: 'flex', gap: '1em' } }, { children: [_jsxs("div", __assign({ style: { flexBasis: '50%' } }, { children: [_jsx("h3", { children: "Editable Demo" }), _jsxs("p", { children: ["You can select an initial step from the drop down in the controls panel.", _jsx("br", {}), "You can edit the JSON below and see the result on the right."] }), _jsx("textarea", { wrap: "off", rows: 40, style: { fontFamily: 'monospace', fontSize: '0.9em', width: '100%' }, value: initialStep, onChange: onTextAreaChange })] })), _jsx("div", __assign({ style: { flexBasis: '50%' } }, { children: _jsx(DynamicFlow, { flowId: "the-flow-id", initialStep: safeParseStepJson(initialStep), fetcher: fixtureFetcher, onComplete: action('onComplete'), onStepChange: action('onStepChange'), onError: action('onError'), onEvent: action('onEvent'), onLog: action('onLog') }, initialStep) }))] })));
32
32
  };
33
33
  function safeParseStepJson(jsonStep) {
34
34
  try {
@@ -1,25 +1,18 @@
1
+ import { EventHandler } from '../common/contexts/events';
1
2
  import { LogEventHandler } from '../common/logging';
2
- import { TrackableEventHandler } from '../common/tracking';
3
3
  import { Action, FormLayout, Schema, Size, Step } from '../dynamic-flow-types';
4
4
  import { OnChangeProps } from '../jsonSchemaForm/JsonSchemaForm';
5
5
  export type DynamicFlowPropsBasic = {
6
- id?: string;
6
+ flowId: string;
7
7
  loaderConfig?: LoaderConfig;
8
8
  displayStepTitle?: boolean;
9
- onClose: (result: Record<string, unknown> | undefined | null) => void;
9
+ fetcher: Fetcher;
10
+ onComplete: (result: Record<string, unknown> | undefined | null) => void;
10
11
  onStepChange?: (newStep: Step, previousStep: Step | undefined) => void;
11
12
  onError: (error: unknown, status?: number) => void;
12
- onTrackableEvent?: TrackableEventHandler;
13
+ onEvent?: EventHandler;
13
14
  onLog?: LogEventHandler;
14
15
  };
15
- type DynamicFlowPropsWithBaseUrl = {
16
- baseUrl: string;
17
- fetcher?: never;
18
- };
19
- type DynamicFlowPropsWithFetcher = {
20
- baseUrl?: never;
21
- fetcher: Fetcher;
22
- };
23
16
  type DynamicFlowPropsWithInitialAction = {
24
17
  initialAction: InitialAction;
25
18
  initialStep?: never;
@@ -30,25 +23,7 @@ type DynamicFlowPropsWithInitialStep = {
30
23
  initialStep: Step;
31
24
  flowUrl?: never;
32
25
  };
33
- type DynamicFlowPropsWithFlowUrl = {
34
- initialAction?: never;
35
- initialStep?: never;
36
- /** @deprecated Use initialAction instead */
37
- flowUrl: string;
38
- };
39
- export type DynamicFlowProps = DynamicFlowPropsBasic & (DynamicFlowPropsWithBaseUrl | DynamicFlowPropsWithFetcher) & (DynamicFlowPropsWithInitialAction | DynamicFlowPropsWithInitialStep | DynamicFlowPropsWithFlowUrl);
40
- /** @deprecated Use DynamicFlowProps instead */
41
- export type DynamicFlowV3Props = DynamicFlowProps;
42
- /** @deprecated Use DynamicFlowPropsWithBaseUrl instead */
43
- export type DynamicFlowV3PropsWithBaseUrl = DynamicFlowPropsWithBaseUrl;
44
- /** @deprecated Use DynamicFlowPropsWithFetcher instead */
45
- export type DynamicFlowV3PropsWithFetcher = DynamicFlowPropsWithFetcher;
46
- /** @deprecated Use DynamicFlowPropsWithInitialAction instead */
47
- export type DynamicFlowV3PropsWithFlowUrl = DynamicFlowPropsWithInitialAction;
48
- /** @deprecated Use DynamicFlowPropsWithInitialStep instead */
49
- export type DynamicFlowV3PropsWithInitialStep = DynamicFlowPropsWithInitialStep;
50
- /** @deprecated Use DynamicFlowPropsBasic instead */
51
- export type DynamicFlowV3PropsBasic = DynamicFlowPropsBasic;
26
+ export type DynamicFlowProps = DynamicFlowPropsBasic & (DynamicFlowPropsWithInitialAction | DynamicFlowPropsWithInitialStep);
52
27
  export declare function isSchema(schema: FormLayout['schema']): schema is Schema;
53
28
  export type Fetcher = typeof fetch;
54
29
  export type ETag = string;
@@ -15,7 +15,7 @@
15
15
  "dynamicFlows.ControlFeedback.minLength": "Bitte gib mindestens {minLength} Zeichen ein.",
16
16
  "dynamicFlows.ControlFeedback.minimum": "Bitte gib eine Zahl ein, die {minimum} oder mehr beträgt.",
17
17
  "dynamicFlows.ControlFeedback.minimumDate": "Bitte gib ein Datum ein, das am oder nach dem {minimum} liegt.",
18
- "dynamicFlows.ControlFeedback.pattern": "Falsches Format",
18
+ "dynamicFlows.ControlFeedback.pattern": "Bitte gib die Angabe im richtigen Format ein.",
19
19
  "dynamicFlows.ControlFeedback.patternDate": "Bitte gib ein Datum im richtigen Format ein.",
20
20
  "dynamicFlows.ControlFeedback.required": "Bitte fülle dieses Feld aus.",
21
21
  "dynamicFlows.ControlFeedback.type": "Falscher Typ",
@@ -24,6 +24,10 @@
24
24
  "dynamicFlows.DynamicParagraph.copy": "Kopieren",
25
25
  "dynamicFlows.ErrorBoundary.errorAlert": "Hoppla – da ist was schiefgelaufen...",
26
26
  "dynamicFlows.ErrorBoundary.retry": "Erneut versuchen",
27
+ "dynamicFlows.ExternalConfirmation.cancel": "Abbrechen",
28
+ "dynamicFlows.ExternalConfirmation.description": "Bitte bestätige, dass du **{origin}** in einem neuen Browser-Tab öffnen möchtest.",
29
+ "dynamicFlows.ExternalConfirmation.open": "In neuem Tab öffnen",
30
+ "dynamicFlows.ExternalConfirmation.title": "Bitte bestätigen",
27
31
  "dynamicFlows.Help.ariaLabel": "Klicke hier für mehr Informationen.",
28
32
  "dynamicFlows.MultipleFileUploadSchema.maxFileSizeError": "Diese Datei ist leider zu groß. Bitte lade eine kleinere Datei hoch.",
29
33
  "dynamicFlows.MultipleFileUploadSchema.maxItemsError": "Bitte lade {maxItems} oder weniger Dateien hoch.",
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "dynamicFlows.ArraySchema.maxItemsError": "Añade {maxItems} o menos.",
3
3
  "dynamicFlows.ArraySchema.minItemsError": "Añade al menos {minItems}.",
4
- "dynamicFlows.CameraCapture.CameraNotSupported.paragraph": "El navegador que estás utilizando no es compatible con una cámara. Prueba con otro navegador o dispositivo o descarga nuestra aplicación móvil.",
4
+ "dynamicFlows.CameraCapture.CameraNotSupported.paragraph": "El navegador que estás utilizando no es compatible con una cámara. Prueba con otro navegador, dispositivo o descarga nuestra app móvil.",
5
5
  "dynamicFlows.CameraCapture.CameraNotSupported.title": "Cámara no compatible",
6
- "dynamicFlows.CameraCapture.NoCameraAccess.action": "Permitir acceso a la cámara",
6
+ "dynamicFlows.CameraCapture.NoCameraAccess.action": "Habilitar acceso a la cámara",
7
7
  "dynamicFlows.CameraCapture.NoCameraAccess.paragraph": "Habilita el acceso a la cámara en la configuración de tu navegador para volver a activarla.",
8
8
  "dynamicFlows.CameraCapture.NoCameraAccess.title": "No podemos acceder a tu cámara",
9
9
  "dynamicFlows.CameraCapture.reviewInstructions": "¿Tu foto es clara, legible y completa?",
@@ -24,11 +24,15 @@
24
24
  "dynamicFlows.DynamicParagraph.copy": "Copiar",
25
25
  "dynamicFlows.ErrorBoundary.errorAlert": "Vaya. Algo ha salido mal...",
26
26
  "dynamicFlows.ErrorBoundary.retry": "Reintentar",
27
+ "dynamicFlows.ExternalConfirmation.cancel": "Cancelar",
28
+ "dynamicFlows.ExternalConfirmation.description": "Confirma que quieres abrir **{origin}** en una nueva pestaña del navegador.",
29
+ "dynamicFlows.ExternalConfirmation.open": "Abrir en nueva pestaña",
30
+ "dynamicFlows.ExternalConfirmation.title": "Por favor, confirma",
27
31
  "dynamicFlows.Help.ariaLabel": "Haz clic aquí para obtener más información.",
28
32
  "dynamicFlows.MultipleFileUploadSchema.maxFileSizeError": "Lo sentimos, el archivo pesa demasiado. Sube uno más pequeño.",
29
33
  "dynamicFlows.MultipleFileUploadSchema.maxItemsError": "Sube {maxItems} o menos archivos.",
30
34
  "dynamicFlows.MultipleFileUploadSchema.minItemsError": "Sube al menos {minItems} archivo(s).",
31
- "dynamicFlows.PersistAsyncSchema.genericError": "Algo ha ido mal. Vuelve a intentarlo más tarde.",
35
+ "dynamicFlows.PersistAsyncSchema.genericError": "Algo ha ido mal. Inténtalo de nuevo más tarde.",
32
36
  "dynamicFlows.ReadOnlySchema.no": "No",
33
37
  "dynamicFlows.ReadOnlySchema.yes": "Sí"
34
38
  }
@@ -1,29 +1,33 @@
1
1
  {
2
2
  "dynamicFlows.ArraySchema.maxItemsError": "Veuillez ajouter {maxItems} ou moins.",
3
3
  "dynamicFlows.ArraySchema.minItemsError": "Veuillez ajouter au moins {minItems}.",
4
- "dynamicFlows.CameraCapture.CameraNotSupported.paragraph": "Le navigateur que vous utilisez ne prend pas en charge l'appareil photo. Veuillez essayer un autre navigateur, un autre appareil ou télécharger notre appli",
4
+ "dynamicFlows.CameraCapture.CameraNotSupported.paragraph": "Le navigateur que vous utilisez ne prend pas en charge l'appareil photo. Veuillez essayer un autre navigateur, un autre appareil ou télécharger notre appli.",
5
5
  "dynamicFlows.CameraCapture.CameraNotSupported.title": "Appareil photo non pris en charge",
6
6
  "dynamicFlows.CameraCapture.NoCameraAccess.action": "Autoriser l'accès à l'appareil photo",
7
7
  "dynamicFlows.CameraCapture.NoCameraAccess.paragraph": "Autorisez l'accès à l'appareil photo depuis les paramètres de votre navigateur.",
8
8
  "dynamicFlows.CameraCapture.NoCameraAccess.title": "Nous n'avons pas accès à votre appareil photo",
9
9
  "dynamicFlows.CameraCapture.reviewInstructions": "Votre image est-elle claire, lisible et dans son intégralité ?",
10
- "dynamicFlows.CameraCapture.reviewRetry": "Non, veuillez réessayer",
10
+ "dynamicFlows.CameraCapture.reviewRetry": "Non, réessayer",
11
11
  "dynamicFlows.CameraCapture.reviewSubmit": "Oui, confirmer",
12
12
  "dynamicFlows.ControlFeedback.maxLength": "Veuillez saisir {maxLength} caractères ou moins.",
13
13
  "dynamicFlows.ControlFeedback.maximum": "Veuillez saisir un nombre inférieur ou égal à {maximum}.",
14
14
  "dynamicFlows.ControlFeedback.maximumDate": "Veuillez saisir une date égale ou antérieure au {maximum}.",
15
- "dynamicFlows.ControlFeedback.minLength": "Veuillez saisir {minLength} caractères minimum.",
15
+ "dynamicFlows.ControlFeedback.minLength": "Veuillez saisir au moins {minLength} caractères.",
16
16
  "dynamicFlows.ControlFeedback.minimum": "Veuillez saisir un nombre supérieur ou égal à {minimum}.",
17
17
  "dynamicFlows.ControlFeedback.minimumDate": "Veuillez saisir une date égale ou postérieure au {minimum}.",
18
18
  "dynamicFlows.ControlFeedback.pattern": "Veuillez saisir les informations dans le bon format.",
19
19
  "dynamicFlows.ControlFeedback.patternDate": "Veuillez saisir une date au format correct.",
20
- "dynamicFlows.ControlFeedback.required": "Veuillez remplir ce champ.",
20
+ "dynamicFlows.ControlFeedback.required": "Champ obligatoire.",
21
21
  "dynamicFlows.ControlFeedback.type": "Type incorrect",
22
22
  "dynamicFlows.DynamicExternal.retryTitle": "Rouvrir la fenêtre",
23
23
  "dynamicFlows.DynamicParagraph.copied": "Copié dans le presse-papier",
24
24
  "dynamicFlows.DynamicParagraph.copy": "Copier",
25
- "dynamicFlows.ErrorBoundary.errorAlert": "Oups ! Quelque chose n'a pas fonctionné...",
25
+ "dynamicFlows.ErrorBoundary.errorAlert": "Oups ! Une erreur s'est produite...",
26
26
  "dynamicFlows.ErrorBoundary.retry": "Réessayer",
27
+ "dynamicFlows.ExternalConfirmation.cancel": "Annuler",
28
+ "dynamicFlows.ExternalConfirmation.description": "Veuillez confirmer que vous souhaitez ouvrir **{origin}** dans un nouvel onglet.",
29
+ "dynamicFlows.ExternalConfirmation.open": "Ouvrir dans un nouvel onglet",
30
+ "dynamicFlows.ExternalConfirmation.title": "Veuillez confirmer",
27
31
  "dynamicFlows.Help.ariaLabel": "Cliquez ici pour plus d'informations.",
28
32
  "dynamicFlows.MultipleFileUploadSchema.maxFileSizeError": "Nous sommes désolés, ce fichier est trop volumineux. Veuillez télécharger un fichier plus petit.",
29
33
  "dynamicFlows.MultipleFileUploadSchema.maxItemsError": "Veuillez télécharger {maxItems} fichiers ou moins.",