@zohodesk/dot 1.0.0-temp-213 → 1.0.0-temp-214

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/.cli/propValidation_report.html +1 -1
  2. package/README.md +8 -0
  3. package/assets/Appearance/dark/mode/Dot_DarkMode.module.css +1 -1
  4. package/assets/Appearance/light/mode/Dot_LightMode.module.css +1 -1
  5. package/assets/Appearance/pureDark/mode/Dot_PureDarkMode.module.css +1 -1
  6. package/es/Attachment/Attachment.module.css +7 -3
  7. package/es/AttachmentViewer/Attachment.js +106 -1
  8. package/es/AttachmentViewer/AttachmentViewer.js +114 -28
  9. package/es/AttachmentViewer/AttachmentViewer.module.css +32 -9
  10. package/es/AttachmentViewer/props/defaultProps.js +1 -1
  11. package/es/AttachmentViewer/props/propTypes.js +9 -1
  12. package/es/AttachmentViewer/utils.js +98 -13
  13. package/es/form/fields/CheckBoxField/CheckBoxField.js +7 -9
  14. package/es/form/fields/CurrencyField/CurrencyField.js +5 -5
  15. package/es/form/fields/DateField/DateField.js +7 -8
  16. package/es/form/fields/Fields.module.css +3 -0
  17. package/es/form/fields/MultiSelectField/MultiSelectField.js +5 -6
  18. package/es/form/fields/RadioField/RadioField.js +1 -1
  19. package/es/form/fields/SelectField/SelectField.js +5 -6
  20. package/es/form/fields/TagsMultiSelectField/TagsMultiSelectField.js +6 -8
  21. package/es/form/fields/TextBoxField/TextBoxField.js +7 -7
  22. package/es/form/fields/TextareaField/TextareaField.js +6 -6
  23. package/es/lookup/Lookup/Lookup.js +2 -1
  24. package/es/lookup/Lookup/Lookup.module.css +6 -1
  25. package/es/lookup/Lookup/props/propTypes.js +1 -0
  26. package/es/utils/General.js +23 -1
  27. package/lib/Attachment/Attachment.module.css +7 -3
  28. package/lib/AttachmentViewer/Attachment.js +109 -1
  29. package/lib/AttachmentViewer/AttachmentViewer.js +121 -25
  30. package/lib/AttachmentViewer/AttachmentViewer.module.css +32 -9
  31. package/lib/AttachmentViewer/props/defaultProps.js +1 -1
  32. package/lib/AttachmentViewer/props/propTypes.js +9 -1
  33. package/lib/AttachmentViewer/utils.js +102 -8
  34. package/lib/form/fields/CheckBoxField/CheckBoxField.js +7 -10
  35. package/lib/form/fields/CurrencyField/CurrencyField.js +4 -5
  36. package/lib/form/fields/DateField/DateField.js +6 -9
  37. package/lib/form/fields/Fields.module.css +3 -0
  38. package/lib/form/fields/MultiSelectField/MultiSelectField.js +5 -7
  39. package/lib/form/fields/RadioField/RadioField.js +1 -1
  40. package/lib/form/fields/SelectField/SelectField.js +5 -7
  41. package/lib/form/fields/TagsMultiSelectField/TagsMultiSelectField.js +5 -8
  42. package/lib/form/fields/TextBoxField/TextBoxField.js +6 -8
  43. package/lib/form/fields/TextareaField/TextareaField.js +5 -6
  44. package/lib/lookup/Lookup/Lookup.js +2 -1
  45. package/lib/lookup/Lookup/Lookup.module.css +6 -1
  46. package/lib/lookup/Lookup/props/propTypes.js +1 -0
  47. package/lib/utils/General.js +25 -1
  48. package/package.json +9 -11
  49. package/result.json +1 -0
  50. package/unittest/index.html +37 -0
  51. package/es/common/dot_common.module.css +0 -4
  52. package/lib/common/dot_common.module.css +0 -4
package/README.md CHANGED
@@ -2,9 +2,17 @@
2
2
 
3
3
  In this Library, we Provide Some Basic Components to Build Your Application
4
4
 
5
+
6
+ # 1.7.19
7
+
8
+ - **AttachmentViewer**
9
+ - Added preview support for Videos and Documents (via iframe)
10
+
5
11
  # 1.7.18
6
12
 
7
13
  - Added UNSAFE_ prefix to deprecated lifecycle methods: componentWillMount, componentWillReceiveProps, and componentWillUpdate.
14
+ - **Lookup** - Added container width and containerClass support.
15
+ - **RadioField** - Fixed spacing between label and field
8
16
 
9
17
  # 1.7.17
10
18
 
