@transferwise/components 46.53.0 → 46.54.1
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/i18n/de.json +2 -0
- package/build/i18n/de.json.js +2 -0
- package/build/i18n/de.json.js.map +1 -1
- package/build/i18n/de.json.mjs +2 -0
- package/build/i18n/de.json.mjs.map +1 -1
- package/build/i18n/en.json +1 -0
- package/build/i18n/en.json.js +1 -0
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +1 -0
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/i18n/es.json +2 -0
- package/build/i18n/es.json.js +2 -0
- package/build/i18n/es.json.js.map +1 -1
- package/build/i18n/es.json.mjs +2 -0
- package/build/i18n/es.json.mjs.map +1 -1
- package/build/i18n/fr.json +2 -0
- package/build/i18n/fr.json.js +2 -0
- package/build/i18n/fr.json.js.map +1 -1
- package/build/i18n/fr.json.mjs +2 -0
- package/build/i18n/fr.json.mjs.map +1 -1
- package/build/i18n/hu.json +2 -0
- package/build/i18n/hu.json.js +2 -0
- package/build/i18n/hu.json.js.map +1 -1
- package/build/i18n/hu.json.mjs +2 -0
- package/build/i18n/hu.json.mjs.map +1 -1
- package/build/i18n/id.json +2 -0
- package/build/i18n/id.json.js +2 -0
- package/build/i18n/id.json.js.map +1 -1
- package/build/i18n/id.json.mjs +2 -0
- package/build/i18n/id.json.mjs.map +1 -1
- package/build/i18n/it.json +2 -0
- package/build/i18n/it.json.js +2 -0
- package/build/i18n/it.json.js.map +1 -1
- package/build/i18n/it.json.mjs +2 -0
- package/build/i18n/it.json.mjs.map +1 -1
- package/build/i18n/ja.json +2 -0
- package/build/i18n/ja.json.js +2 -0
- package/build/i18n/ja.json.js.map +1 -1
- package/build/i18n/ja.json.mjs +2 -0
- package/build/i18n/ja.json.mjs.map +1 -1
- package/build/i18n/pl.json +2 -0
- package/build/i18n/pl.json.js +2 -0
- package/build/i18n/pl.json.js.map +1 -1
- package/build/i18n/pl.json.mjs +2 -0
- package/build/i18n/pl.json.mjs.map +1 -1
- package/build/i18n/pt.json +2 -0
- package/build/i18n/pt.json.js +2 -0
- package/build/i18n/pt.json.js.map +1 -1
- package/build/i18n/pt.json.mjs +2 -0
- package/build/i18n/pt.json.mjs.map +1 -1
- package/build/i18n/ro.json +2 -0
- package/build/i18n/ro.json.js +2 -0
- package/build/i18n/ro.json.js.map +1 -1
- package/build/i18n/ro.json.mjs +2 -0
- package/build/i18n/ro.json.mjs.map +1 -1
- package/build/i18n/ru.json +2 -0
- package/build/i18n/ru.json.js +2 -0
- package/build/i18n/ru.json.js.map +1 -1
- package/build/i18n/ru.json.mjs +2 -0
- package/build/i18n/ru.json.mjs.map +1 -1
- package/build/i18n/th.json +2 -0
- package/build/i18n/th.json.js +2 -0
- package/build/i18n/th.json.js.map +1 -1
- package/build/i18n/th.json.mjs +2 -0
- package/build/i18n/th.json.mjs.map +1 -1
- package/build/i18n/tr.json +2 -0
- package/build/i18n/tr.json.js +2 -0
- package/build/i18n/tr.json.js.map +1 -1
- package/build/i18n/tr.json.mjs +2 -0
- package/build/i18n/tr.json.mjs.map +1 -1
- package/build/i18n/zh-CN.json +2 -0
- package/build/i18n/zh-CN.json.js +2 -0
- package/build/i18n/zh-CN.json.js.map +1 -1
- package/build/i18n/zh-CN.json.mjs +2 -0
- package/build/i18n/zh-CN.json.mjs.map +1 -1
- package/build/i18n/zh-HK.json +2 -0
- package/build/i18n/zh-HK.json.js +2 -0
- package/build/i18n/zh-HK.json.js.map +1 -1
- package/build/i18n/zh-HK.json.mjs +2 -0
- package/build/i18n/zh-HK.json.mjs.map +1 -1
- package/build/main.css +11 -1
- package/build/styles/main.css +11 -1
- package/build/styles/nudge/Nudge.css +1 -1
- package/build/styles/upload/Upload.css +10 -0
- package/build/types/upload/Upload.d.ts +1 -0
- package/build/types/upload/Upload.d.ts.map +1 -1
- package/build/types/upload/Upload.messages.d.ts +4 -0
- package/build/types/upload/Upload.messages.d.ts.map +1 -1
- package/build/types/upload/steps/completeStep/completeStep.d.ts +1 -3
- package/build/types/upload/steps/completeStep/completeStep.d.ts.map +1 -1
- package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts +1 -0
- package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts.map +1 -1
- package/build/upload/Upload.js +26 -12
- package/build/upload/Upload.js.map +1 -1
- package/build/upload/Upload.messages.js +3 -0
- package/build/upload/Upload.messages.js.map +1 -1
- package/build/upload/Upload.messages.mjs +3 -0
- package/build/upload/Upload.messages.mjs.map +1 -1
- package/build/upload/Upload.mjs +26 -12
- package/build/upload/Upload.mjs.map +1 -1
- package/build/upload/steps/completeStep/completeStep.js +15 -30
- package/build/upload/steps/completeStep/completeStep.js.map +1 -1
- package/build/upload/steps/completeStep/completeStep.mjs +16 -31
- package/build/upload/steps/completeStep/completeStep.mjs.map +1 -1
- package/build/upload/steps/uploadImageStep/uploadImageStep.js +56 -32
- package/build/upload/steps/uploadImageStep/uploadImageStep.js.map +1 -1
- package/build/upload/steps/uploadImageStep/uploadImageStep.mjs +56 -32
- package/build/upload/steps/uploadImageStep/uploadImageStep.mjs.map +1 -1
- package/package.json +2 -2
- package/src/i18n/de.json +2 -0
- package/src/i18n/en.json +1 -0
- package/src/i18n/es.json +2 -0
- package/src/i18n/fr.json +2 -0
- package/src/i18n/hu.json +2 -0
- package/src/i18n/id.json +2 -0
- package/src/i18n/it.json +2 -0
- package/src/i18n/ja.json +2 -0
- package/src/i18n/pl.json +2 -0
- package/src/i18n/pt.json +2 -0
- package/src/i18n/ro.json +2 -0
- package/src/i18n/ru.json +2 -0
- package/src/i18n/th.json +2 -0
- package/src/i18n/tr.json +2 -0
- package/src/i18n/zh-CN.json +2 -0
- package/src/i18n/zh-HK.json +2 -0
- package/src/main.css +11 -1
- package/src/nudge/Nudge.css +1 -1
- package/src/nudge/Nudge.less +1 -1
- package/src/upload/Upload.css +10 -0
- package/src/upload/Upload.less +9 -0
- package/src/upload/Upload.messages.ts +4 -0
- package/src/upload/Upload.spec.js +8 -7
- package/src/upload/Upload.story.tsx +1 -0
- package/src/upload/Upload.tsx +39 -20
- package/src/upload/steps/completeStep/completeStep.spec.js +0 -9
- package/src/upload/steps/completeStep/completeStep.tsx +14 -29
- package/src/upload/steps/uploadImageStep/uploadImageStep.spec.js +12 -0
- package/src/upload/steps/uploadImageStep/uploadImageStep.tsx +43 -24
package/src/nudge/Nudge.less
CHANGED
package/src/upload/Upload.css
CHANGED
|
@@ -13,3 +13,13 @@
|
|
|
13
13
|
.tw-droppable-sm {
|
|
14
14
|
min-height: 245px;
|
|
15
15
|
}
|
|
16
|
+
.upload-error-message {
|
|
17
|
+
margin-top: 24px;
|
|
18
|
+
margin-top: var(--padding-medium);
|
|
19
|
+
border-top: 1px solid rgba(0,0,0,0.10196);
|
|
20
|
+
border-top: 1px solid var(--color-border-neutral);
|
|
21
|
+
text-align: start;
|
|
22
|
+
}
|
|
23
|
+
.upload-error-message .alert {
|
|
24
|
+
min-width: 100px;
|
|
25
|
+
}
|
package/src/upload/Upload.less
CHANGED
|
@@ -46,6 +46,7 @@ const props = {
|
|
|
46
46
|
psProcessingText: 'psProcessingText',
|
|
47
47
|
usAccept: 'image/*',
|
|
48
48
|
usButtonText: 'Or Select File',
|
|
49
|
+
usButtonRetryText: 'Try again',
|
|
49
50
|
usDropMessage: 'Drop file to start upload',
|
|
50
51
|
usPlaceholder: 'Drag and drop a file less than 5MB',
|
|
51
52
|
};
|
|
@@ -231,7 +232,7 @@ describe('Upload', () => {
|
|
|
231
232
|
expect(component.find(CompleteStep)).toHaveLength(1);
|
|
232
233
|
});
|
|
233
234
|
|
|
234
|
-
it('step
|
|
235
|
+
it('step UploadImageStep is called with error props', async () => {
|
|
235
236
|
component = mount(<Upload {...props} />);
|
|
236
237
|
const upload = component.children();
|
|
237
238
|
asyncFileRead.mockImplementation(async () => {
|
|
@@ -244,12 +245,12 @@ describe('Upload', () => {
|
|
|
244
245
|
await waitForUpload();
|
|
245
246
|
component.update();
|
|
246
247
|
|
|
247
|
-
expect(component.find(
|
|
248
|
-
...
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
248
|
+
expect(component.find(UploadImageStep).props()).toStrictEqual({
|
|
249
|
+
...UPLOADIMAGE_STEP_PROPS,
|
|
250
|
+
isComplete: false,
|
|
251
|
+
errorMessage: 'csFailureText',
|
|
252
|
+
usButtonText: 'Try again',
|
|
253
|
+
usHelpImage: null,
|
|
253
254
|
});
|
|
254
255
|
});
|
|
255
256
|
|
package/src/upload/Upload.tsx
CHANGED
|
@@ -50,6 +50,7 @@ export interface UploadProps extends WrappedComponentProps {
|
|
|
50
50
|
*/
|
|
51
51
|
usAccept?: string;
|
|
52
52
|
usButtonText?: string;
|
|
53
|
+
usButtonRetryText?: string;
|
|
53
54
|
usDisabled?: boolean;
|
|
54
55
|
usDropMessage?: string;
|
|
55
56
|
usHelpImage?: React.ReactNode;
|
|
@@ -325,6 +326,7 @@ export class Upload extends Component<UploadProps, UploadState> {
|
|
|
325
326
|
usDropMessage,
|
|
326
327
|
usAccept,
|
|
327
328
|
usButtonText,
|
|
329
|
+
usButtonRetryText,
|
|
328
330
|
usDisabled,
|
|
329
331
|
usHelpImage,
|
|
330
332
|
usLabel,
|
|
@@ -359,8 +361,8 @@ export class Upload extends Component<UploadProps, UploadState> {
|
|
|
359
361
|
'tw-droppable-lg droppable-lg': size === 'lg',
|
|
360
362
|
'droppable-dropping': isDroppable,
|
|
361
363
|
'droppable-processing': isProcessing,
|
|
362
|
-
'droppable-complete': isComplete,
|
|
363
|
-
'droppable-negative': isError,
|
|
364
|
+
'droppable-complete': isComplete && !isError,
|
|
365
|
+
'droppable-negative': isError && !isProcessing,
|
|
364
366
|
})}
|
|
365
367
|
onDragEnter={(event) => this.onDragEnter(event)}
|
|
366
368
|
onDragLeave={(event) => this.onDragLeave(event)}
|
|
@@ -383,28 +385,36 @@ export class Upload extends Component<UploadProps, UploadState> {
|
|
|
383
385
|
/>
|
|
384
386
|
)}
|
|
385
387
|
|
|
386
|
-
{
|
|
387
|
-
<ProcessingStep
|
|
388
|
-
isComplete={isComplete}
|
|
389
|
-
isError={isError}
|
|
390
|
-
isSuccess={isSuccess}
|
|
391
|
-
psButtonText={psButtonText || intl.formatMessage(messages.psButtonText)}
|
|
392
|
-
psProcessingText={psProcessingText || intl.formatMessage(messages.psProcessingText)}
|
|
393
|
-
psButtonDisabled={psButtonDisabled}
|
|
394
|
-
onAnimationCompleted={async (status) => this.onAnimationCompleted(status)}
|
|
395
|
-
onClear={(event) => this.handleOnClear(event)}
|
|
396
|
-
/>
|
|
397
|
-
)}
|
|
398
|
-
{/* Starts render the step when isSuccess or isError are true so markup is there when css transition kicks in
|
|
388
|
+
{/* Starts render the step when isSuccess is true so markup is there when css transition kicks in
|
|
399
389
|
css transition to work properly */}
|
|
400
|
-
{(isSuccess ||
|
|
390
|
+
{(isSuccess || isComplete) && !isError && (
|
|
401
391
|
<CompleteStep
|
|
402
392
|
fileName={fileName}
|
|
403
393
|
isComplete={isComplete}
|
|
404
|
-
isError={isError}
|
|
405
394
|
isImage={isImage}
|
|
406
395
|
csButtonText={csButtonText || intl.formatMessage(messages.csButtonText)}
|
|
407
|
-
|
|
396
|
+
csSuccessText={csSuccessText || intl.formatMessage(messages.csSuccessText)}
|
|
397
|
+
uploadedImage={uploadedImage}
|
|
398
|
+
onClear={(event) => this.handleOnClear(event)}
|
|
399
|
+
/>
|
|
400
|
+
)}
|
|
401
|
+
{isError && !isProcessing && (
|
|
402
|
+
<UploadImageStep
|
|
403
|
+
fileDropped={async (file) => {
|
|
404
|
+
this.reset();
|
|
405
|
+
await this.fileDropped(file);
|
|
406
|
+
}}
|
|
407
|
+
isComplete={!isError}
|
|
408
|
+
usAccept={usAccept}
|
|
409
|
+
usButtonText={usButtonRetryText || intl.formatMessage(messages.retry)}
|
|
410
|
+
usDisabled={usDisabled}
|
|
411
|
+
usHelpImage={null}
|
|
412
|
+
usLabel={usLabel}
|
|
413
|
+
usPlaceholder={
|
|
414
|
+
usPlaceholder ||
|
|
415
|
+
intl.formatMessage(messages.usPlaceholder, { maxSize: maxSize / 1000000 })
|
|
416
|
+
}
|
|
417
|
+
errorMessage={this.getErrorMessage(
|
|
408
418
|
response != null &&
|
|
409
419
|
typeof response === 'object' &&
|
|
410
420
|
'status' in response &&
|
|
@@ -412,8 +422,17 @@ export class Upload extends Component<UploadProps, UploadState> {
|
|
|
412
422
|
? response.status
|
|
413
423
|
: undefined,
|
|
414
424
|
)}
|
|
415
|
-
|
|
416
|
-
|
|
425
|
+
/>
|
|
426
|
+
)}
|
|
427
|
+
{isProcessing && (
|
|
428
|
+
<ProcessingStep
|
|
429
|
+
isComplete={isComplete}
|
|
430
|
+
isError={isError}
|
|
431
|
+
isSuccess={isSuccess}
|
|
432
|
+
psButtonText={psButtonText || intl.formatMessage(messages.psButtonText)}
|
|
433
|
+
psProcessingText={psProcessingText || intl.formatMessage(messages.psProcessingText)}
|
|
434
|
+
psButtonDisabled={psButtonDisabled}
|
|
435
|
+
onAnimationCompleted={async (status) => this.onAnimationCompleted(status)}
|
|
417
436
|
onClear={(event) => this.handleOnClear(event)}
|
|
418
437
|
/>
|
|
419
438
|
)}
|
|
@@ -3,7 +3,6 @@ import { shallow } from 'enzyme';
|
|
|
3
3
|
|
|
4
4
|
import Body from '../../../body';
|
|
5
5
|
import Button from '../../../button';
|
|
6
|
-
import StatusIcon from '../../../statusIcon/StatusIcon';
|
|
7
6
|
|
|
8
7
|
import CompleteStep from '.';
|
|
9
8
|
|
|
@@ -41,14 +40,6 @@ describe('CompleteStep', () => {
|
|
|
41
40
|
});
|
|
42
41
|
});
|
|
43
42
|
|
|
44
|
-
describe('when error is true', () => {
|
|
45
|
-
it('renders errorMessage and icon when error is true', () => {
|
|
46
|
-
component = shallow(<CompleteStep {...COMPLETED_STEP_PROPS} isError />);
|
|
47
|
-
expect(component.find('p').text()).toBe(COMPLETED_STEP_PROPS.csFailureText);
|
|
48
|
-
expect(component.find(StatusIcon)).toHaveLength(1);
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
43
|
it('renders button when csButtonText is set up', () => {
|
|
53
44
|
expect(component.find(Button)).toHaveLength(1);
|
|
54
45
|
});
|
|
@@ -3,17 +3,13 @@ import { Document as DocumentIcon } from '@transferwise/icons';
|
|
|
3
3
|
import { Typography } from '../../..';
|
|
4
4
|
import Body from '../../../body';
|
|
5
5
|
import Button from '../../../button';
|
|
6
|
-
import { Sentiment, Size } from '../../../common';
|
|
7
|
-
import StatusIcon from '../../../statusIcon';
|
|
8
6
|
import Title from '../../../title';
|
|
9
7
|
|
|
10
8
|
export interface CompleteStepProps {
|
|
11
9
|
csButtonText: string;
|
|
12
10
|
csSuccessText: string;
|
|
13
|
-
csFailureText: string;
|
|
14
11
|
fileName: string;
|
|
15
12
|
isComplete: boolean;
|
|
16
|
-
isError: boolean;
|
|
17
13
|
isImage: boolean;
|
|
18
14
|
uploadedImage?: string;
|
|
19
15
|
onClear: React.MouseEventHandler<HTMLButtonElement>;
|
|
@@ -21,11 +17,9 @@ export interface CompleteStepProps {
|
|
|
21
17
|
|
|
22
18
|
export default function CompleteStep({
|
|
23
19
|
csButtonText,
|
|
24
|
-
csFailureText,
|
|
25
20
|
csSuccessText,
|
|
26
21
|
fileName,
|
|
27
22
|
isComplete,
|
|
28
|
-
isError,
|
|
29
23
|
isImage,
|
|
30
24
|
onClear,
|
|
31
25
|
uploadedImage,
|
|
@@ -37,34 +31,25 @@ export default function CompleteStep({
|
|
|
37
31
|
className="droppable-card-content d-flex flex-column align-items-center"
|
|
38
32
|
aria-live="polite"
|
|
39
33
|
>
|
|
40
|
-
{
|
|
41
|
-
|
|
42
|
-
<StatusIcon size={Size.LARGE} sentiment={Sentiment.NEGATIVE} />
|
|
43
|
-
{csFailureText && <p className="m-t-2 m-b-0">{csFailureText}</p>}
|
|
44
|
-
</>
|
|
34
|
+
{isImage && uploadedImage ? (
|
|
35
|
+
<img src={uploadedImage} alt="OK" className="thumbnail " />
|
|
45
36
|
) : (
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
<img src={uploadedImage} alt="OK" className="thumbnail " />
|
|
49
|
-
) : (
|
|
50
|
-
<DocumentIcon />
|
|
51
|
-
)}
|
|
37
|
+
<DocumentIcon />
|
|
38
|
+
)}
|
|
52
39
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
)}
|
|
63
|
-
</>
|
|
40
|
+
{fileName && (
|
|
41
|
+
<Body as="p" className="m-b-0">
|
|
42
|
+
{fileName}
|
|
43
|
+
</Body>
|
|
44
|
+
)}
|
|
45
|
+
{csSuccessText && (
|
|
46
|
+
<Title className="caption m-t-1" type={Typography.TITLE_BODY}>
|
|
47
|
+
{csSuccessText}
|
|
48
|
+
</Title>
|
|
64
49
|
)}
|
|
65
50
|
</div>
|
|
66
51
|
{csButtonText && (
|
|
67
|
-
<Button className=
|
|
52
|
+
<Button className="m-t-1" onClick={onClear}>
|
|
68
53
|
{csButtonText}
|
|
69
54
|
</Button>
|
|
70
55
|
)}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Upload as UploadIcon } from '@transferwise/icons';
|
|
2
2
|
import { shallow } from 'enzyme';
|
|
3
|
+
import StatusIcon from '../../../statusIcon/StatusIcon';
|
|
3
4
|
|
|
4
5
|
import UploadImageStep from '.';
|
|
5
6
|
|
|
@@ -13,6 +14,7 @@ describe('uploadImageStep', () => {
|
|
|
13
14
|
usLabel: '',
|
|
14
15
|
usHelpImage: '',
|
|
15
16
|
usPlaceholder: '',
|
|
17
|
+
errorMessage: '',
|
|
16
18
|
};
|
|
17
19
|
let component;
|
|
18
20
|
beforeEach(() => {
|
|
@@ -63,4 +65,14 @@ describe('uploadImageStep', () => {
|
|
|
63
65
|
|
|
64
66
|
expect(component.find('.test-image')).toHaveLength(1);
|
|
65
67
|
});
|
|
68
|
+
|
|
69
|
+
describe('when errorMessage is not empty', () => {
|
|
70
|
+
it('renders errorMessage and icon when error is true', () => {
|
|
71
|
+
component = shallow(
|
|
72
|
+
<UploadImageStep {...UPLOADIMAGE_STEP_PROPS} errorMessage="error message" />,
|
|
73
|
+
);
|
|
74
|
+
expect(component.find('.upload-error-message').text()).toBe('<InlineAlert />');
|
|
75
|
+
expect(component.find(StatusIcon)).toHaveLength(1);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
66
78
|
});
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Upload as UploadIcon } from '@transferwise/icons';
|
|
2
2
|
import { createRef, PureComponent } from 'react';
|
|
3
|
+
import StatusIcon from '../../../statusIcon';
|
|
4
|
+
import { Sentiment, Size } from '../../../common';
|
|
5
|
+
import InlineAlert from '../../../inlineAlert';
|
|
3
6
|
|
|
4
7
|
export interface UploadImageStepProps {
|
|
5
8
|
fileDropped: (file: File) => void;
|
|
@@ -10,6 +13,7 @@ export interface UploadImageStepProps {
|
|
|
10
13
|
usHelpImage: React.ReactNode;
|
|
11
14
|
usLabel: string;
|
|
12
15
|
usPlaceholder: string;
|
|
16
|
+
errorMessage?: string | string[];
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
export default class UploadImageStep extends PureComponent<UploadImageStepProps> {
|
|
@@ -25,6 +29,15 @@ export default class UploadImageStep extends PureComponent<UploadImageStepProps>
|
|
|
25
29
|
|
|
26
30
|
getImage = () => {
|
|
27
31
|
const { usHelpImage, usLabel } = this.props;
|
|
32
|
+
const { errorMessage } = this.props;
|
|
33
|
+
|
|
34
|
+
if (errorMessage) {
|
|
35
|
+
return (
|
|
36
|
+
<div className="d-flex flex-column align-items-center">
|
|
37
|
+
<StatusIcon size={Size.LARGE} sentiment={Sentiment.NEGATIVE} />
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
28
41
|
|
|
29
42
|
if (!usHelpImage) {
|
|
30
43
|
return (
|
|
@@ -42,32 +55,38 @@ export default class UploadImageStep extends PureComponent<UploadImageStepProps>
|
|
|
42
55
|
};
|
|
43
56
|
|
|
44
57
|
render() {
|
|
45
|
-
const { isComplete, usAccept, usButtonText, usDisabled, usLabel, usPlaceholder } =
|
|
58
|
+
const { isComplete, usAccept, usButtonText, usDisabled, usLabel, usPlaceholder, errorMessage } =
|
|
59
|
+
this.props;
|
|
46
60
|
|
|
47
61
|
return (
|
|
48
|
-
<div>
|
|
49
|
-
<div className="droppable-
|
|
50
|
-
<div className="
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
{usButtonText
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
<div className="droppable-default-card" aria-hidden={isComplete}>
|
|
63
|
+
<div className="droppable-card-content">
|
|
64
|
+
<div className="m-b-3">{this.getImage()}</div>
|
|
65
|
+
{usLabel && <h4 className="np-text-title-body m-b-1">{usLabel}</h4>}
|
|
66
|
+
{usPlaceholder && <p className="np-text-body-large m-b-3">{String(usPlaceholder)}</p>}
|
|
67
|
+
<label className={`btn btn-primary btn-md ${usDisabled ? 'disabled' : ''}`}>
|
|
68
|
+
{usButtonText ? (
|
|
69
|
+
<span>{usButtonText}</span>
|
|
70
|
+
) : (
|
|
71
|
+
<UploadIcon size={24} className="m-r-0" />
|
|
72
|
+
)}
|
|
73
|
+
<input
|
|
74
|
+
ref={this.uploadInputRef}
|
|
75
|
+
type="file"
|
|
76
|
+
accept={usAccept === '*' ? undefined : usAccept}
|
|
77
|
+
className="tw-droppable-input hidden"
|
|
78
|
+
disabled={usDisabled}
|
|
79
|
+
name="file-upload"
|
|
80
|
+
onChange={() => this.onManualUpload()}
|
|
81
|
+
/>
|
|
82
|
+
</label>
|
|
83
|
+
{errorMessage && (
|
|
84
|
+
<div className="upload-error-message">
|
|
85
|
+
<div className="m-t-3 has-error">
|
|
86
|
+
<InlineAlert type={Sentiment.NEGATIVE}>{errorMessage}</InlineAlert>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
)}
|
|
71
90
|
</div>
|
|
72
91
|
</div>
|
|
73
92
|
);
|