@wise/dynamic-flow-client-internal 5.28.2 → 5.28.3
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/main.js +1 -1
- package/build/main.mjs +1 -1
- package/package.json +2 -2
- package/build/dynamicFlow/DynamicFlow.js +0 -11
- package/build/dynamicFlow/DynamicFlowModal.js +0 -21
- package/build/dynamicFlow/DynamicFlowWiseProps.js +0 -1
- package/build/dynamicFlow/DynamicFlowWithRef.js +0 -19
- package/build/dynamicFlow/context-menu/useContextMenu.js +0 -33
- package/build/dynamicFlow/context-menu/useDFContextMenu.js +0 -135
- package/build/dynamicFlow/context-menu/useDFContextMenu.test.js +0 -101
- package/build/dynamicFlow/getMergedRenderers.js +0 -36
- package/build/dynamicFlow/messages.js +0 -13
- package/build/dynamicFlow/renderers.js +0 -10
- package/build/dynamicFlow/telemetry/app-version.js +0 -4
- package/build/dynamicFlow/telemetry/dispatchAnalyticsEvent.js +0 -8
- package/build/dynamicFlow/telemetry/getLogEvent.js +0 -22
- package/build/dynamicFlow/telemetry/getTrackEvent.js +0 -39
- package/build/dynamicFlow/telemetry/index.js +0 -2
- package/build/dynamicFlow/useCreateSnackBar.js +0 -9
- package/build/dynamicFlow/useOnCopy.js +0 -16
- package/build/dynamicFlow/useWiseHttpClient.js +0 -24
- package/build/dynamicFlow/useWiseToCoreProps.js +0 -42
- package/build/i18n/index.js +0 -43
- package/build/index.js +0 -6
- package/build/stories/ButtonLoader.story.js +0 -109
- package/build/stories/ContainerQueries.story.js +0 -74
- package/build/stories/DynamicFlow.story.js +0 -37
- package/build/stories/DynamicFlowWithRef.story.js +0 -72
- package/build/stories/Editable.story.js +0 -58
- package/build/stories/Initialisation.story.js +0 -33
- package/build/stories/PinnedButtons.story.js +0 -94
- package/build/stories/SCAIntegration.story.js +0 -67
- package/build/stories/utils/fixtureHttpClient.js +0 -59
- package/build/test-utils/NeptuneProviders.js +0 -11
- package/build/test-utils/index.js +0 -4
- package/build/test-utils/respond-with.js +0 -6
- package/build/test-utils/rtl-utils.js +0 -7
- package/build/test-utils/wait.js +0 -3
- package/build/tests/DynamicFlow.test.js +0 -177
- package/build/tests/HideStepTitle.test.js +0 -58
- package/build/tests/RequestCache.test.js +0 -34
- package/build/tests/SCARejectionHandling.test.js +0 -71
- package/build/tests/Subflow.Wise.test.js +0 -650
- package/build/tests/events.test.js +0 -124
- package/build/tests/logging.test.js +0 -12
- package/build/tests/onNotification.test.js +0 -96
- package/build/tests/renderers/ControlAndTags.test.js +0 -225
- package/build/tests/renderers/ImageRenderer.test.js +0 -129
- package/build/tests/renderers/RadioInputRendererComponent.test.js +0 -89
- package/build/tests/renderers/ReviewRenderer.test.js +0 -41
- package/build/tests/renderers/TextInputRenderer.test.js +0 -44
- package/build/tests/renderers/TimeZoneHeader.test.js +0 -19
- package/build/tests/renderers/UploadInputRenderer.maxSize.test.js +0 -22
- package/build/tests/renderers/value-utils.test.js +0 -24
package/build/index.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { makeHttpClient as makeCustomFetch } from '@wise/dynamic-flow-client';
|
|
2
|
-
export { DynamicFlow } from './dynamicFlow/DynamicFlow';
|
|
3
|
-
export { DynamicFlowWithRef } from './dynamicFlow/DynamicFlowWithRef';
|
|
4
|
-
export { findRendererPropsByType } from '@wise/dynamic-flow-client';
|
|
5
|
-
export { createCollectionRenderer, getMargin, Header, Media } from './dynamicFlow/renderers';
|
|
6
|
-
export { default as translations } from './i18n';
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { action } from 'storybook/actions';
|
|
3
|
-
import { DynamicFlow } from '../dynamicFlow/DynamicFlow';
|
|
4
|
-
import { fixtureHttpClient } from './utils/fixtureHttpClient';
|
|
5
|
-
export default {
|
|
6
|
-
title: 'Initialisation',
|
|
7
|
-
component: DynamicFlow,
|
|
8
|
-
};
|
|
9
|
-
const onCompletion = action('onCompletion');
|
|
10
|
-
const onError = action('onError');
|
|
11
|
-
const onEvent = action('onEvent');
|
|
12
|
-
const onLog = action('onLog');
|
|
13
|
-
export const ButtonLoader = {
|
|
14
|
-
render: () => (_jsx(DynamicFlow, { flowId: "initialisation-telemetry", customFetch: fixtureHttpClient, initialStep: step, onCompletion: onCompletion, onError: onError, onEvent: onEvent, onLog: onLog })),
|
|
15
|
-
};
|
|
16
|
-
const step = {
|
|
17
|
-
id: 'convert-review',
|
|
18
|
-
title: 'Does everything look right?',
|
|
19
|
-
schemas: [
|
|
20
|
-
{
|
|
21
|
-
properties: {
|
|
22
|
-
quoteId: {
|
|
23
|
-
const: '123',
|
|
24
|
-
},
|
|
25
|
-
profileId: {
|
|
26
|
-
const: 6666,
|
|
27
|
-
},
|
|
28
|
-
context: {
|
|
29
|
-
const: 'CONVERT',
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
displayOrder: ['quoteId', 'profileId', 'context'],
|
|
33
|
-
required: ['quoteId', 'profileId', 'context'],
|
|
34
|
-
hidden: true,
|
|
35
|
-
type: 'object',
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
layout: [
|
|
39
|
-
{
|
|
40
|
-
components: [
|
|
41
|
-
{
|
|
42
|
-
fields: [
|
|
43
|
-
{
|
|
44
|
-
label: "You're converting",
|
|
45
|
-
value: '123 EUR',
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
label: 'To',
|
|
49
|
-
value: '101.61 GBP',
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
label: 'Our fee',
|
|
53
|
-
value: '6.15 EUR',
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
label: 'Rate',
|
|
57
|
-
value: '1 EUR = 0.8696 GBP',
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
title: 'Conversion details',
|
|
61
|
-
callToAction: {
|
|
62
|
-
title: 'Edit',
|
|
63
|
-
behavior: {
|
|
64
|
-
action: {
|
|
65
|
-
exit: true,
|
|
66
|
-
result: {
|
|
67
|
-
action: 'EDIT',
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
type: 'action',
|
|
71
|
-
},
|
|
72
|
-
action: {
|
|
73
|
-
exit: true,
|
|
74
|
-
result: {
|
|
75
|
-
action: 'EDIT',
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
control: 'horizontal',
|
|
80
|
-
type: 'review',
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
title: 'Convert',
|
|
84
|
-
behavior: {
|
|
85
|
-
action: {
|
|
86
|
-
exit: true,
|
|
87
|
-
result: {
|
|
88
|
-
action: 'CONVERT',
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
type: 'action',
|
|
92
|
-
},
|
|
93
|
-
control: 'primary',
|
|
94
|
-
margin: 'xs',
|
|
95
|
-
type: 'button',
|
|
96
|
-
action: {
|
|
97
|
-
exit: true,
|
|
98
|
-
result: {
|
|
99
|
-
action: 'CONVERT',
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
],
|
|
104
|
-
control: 'bordered',
|
|
105
|
-
type: 'box',
|
|
106
|
-
},
|
|
107
|
-
],
|
|
108
|
-
refreshUrl: '/v1/convert/review?refresh=true',
|
|
109
|
-
};
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { action } from 'storybook/actions';
|
|
3
|
-
import { DynamicFlow } from '../dynamicFlow/DynamicFlow';
|
|
4
|
-
import { Fragment } from 'react/jsx-runtime';
|
|
5
|
-
export default {
|
|
6
|
-
component: ImageLayoutWithSize,
|
|
7
|
-
title: 'Dev Tools/Container Queries',
|
|
8
|
-
argTypes: {
|
|
9
|
-
width: {
|
|
10
|
-
options: ['100%', '900px', '600px', '575px', '400px'],
|
|
11
|
-
control: { type: 'select' },
|
|
12
|
-
description: 'Width of the div containing the DynamicFlow component',
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
args: {
|
|
16
|
-
width: '575px',
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
export function ImageLayoutWithSize({ width }) {
|
|
20
|
-
return _jsx(Fragment, { children: renderWithStep(imageLayoutStep, width) }, width);
|
|
21
|
-
}
|
|
22
|
-
function renderWithStep(step, width) {
|
|
23
|
-
const getDF = () => (_jsx(DynamicFlow, { flowId: "new-df-flow-id", className: "df-prefer-container-queries", customFetch: async (input, init) => {
|
|
24
|
-
action('httpClient')(input, init === null || init === void 0 ? void 0 : init.body);
|
|
25
|
-
return fetch(input, init);
|
|
26
|
-
}, initialStep: Object.assign(Object.assign({}, step), { title: `Dynamic Flow Step - ${width}`, description: `This is a DynamicFlow component inside a ${width}-wide <div> container. You can change the width in the Storybook controls.` }), onCompletion: action('onCompletion'), onEvent: action('onEvent'), onLog: action('onLog'), onError: (error) => {
|
|
27
|
-
action('onError');
|
|
28
|
-
console.error(error);
|
|
29
|
-
} }));
|
|
30
|
-
return (_jsxs("div", { className: "d-flex", children: [_jsx("div", { style: { flexGrow: 1, backgroundColor: '#EEE', textAlign: 'center' }, children: " NOT-DF " }), _jsx("div", { style: { width, backgroundColor: 'white' }, children: getDF() }), _jsx("div", { style: { flexGrow: 1, backgroundColor: '#EEE', textAlign: 'center' }, children: " NOT-DF " })] }));
|
|
31
|
-
}
|
|
32
|
-
const imageLayoutStep = {
|
|
33
|
-
id: 'step-id',
|
|
34
|
-
title: 'Dynamic Flow Step',
|
|
35
|
-
description: 'This is a step in the dynamic flow.',
|
|
36
|
-
schemas: [],
|
|
37
|
-
layout: [
|
|
38
|
-
{
|
|
39
|
-
type: 'image',
|
|
40
|
-
size: 'xs',
|
|
41
|
-
content: {
|
|
42
|
-
uri: 'https://placehold.co/600x600?text=Cat',
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
type: 'image',
|
|
47
|
-
size: 'sm',
|
|
48
|
-
content: {
|
|
49
|
-
uri: 'https://placehold.co/600x600?text=Cat',
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
type: 'image',
|
|
54
|
-
size: 'md',
|
|
55
|
-
content: {
|
|
56
|
-
uri: 'https://placehold.co/600x600?text=Cat',
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
type: 'image',
|
|
61
|
-
size: 'lg',
|
|
62
|
-
content: {
|
|
63
|
-
uri: 'https://placehold.co/600x600?text=Cat',
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
type: 'image',
|
|
68
|
-
size: 'xl',
|
|
69
|
-
content: {
|
|
70
|
-
uri: 'https://placehold.co/600x600?text=Cat',
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { action } from 'storybook/actions';
|
|
3
|
-
import { layouts, schemas, misc, step } from '@wise/dynamic-flow-fixtures';
|
|
4
|
-
import { DynamicFlow } from '../index';
|
|
5
|
-
import { fixtureHttpClient } from './utils/fixtureHttpClient';
|
|
6
|
-
const fixtures = Object.assign(Object.assign(Object.assign(Object.assign({}, schemas), layouts), misc), step);
|
|
7
|
-
function DynamicFlowRenderer({ initialStepName = '', }) {
|
|
8
|
-
const selectedStep = fixtures[initialStepName] || {};
|
|
9
|
-
const parsedStep = typeof selectedStep === 'string' ? JSON.parse(selectedStep) : selectedStep;
|
|
10
|
-
const props = {
|
|
11
|
-
flowId: 'storybook',
|
|
12
|
-
customFetch: fixtureHttpClient,
|
|
13
|
-
onCompletion: action('onCompletion'),
|
|
14
|
-
onError: action('onError'),
|
|
15
|
-
onEvent: action('onEvent'),
|
|
16
|
-
onLog: action('onLog'),
|
|
17
|
-
};
|
|
18
|
-
return (_jsx(DynamicFlow, Object.assign({}, props, { initialAction: { method: 'GET', url: `/steps/${initialStepName}` } }), parsedStep.id));
|
|
19
|
-
}
|
|
20
|
-
const meta = {
|
|
21
|
-
title: 'Multi-fixture',
|
|
22
|
-
component: DynamicFlowRenderer,
|
|
23
|
-
};
|
|
24
|
-
export const AllFixtures = {
|
|
25
|
-
argTypes: {
|
|
26
|
-
initialStepName: {
|
|
27
|
-
label: 'Initial Step',
|
|
28
|
-
control: 'select',
|
|
29
|
-
options: Object.keys(fixtures),
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
args: { initialStepName: Object.keys(fixtures)[1], revampEnabled: false },
|
|
33
|
-
parameters: {
|
|
34
|
-
chromatic: { disableSnapshot: true },
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
export default meta;
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { action } from 'storybook/actions';
|
|
3
|
-
import { Button } from '@transferwise/components';
|
|
4
|
-
import { useRef, useState } from 'react';
|
|
5
|
-
import { DynamicFlowWithRef } from '..';
|
|
6
|
-
import { fixtureHttpClient } from './utils/fixtureHttpClient';
|
|
7
|
-
const step = {
|
|
8
|
-
id: 'dynamic-form-story',
|
|
9
|
-
title: 'Dynamic Form',
|
|
10
|
-
schemas: [
|
|
11
|
-
{
|
|
12
|
-
$id: '#form',
|
|
13
|
-
type: 'object',
|
|
14
|
-
displayOrder: ['name', 'city'],
|
|
15
|
-
required: ['name'],
|
|
16
|
-
properties: {
|
|
17
|
-
name: { type: 'string', title: 'Name', minLength: 2 },
|
|
18
|
-
city: {
|
|
19
|
-
title: 'City',
|
|
20
|
-
oneOf: [
|
|
21
|
-
{ title: 'London', const: 'London', icon: { name: 'flag-gb' } },
|
|
22
|
-
{ title: 'Paris', const: 'Paris', icon: { name: 'flag-fr' } },
|
|
23
|
-
{ title: 'New York', const: 'New York', icon: { name: 'flag-us' } },
|
|
24
|
-
],
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
layout: [
|
|
30
|
-
{
|
|
31
|
-
type: 'form',
|
|
32
|
-
schemaId: '#form',
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
};
|
|
36
|
-
function DynamicFlowWithRefStory() {
|
|
37
|
-
const ref = useRef(null);
|
|
38
|
-
const props = {
|
|
39
|
-
flowId: 'storybook',
|
|
40
|
-
analyticsId: 'storybook',
|
|
41
|
-
customFetch: fixtureHttpClient,
|
|
42
|
-
onValueChange: action('onValueChange'),
|
|
43
|
-
onError: action('onError'),
|
|
44
|
-
onEvent: action('onEvent'),
|
|
45
|
-
onLog: action('onLog'),
|
|
46
|
-
};
|
|
47
|
-
const [currentValue, setCurrentValue] = useState('');
|
|
48
|
-
const [isValid, setValid] = useState(null);
|
|
49
|
-
const backgroundColor = isValid === null ? '#eeeeee' : isValid ? '#eeffee' : '#ffeeee';
|
|
50
|
-
const validityText = isValid === null ? '' : isValid ? '✅ valid\n\n' : '❌ invalid\n\n';
|
|
51
|
-
return (_jsxs(_Fragment, { children: [_jsx(DynamicFlowWithRef, Object.assign({ ref: ref }, props, { initialStep: step, onValueChange: async () => {
|
|
52
|
-
var _a;
|
|
53
|
-
var _b;
|
|
54
|
-
const newValue = (_b = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.getValue()) !== null && _b !== void 0 ? _b : null;
|
|
55
|
-
setCurrentValue(JSON.stringify(newValue, null, 2));
|
|
56
|
-
}, onCompletion: () => { } }), JSON.stringify(step)), _jsx(Button, { onClick: async () => {
|
|
57
|
-
var _a;
|
|
58
|
-
var _b;
|
|
59
|
-
const ok = (_b = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.validate()) !== null && _b !== void 0 ? _b : false;
|
|
60
|
-
setValid(ok);
|
|
61
|
-
}, children: "validate()" }), _jsx("hr", {}), _jsxs("pre", { style: { backgroundColor }, children: [validityText, currentValue] })] }));
|
|
62
|
-
}
|
|
63
|
-
const meta = {
|
|
64
|
-
title: 'Dynamic Form',
|
|
65
|
-
component: DynamicFlowWithRefStory,
|
|
66
|
-
};
|
|
67
|
-
export const AllFixtures = {
|
|
68
|
-
parameters: {
|
|
69
|
-
chromatic: { disableSnapshot: true },
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
export default meta;
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { action } from 'storybook/actions';
|
|
3
|
-
import { layouts, schemas } from '@wise/dynamic-flow-fixtures';
|
|
4
|
-
import { useMemo, useState } from 'react';
|
|
5
|
-
import { DynamicFlow } from '../dynamicFlow/DynamicFlow';
|
|
6
|
-
const fixtures = Object.assign(Object.assign({}, schemas), layouts);
|
|
7
|
-
export function Editable({ initialStepName = '' }) {
|
|
8
|
-
const selectedStep = fixtures[initialStepName] || {};
|
|
9
|
-
const selectedInitialStep = JSON.stringify(selectedStep, null, 2);
|
|
10
|
-
return _jsx(InteractiveDemo, { selectedInitialStep: selectedInitialStep }, selectedInitialStep);
|
|
11
|
-
}
|
|
12
|
-
function InteractiveDemo({ selectedInitialStep }) {
|
|
13
|
-
const [initialStatusCode, setInitialStatusCode] = useState(200);
|
|
14
|
-
const [initialStep, setInitialStep] = useState(selectedInitialStep);
|
|
15
|
-
const onTextAreaChange = (event) => {
|
|
16
|
-
setInitialStep(event.target.value);
|
|
17
|
-
};
|
|
18
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsx("h3", { children: "Editable Demo" }), _jsx("p", { children: "You can specify a response status code and body, and DF will load your step below." }), _jsxs("fieldset", { children: [_jsx("label", { htmlFor: "status-code", children: "Response Status code: " }), _jsx(StatusCodeSelect, { id: "status-code", state: [initialStatusCode, setInitialStatusCode] })] }), _jsxs("fieldset", { children: [_jsx("label", { htmlFor: "textarea", children: "Response Body:" }), _jsx(InvalidJsonWarning, { initialStep: initialStep }), _jsx("textarea", { id: "textarea", wrap: "off", rows: 40, style: {
|
|
19
|
-
fontFamily: 'monospace',
|
|
20
|
-
fontSize: '0.9em',
|
|
21
|
-
width: '100%',
|
|
22
|
-
maxHeight: '200px',
|
|
23
|
-
}, value: initialStep, onChange: onTextAreaChange })] })] }), isValidJson(initialStep) ? (_jsx(DynamicFlow, { flowId: "storybook", customFetch: fetch, initialStep: JSON.parse(initialStep), onCompletion: action('onCompletion'), onError: (error) => {
|
|
24
|
-
action('onError')(error);
|
|
25
|
-
console.error(error);
|
|
26
|
-
} }, `${initialStep}-${initialStatusCode}`)) : null] }));
|
|
27
|
-
}
|
|
28
|
-
function InvalidJsonWarning({ initialStep }) {
|
|
29
|
-
const validJson = useMemo(() => isValidJson(initialStep), [initialStep]);
|
|
30
|
-
return !validJson ? (_jsx("p", { children: "\u274C Invalid syntax or missing elements are preventing the JSON code you entered from being parsed." })) : null;
|
|
31
|
-
}
|
|
32
|
-
const isValidJson = (value) => {
|
|
33
|
-
try {
|
|
34
|
-
JSON.parse(value);
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
catch (_a) {
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
function StatusCodeSelect({ id, state: [value, setValue], }) {
|
|
42
|
-
return (_jsxs("select", { id: id, value: value, onChange: (event) => setValue(Number.parseInt(event.target.value, 10)), children: [_jsx("option", { children: "200" }), _jsx("option", { children: "400" }), _jsx("option", { children: "500" })] }));
|
|
43
|
-
}
|
|
44
|
-
export default {
|
|
45
|
-
component: Editable,
|
|
46
|
-
title: 'Multi-fixture',
|
|
47
|
-
parameters: {
|
|
48
|
-
chromatic: { disableSnapshot: true },
|
|
49
|
-
},
|
|
50
|
-
argTypes: {
|
|
51
|
-
initialStepName: {
|
|
52
|
-
label: 'Initial Step',
|
|
53
|
-
control: 'select',
|
|
54
|
-
options: Object.keys(fixtures),
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
args: { initialStepName: Object.keys(fixtures)[0] },
|
|
58
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { action } from 'storybook/actions';
|
|
3
|
-
import { DynamicFlow } from '../dynamicFlow/DynamicFlow';
|
|
4
|
-
export default {
|
|
5
|
-
title: 'Initialisation',
|
|
6
|
-
component: DynamicFlow,
|
|
7
|
-
};
|
|
8
|
-
const mockFetch = async (url, init) => {
|
|
9
|
-
action('mockFetch')(url, init);
|
|
10
|
-
switch (url) {
|
|
11
|
-
case '/first-step':
|
|
12
|
-
return new Response(JSON.stringify({
|
|
13
|
-
id: 'first-step',
|
|
14
|
-
title: 'First Step',
|
|
15
|
-
layout: [],
|
|
16
|
-
schemas: [],
|
|
17
|
-
}));
|
|
18
|
-
default:
|
|
19
|
-
return new Response(null, { status: 404 });
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
const onCompletion = action('onCompletion');
|
|
23
|
-
const onError = action('onError');
|
|
24
|
-
const onEvent = action('onEvent');
|
|
25
|
-
const onLog = action('onLog');
|
|
26
|
-
const initialActionValid = { method: 'GET', url: '/first-step' };
|
|
27
|
-
export const InitialisationWithSuccessfulStep = {
|
|
28
|
-
render: () => (_jsx(DynamicFlow, { flowId: "initialisation-telemetry", customFetch: mockFetch, initialAction: initialActionValid, onCompletion: onCompletion, onError: onError, onEvent: onEvent, onLog: onLog })),
|
|
29
|
-
};
|
|
30
|
-
const initialActionInvalid = { method: 'GET', url: '/invalid-step' };
|
|
31
|
-
export const InitialisationWith404Step = {
|
|
32
|
-
render: () => (_jsx(DynamicFlow, { flowId: "initialisation-telemetry", customFetch: mockFetch, initialAction: initialActionInvalid, onCompletion: onCompletion, onError: onError, onEvent: onEvent, onLog: onLog })),
|
|
33
|
-
};
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { action } from 'storybook/actions';
|
|
3
|
-
import { Modal, Button } from '@transferwise/components';
|
|
4
|
-
import { useState } from 'react';
|
|
5
|
-
import { DynamicFlow } from '../dynamicFlow/DynamicFlow';
|
|
6
|
-
const httpClient = async (input, init) => {
|
|
7
|
-
action('httpClient')(input, init);
|
|
8
|
-
return fetch(input, init);
|
|
9
|
-
};
|
|
10
|
-
export default {
|
|
11
|
-
component: DynamicFlow,
|
|
12
|
-
title: 'Revamp/Features/Pinned Buttons',
|
|
13
|
-
parameters: {
|
|
14
|
-
chromatic: { disableSnapshot: true },
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
export function Basic() {
|
|
18
|
-
return _jsx(DynamicFlow, Object.assign({}, defaultProps, { initialStep: getStep(20) }));
|
|
19
|
-
}
|
|
20
|
-
export function BasicMobileWeb() {
|
|
21
|
-
return _jsx(DynamicFlow, Object.assign({}, defaultProps, { initialStep: getStep(20) }));
|
|
22
|
-
}
|
|
23
|
-
BasicMobileWeb.globals = {
|
|
24
|
-
viewport: { value: 'mobile2' },
|
|
25
|
-
};
|
|
26
|
-
export function InAModal() {
|
|
27
|
-
const [open, setOpen] = useState(true);
|
|
28
|
-
return (_jsxs(_Fragment, { children: [_jsx(Button, { onClick: () => setOpen(true), children: "Open Modal" }), _jsx(Modal, { title: "Modal Title", open: open, body: _jsx(DynamicFlow, Object.assign({}, defaultProps, { initialStep: getStep(10) })), onClose: () => setOpen(false) })] }));
|
|
29
|
-
}
|
|
30
|
-
export function InAModalMobileWeb() {
|
|
31
|
-
const [open, setOpen] = useState(true);
|
|
32
|
-
return (_jsxs(_Fragment, { children: [_jsx(Button, { onClick: () => setOpen(true), children: "Open Modal (large phone)" }), _jsx(Modal, { title: "Modal Title", open: open, body: _jsx(DynamicFlow, Object.assign({}, defaultProps, { initialStep: getStep(10) })), onClose: () => setOpen(false) })] }));
|
|
33
|
-
}
|
|
34
|
-
InAModalMobileWeb.globals = {
|
|
35
|
-
viewport: { value: 'mobile2' },
|
|
36
|
-
};
|
|
37
|
-
export function InAModalInAModal() {
|
|
38
|
-
const [openFirst, setOpenFirst] = useState(true);
|
|
39
|
-
const [openSecond, setOpenSecond] = useState(true);
|
|
40
|
-
return (_jsxs(_Fragment, { children: [_jsx(Button, { onClick: () => setOpenFirst(true), children: "Open First Modal" }), _jsx(Modal, { title: "First Modal", open: openFirst, body: _jsx(Button, { onClick: () => setOpenSecond(true), children: "Open Second Modal" }), scroll: "content", onClose: () => setOpenFirst(false) }), _jsx(Modal, { title: "Second Modal", open: openSecond, body: _jsx(DynamicFlow, Object.assign({}, defaultProps, { initialStep: getStep(10) })), scroll: "content", onClose: () => setOpenSecond(false) })] }));
|
|
41
|
-
}
|
|
42
|
-
const defaultProps = {
|
|
43
|
-
flowId: 'storybook',
|
|
44
|
-
httpClient,
|
|
45
|
-
loaderConfig: { size: 'xl', initial: true, submission: false },
|
|
46
|
-
features: {
|
|
47
|
-
pinnedButtons: true,
|
|
48
|
-
},
|
|
49
|
-
onCompletion: action('onCompletion'),
|
|
50
|
-
onError: action('onError'),
|
|
51
|
-
onEvent: action('onEvent'),
|
|
52
|
-
onLog: action('onLog'),
|
|
53
|
-
};
|
|
54
|
-
const getStep = (numberOfParagraphs) => ({
|
|
55
|
-
id: 'id',
|
|
56
|
-
title: 'Heading',
|
|
57
|
-
schemas: [],
|
|
58
|
-
layout: [
|
|
59
|
-
...Array.from({ length: numberOfParagraphs }, () => ({
|
|
60
|
-
text: 'Lorem ipsum lorem ipsum amet, consectetur adipiscing elit. Toolbarum buttonis dynamicus flowus adaptare semper est laboriosum. Frustratio crescit cum mutationibus constantibus, et semper nova repositione buttonorum. Complexitas crescit, et usus seamless conservare fit arduum, quasi pugna contra interfaciem mutantem. Lorem ipsum lorem ipsum amet, consectetur adipiscing elit. Toolbarum buttonis dynamicus flowus adaptare semper est laboriosum. Frustratio crescit cum mutationibus constantibus, et semper nova repositione buttonorum. Complexitas crescit, et usus seamless conservare fit arduum, quasi pugna contra interfaciem mutantem. Lorem ipsum lorem ipsum amet, consectetur adipiscing elit. Toolbarum buttonis dynamicus flowus adaptare semper est laboriosum. Frustratio crescit cum mutationibus constantibus, et semper nova repositione buttonorum. Complexitas crescit, et usus seamless conservare fit arduum, quasi pugna contra interfaciem mutantem. Lorem ipsum lorem ipsum amet, consectetur adipiscing elit. Toolbarum buttonis dynamicus flowus adaptare semper est laboriosum. Frustratio crescit cum mutationibus constantibus, et semper nova repositione buttonorum. Complexitas crescit, et usus seamless conservare fit arduum, quasi pugna contra interfaciem mutantem.',
|
|
61
|
-
type: 'paragraph',
|
|
62
|
-
})),
|
|
63
|
-
{
|
|
64
|
-
type: 'button',
|
|
65
|
-
title: 'I am the first pinned button',
|
|
66
|
-
control: 'primary',
|
|
67
|
-
action: {
|
|
68
|
-
url: '/v2/accounts',
|
|
69
|
-
method: 'POST',
|
|
70
|
-
},
|
|
71
|
-
pinOrder: 0,
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
type: 'button',
|
|
75
|
-
title: 'I am the second',
|
|
76
|
-
context: 'negative',
|
|
77
|
-
control: 'secondary',
|
|
78
|
-
action: {
|
|
79
|
-
url: '/v2/accounts',
|
|
80
|
-
method: 'POST',
|
|
81
|
-
},
|
|
82
|
-
pinOrder: 1,
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
type: 'button',
|
|
86
|
-
title: 'I am not pinned',
|
|
87
|
-
control: 'tertiary',
|
|
88
|
-
action: {
|
|
89
|
-
url: '/v2/accounts',
|
|
90
|
-
method: 'POST',
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
|
-
});
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
/* eslint-disable no-console */
|
|
3
|
-
import { action } from 'storybook/actions';
|
|
4
|
-
import { DynamicFlow } from '../index';
|
|
5
|
-
import { useCallback } from 'react';
|
|
6
|
-
export default {
|
|
7
|
-
component: DynamicFlow,
|
|
8
|
-
title: 'Dev Tools/Features',
|
|
9
|
-
parameters: {
|
|
10
|
-
chromatic: { disableSnapshot: true },
|
|
11
|
-
},
|
|
12
|
-
};
|
|
13
|
-
export function SCAIntegration() {
|
|
14
|
-
// const [isModalOpen, setIsModalOpen] = useState(false);
|
|
15
|
-
const customFetch = useCallback(async (input, init) => {
|
|
16
|
-
action('httpClient')(input, init === null || init === void 0 ? void 0 : init.body);
|
|
17
|
-
await wait(250);
|
|
18
|
-
// simulate SCARequest rejecting when user closes the modal
|
|
19
|
-
throw new Error('SCA_MODAL_CLOSED');
|
|
20
|
-
}, []);
|
|
21
|
-
return (_jsx(DynamicFlow, { flowId: "new-df-flow-id", customFetch: customFetch, initialStep: initialStep, onCompletion: action('onCompletion'), onEvent: action('onEvent'), onLog: action('onLog'), onError: (error) => {
|
|
22
|
-
action('onError');
|
|
23
|
-
console.error(error);
|
|
24
|
-
} }));
|
|
25
|
-
}
|
|
26
|
-
const wait = async (ms) => {
|
|
27
|
-
return new Promise((resolve) => {
|
|
28
|
-
setTimeout(() => {
|
|
29
|
-
resolve(true);
|
|
30
|
-
}, ms);
|
|
31
|
-
});
|
|
32
|
-
};
|
|
33
|
-
const initialStep = {
|
|
34
|
-
id: 'step-id',
|
|
35
|
-
title: 'Enter your email',
|
|
36
|
-
description: "When you submit we'll simulate the SCARequest rejecting with 'SCA_MODAL_CLOSED'",
|
|
37
|
-
schemas: [
|
|
38
|
-
{
|
|
39
|
-
$id: '#schema',
|
|
40
|
-
type: 'object',
|
|
41
|
-
displayOrder: ['key'],
|
|
42
|
-
properties: {
|
|
43
|
-
key: {
|
|
44
|
-
minLength: 4,
|
|
45
|
-
title: 'Email',
|
|
46
|
-
control: 'email',
|
|
47
|
-
type: 'string',
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
],
|
|
52
|
-
layout: [
|
|
53
|
-
{
|
|
54
|
-
type: 'paragraph',
|
|
55
|
-
text: 'There should be no error message in this page after submission.',
|
|
56
|
-
align: 'center',
|
|
57
|
-
},
|
|
58
|
-
{ schemaId: '#schema', type: 'form' },
|
|
59
|
-
{
|
|
60
|
-
type: 'button',
|
|
61
|
-
title: 'Continue',
|
|
62
|
-
action: { url: '/submit' },
|
|
63
|
-
control: 'primary',
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
navigation: { back: { title: 'Back', action: { url: '/go-back', method: 'GET' } } },
|
|
67
|
-
};
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { action } from 'storybook/actions';
|
|
2
|
-
import { layouts, schemas, responses } from '@wise/dynamic-flow-fixtures';
|
|
3
|
-
export const getObjectKeys = Object.keys;
|
|
4
|
-
const fixtures = Object.assign(Object.assign({}, schemas), layouts);
|
|
5
|
-
const isObject = (val) => typeof val === 'object' && val !== null;
|
|
6
|
-
export const fixtureHttpClient = async (input, init) => {
|
|
7
|
-
action('httpClient')(input, init);
|
|
8
|
-
const url = getURL(input);
|
|
9
|
-
if (url.pathname.startsWith('/steps/')) {
|
|
10
|
-
return respondWithFixture(fixtures, url, init);
|
|
11
|
-
}
|
|
12
|
-
if (url.pathname.startsWith('/responses/')) {
|
|
13
|
-
return respondWithFixture(responses, url, init);
|
|
14
|
-
}
|
|
15
|
-
if (url.pathname.startsWith('/validate')) {
|
|
16
|
-
return new Response(JSON.stringify({ message: 'Validation-async OK' }));
|
|
17
|
-
}
|
|
18
|
-
return new Response(null, { status: 404 });
|
|
19
|
-
};
|
|
20
|
-
const getURL = (input) => {
|
|
21
|
-
if (input instanceof URL) {
|
|
22
|
-
return input;
|
|
23
|
-
}
|
|
24
|
-
if (input instanceof Request) {
|
|
25
|
-
return new URL(input.url, 'http://foo');
|
|
26
|
-
}
|
|
27
|
-
return new URL(input, 'http://foo');
|
|
28
|
-
};
|
|
29
|
-
const respondWithFixture = async (fixtureList, url, init) => {
|
|
30
|
-
var _a;
|
|
31
|
-
const fixtureNames = getObjectKeys(fixtureList);
|
|
32
|
-
const name = url.pathname
|
|
33
|
-
.split('/')
|
|
34
|
-
.filter((part) => Boolean(part))
|
|
35
|
-
.pop();
|
|
36
|
-
if (fixtureNames.includes(name !== null && name !== void 0 ? name : '')) {
|
|
37
|
-
const fixture = fixtureList[name];
|
|
38
|
-
// by convention if the url contains a "delay" query parameter, we delay the response
|
|
39
|
-
if (url.searchParams.has('delay')) {
|
|
40
|
-
await new Promise((resolve) => {
|
|
41
|
-
setTimeout(resolve, Number(url.searchParams.get('delay')));
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
// by convention if the url contains a "refresh"query parameterm we use the payload as model
|
|
45
|
-
if (url.searchParams.has('refresh') &&
|
|
46
|
-
(init === null || init === void 0 ? void 0 : init.body) &&
|
|
47
|
-
typeof init.body === 'string' &&
|
|
48
|
-
isObject(fixture)) {
|
|
49
|
-
const body = JSON.parse(init.body);
|
|
50
|
-
return new Response(JSON.stringify(Object.assign(Object.assign({}, fixture), { model: Object.assign(Object.assign({}, ((_a = fixture.model) !== null && _a !== void 0 ? _a : {})), body) })));
|
|
51
|
-
}
|
|
52
|
-
if (url.pathname.includes('exit')) {
|
|
53
|
-
return new Response(JSON.stringify(fixture), { headers: { 'X-DF-Exit': 'true' } });
|
|
54
|
-
}
|
|
55
|
-
return new Response(JSON.stringify(fixture));
|
|
56
|
-
}
|
|
57
|
-
action('ERROR 404')(url);
|
|
58
|
-
return new Response(null, { status: 404 });
|
|
59
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Provider as ComponentProvider, DEFAULT_LANG, DEFAULT_LOCALE, SnackbarProvider, translations as componentTranslations, getLangFromLocale, } from '@transferwise/components';
|
|
3
|
-
import { ThemeProvider } from '@wise/components-theming';
|
|
4
|
-
import { translations } from '@wise/dynamic-flow-client';
|
|
5
|
-
const locale = DEFAULT_LOCALE;
|
|
6
|
-
const lang = getLangFromLocale(locale) || DEFAULT_LANG;
|
|
7
|
-
const messages = Object.assign(Object.assign({}, componentTranslations[lang]), translations[lang]);
|
|
8
|
-
function NeptuneProviders({ children }) {
|
|
9
|
-
return (_jsx(ThemeProvider, { theme: "personal", screenMode: "light", children: _jsx(SnackbarProvider, { children: _jsx(ComponentProvider, { i18n: { locale, messages }, children: children }) }) }));
|
|
10
|
-
}
|
|
11
|
-
export default NeptuneProviders;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export const respondWith = async (data, init) => new Response(data == null ? null : JSON.stringify(data), init);
|
|
2
|
-
export const respondWithDelay = async (data, delayMs, init) => new Promise((resolve) => {
|
|
3
|
-
setTimeout(() => {
|
|
4
|
-
resolve(new Response(JSON.stringify(data), init));
|
|
5
|
-
}, delayMs);
|
|
6
|
-
});
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { render } from '@testing-library/react';
|
|
3
|
-
import NeptuneProviders from './NeptuneProviders';
|
|
4
|
-
export const renderWithProviders = (children, options) => {
|
|
5
|
-
const renderedResult = render(_jsx(NeptuneProviders, { children: children }), options);
|
|
6
|
-
return Object.assign(Object.assign({}, renderedResult), { rerender: (ui, renderOptions) => renderWithProviders(ui, Object.assign({ container: renderedResult.container }, renderOptions)) });
|
|
7
|
-
};
|
package/build/test-utils/wait.js
DELETED