@@ -221,7 +221,7 @@
221
221
  --zdt_gridstencils_default_border: hsla(218, 23.08%, calc(22.94% + var(--zdc_default_inverse_medium)), calc(1 + var(--zdc_alpha_low)));
222
222
  --zdt_gridstencils_after_bg: hsla(217, 23.23%, calc(19.41% + var(--zdc_default_inverse)), calc(1 + var(--zdc_alpha_high)));
223
223
  --zdt_gridstencils_listbar_bg: hsla(217, 23.23%, calc(19.41% + var(--zdc_default)), calc(1 + var(--zdc_alpha_high)));
224
- --zdt_gridstencils_listbar_gradient_bg /* rtl:as:background-image */: linear-gradient(to left, #383f55 0, #414961 20%, #414961 40%, #383f55 100%);
224
+ --zdt_gridstencils_listbar_gradient_bg: linear-gradient(to left, #383f55 0, #414961 20%, #414961 40%, #383f55 100%);
225
225
 
226
226
  /* icons */
227
227
  --zdt_icons_default: hsla(217, 13.73%, calc(70.00% + var(--zdc_default_inverse)), calc(1 + var(--zdc_alpha_high)));
@@ -221,7 +221,7 @@
221
221
  --zdt_gridstencils_default_border: hsla(0, 0.00%, calc(94.51% + var(--zdc_default_inverse_medium)), calc(1 + var(--zdc_alpha_low)));
222
222
  --zdt_gridstencils_after_bg: hsla(0, 0.00%, calc(92.16% + var(--zdc_default_inverse)), calc(1 + var(--zdc_alpha_high)));
223
223
  --zdt_gridstencils_listbar_bg: hsla(210, 12.50%, calc(96.86% + var(--zdc_default)), calc(1 + var(--zdc_alpha_high)));
224
- --zdt_gridstencils_listbar_gradient_bg /* rtl:as:background-image */: linear-gradient(to left, var(--zd_smoke78) 0, #edeef1 20%, var(--zd_smoke78) 40%, var(--zd_smoke78) 100%);
224
+ --zdt_gridstencils_listbar_gradient_bg: linear-gradient(to left, var(--zd_smoke78) 0, #edeef1 20%, var(--zd_smoke78) 40%, var(--zd_smoke78) 100%);
225
225
 
226
226
  /* icons */
227
227
  --zdt_icons_default: hsla(220, 10.45%, calc(39.41% + var(--zdc_default_inverse)), calc(1 + var(--zdc_alpha_high)));
@@ -221,7 +221,7 @@
221
221
  --zdt_gridstencils_default_border: hsla(0, 2.33%, calc(8.43% + var(--zdc_default_inverse_medium)), calc(1 + var(--zdc_alpha_low)));
222
222
  --zdt_gridstencils_after_bg: hsla(0, 0.00%, calc(16.86% + var(--zdc_default_inverse)), calc(1 + var(--zdc_alpha_high)));
223
223
  --zdt_gridstencils_listbar_bg: hsla(0, 0.00%, calc(16.86% + var(--zdc_default)), calc(1 + var(--zdc_alpha_high)));
224
- --zdt_gridstencils_listbar_gradient_bg /* rtl:as:background-image */: linear-gradient(to left, #212121 0, #262626 20%, #262626 40%, #212121 100%);
224
+ --zdt_gridstencils_listbar_gradient_bg: linear-gradient(to left, #212121 0, #262626 20%, #262626 40%, #212121 100%);
225
225
 
226
226
  /* icons */
227
227
  --zdt_icons_default: hsla(0, 0.00%, calc(60.00% + var(--zdc_default_inverse)), calc(1 + var(--zdc_alpha_high)));
@@ -14,15 +14,15 @@
14
14
  height: 100% ;
15
15
  width: 100% ;
16
16
  position: absolute;
17
- top:0
17
+ top: 0
18
18
  }
19
19
 
20
20
  [dir=ltr] .disableLayer {
21
- left:0
21
+ left: 0
22
22
  }
23
23
 
24
24
  [dir=rtl] .disableLayer {
25
- right:0
25
+ right: 0
26
26
  }
27
27
 
28
28
  .attachmentHover {
@@ -66,6 +66,10 @@
66
66
  height: var(--zd_size40) ;
67
67
  }
68
68
 
69
+ .attachleft {
70
+ padding: var(--zd_size3) ;
71
+ }
72
+
69
73
  [dir=ltr] .attachleft {
70
74
  border-right: 1px solid var(--zdt_attachment_default_border);
71
75
  }
@@ -1,4 +1,6 @@
1
- const UNASSIGNED = 'Unassigned';
1
+ import { getBrowserWithVersion } from "../utils/General";
2
+ import { SUPPORTED_FILE_EXTENSIONS } from "./utils"; // const UNASSIGNED = 'Unassigned';
3
+
2
4
  const BROWSER_SUPPORTED_FILES = ['pdf', 'text', 'txt', 'css', 'jpg', 'jpeg', 'gif', 'png', 'bmp', 'ico', 'sh', 'mp3', 'wav', 'ogg'];
3
5
  export function isAudioFile(fileName) {
4
6
  const extension = getExtensionFromFileName(fileName);
@@ -14,4 +16,107 @@ export function getExtensionFromFileName(fileName) {
14
16
  export function isBrowserSupportedFile(fileName) {
15
17
  const extension = getExtensionFromFileName(fileName);
16
18
  return BROWSER_SUPPORTED_FILES.indexOf(extension) !== -1;
19
+ }
20
+ export function getAttachmentIconDetails(fileName) {
21
+ const extension = (getExtensionFromFileName(fileName) || '').toLowerCase();
22
+
23
+ if (!extension) {
24
+ return 'ZD-GN-fileUnknown';
25
+ }
26
+
27
+ const {
28
+ image,
29
+ doc,
30
+ pdf,
31
+ html,
32
+ ppt,
33
+ zip,
34
+ word,
35
+ xml,
36
+ sheet,
37
+ audio,
38
+ video,
39
+ mail,
40
+ linux,
41
+ css,
42
+ exe,
43
+ event
44
+ } = SUPPORTED_FILE_EXTENSIONS;
45
+
46
+ if (image.includes(extension)) {
47
+ return 'ZD-EF-fileImage';
48
+ }
49
+
50
+ if (doc.includes(extension)) {
51
+ return 'ZD-GN-fileDoc';
52
+ }
53
+
54
+ if (pdf.includes(extension)) {
55
+ return 'ZD-EF-filePdf';
56
+ }
57
+
58
+ if (ppt.includes(extension)) {
59
+ return 'ZD-GN-filePpt';
60
+ }
61
+
62
+ if (zip.includes(extension)) {
63
+ return 'ZD-EF-fileZip';
64
+ }
65
+
66
+ if (word.includes(extension)) {
67
+ const OSName = (navigator.platform || '').toLowerCase();
68
+ return OSName.includes('mac') || OSName.includes('linux') ? 'ZD-EF-fileOffice' : 'ZD-EF-fileWord';
69
+ }
70
+
71
+ if (xml.includes(extension)) {
72
+ return 'ZD-EF-fileXml';
73
+ }
74
+
75
+ if (sheet.includes(extension)) {
76
+ return 'ZD-GN-fileSheet';
77
+ }
78
+
79
+ if (audio.includes(extension)) {
80
+ return 'ZD-EF-fileMp3';
81
+ }
82
+
83
+ if (video.includes(extension)) {
84
+ return 'ZD-EF-fileMp4';
85
+ }
86
+
87
+ if (mail.includes(extension)) {
88
+ return 'ZD-GN-fileMail';
89
+ }
90
+
91
+ if (linux.includes(extension)) {
92
+ return 'ZD-EF-linux';
93
+ }
94
+
95
+ if (css.includes(extension)) {
96
+ return 'ZD-EF-clrCss';
97
+ }
98
+
99
+ if (exe.includes(extension)) {
100
+ return 'ZD-EF-exe';
101
+ }
102
+
103
+ if (event.includes(extension)) {
104
+ return 'ZD-TK-event';
105
+ }
106
+
107
+ if (html.includes(extension)) {
108
+ const browser = (getBrowserWithVersion() || '').toLowerCase();
109
+
110
+ if (browser.includes('chrome') || browser.includes('safari')) {
111
+ return 'ZD-EF-fileXml';
112
+ }
113
+
114
+ if (browser.includes('ie') || browser.includes('edge')) {
115
+ return 'ZD-EF-explorer';
116
+ }
117
+
118
+ return 'ZD-EF-firebox';
119
+ }
120
+
121
+ return 'ZD-GN-fileUnknown';
17
122
  }
@@ -5,16 +5,17 @@ import { Container, Box } from '@zohodesk/components/lib/Layout';
5
5
  import { Icon } from '@zohodesk/icons';
6
6
  import Avatar from '@zohodesk/components/lib/Avatar/Avatar';
7
7
  import { ResponsiveReceiver } from '@zohodesk/components/lib/Responsive/CustomResponsive';
8
+ import Typography from '@zohodesk/components/lib/Typography/Typography';
8
9
  import { getUniqueId } from '@zohodesk/components/lib/Provider/IdProvider';
10
+ import Button from '@zohodesk/components/es/Button/Button';
9
11
  import AttachmentImage from "./AttachmentImage";
10
12
  import Link from "../Link/Link";
11
13
  import IconButton from "../IconButton/IconButton";
12
14
  import FreezeLayer from "../FreezeLayer/FreezeLayer";
13
- import { isAudioFile, getExtensionFromFileName } from "./Attachment";
15
+ import { getExtensionFromFileName, getAttachmentIconDetails } from "./Attachment";
14
16
  import { shallowDiff } from "../utils/General";
17
+ import { checkFileSourcesValidation, FILE_EXTENSIONS } from "./utils";
15
18
  import style from "./AttachmentViewer.module.css";
16
- import { checkFileSourcesValidation } from "./utils";
17
- import audioThumbNail from "../../images/audio_thumbnail.png";
18
19
  export default class AttachmentViewer extends Component {
19
20
  constructor(props) {
20
21
  super(props);
@@ -43,6 +44,26 @@ export default class AttachmentViewer extends Component {
43
44
  this.getUpdateDataList = this.getUpdateDataList.bind(this);
44
45
  this.zoomMaintain = this.zoomMaintain.bind(this);
45
46
  this.handleMenuValidation = this.handleMenuValidation.bind(this);
47
+ this.getPreviewIconData = this.getPreviewIconData.bind(this);
48
+ this.renderIframe = this.renderIframe.bind(this);
49
+ }
50
+
51
+ isImageFileType(fileName) {
52
+ const extension = (getExtensionFromFileName(fileName) || '').toLowerCase();
53
+ if (!extension) return false;
54
+ return FILE_EXTENSIONS.image.map(ext => ext.toLowerCase()).includes(extension);
55
+ }
56
+
57
+ isVideoFileType(fileName) {
58
+ const extension = (getExtensionFromFileName(fileName) || '').toLowerCase();
59
+ if (!extension) return false;
60
+ return FILE_EXTENSIONS.video.map(ext => ext.toLowerCase()).includes(extension);
61
+ }
62
+
63
+ isAudioFileType(fileName) {
64
+ const extension = (getExtensionFromFileName(fileName) || '').toLowerCase();
65
+ if (!extension) return false;
66
+ return FILE_EXTENSIONS.audio.map(ext => ext.toLowerCase()).includes(extension);
46
67
  }
47
68
 
48
69
  componentDidMount() {
@@ -87,13 +108,19 @@ export default class AttachmentViewer extends Component {
87
108
  data,
88
109
  selectedIndex
89
110
  } = this.state;
111
+ const {
112
+ allowedPreviewExtensionsData
113
+ } = this.props;
90
114
  const selectedAttachment = data[selectedIndex] || {};
91
- const selectedAttachmentViewUrl = selectedAttachment.viewUrl;
92
- const selectedAttachmentDownloadUrl = selectedAttachment.downloadUrl;
115
+ const selectedAttachmentViewUrl = selectedAttachment.viewUrl; // const selectedAttachmentDownloadUrl = selectedAttachment.downloadUrl;
116
+
93
117
  const selectedAttachmentName = selectedAttachment.name;
118
+ const selectedAttachmentPreviewUrl = selectedAttachment.previewurl;
94
119
  checkFileSourcesValidation({
95
120
  fileName: selectedAttachmentName,
96
- viewURL: selectedAttachmentViewUrl
121
+ viewURL: selectedAttachmentViewUrl,
122
+ previewUrl: selectedAttachmentPreviewUrl,
123
+ allowedPreviewExtensionsData
97
124
  }).then(fileSourceValidation => {
98
125
  const {
99
126
  isViewURLValid,
@@ -250,7 +277,37 @@ export default class AttachmentViewer extends Component {
250
277
  };
251
278
  }
252
279
 
253
- imgPreviewView() {
280
+ getPreviewIconData(name, size, dataId) {
281
+ const fileUnknown = {
282
+ iconName: 'ZD-GN-fileUnknown',
283
+ iconSize: '40'
284
+ };
285
+ const fileIconName = getAttachmentIconDetails(name);
286
+ const fileDetails = name ? {
287
+ iconName: fileIconName,
288
+ iconSize: size
289
+ } : fileUnknown;
290
+ const {
291
+ iconName,
292
+ iconSize
293
+ } = fileDetails;
294
+ return /*#__PURE__*/React.createElement(Icon, {
295
+ iconClass: style.prevFooterIcon,
296
+ name: iconName,
297
+ size: iconSize,
298
+ "data-id": dataId
299
+ });
300
+ }
301
+
302
+ renderIframe(previewurl) {
303
+ return /*#__PURE__*/React.createElement("iframe", {
304
+ src: previewurl,
305
+ className: style.previewFrame,
306
+ ...this.props.customProps.iframeProps
307
+ });
308
+ }
309
+
310
+ imgPreviewView(downloadUrl) {
254
311
  var _this = this;
255
312
 
256
313
  const {
@@ -262,7 +319,9 @@ export default class AttachmentViewer extends Component {
262
319
  } = this.state;
263
320
  const {
264
321
  maintainZoom,
265
- dataId
322
+ dataId,
323
+ i18nKeys,
324
+ renderUnSupportedElement
266
325
  } = this.props;
267
326
 
268
327
  const getImgStyle = i => {
@@ -299,17 +358,25 @@ export default class AttachmentViewer extends Component {
299
358
  children,
300
359
  dataId = 'attachViewer',
301
360
  customClass = {},
302
- customProps = {}
361
+ customProps = {},
362
+ previewurl,
363
+ type
303
364
  } = data;
304
365
  const {
305
366
  audioProps = {},
306
- imageProps = {}
367
+ imageProps = {},
368
+ videoProps = {}
307
369
  } = customProps;
308
370
  const {
309
371
  customImageClass = '',
310
372
  customChildrenClass = ''
311
373
  } = customClass;
312
374
  const retainZoom = canZoom && selectedIndex == i && maintainZoom;
375
+ const extension = getExtensionFromFileName(name);
376
+ const {
377
+ previewUnsupportedText = "Preview not available for the selected file type.",
378
+ downloadText = "Download"
379
+ } = i18nKeys;
313
380
  return /*#__PURE__*/React.createElement(Container, {
314
381
  className: style.imgBox,
315
382
  id: `imgBox${i}`,
@@ -320,32 +387,52 @@ export default class AttachmentViewer extends Component {
320
387
  }, /*#__PURE__*/React.createElement(Box, {
321
388
  className: style.imgRef,
322
389
  id: `imgPreviewRef${i}`
323
- }, isAudioFile(name) ? selectedIndex == i ? /*#__PURE__*/React.createElement("video", {
324
- autoPlay: true,
390
+ }, selectedIndex == i && /*#__PURE__*/React.createElement(React.Fragment, null, _this.isAudioFileType(name) ? /*#__PURE__*/React.createElement("audio", {
391
+ controls: true,
392
+ className: style.zoomIn,
393
+ "data-id": `${dataId}_audioPreview`,
394
+ "data-test-id": `${dataId}_audioPreview`,
395
+ ...audioProps
396
+ }, /*#__PURE__*/React.createElement("source", {
397
+ src: previewurl || viewUrl,
398
+ type: `audio/${extension}`
399
+ })) : _this.isVideoFileType(name) ? /*#__PURE__*/React.createElement("video", {
325
400
  controls: true,
326
401
  className: style.zoomIn,
327
402
  "data-id": `${dataId}_videoPreview`,
328
403
  "data-test-id": `${dataId}_videoPreview`,
329
- ...audioProps
404
+ ...videoProps
330
405
  }, /*#__PURE__*/React.createElement("source", {
331
406
  src: viewUrl,
332
- type: `audio/${getExtensionFromFileName(name)}`
333
- })) : null : /*#__PURE__*/React.createElement(AttachmentImage, {
407
+ type: `video/${extension}`
408
+ })) : _this.isImageFileType(name) || children ? /*#__PURE__*/React.createElement(AttachmentImage, {
334
409
  customClass: {
335
- customImageClass: `${style.img} ${style.altText}
336
- ${canZoom || retainZoom ? isZoomed ? `${style.zoomedImg} ${style.zoomOutCursor}` : `${style.normalImg} ${style.zoomInCursor}` : ''} ${customImageClass}`,
410
+ customImageClass: `${style.img} ${style.altText} ${canZoom || retainZoom ? isZoomed ? `${style.zoomedImg} ${style.zoomOutCursor}` : `${style.normalImg} ${style.zoomInCursor}` : ''} ${customImageClass}`,
337
411
  customChildrenClass
338
412
  },
339
413
  src: viewUrl,
340
- onClick: isPreviewAttachmentValid ? isZoomed ? _this.zoomOut.bind(_this, i) : e => {
341
- _this.zoomIn(e, i, true);
342
- } : undefined,
414
+ onClick: isPreviewAttachmentValid ? isZoomed ? _this.zoomOut.bind(_this, i) : e => _this.zoomIn(e, i, true) : undefined,
343
415
  alt: name,
344
416
  dataId: dataId,
345
417
  id: `img${i}`,
346
418
  isCover: false,
347
419
  ...imageProps
348
- }, children)));
420
+ }, children) : type === "document" && previewurl != null ? _this.renderIframe(previewurl) : typeof renderUnSupportedElement === 'function' ? renderUnSupportedElement(data) : /*#__PURE__*/React.createElement("div", {
421
+ className: style.previewNone
422
+ }, /*#__PURE__*/React.createElement("div", {
423
+ className: style.fileTypeImg
424
+ }, _this.getPreviewIconData(name, '70')), /*#__PURE__*/React.createElement(Typography, {
425
+ $ui_size: "20",
426
+ $ui_weight: "semibold"
427
+ }, previewUnsupportedText), downloadUrl ? /*#__PURE__*/React.createElement(Link, {
428
+ href: downloadUrl,
429
+ className: style.downloadLink,
430
+ hasReload: true,
431
+ download: true
432
+ }, /*#__PURE__*/React.createElement(Button, {
433
+ palette: "primaryFilled",
434
+ text: downloadText
435
+ })) : null))));
349
436
  });
350
437
  }
351
438
 
@@ -371,7 +458,7 @@ export default class AttachmentViewer extends Component {
371
458
  } = customProps;
372
459
  const totalLen = data.length;
373
460
  const selectedAttachment = data[selectedIndex] || {};
374
- const selectedImgUrl = selectedAttachment.viewUrl;
461
+ const selectedImgUrl = selectedAttachment.previewurl || selectedAttachment.viewUrl;
375
462
  const downloadUrl = selectedAttachment.downloadUrl;
376
463
  let authorHref;
377
464
  let authorName;
@@ -526,7 +613,7 @@ export default class AttachmentViewer extends Component {
526
613
  eleRef: this.setImgBoxRef,
527
614
  scroll: "both",
528
615
  flexible: true
529
- }, this.imgPreviewView()), /*#__PURE__*/React.createElement(Box, {
616
+ }, this.imgPreviewView(downloadUrl)), /*#__PURE__*/React.createElement(Box, {
530
617
  className: `${style.arrowBox} ${uptoTablet ? style.mbleArrowBox : style.nrmlArrowBox} ${totalLen === selectedIndex + 1 ? style.hidden : ''}`,
531
618
  onClick: this.changeSelectedIndex.bind(this, selectedIndex + 1),
532
619
  "data-title": i18nKeys.nextText,
@@ -582,20 +669,19 @@ export default class AttachmentViewer extends Component {
582
669
  let {
583
670
  thumbnail
584
671
  } = item;
672
+ const isImageFileType = this.isImageFileType(name) || thumbnail;
585
673
  const {
586
674
  customImageClass = '',
587
675
  customChildrenClass = ''
588
676
  } = customClass;
589
- thumbnail = isAudioFile(name) ? thumbnail || audioThumbNail : thumbnail; //fallback thumbnail for audio
590
-
591
677
  return /*#__PURE__*/React.createElement(Box, {
592
- className: `${style.imgItem} ${index === selectedIndex ? style.selected : ''}`,
678
+ className: `${style.imgItem} ${index === selectedIndex ? style.selected : ''} ${isImageFileType ? '' : style.previewIconDiv}`,
593
679
  key: index,
594
680
  onClick: this.changeSelectedIndex.bind(this, index),
595
681
  eleRef: el => this[`img_${index}`] = el,
596
682
  dataId: "attachPreviewList",
597
683
  "data-title": name
598
- }, /*#__PURE__*/React.createElement(AttachmentImage, {
684
+ }, isImageFileType || children ? /*#__PURE__*/React.createElement(AttachmentImage, {
599
685
  src: thumbnail || viewUrl,
600
686
  size: "small",
601
687
  alt: name,
@@ -605,7 +691,7 @@ export default class AttachmentViewer extends Component {
605
691
  },
606
692
  dataId: dataId,
607
693
  ...customProps
608
- }, children));
694
+ }, children) : this.getPreviewIconData(name, '40'));
609
695
  }))))), totalLen !== 1 && /*#__PURE__*/React.createElement(IconButton, {
610
696
  dataId: "attachToggle",
611
697
  onClick: this.togglePViewList,
@@ -79,7 +79,7 @@
79
79
  font-size: var(--zd_font_size22) ;
80
80
  height: var(--zd_size38) ;
81
81
  width: var(--zd_size38) ;
82
- line-height: 1.6364;
82
+ line-height: 1.6;
83
83
  border-radius: 50%;
84
84
  cursor: pointer;
85
85
  }
@@ -230,14 +230,10 @@
230
230
  transform: rotateX(0deg);
231
231
  }
232
232
 
233
- .isAudio {
234
- composes: audioImage from '../common/dot_common.module.css';
235
- width: var(--zd_size100) ;
236
- background-size: 100% 100%;
237
- }
238
-
239
- .isAudio .image {
240
- opacity: 0;
233
+ .previewFrame {
234
+ height: 100% ;
235
+ width: 100% ;
236
+ border: 0;
241
237
  }
242
238
 
243
239
  .video {
@@ -362,4 +358,31 @@
362
358
  background-color: var(--dot_mirror);
363
359
  border: 0;
364
360
  cursor: pointer;
361
+ }
362
+
363
+ .fileTypeImg {
364
+ margin-bottom: var(--zd_size30) ;
365
+ }
366
+
367
+ .previewNone {
368
+ color: var(--zdt_attachmentviewer_title_text);
369
+ max-width: 70% ;
370
+ text-align: center;
371
+ margin: auto ;
372
+ }
373
+
374
+ .downloadLink {
375
+ display: inline-block;
376
+ padding-top: var(--zd_size15) ;
377
+ }
378
+
379
+ .previewIconDiv {
380
+ width: var(--zd_size60) ;
381
+ composes: dflex from '~@zohodesk/components/lib/common/common.module.css';
382
+ }
383
+
384
+ .prevFooterIcon {
385
+ color: var(--zdt_attachmentviewer_title_text);
386
+ padding: var(--zd_size2) ;
387
+ margin: auto ;
365
388
  }
@@ -8,9 +8,9 @@ export const AttachmentImage_defaultProps = {
8
8
  export const AttachmentViewer_defaultProps = {
9
9
  responsiveId: "Helmet",
10
10
  needDownload: true,
11
- i18nKeys: {},
12
11
  maintainZoom: false,
13
12
  isActive: false,
14
13
  dataId: 'AttachmentViewer',
14
+ i18nKeys: {},
15
15
  customProps: {}
16
16
  };
@@ -26,7 +26,8 @@ export const AttachmentViewer_propTypes = {
26
26
  downloadText: PropTypes.string,
27
27
  closeText: PropTypes.string,
28
28
  hideText: PropTypes.string,
29
- showText: PropTypes.string
29
+ showText: PropTypes.string,
30
+ previewUnsupportedText: PropTypes.string
30
31
  }),
31
32
  needDownload: PropTypes.string,
32
33
  previewObj: PropTypes.object,
@@ -34,6 +35,13 @@ export const AttachmentViewer_propTypes = {
34
35
  maintainZoom: PropTypes.bool,
35
36
  isActive: PropTypes.bool,
36
37
  dataId: PropTypes.string,
38
+ allowedPreviewExtensionsData: PropTypes.shape({
39
+ audio: PropTypes.arrayOf(PropTypes.string),
40
+ video: PropTypes.arrayOf(PropTypes.string),
41
+ image: PropTypes.arrayOf(PropTypes.string),
42
+ document: PropTypes.arrayOf(PropTypes.string)
43
+ }),
44
+ renderUnSupportedElement: PropTypes.func,
37
45
  customProps: PropTypes.shape({
38
46
  avatarProps: PropTypes.exact(AvatarProps)
39
47
  })
@@ -1,4 +1,4 @@
1
- import { isAudioFile } from "./Attachment";
1
+ import { getExtensionFromFileName } from "./Attachment";
2
2
  export class Zoom {
3
3
  constructor() {
4
4
  const matrix = [1, 0, 0, 1, 0, 0]; // current view transform
@@ -120,6 +120,16 @@ export function checkImageValidity(src) {
120
120
  };
121
121
  });
122
122
  }
123
+ export function checkVideoUrlValidity(url) {
124
+ return new Promise(resolve => {
125
+ const video = document.createElement('video');
126
+ video.src = url;
127
+
128
+ video.oncanplaythrough = () => resolve(true);
129
+
130
+ video.onerror = () => resolve(false);
131
+ });
132
+ }
123
133
  export function checkAudioUrlValidity(url) {
124
134
  return new Promise(resolve => {
125
135
  const audio = new Audio(url);
@@ -134,23 +144,98 @@ export function checkAudioUrlValidity(url) {
134
144
  });
135
145
  }
136
146
  ;
147
+ export function isValidDocument(url) {
148
+ if (!url) {
149
+ return false;
150
+ }
151
+
152
+ return true;
153
+ }
154
+ export const FILE_EXTENSIONS = {
155
+ audio: ['mp3', 'wav', 'wma', 'aac', 'm4r', 'm4a', 'flac', 'aiff', 'alac', 'ogg', 'opus', 'amr', 'mid', 'midi'],
156
+ video: ['mp4', 'mkv', 'mov', 'mpeg', 'mpg', 'flv', 'wmv', 'avi', 'webm', 'ogv', 'm4v', '3gp', '3g2'],
157
+ document: ['doc', 'docx', 'docm', 'dot', 'dotx', 'dotm', 'odt', 'rtf', 'txt', 'md', 'pages', 'xls', 'xlsx', 'xlsm', 'xlsb', 'csv', 'tsv', 'ods', 'sxc', 'numbers', 'ppt', 'pptx', 'pps', 'ppsx', 'pot', 'potx', 'odp', 'sxi', 'key', 'pdf', 'xml', 'json', 'yaml', 'yml', 'log', 'eml', 'msg'],
158
+ image: ['jpeg', 'jpg', 'png', 'apng', 'gif', 'bmp', 'dib', 'tiff', 'tif', 'ico', 'svg', 'webp', 'heic', 'heif', 'jfif', 'pjpeg', 'pjp', 'avif']
159
+ };
160
+ export const SUPPORTED_FILE_EXTENSIONS = {
161
+ image: ['jpeg', 'jpg', 'png', 'apng', 'gif', 'bmp', 'tiff', 'tif', 'ico', 'svg', 'heic', 'webp'],
162
+ doc: ['txt'],
163
+ pdf: ['pdf'],
164
+ html: ['html', 'htm', 'xhtml'],
165
+ ppt: ['ppt', 'pps', 'odp', 'sxi', 'pptx', 'ppsx', 'pot', 'potx', 'key'],
166
+ zip: ['rar', 'jar', 'zip'],
167
+ word: ['doc', 'docx', 'sxw', 'odt', 'docm', 'dot', 'dotm', 'dotx', 'rtf', 'pages'],
168
+ xml: ['xml'],
169
+ sheet: ['xls', 'xlsx', 'xlsm', 'xlsb', 'sxc', 'ods', 'csv', 'tsv', 'numbers'],
170
+ audio: ['mp3', 'wav', 'wma', 'aac', 'm4r', 'ogg', 'opus'],
171
+ video: ['mp4', 'mkv', 'mov', 'mpeg', 'flv', 'wmv', 'avi', 'webm', 'ogv'],
172
+ mail: ['eml', 'msg'],
173
+ linux: ['sh', 'bin'],
174
+ css: ['css'],
175
+ exe: ['exe'],
176
+ event: ['ics']
177
+ };
137
178
  export function checkFileSourcesValidation(_ref) {
138
179
  let {
139
180
  fileName,
140
- viewURL
181
+ viewURL,
182
+ previewUrl,
183
+ allowedPreviewExtensionsData
141
184
  } = _ref;
185
+ const extension = (getExtensionFromFileName(fileName) || '').toLowerCase();
142
186
 
143
- if (isAudioFile(fileName)) {
144
- const audioValidityPromise = checkAudioUrlValidity(viewURL);
145
- return audioValidityPromise.then(isURLValid => ({
146
- isViewURLValid: isURLValid,
187
+ if (!extension) {
188
+ return Promise.resolve({
189
+ isViewURLValid: false,
147
190
  canZoom: false
148
- }));
149
- } else {
150
- const imageValidityPromise = checkImageValidity(viewURL);
151
- return imageValidityPromise.then(isURLValid => ({
152
- isViewURLValid: isURLValid,
153
- canZoom: isURLValid
154
- }));
191
+ });
192
+ }
193
+
194
+ const extensionSource = allowedPreviewExtensionsData || FILE_EXTENSIONS;
195
+
196
+ const fileExtensionValidation = type => {
197
+ const list = extensionSource[type];
198
+ if (!Array.isArray(list)) return false;
199
+ return list.map(e => e.toLowerCase()).includes(extension);
200
+ };
201
+
202
+ if (fileExtensionValidation('audio')) {
203
+ return checkAudioUrlValidity(viewURL).then(isURLValid => {
204
+ return {
205
+ isViewURLValid: isURLValid,
206
+ canZoom: false
207
+ };
208
+ });
155
209
  }
210
+
211
+ if (fileExtensionValidation('video')) {
212
+ return checkVideoUrlValidity(viewURL).then(isURLValid => {
213
+ return {
214
+ isViewURLValid: isURLValid,
215
+ canZoom: false
216
+ };
217
+ });
218
+ }
219
+
220
+ if (fileExtensionValidation('document')) {
221
+ const isValid = isValidDocument(previewUrl, fileName);
222
+ return Promise.resolve({
223
+ isViewURLValid: isValid,
224
+ canZoom: false
225
+ });
226
+ }
227
+
228
+ if (fileExtensionValidation('image')) {
229
+ return checkImageValidity(viewURL).then(isURLValid => {
230
+ return {
231
+ isViewURLValid: isURLValid,
232
+ canZoom: isURLValid
233
+ };
234
+ });
235
+ }
236
+
237
+ return Promise.resolve({
238
+ isViewURLValid: false,
239
+ canZoom: false
240
+ });
156
241
  }