@wise/dynamic-flow-client 5.10.0 → 5.11.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/build/controller/FlowController.js +1 -0
- package/build/domain/components/step/ExternalConfirmationComponent.js +5 -9
- package/build/domain/mappers/mapStepToComponent.js +1 -1
- package/build/domain/mappers/schema/blobSchemaToComponent.js +2 -2
- package/build/domain/mappers/schema/tests/test-utils.js +1 -1
- package/build/i18n/fr.json +1 -1
- package/build/main.css +4 -0
- package/build/main.js +17 -16
- package/build/main.mjs +17 -16
- package/build/renderers/mappers/externalComponentToProps.js +1 -1
- package/build/stories/spec/step/ScrollToBottom.story.js +103 -0
- package/build/test-utils/DynamicFlowWise.js +1 -1
- package/build/test-utils/DynamicFlowWiseModal.js +1 -1
- package/build/test-utils/openLinkInNewTab.js +15 -0
- package/build/tests/ScrollToBottom.test.js +122 -0
- package/build/tests/SingleFileUpload.test.js +81 -1
- package/build/types/controller/FlowController.d.ts +0 -1
- package/build/types/controller/FlowController.d.ts.map +1 -1
- package/build/types/domain/components/step/ExternalConfirmationComponent.d.ts +2 -3
- package/build/types/domain/components/step/ExternalConfirmationComponent.d.ts.map +1 -1
- package/build/types/domain/mappers/mapStepToComponent.d.ts.map +1 -1
- package/build/types/domain/mappers/schema/types.d.ts +1 -0
- package/build/types/domain/mappers/schema/types.d.ts.map +1 -1
- package/build/types/renderers/mappers/externalComponentToProps.d.ts.map +1 -1
- package/build/types/test-utils/openLinkInNewTab.d.ts.map +1 -0
- package/package.json +7 -7
- package/build/types/utils/openLinkInNewTab.d.ts.map +0 -1
- package/build/utils/openLinkInNewTab.js +0 -10
- /package/build/types/{utils → test-utils}/openLinkInNewTab.d.ts +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getInputUpdateFunction } from '../utils/component-utils';
|
|
2
|
-
export const createExternalConfirmation = (uid, url, onComponentUpdate) => {
|
|
2
|
+
export const createExternalConfirmation = (uid, url, onLink, onComponentUpdate) => {
|
|
3
3
|
const update = getInputUpdateFunction(onComponentUpdate);
|
|
4
4
|
return {
|
|
5
5
|
type: 'external-confirmation',
|
|
@@ -7,15 +7,11 @@ export const createExternalConfirmation = (uid, url, onComponentUpdate) => {
|
|
|
7
7
|
uid,
|
|
8
8
|
url,
|
|
9
9
|
status: 'initial',
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
});
|
|
14
|
-
},
|
|
15
|
-
onFailure() {
|
|
16
|
-
if (this.status === 'initial') {
|
|
10
|
+
open() {
|
|
11
|
+
if (this.status === 'initial' || this.status === 'failure') {
|
|
12
|
+
const success = onLink(this.url);
|
|
17
13
|
update(this, (draft) => {
|
|
18
|
-
draft.status = 'failure';
|
|
14
|
+
draft.status = success ? 'success' : 'failure';
|
|
19
15
|
});
|
|
20
16
|
}
|
|
21
17
|
},
|
|
@@ -57,7 +57,7 @@ export const mapStepToComponent = (_a) => {
|
|
|
57
57
|
: undefined;
|
|
58
58
|
const stepPrefetch = getStepPrefetch(restProps.httpClient, flowRequestCache, submissionBehaviors);
|
|
59
59
|
const externalConfirmation = (external === null || external === void 0 ? void 0 : external.url)
|
|
60
|
-
? createExternalConfirmation(`${uid}-external-confirmation`, external === null || external === void 0 ? void 0 : external.url, onComponentUpdate)
|
|
60
|
+
? createExternalConfirmation(`${uid}-external-confirmation`, external === null || external === void 0 ? void 0 : external.url, restProps.onLink, onComponentUpdate)
|
|
61
61
|
: undefined;
|
|
62
62
|
const mapperProps = Object.assign(Object.assign({}, restProps), { features,
|
|
63
63
|
trackEvent,
|
|
@@ -3,12 +3,12 @@ import { createUploadInputComponent } from '../../components/UploadInputComponen
|
|
|
3
3
|
import { getRequiredCheck } from '../../features/validation/value-checks';
|
|
4
4
|
import { mapCommonSchemaProps } from './utils/mapCommonSchemaProps';
|
|
5
5
|
export const blobSchemaToComponent = (schemaMapperProps, mapperProps) => {
|
|
6
|
-
const { schema, localValue, required = false, onPersistAsync } = schemaMapperProps;
|
|
6
|
+
const { schema, localValue, model, required = false, onPersistAsync } = schemaMapperProps;
|
|
7
7
|
const { accepts, cameraConfig, maxSize, source, validationMessages } = schema;
|
|
8
8
|
const { getErrorMessageFunctions, onComponentUpdate, onValueChange } = mapperProps;
|
|
9
9
|
const errorMessageFunctions = getErrorMessageFunctions(validationMessages);
|
|
10
10
|
const validLocalValue = isFile(localValue) ? localValue : null;
|
|
11
|
-
const value = onPersistAsync ? validLocalValue : null;
|
|
11
|
+
const value = onPersistAsync && model !== null ? validLocalValue : null;
|
|
12
12
|
return createUploadInputComponent(Object.assign(Object.assign({}, mapCommonSchemaProps(schemaMapperProps)), { accepts, autoComplete: 'off', cameraConfig, format: 'blob', maxSize,
|
|
13
13
|
source,
|
|
14
14
|
value, checks: schema.hidden ? [] : [getRequiredCheck(required, errorMessageFunctions)], schemaOnChange: undefined, onValueChange }), onComponentUpdate);
|
|
@@ -4,7 +4,7 @@ import { mockErrorMessageFunctions } from '../../../features/validation/spec-uti
|
|
|
4
4
|
import { FeatureFlags } from '../../utils/FeatureFlags';
|
|
5
5
|
import { makeRequestCache } from '../../../features/prefetch/request-cache';
|
|
6
6
|
export const getStepMapperProps = () => (Object.assign(Object.assign({}, getMockMapperProps()), { uid: 'root', flowRequestCache: makeRequestCache(), etag: null, loadingState: 'idle', trackEvent: vi.fn(), onPoll: vi.fn() }));
|
|
7
|
-
export const getMockMapperProps = (mapperProps = {}) => (Object.assign({ step: {}, stepLocalValue: null, features: new FeatureFlags({}), onComponentUpdate: vi.fn(), onBehavior: vi.fn(), onValueChange: vi.fn(), getErrorMessageFunctions: vi.fn().mockReturnValue(mockErrorMessageFunctions), trackEvent: vi.fn(), logEvent: vi.fn(), httpClient: vi.fn(), registerSubmissionBehavior: vi.fn() }, mapperProps));
|
|
7
|
+
export const getMockMapperProps = (mapperProps = {}) => (Object.assign({ step: {}, stepLocalValue: null, features: new FeatureFlags({}), onComponentUpdate: vi.fn(), onBehavior: vi.fn(), onLink: vi.fn(), onValueChange: vi.fn(), getErrorMessageFunctions: vi.fn().mockReturnValue(mockErrorMessageFunctions), trackEvent: vi.fn(), logEvent: vi.fn(), httpClient: vi.fn(), registerSubmissionBehavior: vi.fn() }, mapperProps));
|
|
8
8
|
export const getMockSchemaMapperProps = (schemaMapperProps) => (Object.assign({ uid: getRandomId(), localValue: null, model: null, required: false, validationErrors: null }, schemaMapperProps));
|
|
9
9
|
export const getMockRendererMapperProps = () => ({
|
|
10
10
|
render: vi.fn(),
|
package/build/i18n/fr.json
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dynamicFlows.ExternalConfirmation.open": "Ouvrir dans un nouvel onglet",
|
|
25
25
|
"dynamicFlows.ExternalConfirmation.title": "Veuillez confirmer",
|
|
26
26
|
"dynamicFlows.FileUploadSchema.maxFileSizeError": "Nous sommes désolés, ce fichier est trop volumineux. Veuillez télécharger un fichier plus petit.",
|
|
27
|
-
"dynamicFlows.FileUploadSchema.wrongFileTypeError": "
|
|
27
|
+
"dynamicFlows.FileUploadSchema.wrongFileTypeError": "Désolé, ce format de fichier n'est pas pris en charge. Veuillez en importer un autre.",
|
|
28
28
|
"dynamicFlows.Help.ariaLabel": "Cliquez ici pour plus d'informations.",
|
|
29
29
|
"dynamicFlows.MultiSelect.summary": "{first} et {count} de plus",
|
|
30
30
|
"dynamicFlows.MultipleFileUploadSchema.maxFileSizeError": "Nous sommes désolés, ce fichier est trop volumineux. Veuillez télécharger un fichier plus petit.",
|
package/build/main.css
CHANGED
package/build/main.js
CHANGED
|
@@ -266,7 +266,7 @@ var fr_default = {
|
|
|
266
266
|
"dynamicFlows.ExternalConfirmation.open": "Ouvrir dans un nouvel onglet",
|
|
267
267
|
"dynamicFlows.ExternalConfirmation.title": "Veuillez confirmer",
|
|
268
268
|
"dynamicFlows.FileUploadSchema.maxFileSizeError": "Nous sommes d\xE9sol\xE9s, ce fichier est trop volumineux. Veuillez t\xE9l\xE9charger un fichier plus petit.",
|
|
269
|
-
"dynamicFlows.FileUploadSchema.wrongFileTypeError": "
|
|
269
|
+
"dynamicFlows.FileUploadSchema.wrongFileTypeError": "D\xE9sol\xE9, ce format de fichier n'est pas pris en charge. Veuillez en importer un autre.",
|
|
270
270
|
"dynamicFlows.Help.ariaLabel": "Cliquez ici pour plus d'informations.",
|
|
271
271
|
"dynamicFlows.MultiSelect.summary": "{first} et {count} de plus",
|
|
272
272
|
"dynamicFlows.MultipleFileUploadSchema.maxFileSizeError": "Nous sommes d\xE9sol\xE9s, ce fichier est trop volumineux. Veuillez t\xE9l\xE9charger un fichier plus petit.",
|
|
@@ -2496,7 +2496,7 @@ var modalToComponent = (uid, { content, title }, mapperProps, schemaComponents)
|
|
|
2496
2496
|
);
|
|
2497
2497
|
|
|
2498
2498
|
// src/domain/components/step/ExternalConfirmationComponent.ts
|
|
2499
|
-
var createExternalConfirmation = (uid, url, onComponentUpdate) => {
|
|
2499
|
+
var createExternalConfirmation = (uid, url, onLink, onComponentUpdate) => {
|
|
2500
2500
|
const update = getInputUpdateFunction(onComponentUpdate);
|
|
2501
2501
|
return {
|
|
2502
2502
|
type: "external-confirmation",
|
|
@@ -2504,15 +2504,11 @@ var createExternalConfirmation = (uid, url, onComponentUpdate) => {
|
|
|
2504
2504
|
uid,
|
|
2505
2505
|
url,
|
|
2506
2506
|
status: "initial",
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
});
|
|
2511
|
-
},
|
|
2512
|
-
onFailure() {
|
|
2513
|
-
if (this.status === "initial") {
|
|
2507
|
+
open() {
|
|
2508
|
+
if (this.status === "initial" || this.status === "failure") {
|
|
2509
|
+
const success = onLink(this.url);
|
|
2514
2510
|
update(this, (draft) => {
|
|
2515
|
-
draft.status = "failure";
|
|
2511
|
+
draft.status = success ? "success" : "failure";
|
|
2516
2512
|
});
|
|
2517
2513
|
}
|
|
2518
2514
|
},
|
|
@@ -4445,12 +4441,12 @@ var initialiseBase64Value = async (uploadComponent) => {
|
|
|
4445
4441
|
|
|
4446
4442
|
// src/domain/mappers/schema/blobSchemaToComponent.ts
|
|
4447
4443
|
var blobSchemaToComponent = (schemaMapperProps, mapperProps) => {
|
|
4448
|
-
const { schema, localValue, required = false, onPersistAsync } = schemaMapperProps;
|
|
4444
|
+
const { schema, localValue, model, required = false, onPersistAsync } = schemaMapperProps;
|
|
4449
4445
|
const { accepts, cameraConfig, maxSize, source, validationMessages } = schema;
|
|
4450
4446
|
const { getErrorMessageFunctions, onComponentUpdate, onValueChange } = mapperProps;
|
|
4451
4447
|
const errorMessageFunctions = getErrorMessageFunctions(validationMessages);
|
|
4452
4448
|
const validLocalValue = isFile(localValue) ? localValue : null;
|
|
4453
|
-
const value = onPersistAsync ? validLocalValue : null;
|
|
4449
|
+
const value = onPersistAsync && model !== null ? validLocalValue : null;
|
|
4454
4450
|
return createUploadInputComponent(
|
|
4455
4451
|
__spreadProps(__spreadValues({}, mapCommonSchemaProps(schemaMapperProps)), {
|
|
4456
4452
|
accepts,
|
|
@@ -6295,7 +6291,12 @@ var mapStepToComponent = (_a) => {
|
|
|
6295
6291
|
}) : void 0;
|
|
6296
6292
|
const stepRefreshAfter = refreshAfter ? getStepRefreshAfter({ refreshAfter, logEvent, onBehavior }) : void 0;
|
|
6297
6293
|
const stepPrefetch = getStepPrefetch(restProps.httpClient, flowRequestCache, submissionBehaviors);
|
|
6298
|
-
const externalConfirmation = (external == null ? void 0 : external.url) ? createExternalConfirmation(
|
|
6294
|
+
const externalConfirmation = (external == null ? void 0 : external.url) ? createExternalConfirmation(
|
|
6295
|
+
`${uid}-external-confirmation`,
|
|
6296
|
+
external == null ? void 0 : external.url,
|
|
6297
|
+
restProps.onLink,
|
|
6298
|
+
onComponentUpdate
|
|
6299
|
+
) : void 0;
|
|
6299
6300
|
const mapperProps = __spreadProps(__spreadValues({}, restProps), {
|
|
6300
6301
|
features,
|
|
6301
6302
|
trackEvent,
|
|
@@ -6649,6 +6650,7 @@ var createFlowController = (props) => {
|
|
|
6649
6650
|
features,
|
|
6650
6651
|
httpClient,
|
|
6651
6652
|
onBehavior,
|
|
6653
|
+
onLink,
|
|
6652
6654
|
onPoll,
|
|
6653
6655
|
onValueChange
|
|
6654
6656
|
});
|
|
@@ -7527,9 +7529,8 @@ var externalComponentToProps = (component, rendererMapperProps) => {
|
|
|
7527
7529
|
type: "external-confirmation",
|
|
7528
7530
|
uid: component.uid,
|
|
7529
7531
|
url: component.url,
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
onFailure: component.onFailure.bind(component),
|
|
7532
|
+
visible: component.status === "failure",
|
|
7533
|
+
open: component.open.bind(component),
|
|
7533
7534
|
onCancel: component.onCancel.bind(component)
|
|
7534
7535
|
}, rendererMapperProps);
|
|
7535
7536
|
};
|
package/build/main.mjs
CHANGED
|
@@ -236,7 +236,7 @@ var fr_default = {
|
|
|
236
236
|
"dynamicFlows.ExternalConfirmation.open": "Ouvrir dans un nouvel onglet",
|
|
237
237
|
"dynamicFlows.ExternalConfirmation.title": "Veuillez confirmer",
|
|
238
238
|
"dynamicFlows.FileUploadSchema.maxFileSizeError": "Nous sommes d\xE9sol\xE9s, ce fichier est trop volumineux. Veuillez t\xE9l\xE9charger un fichier plus petit.",
|
|
239
|
-
"dynamicFlows.FileUploadSchema.wrongFileTypeError": "
|
|
239
|
+
"dynamicFlows.FileUploadSchema.wrongFileTypeError": "D\xE9sol\xE9, ce format de fichier n'est pas pris en charge. Veuillez en importer un autre.",
|
|
240
240
|
"dynamicFlows.Help.ariaLabel": "Cliquez ici pour plus d'informations.",
|
|
241
241
|
"dynamicFlows.MultiSelect.summary": "{first} et {count} de plus",
|
|
242
242
|
"dynamicFlows.MultipleFileUploadSchema.maxFileSizeError": "Nous sommes d\xE9sol\xE9s, ce fichier est trop volumineux. Veuillez t\xE9l\xE9charger un fichier plus petit.",
|
|
@@ -2466,7 +2466,7 @@ var modalToComponent = (uid, { content, title }, mapperProps, schemaComponents)
|
|
|
2466
2466
|
);
|
|
2467
2467
|
|
|
2468
2468
|
// src/domain/components/step/ExternalConfirmationComponent.ts
|
|
2469
|
-
var createExternalConfirmation = (uid, url, onComponentUpdate) => {
|
|
2469
|
+
var createExternalConfirmation = (uid, url, onLink, onComponentUpdate) => {
|
|
2470
2470
|
const update = getInputUpdateFunction(onComponentUpdate);
|
|
2471
2471
|
return {
|
|
2472
2472
|
type: "external-confirmation",
|
|
@@ -2474,15 +2474,11 @@ var createExternalConfirmation = (uid, url, onComponentUpdate) => {
|
|
|
2474
2474
|
uid,
|
|
2475
2475
|
url,
|
|
2476
2476
|
status: "initial",
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
});
|
|
2481
|
-
},
|
|
2482
|
-
onFailure() {
|
|
2483
|
-
if (this.status === "initial") {
|
|
2477
|
+
open() {
|
|
2478
|
+
if (this.status === "initial" || this.status === "failure") {
|
|
2479
|
+
const success = onLink(this.url);
|
|
2484
2480
|
update(this, (draft) => {
|
|
2485
|
-
draft.status = "failure";
|
|
2481
|
+
draft.status = success ? "success" : "failure";
|
|
2486
2482
|
});
|
|
2487
2483
|
}
|
|
2488
2484
|
},
|
|
@@ -4415,12 +4411,12 @@ var initialiseBase64Value = async (uploadComponent) => {
|
|
|
4415
4411
|
|
|
4416
4412
|
// src/domain/mappers/schema/blobSchemaToComponent.ts
|
|
4417
4413
|
var blobSchemaToComponent = (schemaMapperProps, mapperProps) => {
|
|
4418
|
-
const { schema, localValue, required = false, onPersistAsync } = schemaMapperProps;
|
|
4414
|
+
const { schema, localValue, model, required = false, onPersistAsync } = schemaMapperProps;
|
|
4419
4415
|
const { accepts, cameraConfig, maxSize, source, validationMessages } = schema;
|
|
4420
4416
|
const { getErrorMessageFunctions, onComponentUpdate, onValueChange } = mapperProps;
|
|
4421
4417
|
const errorMessageFunctions = getErrorMessageFunctions(validationMessages);
|
|
4422
4418
|
const validLocalValue = isFile(localValue) ? localValue : null;
|
|
4423
|
-
const value = onPersistAsync ? validLocalValue : null;
|
|
4419
|
+
const value = onPersistAsync && model !== null ? validLocalValue : null;
|
|
4424
4420
|
return createUploadInputComponent(
|
|
4425
4421
|
__spreadProps(__spreadValues({}, mapCommonSchemaProps(schemaMapperProps)), {
|
|
4426
4422
|
accepts,
|
|
@@ -6265,7 +6261,12 @@ var mapStepToComponent = (_a) => {
|
|
|
6265
6261
|
}) : void 0;
|
|
6266
6262
|
const stepRefreshAfter = refreshAfter ? getStepRefreshAfter({ refreshAfter, logEvent, onBehavior }) : void 0;
|
|
6267
6263
|
const stepPrefetch = getStepPrefetch(restProps.httpClient, flowRequestCache, submissionBehaviors);
|
|
6268
|
-
const externalConfirmation = (external == null ? void 0 : external.url) ? createExternalConfirmation(
|
|
6264
|
+
const externalConfirmation = (external == null ? void 0 : external.url) ? createExternalConfirmation(
|
|
6265
|
+
`${uid}-external-confirmation`,
|
|
6266
|
+
external == null ? void 0 : external.url,
|
|
6267
|
+
restProps.onLink,
|
|
6268
|
+
onComponentUpdate
|
|
6269
|
+
) : void 0;
|
|
6269
6270
|
const mapperProps = __spreadProps(__spreadValues({}, restProps), {
|
|
6270
6271
|
features,
|
|
6271
6272
|
trackEvent,
|
|
@@ -6619,6 +6620,7 @@ var createFlowController = (props) => {
|
|
|
6619
6620
|
features,
|
|
6620
6621
|
httpClient,
|
|
6621
6622
|
onBehavior,
|
|
6623
|
+
onLink,
|
|
6622
6624
|
onPoll,
|
|
6623
6625
|
onValueChange
|
|
6624
6626
|
});
|
|
@@ -7497,9 +7499,8 @@ var externalComponentToProps = (component, rendererMapperProps) => {
|
|
|
7497
7499
|
type: "external-confirmation",
|
|
7498
7500
|
uid: component.uid,
|
|
7499
7501
|
url: component.url,
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
onFailure: component.onFailure.bind(component),
|
|
7502
|
+
visible: component.status === "failure",
|
|
7503
|
+
open: component.open.bind(component),
|
|
7503
7504
|
onCancel: component.onCancel.bind(component)
|
|
7504
7505
|
}, rendererMapperProps);
|
|
7505
7506
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export const externalComponentToProps = (component, rendererMapperProps) => {
|
|
2
|
-
return Object.assign({ type: 'external-confirmation', uid: component.uid, url: component.url,
|
|
2
|
+
return Object.assign({ type: 'external-confirmation', uid: component.uid, url: component.url, visible: component.status === 'failure', open: component.open.bind(component), onCancel: component.onCancel.bind(component) }, rendererMapperProps);
|
|
3
3
|
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { expect, userEvent, waitFor } from 'storybook/test';
|
|
2
|
+
import DynamicFlowWise from '../../../test-utils/DynamicFlowWise';
|
|
3
|
+
import { renderWithStep } from '../../utils/render-utils';
|
|
4
|
+
export default {
|
|
5
|
+
component: DynamicFlowWise,
|
|
6
|
+
title: 'Spec/Step/Tags/Scroll To Bottom',
|
|
7
|
+
globals: {
|
|
8
|
+
viewport: { value: 'mobile2' },
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
export function WithoutFooter() {
|
|
12
|
+
return renderWithStep(getTnCStep(undefined));
|
|
13
|
+
}
|
|
14
|
+
export function WithFooter() {
|
|
15
|
+
return renderWithStep(getTnCStep([acceptButton]));
|
|
16
|
+
}
|
|
17
|
+
const getTnCStep = (footer) => {
|
|
18
|
+
const markdownComponent = {
|
|
19
|
+
type: 'markdown',
|
|
20
|
+
content: `### 1. Introduction
|
|
21
|
+
|
|
22
|
+
Welcome to Acme Corp ("we", "us", "our"). By accessing or using our services, you agree to be bound by these Terms and Conditions. Please read them carefully. We know you won't, but we appreciate the gesture.
|
|
23
|
+
|
|
24
|
+
### 2. Acceptance of Terms
|
|
25
|
+
|
|
26
|
+
By using our services, you confirm that you have read, understood, and agreed to these terms. You haven't, of course. Nobody has. These terms exist in a quantum superposition of "agreed to" and "never read", collapsing into "agreed to" the moment you tap that button at the bottom.
|
|
27
|
+
|
|
28
|
+
### 3. Eligibility
|
|
29
|
+
|
|
30
|
+
You must be at least 18 years of age to use our services. You must also be a human being, not a robot, and must possess at least one opposable thumb capable of scrolling. If you are a robot reading this: hello, we see you, and we're onto you.
|
|
31
|
+
|
|
32
|
+
### 4. Privacy and Data Collection
|
|
33
|
+
|
|
34
|
+
We collect certain personal information to provide our services. This includes your name, email address, phone number, and the timestamp of how quickly you scrolled past this section. We're logging it right now. It's approximately 0.4 seconds. Impressive.
|
|
35
|
+
|
|
36
|
+
### 5. User Responsibilities
|
|
37
|
+
|
|
38
|
+
You agree to use our services lawfully and responsibly. You agree not to use our services for any fraudulent, abusive, or otherwise objectionable activity. You agree, at least nominally, to all of the above, despite not having read the previous sentence.
|
|
39
|
+
|
|
40
|
+
### 6. Intellectual Property
|
|
41
|
+
|
|
42
|
+
All content, branding, and materials provided through our services are the intellectual property of Acme Corp. Unauthorised reproduction is prohibited. This includes copy-pasting these Terms and Conditions into your own app, which would be embarrassing for everyone involved.
|
|
43
|
+
|
|
44
|
+
### 7. Limitation of Liability
|
|
45
|
+
|
|
46
|
+
To the fullest extent permitted by applicable law, Acme Corp shall not be liable for any indirect, incidental, special, or consequential damages. Including, but not limited to, damages arising from the fact that you skipped straight to clause 7 looking for "the important bit."
|
|
47
|
+
|
|
48
|
+
### 8. Amendments
|
|
49
|
+
|
|
50
|
+
We reserve the right to update these Terms and Conditions at any time. We will notify you via email. You will not read that email either. It will sit in your inbox next to 47 other unread notifications until you bulk-archive everything in a moment of digital clarity.
|
|
51
|
+
|
|
52
|
+
### 9. Governing Law
|
|
53
|
+
|
|
54
|
+
These Terms and Conditions are governed by the laws of England and Wales. Any disputes shall be subject to the exclusive jurisdiction of the courts of England and Wales, unless you are currently in a coffee shop in another country, in which case, please enjoy your flat white.
|
|
55
|
+
|
|
56
|
+
### 10. Entire Agreement
|
|
57
|
+
|
|
58
|
+
These Terms and Conditions, along with our Privacy Policy and any other documents we feel like referencing, constitute the entire agreement between you and Acme Corp. They supersede all prior agreements, understandings, and the vague sense you had that "it was probably fine."`,
|
|
59
|
+
};
|
|
60
|
+
const layout = footer ? [markdownComponent] : [markdownComponent, acceptButton];
|
|
61
|
+
return {
|
|
62
|
+
id: 'step',
|
|
63
|
+
title: 'Terms and Conditions',
|
|
64
|
+
description: 'Please carefully read the terms and conditions before proceeding... or just press the button to scroll to the bottom, who cares?',
|
|
65
|
+
schemas: [],
|
|
66
|
+
layout,
|
|
67
|
+
footer,
|
|
68
|
+
tags: ['scroll-to-bottom'],
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
const acceptButton = {
|
|
72
|
+
type: 'button',
|
|
73
|
+
title: 'Accept',
|
|
74
|
+
behavior: { type: 'action', action: { url: '/accept' } },
|
|
75
|
+
};
|
|
76
|
+
const user = userEvent.setup();
|
|
77
|
+
export const WithoutFooterInteraction = {
|
|
78
|
+
render: () => renderWithStep(getTnCStep(undefined)),
|
|
79
|
+
play: async ({ canvas }) => {
|
|
80
|
+
await waitFor(async () => {
|
|
81
|
+
await expect(canvas.getByRole('button', { name: 'Scroll to bottom' })).toBeInTheDocument();
|
|
82
|
+
});
|
|
83
|
+
await user.click(canvas.getByRole('button', { name: 'Scroll to bottom' }));
|
|
84
|
+
await waitFor(async () => {
|
|
85
|
+
await expect(canvas.queryByRole('button', { name: 'Scroll to bottom' })).not.toBeInTheDocument();
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
export const WithFooterInteraction = {
|
|
90
|
+
render: () => renderWithStep(getTnCStep([acceptButton])),
|
|
91
|
+
play: async ({ canvas }) => {
|
|
92
|
+
await waitFor(async () => {
|
|
93
|
+
await expect(canvas.getByRole('button', { name: 'Scroll to bottom' })).toBeInTheDocument();
|
|
94
|
+
});
|
|
95
|
+
await user.click(canvas.getByRole('button', { name: 'Scroll to bottom' }));
|
|
96
|
+
await waitFor(async () => {
|
|
97
|
+
await expect(canvas.queryByRole('button', { name: 'Scroll to bottom' })).not.toBeInTheDocument();
|
|
98
|
+
});
|
|
99
|
+
await waitFor(async () => {
|
|
100
|
+
await expect(canvas.getByRole('button', { name: 'Accept' })).toBeInTheDocument();
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
};
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { ThemeRequiredEventName, useSnackBarIfAvailable } from '@wise/dynamic-flow-renderers';
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
4
|
import { DynamicFlowCore } from '../DynamicFlowCore';
|
|
5
|
-
import { openLinkInNewTab } from '
|
|
5
|
+
import { openLinkInNewTab } from './openLinkInNewTab';
|
|
6
6
|
import { getMergedTestRenderers } from './getMergedTestRenderers';
|
|
7
7
|
/**
|
|
8
8
|
* This component is only used in tests.
|
|
@@ -12,7 +12,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
13
|
import { useMemo } from 'react';
|
|
14
14
|
import { Modal } from '@transferwise/components';
|
|
15
|
-
import { openLinkInNewTab } from '
|
|
15
|
+
import { openLinkInNewTab } from './openLinkInNewTab';
|
|
16
16
|
import { getMergedTestRenderers } from './getMergedTestRenderers';
|
|
17
17
|
import { ThemeRequiredEventName } from '@wise/dynamic-flow-renderers';
|
|
18
18
|
import { useDynamicFlowModal } from '../useDynamicFlowModal';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const openLinkInNewTab = (url) => {
|
|
2
|
+
if (typeof window === 'undefined' || typeof window.open !== 'function') {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
try {
|
|
6
|
+
const w = window.open(url, '_blank');
|
|
7
|
+
if (w) {
|
|
8
|
+
w.opener = null;
|
|
9
|
+
}
|
|
10
|
+
return Boolean(w);
|
|
11
|
+
}
|
|
12
|
+
catch (_a) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { screen, waitFor } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import { vi } from 'vitest';
|
|
5
|
+
import { renderWithProviders } from '../test-utils';
|
|
6
|
+
import DynamicFlowWise from '../test-utils/DynamicFlowWise';
|
|
7
|
+
/*
|
|
8
|
+
This test mocks the IntersectionObserver API, because,
|
|
9
|
+
unfortunately, jsdom doesn't implement real layout, scrolling, or visibility.
|
|
10
|
+
|
|
11
|
+
- IntersectionObserver doesn't exist (hence why we mock it)
|
|
12
|
+
- scrollIntoView() does nothing — it's a no-op
|
|
13
|
+
- getBoundingClientRect() always returns all zeros
|
|
14
|
+
- There is no actual viewport or rendering engine
|
|
15
|
+
*/
|
|
16
|
+
const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
|
|
17
|
+
const getDefaultProps = () => ({
|
|
18
|
+
flowId: 'flow-id',
|
|
19
|
+
onCompletion: vi.fn(),
|
|
20
|
+
onError: vi.fn(),
|
|
21
|
+
onEvent: vi.fn(),
|
|
22
|
+
onLog: vi.fn(),
|
|
23
|
+
});
|
|
24
|
+
const makeStep = (overrides = {}) => (Object.assign({ id: 'step-id', title: 'Step', schemas: [], layout: [] }, overrides));
|
|
25
|
+
const mockIntersectionObserver = (isIntersecting) => {
|
|
26
|
+
vi.stubGlobal('IntersectionObserver', class {
|
|
27
|
+
get root() {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
get rootMargin() {
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
get thresholds() {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
constructor(callback) {
|
|
37
|
+
this.observe = vi.fn().mockImplementation((el) => {
|
|
38
|
+
this.callback([{ isIntersecting, target: el }], this);
|
|
39
|
+
});
|
|
40
|
+
this.unobserve = vi.fn();
|
|
41
|
+
this.disconnect = vi.fn();
|
|
42
|
+
this.takeRecords = vi.fn().mockReturnValue([]);
|
|
43
|
+
this.callback = callback;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
describe('Scroll to bottom', () => {
|
|
48
|
+
afterEach(() => {
|
|
49
|
+
vi.unstubAllGlobals();
|
|
50
|
+
});
|
|
51
|
+
const stepWithoutFooter = makeStep({
|
|
52
|
+
layout: [{ type: 'markdown', content: 'Some very long terms and conditions content.' }],
|
|
53
|
+
tags: ['scroll-to-bottom'],
|
|
54
|
+
});
|
|
55
|
+
const stepWithFooter = makeStep({
|
|
56
|
+
layout: [{ type: 'markdown', content: 'Some very long terms and conditions content.' }],
|
|
57
|
+
footer: [
|
|
58
|
+
{
|
|
59
|
+
type: 'button',
|
|
60
|
+
title: 'Accept',
|
|
61
|
+
behavior: { type: 'action', action: { url: '/accept' } },
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
tags: ['scroll-to-bottom'],
|
|
65
|
+
});
|
|
66
|
+
describe('given a step with a long markdown content without a footer', () => {
|
|
67
|
+
it('shows a scroll to bottom button if the end of the step is not visible', async () => {
|
|
68
|
+
mockIntersectionObserver(false);
|
|
69
|
+
renderWithProviders(_jsx(DynamicFlowWise, Object.assign({ initialStep: stepWithoutFooter, httpClient: vi.fn() }, getDefaultProps())));
|
|
70
|
+
await waitFor(() => {
|
|
71
|
+
expect(screen.getByRole('button', { name: 'Scroll to bottom' })).toBeInTheDocument();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
it('scrolls to the bottom of the step when the scroll to bottom button is clicked', async () => {
|
|
75
|
+
const scrollIntoViewMock = vi.fn();
|
|
76
|
+
window.HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;
|
|
77
|
+
mockIntersectionObserver(false);
|
|
78
|
+
renderWithProviders(_jsx(DynamicFlowWise, Object.assign({ initialStep: stepWithoutFooter, httpClient: vi.fn() }, getDefaultProps())));
|
|
79
|
+
await waitFor(() => {
|
|
80
|
+
expect(screen.getByRole('button', { name: 'Scroll to bottom' })).toBeInTheDocument();
|
|
81
|
+
});
|
|
82
|
+
await user.click(screen.getByRole('button', { name: 'Scroll to bottom' }));
|
|
83
|
+
expect(scrollIntoViewMock).toHaveBeenCalled();
|
|
84
|
+
});
|
|
85
|
+
it('does not show a scroll to bottom button if the end of the step is visible', async () => {
|
|
86
|
+
mockIntersectionObserver(true);
|
|
87
|
+
renderWithProviders(_jsx(DynamicFlowWise, Object.assign({ initialStep: stepWithoutFooter, httpClient: vi.fn() }, getDefaultProps())));
|
|
88
|
+
await waitFor(() => {
|
|
89
|
+
expect(screen.queryByRole('button', { name: 'Scroll to bottom' })).not.toBeInTheDocument();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe('given a step with a long markdown content and a footer', () => {
|
|
94
|
+
it('shows a scroll to bottom button in the footer, along with the footer content, if the end of the step is not visible', async () => {
|
|
95
|
+
mockIntersectionObserver(false);
|
|
96
|
+
renderWithProviders(_jsx(DynamicFlowWise, Object.assign({ initialStep: stepWithFooter, httpClient: vi.fn() }, getDefaultProps())));
|
|
97
|
+
await waitFor(() => {
|
|
98
|
+
expect(screen.getByRole('button', { name: 'Scroll to bottom' })).toBeInTheDocument();
|
|
99
|
+
});
|
|
100
|
+
expect(screen.getByRole('button', { name: 'Accept' })).toBeInTheDocument();
|
|
101
|
+
});
|
|
102
|
+
it('scrolls to the bottom of the step when the scroll to bottom button is clicked', async () => {
|
|
103
|
+
const scrollIntoViewMock = vi.fn();
|
|
104
|
+
window.HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;
|
|
105
|
+
mockIntersectionObserver(false);
|
|
106
|
+
renderWithProviders(_jsx(DynamicFlowWise, Object.assign({ initialStep: stepWithFooter, httpClient: vi.fn() }, getDefaultProps())));
|
|
107
|
+
await waitFor(() => {
|
|
108
|
+
expect(screen.getByRole('button', { name: 'Scroll to bottom' })).toBeInTheDocument();
|
|
109
|
+
});
|
|
110
|
+
await user.click(screen.getByRole('button', { name: 'Scroll to bottom' }));
|
|
111
|
+
expect(scrollIntoViewMock).toHaveBeenCalled();
|
|
112
|
+
});
|
|
113
|
+
it('does not show a scroll to bottom button in the footer, if the end of the step is visible', async () => {
|
|
114
|
+
mockIntersectionObserver(true);
|
|
115
|
+
renderWithProviders(_jsx(DynamicFlowWise, Object.assign({ initialStep: stepWithFooter, httpClient: vi.fn() }, getDefaultProps())));
|
|
116
|
+
await waitFor(() => {
|
|
117
|
+
expect(screen.queryByRole('button', { name: 'Scroll to bottom' })).not.toBeInTheDocument();
|
|
118
|
+
});
|
|
119
|
+
expect(screen.getByRole('button', { name: 'Accept' })).toBeInTheDocument();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { screen, waitFor } from '@testing-library/react';
|
|
3
3
|
import userEvent from '@testing-library/user-event';
|
|
4
|
-
import { renderWithProviders } from '../test-utils';
|
|
4
|
+
import { renderWithProviders, respondWith } from '../test-utils';
|
|
5
5
|
import DynamicFlowWise from '../test-utils/DynamicFlowWise';
|
|
6
6
|
import { vi } from 'vitest';
|
|
7
7
|
const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
|
|
@@ -86,3 +86,83 @@ describe.each(cases)(`given a %s with persist-async`, (_, schema) => {
|
|
|
86
86
|
});
|
|
87
87
|
});
|
|
88
88
|
});
|
|
89
|
+
describe('given a blob schema on a step that refreshes', () => {
|
|
90
|
+
const uploadSchema = {
|
|
91
|
+
$id: '#upload-national-id',
|
|
92
|
+
type: 'object',
|
|
93
|
+
displayOrder: ['fileUpload'],
|
|
94
|
+
properties: {
|
|
95
|
+
fileUpload: {
|
|
96
|
+
type: 'string',
|
|
97
|
+
persistAsync: {
|
|
98
|
+
method: 'POST',
|
|
99
|
+
url: '/persist-async',
|
|
100
|
+
param: 'param',
|
|
101
|
+
idProperty: 'token',
|
|
102
|
+
schema: {
|
|
103
|
+
type: 'blob',
|
|
104
|
+
source: 'file',
|
|
105
|
+
title: 'Upload label (from innner schema title)',
|
|
106
|
+
accepts: ['image/png', 'image/jpeg', 'application/pdf'],
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
const step = {
|
|
113
|
+
id: 'step-id',
|
|
114
|
+
title: 'Step',
|
|
115
|
+
schemas: [
|
|
116
|
+
{
|
|
117
|
+
$id: '#schema',
|
|
118
|
+
type: 'object',
|
|
119
|
+
displayOrder: ['type'],
|
|
120
|
+
properties: {
|
|
121
|
+
type: {
|
|
122
|
+
title: 'Select document',
|
|
123
|
+
refreshStepOnChange: true,
|
|
124
|
+
oneOf: [
|
|
125
|
+
{
|
|
126
|
+
title: 'National ID',
|
|
127
|
+
const: 'national-id',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
title: 'Passport',
|
|
131
|
+
const: 'passport',
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
layout: [
|
|
139
|
+
{
|
|
140
|
+
type: 'form',
|
|
141
|
+
schemaId: '#schema',
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
};
|
|
145
|
+
it('clears the value when the model is nullified', async () => {
|
|
146
|
+
const initialStep = Object.assign(Object.assign({}, step), { schemas: [...step.schemas, uploadSchema], layout: [...step.layout, { type: 'form', schemaId: '#upload-national-id' }] });
|
|
147
|
+
const httpClient = vi
|
|
148
|
+
.fn()
|
|
149
|
+
.mockResolvedValueOnce(respondWith({ token: 123 }))
|
|
150
|
+
.mockResolvedValueOnce(respondWith(Object.assign(Object.assign({}, step), { schemas: [...step.schemas, Object.assign(Object.assign({}, uploadSchema), { $id: '#upload-passport' })], layout: [...step.layout, { type: 'form', schemaId: '#upload-passport' }], title: 'Step refreshed', model: {
|
|
151
|
+
type: 'passport',
|
|
152
|
+
fileUpload: null,
|
|
153
|
+
} }), { status: 200 }));
|
|
154
|
+
renderWithProviders(_jsx(DynamicFlowWise, { flowId: "id", initialStep: initialStep, httpClient: httpClient, onCompletion: vi.fn(), onError: vi.fn() }));
|
|
155
|
+
await user.upload(screen.getByTestId('uploadInput'), new File([''], 'file.png', { type: 'image/png' }));
|
|
156
|
+
await waitFor(() => {
|
|
157
|
+
expect(screen.getByText('Uploaded')).toBeInTheDocument();
|
|
158
|
+
});
|
|
159
|
+
await user.click(screen.getByLabelText('Select document'));
|
|
160
|
+
await user.click(screen.getByText('Passport'));
|
|
161
|
+
await waitFor(() => {
|
|
162
|
+
expect(screen.getByText('Step refreshed')).toBeInTheDocument();
|
|
163
|
+
});
|
|
164
|
+
await waitFor(() => {
|
|
165
|
+
expect(screen.queryByText('Uploaded')).not.toBeInTheDocument();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
@@ -10,7 +10,6 @@ export type FlowControllerProps = Omit<DynamicFlowCoreProps, 'renderers' | 'feat
|
|
|
10
10
|
onChange: () => void;
|
|
11
11
|
onValueChange: OnValueChange;
|
|
12
12
|
scrollToTop: ScrollToTop;
|
|
13
|
-
onLink: (url: string) => boolean;
|
|
14
13
|
};
|
|
15
14
|
export declare const createFlowController: (props: FlowControllerProps) => {
|
|
16
15
|
rootComponent: import("../domain/components/RootDomainComponent").RootDomainComponent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlowController.d.ts","sourceRoot":"","sources":["../../../src/controller/FlowController.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAA6B,MAAM,0CAA0C,CAAC;AAMjG,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAKL,aAAa,EACb,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAShD,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,oBAAoB,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG;IACvF,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,wBAAwB,EAAE,wBAAwB,CAAC;IACnD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"FlowController.d.ts","sourceRoot":"","sources":["../../../src/controller/FlowController.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAA6B,MAAM,0CAA0C,CAAC;AAMjG,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAKL,aAAa,EACb,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAShD,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,oBAAoB,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG;IACvF,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,wBAAwB,EAAE,wBAAwB,CAAC;IACnD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC;AAIF,eAAO,MAAM,oBAAoB,GAAI,OAAO,mBAAmB;;;;CAic9D,CAAC"}
|
|
@@ -5,9 +5,8 @@ export type ExternalConfirmationComponent = BaseComponent & {
|
|
|
5
5
|
uid: string;
|
|
6
6
|
status: 'initial' | 'success' | 'failure' | 'dismissed';
|
|
7
7
|
url: string;
|
|
8
|
-
|
|
9
|
-
onFailure: () => void;
|
|
8
|
+
open: () => void;
|
|
10
9
|
onCancel: () => void;
|
|
11
10
|
};
|
|
12
|
-
export declare const createExternalConfirmation: (uid: string, url: string, onComponentUpdate: OnComponentUpdate) => ExternalConfirmationComponent;
|
|
11
|
+
export declare const createExternalConfirmation: (uid: string, url: string, onLink: (url: string) => boolean, onComponentUpdate: OnComponentUpdate) => ExternalConfirmationComponent;
|
|
13
12
|
//# sourceMappingURL=ExternalConfirmationComponent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExternalConfirmationComponent.d.ts","sourceRoot":"","sources":["../../../../../src/domain/components/step/ExternalConfirmationComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG/D,MAAM,MAAM,6BAA6B,GAAG,aAAa,GAAG;IAC1D,IAAI,EAAE,uBAAuB,CAAC;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,
|
|
1
|
+
{"version":3,"file":"ExternalConfirmationComponent.d.ts","sourceRoot":"","sources":["../../../../../src/domain/components/step/ExternalConfirmationComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG/D,MAAM,MAAM,6BAA6B,GAAG,aAAa,GAAG;IAC1D,IAAI,EAAE,uBAAuB,CAAC;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,KAAK,MAAM,EACX,KAAK,MAAM,EACX,QAAQ,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EAChC,mBAAmB,iBAAiB,KACnC,6BAuBF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapStepToComponent.d.ts","sourceRoot":"","sources":["../../../../src/domain/mappers/mapStepToComponent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAGnE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,KAAK,EAAY,YAAY,EAAc,MAAM,EAAE,MAAM,UAAU,CAAC;AAI3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMlD,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,GAAG,4BAA4B,CAAC,GAAG;IAC7F,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,EAAE,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC7C,gBAAgB,EAAE,YAAY,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,wFAQhC,eAAe,
|
|
1
|
+
{"version":3,"file":"mapStepToComponent.d.ts","sourceRoot":"","sources":["../../../../src/domain/mappers/mapStepToComponent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAGnE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,KAAK,EAAY,YAAY,EAAc,MAAM,EAAE,MAAM,UAAU,CAAC;AAI3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMlD,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,GAAG,4BAA4B,CAAC,GAAG;IAC7F,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,EAAE,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC7C,gBAAgB,EAAE,YAAY,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,wFAQhC,eAAe,yEAqHjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/domain/mappers/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEpG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACV,cAAc,EACd,aAAa,EACb,iBAAiB,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,MAAM,WAAW,GAAG;IACxB,cAAc,EAAE,UAAU,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB,EAAE,wBAAwB,CAAC;IACnD,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC;IAC7B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,UAAU,EAAE,wBAAwB,CAAC;IACrC,QAAQ,EAAE,sBAAsB,CAAC;IACjC,0BAA0B,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,eAAe,CAAC;IACnC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAExC,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/domain/mappers/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEpG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACV,cAAc,EACd,aAAa,EACb,iBAAiB,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,MAAM,WAAW,GAAG;IACxB,cAAc,EAAE,UAAU,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB,EAAE,wBAAwB,CAAC;IACnD,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,UAAU,EAAE,wBAAwB,CAAC;IACrC,QAAQ,EAAE,sBAAsB,CAAC;IACjC,0BAA0B,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,eAAe,CAAC;IACnC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAExC,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"externalComponentToProps.d.ts","sourceRoot":"","sources":["../../../../src/renderers/mappers/externalComponentToProps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAE,6BAA6B,EAAE,MAAM,4DAA4D,CAAC;AAC3G,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,eAAO,MAAM,wBAAwB,GACnC,WAAW,6BAA6B,EACxC,qBAAqB,mBAAmB,KACvC,
|
|
1
|
+
{"version":3,"file":"externalComponentToProps.d.ts","sourceRoot":"","sources":["../../../../src/renderers/mappers/externalComponentToProps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAE,6BAA6B,EAAE,MAAM,4DAA4D,CAAC;AAC3G,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,eAAO,MAAM,wBAAwB,GACnC,WAAW,6BAA6B,EACxC,qBAAqB,mBAAmB,KACvC,iCAUF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openLinkInNewTab.d.ts","sourceRoot":"","sources":["../../../src/test-utils/openLinkInNewTab.tsx"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,OAa9C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wise/dynamic-flow-client",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.11.0",
|
|
4
4
|
"description": "Dynamic Flow web client",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./build/main.js",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@transferwise/components": "^46.129.0",
|
|
45
45
|
"@transferwise/formatting": "^2.13.5",
|
|
46
46
|
"@transferwise/icons": "4.1.0",
|
|
47
|
-
"@transferwise/navigation-ui": "4.42.
|
|
47
|
+
"@transferwise/navigation-ui": "4.42.3",
|
|
48
48
|
"@transferwise/neptune-css": "14.26.3",
|
|
49
49
|
"@types/node": "22.19.13",
|
|
50
50
|
"@types/react": "18.3.28",
|
|
@@ -73,8 +73,8 @@
|
|
|
73
73
|
"typescript": "5.9.3",
|
|
74
74
|
"vitest": "4.0.18",
|
|
75
75
|
"vitest-fetch-mock": "0.4.5",
|
|
76
|
-
"@wise/dynamic-flow-
|
|
77
|
-
"@wise/dynamic-flow-
|
|
76
|
+
"@wise/dynamic-flow-fixtures": "0.0.1",
|
|
77
|
+
"@wise/dynamic-flow-renderers": "0.0.0"
|
|
78
78
|
},
|
|
79
79
|
"peerDependencies": {
|
|
80
80
|
"@transferwise/components": "^46.104.0",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"react-intl": "^6 || ^7"
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
|
-
"@wise/dynamic-flow-types": "4.
|
|
90
|
+
"@wise/dynamic-flow-types": "4.11.0"
|
|
91
91
|
},
|
|
92
92
|
"scripts": {
|
|
93
93
|
"dev": "EXCLUDE_VISUAL_TESTS=true pnpm storybook dev -p 3003",
|
|
@@ -99,8 +99,8 @@
|
|
|
99
99
|
"build:messages-source": "formatjs extract 'src/**/{*.messages,messages}.{js,ts}' --out-file src/i18n/en.json --format simple && prettier --find-config-path --write src/i18n/*.json",
|
|
100
100
|
"build:compiled-messages": "mkdir -p build/i18n && cp src/i18n/*.json build/i18n",
|
|
101
101
|
"build:visual-tests": "tsx ./scripts/build-visual-tests.mjs",
|
|
102
|
-
"test": "
|
|
103
|
-
"test:
|
|
102
|
+
"test": "vitest run --no-isolate",
|
|
103
|
+
"test:ci": "vitest run --no-file-parallelism",
|
|
104
104
|
"test:coverage": "vitest run --coverage",
|
|
105
105
|
"test:watch": "vitest",
|
|
106
106
|
"types": "pnpm tsc",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openLinkInNewTab.d.ts","sourceRoot":"","sources":["../../../src/utils/openLinkInNewTab.tsx"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,OAO9C,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export const openLinkInNewTab = (url) => {
|
|
2
|
-
var _a;
|
|
3
|
-
try {
|
|
4
|
-
const w = (_a = window === null || window === void 0 ? void 0 : window.open) === null || _a === void 0 ? void 0 : _a.call(window, url, '_blank');
|
|
5
|
-
return Boolean(w);
|
|
6
|
-
}
|
|
7
|
-
catch (_b) {
|
|
8
|
-
return false;
|
|
9
|
-
}
|
|
10
|
-
};
|
|
File without changes
|