@selkirk-systems/attachments 1.0.4

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 (84) hide show
  1. package/README.md +0 -0
  2. package/dist/actions/AttachmentActions.js +11 -0
  3. package/dist/actions/FileActions.js +37 -0
  4. package/dist/actions/ImageUploadActions.js +99 -0
  5. package/dist/actions/PhotoActions.js +53 -0
  6. package/dist/components/FileDeleteIcon.js +30 -0
  7. package/dist/components/FileDownloadIcon.js +34 -0
  8. package/dist/components/FileList.js +111 -0
  9. package/dist/components/Icons/ExcelFileTypeImage.js +8 -0
  10. package/dist/components/Icons/HTMLFileTypeImage.js +7 -0
  11. package/dist/components/Icons/JSONFileTypeImage.js +7 -0
  12. package/dist/components/Icons/PDFFileTypeImage.js +7 -0
  13. package/dist/components/Icons/PhotoFileTypeImage.js +6 -0
  14. package/dist/components/Icons/PowerPointTypeImage.js +7 -0
  15. package/dist/components/Icons/TextFileTypeImage.js +7 -0
  16. package/dist/components/Icons/UnknownFileTypeImage.js +7 -0
  17. package/dist/components/Icons/WordFileTypeImage.js +7 -0
  18. package/dist/components/Icons/ZipFileTypeImage.js +7 -0
  19. package/dist/components/ImageViewerDialog.js +78 -0
  20. package/dist/components/MimeTypeIcons.js +28 -0
  21. package/dist/components/PhotoGallery.js +130 -0
  22. package/dist/components/ResponsiveImageUploadList.js +57 -0
  23. package/dist/components/UploadImageDialog.js +85 -0
  24. package/dist/constants/MessageConstants.js +5 -0
  25. package/dist/constants/PhotosConstants.js +18 -0
  26. package/dist/css/attachments.css +143 -0
  27. package/dist/css/image-viewer.css +45 -0
  28. package/dist/img/PowerPoint-filetype.png +0 -0
  29. package/dist/img/blue-pattern-bg.jpg +0 -0
  30. package/dist/img/excel-filetype.png +0 -0
  31. package/dist/img/html-filetype.png +0 -0
  32. package/dist/img/json-filetype.png +0 -0
  33. package/dist/img/pdf-filetype.png +0 -0
  34. package/dist/img/photo-filetype.png +0 -0
  35. package/dist/img/txt-filetype.png +0 -0
  36. package/dist/img/unknown-filetype.png +0 -0
  37. package/dist/img/word-filetype.png +0 -0
  38. package/dist/img/zip-filetype.png +0 -0
  39. package/dist/index.js +19 -0
  40. package/dist/stores/DownloadStore.js +16 -0
  41. package/dist/stores/ImageUploadStore.js +24 -0
  42. package/dist/stores/PhotosStore.js +59 -0
  43. package/lib/actions/AttachmentActions.js +14 -0
  44. package/lib/actions/FileActions.js +34 -0
  45. package/lib/actions/ImageUploadActions.js +134 -0
  46. package/lib/actions/PhotoActions.js +65 -0
  47. package/lib/components/FileDeleteIcon.jsx +42 -0
  48. package/lib/components/FileDownloadIcon.jsx +42 -0
  49. package/lib/components/FileList.jsx +111 -0
  50. package/lib/components/Icons/ExcelFileTypeImage.jsx +6 -0
  51. package/lib/components/Icons/HTMLFileTypeImage.jsx +5 -0
  52. package/lib/components/Icons/JSONFileTypeImage.jsx +5 -0
  53. package/lib/components/Icons/PDFFileTypeImage.jsx +5 -0
  54. package/lib/components/Icons/PhotoFileTypeImage.jsx +5 -0
  55. package/lib/components/Icons/PowerPointTypeImage.jsx +5 -0
  56. package/lib/components/Icons/TextFileTypeImage.jsx +5 -0
  57. package/lib/components/Icons/UnknownFileTypeImage.jsx +5 -0
  58. package/lib/components/Icons/WordFileTypeImage.jsx +5 -0
  59. package/lib/components/Icons/ZipFileTypeImage.jsx +5 -0
  60. package/lib/components/ImageViewerDialog.jsx +72 -0
  61. package/lib/components/MimeTypeIcons.jsx +30 -0
  62. package/lib/components/PhotoGallery.jsx +160 -0
  63. package/lib/components/ResponsiveImageUploadList.jsx +61 -0
  64. package/lib/components/UploadImageDialog.jsx +93 -0
  65. package/lib/constants/MessageConstants.js +5 -0
  66. package/lib/constants/PhotosConstants.js +21 -0
  67. package/lib/css/attachments.css +143 -0
  68. package/lib/css/image-viewer.css +45 -0
  69. package/lib/img/PowerPoint-filetype.png +0 -0
  70. package/lib/img/blue-pattern-bg.jpg +0 -0
  71. package/lib/img/excel-filetype.png +0 -0
  72. package/lib/img/html-filetype.png +0 -0
  73. package/lib/img/json-filetype.png +0 -0
  74. package/lib/img/pdf-filetype.png +0 -0
  75. package/lib/img/photo-filetype.png +0 -0
  76. package/lib/img/txt-filetype.png +0 -0
  77. package/lib/img/unknown-filetype.png +0 -0
  78. package/lib/img/word-filetype.png +0 -0
  79. package/lib/img/zip-filetype.png +0 -0
  80. package/lib/index.js +19 -0
  81. package/lib/stores/DownloadStore.js +23 -0
  82. package/lib/stores/ImageUploadStore.js +31 -0
  83. package/lib/stores/PhotosStore.js +81 -0
  84. package/package.json +50 -0
@@ -0,0 +1,34 @@
1
+ import { FILE_DELETE, FILE_DELETED, FILE_DOWNLOAD, FILE_DOWNLOADED } from "../constants/PhotosConstants";
2
+ import DownloadStore from "../stores/DownloadStore";
3
+ import { fetch } from "@selkirk-systems/fetch";
4
+ import { dispatch } from "@selkirk-systems/state-management";
5
+
6
+ export const downloadFile = ( url, mimeType, fileName ) => {
7
+
8
+ const { downloading } = DownloadStore.getState();
9
+
10
+ if ( downloading ) return;
11
+
12
+ dispatch( FILE_DOWNLOAD, { url: url, mimeType: mimeType, fileName: fileName } );
13
+
14
+ return fetch( url, { contentType: mimeType, downloadFileName: fileName } )
15
+ .finally( () => {
16
+ dispatch( FILE_DOWNLOADED )
17
+ } )
18
+
19
+ }
20
+
21
+ export const deleteFile = ( url, fileName ) => {
22
+
23
+ const { deleting } = DownloadStore.getState();
24
+
25
+ if ( deleting ) return;
26
+
27
+ dispatch( FILE_DELETE, { fileName: fileName } );
28
+
29
+ return fetch( url, { method: "DELETE" } )
30
+ .finally( () => {
31
+ dispatch( FILE_DELETED, { fileName: fileName } )
32
+ } )
33
+
34
+ }
@@ -0,0 +1,134 @@
1
+ /* eslint-disable no-loop-func */
2
+ import { dispatch } from "@selkirk-systems/state-management";
3
+ import { CLEAR_UPLOADS, DELETED_IMAGE, DELETE_IMAGE, HIDE_IMAGE_UPLOAD_DIALOG, IMAGE_UPLOAD_COMPLETE, SET_UPLOAD_PROGRESS, SHOW_IMAGE_UPLOAD_DIALOG } from "../constants/PhotosConstants";
4
+ import { ADD_ERROR, fetch } from "@selkirk-systems/fetch";
5
+ import { createProxiedURL } from "@selkirk-systems/selkirk-utils";
6
+ import PhotoStore from "../stores/PhotosStore";
7
+ import { confirmDialog } from "primereact/confirmdialog";
8
+ import { extractDataArray } from "@selkirk-systems/selkirk-utils";
9
+
10
+ export const closeImageUploadDialog = () => {
11
+
12
+ dispatch( HIDE_IMAGE_UPLOAD_DIALOG );
13
+ dispatch( CLEAR_UPLOADS );
14
+
15
+ }
16
+ export const showImageUploadDialog = ( tag ) => {
17
+
18
+ dispatch( SHOW_IMAGE_UPLOAD_DIALOG, tag );
19
+
20
+ };
21
+
22
+ export const invokeUploadInput = () => {
23
+
24
+ const element = document.querySelector( "input[type='file']" );
25
+
26
+ if ( !element ) return;
27
+
28
+ element.click();
29
+
30
+ }
31
+ export const deleteImageById = ( id ) => {
32
+
33
+ dispatch( DELETE_IMAGE, id )
34
+
35
+ return fetch( `/image/${id}`, { method: "DELETE" } )
36
+ .then( response => {
37
+ dispatch( DELETED_IMAGE, id );
38
+ } );
39
+
40
+ }
41
+
42
+ export const uploadFiles = ( url, files ) => {
43
+
44
+ return new Promise( ( resolve, reject ) => {
45
+ const uploads = [];
46
+
47
+ const { photos } = PhotoStore.getState();
48
+
49
+ if ( !url ) return;
50
+
51
+ for ( let file of files ) {
52
+ const exists = photos.find( ( p ) => p.name === file.name );
53
+
54
+ if ( exists ) {
55
+ confirmDialog( {
56
+ message: `${file.name} already exists. \n Do you want to replace it?`,
57
+ header: 'Confirm Upload',
58
+ position: 'center',
59
+ accept: () => {
60
+ uploadFinalFile( file );
61
+ }
62
+ } );
63
+ }
64
+ else {
65
+ uploadFinalFile( file );
66
+ }
67
+ }
68
+
69
+ function uploadFinalFile( file ) {
70
+
71
+
72
+ const caption = file.name;
73
+ const formData = new FormData();
74
+ const finalURL = new URL( `${url}?force=true&name=${file.name}` );
75
+
76
+ formData.append( "file", file, file.name );
77
+
78
+ const options = {
79
+ headers: {
80
+ accept: "*/*",
81
+ 'content-length': file.size
82
+ },
83
+ form: formData,
84
+ method: "POST",
85
+ };
86
+
87
+ dispatch( SET_UPLOAD_PROGRESS, {
88
+ id: caption,
89
+ title: caption,
90
+ mimeType: file.type,
91
+ progress: 10,
92
+ response: null
93
+ } )
94
+
95
+ uploads.push(
96
+ fetch( finalURL, options )
97
+ .then( ( [response] ) => {
98
+ if ( response.status.code > 299 || response.status.code < 200 ) {
99
+ throw response
100
+ }
101
+
102
+ response.data = extractDataArray( response.data );
103
+
104
+ dispatch( SET_UPLOAD_PROGRESS, {
105
+ id: caption,
106
+ title: caption,
107
+ mimeType: file.type,
108
+ progress: 100,
109
+ response: response
110
+ } )
111
+ } )
112
+ .catch( response => {
113
+ dispatch( SET_UPLOAD_PROGRESS, {
114
+ id: caption,
115
+ title: caption,
116
+ mimeType: file.type,
117
+ progress: 100,
118
+ error: response.data
119
+ } )
120
+ return dispatch( ADD_ERROR, response );
121
+ } )
122
+ )
123
+ }
124
+
125
+ Promise.all( uploads )
126
+ .finally( () => {
127
+ dispatch( IMAGE_UPLOAD_COMPLETE );
128
+ resolve();
129
+ } )
130
+
131
+ } );
132
+
133
+
134
+ };
@@ -0,0 +1,65 @@
1
+ import { fetch } from "@selkirk-systems/fetch";
2
+ import { DELETED_IMAGE, DELETE_IMAGE, FETCHED_PHOTOS, FETCH_PHOTOS } from "../constants/PhotosConstants";
3
+ import { dispatch } from "@selkirk-systems/state-management";
4
+ import { hideImageViewerDialog } from "./AttachmentActions";
5
+ import { ADD_IGNORE_ERROR, REMOVE_IGNORE_ERROR_BY_ID } from "../constants/MessageConstants";
6
+
7
+
8
+ export const fetchPhotos = ( url ) => {
9
+
10
+ dispatch( FETCH_PHOTOS );
11
+
12
+ //Filestore requires both of these set to application/json to get json details
13
+ //Proxy web server defaults to accept:'*/*' which does not work so we have to override here.
14
+ const options = {
15
+ skipCache: true,
16
+ headers: {
17
+ 'Accept': "application/json",
18
+ 'content-type': 'application/json'
19
+ }
20
+ };
21
+
22
+ dispatch(ADD_IGNORE_ERROR,[{id:url.toString(),statusCodes:[404]}]);
23
+
24
+ return fetch( url, options ).then( ( [response] ) => {
25
+
26
+ dispatch(REMOVE_IGNORE_ERROR_BY_ID,[{id:url.toString()}]);
27
+
28
+ if ( response.status.code > 299 || response.status.code < 200 ) {
29
+ dispatch( FETCHED_PHOTOS, [] )
30
+ return;
31
+ }
32
+
33
+ const onlyFiles = getAllFiles( response.data.children );
34
+
35
+ dispatch( FETCHED_PHOTOS, onlyFiles )
36
+
37
+ } )
38
+ }
39
+ export const clearPhotos = ()=>{
40
+ dispatch(FETCHED_PHOTOS,[]);
41
+ }
42
+ export const deleteImage = ( url, name ) => {
43
+
44
+ dispatch( DELETE_IMAGE, name );
45
+
46
+ return fetch( url, { method: "DELETE" } )
47
+ .then( response => {
48
+ dispatch( DELETED_IMAGE, name );
49
+ hideImageViewerDialog();
50
+ } );
51
+
52
+ }
53
+
54
+ function getAllFiles( children ) {
55
+ let ret = [];
56
+
57
+ children.forEach( c => {
58
+ if ( c.nodeType === 'FILE' ) ret.push( c );
59
+
60
+ if ( c.children && c.children.length ) ret = ret.concat( getAllFiles( c.children ) )
61
+ } )
62
+
63
+
64
+ return ret;
65
+ }
@@ -0,0 +1,42 @@
1
+ import * as React from 'react'
2
+ import { Connect } from '@selkirk-systems/state-management';
3
+ import { Trash2 } from 'lucide-react';
4
+ import { ProgressSpinner } from '@selkirk-systems/selkirk-components';
5
+ import { Button } from 'primereact/button';
6
+ import DownloadStore from '../stores/DownloadStore';
7
+
8
+ class FileDownloadIcon extends React.Component {
9
+
10
+
11
+ static subscribe = [DownloadStore];
12
+
13
+
14
+ static defaultProps = {
15
+ deleting: false,
16
+ name: ''
17
+ }
18
+
19
+
20
+ static storeStateToProps = {
21
+ deleting: ( props, state ) => state.deleting
22
+ }
23
+
24
+
25
+ render() {
26
+ const { deleting, name, ...other } = this.props;
27
+
28
+ const isDeleting = deleting && deleting.fileName === name;
29
+
30
+ return (
31
+ <Button text type='button' {...other} >
32
+ {isDeleting && <ProgressSpinner />}
33
+ {!isDeleting && <Trash2 />}
34
+ </Button>
35
+ )
36
+ }
37
+
38
+
39
+ }
40
+
41
+
42
+ export default Connect( FileDownloadIcon );
@@ -0,0 +1,42 @@
1
+ import * as React from 'react'
2
+ import { Connect } from '@selkirk-systems/state-management';
3
+ import { Download } from 'lucide-react';
4
+ import { ProgressSpinner } from '@selkirk-systems/selkirk-components';
5
+ import { Button } from 'primereact/button';
6
+ import DownloadStore from '../stores/DownloadStore';
7
+
8
+ class FileDownloadIcon extends React.Component {
9
+
10
+
11
+ static subscribe = [DownloadStore];
12
+
13
+
14
+ static defaultProps = {
15
+ downloading: false,
16
+ name: ''
17
+ }
18
+
19
+
20
+ static storeStateToProps = {
21
+ downloading: ( props, state ) => state.downloading
22
+ }
23
+
24
+
25
+ render() {
26
+ const { downloading, name, ...other } = this.props;
27
+
28
+ const isDownloading = downloading && downloading.fileName === name;
29
+
30
+ return (
31
+ <Button text type='button' {...other} >
32
+ {isDownloading && <ProgressSpinner style={{ color: 'inherit' }} />}
33
+ {!isDownloading && <Download />}
34
+ </Button>
35
+ )
36
+ }
37
+
38
+
39
+ }
40
+
41
+
42
+ export default Connect( FileDownloadIcon );
@@ -0,0 +1,111 @@
1
+ import React, { Component } from "react";
2
+ import { Connect } from '@selkirk-systems/state-management';
3
+ import PhotoStore from "../stores/PhotosStore";
4
+ import { FileIcon, Trash2 } from "lucide-react";
5
+ import { Column, Row } from "@selkirk-systems/layout";
6
+ import { Skeleton } from "primereact/skeleton";
7
+ import memoizee from "memoizee";
8
+ import { fetchPhotos } from "../actions/PhotoActions";
9
+ import { Typography, Paper } from "@selkirk-systems/selkirk-components";
10
+ import UploadImageDialog from "./UploadImageDialog";
11
+ import { deleteFile, downloadFile } from "../actions/FileActions";
12
+ import { createProxiedURL } from "@selkirk-systems/selkirk-utils";
13
+ import FileDownloadIcon from "./FileDownloadIcon";
14
+ import UnknownFileTypeImage from "./Icons/UnknownFileTypeImage";
15
+ import MIME_TYPE_ICONS from "./MimeTypeIcons";
16
+ import { sortByProp } from "@selkirk-systems/selkirk-utils";
17
+ import { Button } from "primereact/button";
18
+ import FileDeleteIcon from "./FileDeleteIcon";
19
+
20
+
21
+ class PhotoGallery extends React.Component {
22
+
23
+
24
+ static subscribe = [PhotoStore];
25
+
26
+
27
+ static defaultProps = {
28
+ baseURL: "",
29
+ items: [],
30
+ fetching: false
31
+ }
32
+
33
+
34
+ static storeStateToProps = {
35
+
36
+ items: ( props, state ) => filesOnly( state.photos ),
37
+ fetching: ( props, state ) => state.fetching
38
+
39
+ }
40
+
41
+ handleFileClick = ( file ) => ( e ) => {
42
+
43
+ e.stopPropagation();
44
+
45
+ downloadFile( createProxiedURL( file._links.self.href ), file.mimeType, file.name );
46
+
47
+ }
48
+
49
+ handleFileDelete = ( file ) => ( e ) => {
50
+
51
+ e.stopPropagation();
52
+
53
+ const href = file.links ? file.links[0].href : file._links.self.href;
54
+
55
+ deleteFile( createProxiedURL( href ), file.name )
56
+ }
57
+
58
+ render() {
59
+
60
+ const { baseURL, items, fetching, ...other } = this.props;
61
+
62
+ const count = items.length;
63
+
64
+ return (
65
+ <div className="file-gallery paralax-content" {...other}>
66
+ {count < 1 && !fetching &&
67
+ <Column center className='text-secondary' >
68
+ <FileIcon mt="-xxxl" mb='sm' style={{ width: '75px', height: '75px', strokeWidth: 1 }} />
69
+ <Typography style={{ fontWeight: 500 }} variant="subtitle2">NO FILES FOUND.</Typography>
70
+ </Column>
71
+ }
72
+ {fetching && <Skeleton width="100%" height={window.innerHeight - 300} />}
73
+ {count > 0 &&
74
+ <div p='md' style={{ flex: "1 1 auto" }}>
75
+ {
76
+ items.map( ( f, i ) => {
77
+ return (
78
+ <Paper mb='sm' p='sm' key={f.id} elevation={1} {...other}>
79
+ <Row align='center' xs="auto 1fr auto auto">
80
+ {MIME_TYPE_ICONS[f.mimeType] || <UnknownFileTypeImage />}
81
+ <Column gap='xs' ml='sm'>
82
+ <Typography variant="body1">{f.name}</Typography>
83
+ <Row className='text-secondary' gap='sm' justify='left'>
84
+ <Typography variant='caption'>Size: </Typography>
85
+ <Typography variant='caption'>{f.sizeInKB < 1000 ? `${f.sizeInKB.toFixed( 3 )} KB` : `${( f.sizeInKB / 1000 ).toFixed( 3 )} MB`}</Typography>
86
+ </Row>
87
+ </Column>
88
+ <FileDownloadIcon size="small" onClick={this.handleFileClick( f )} name={f.name} />
89
+ <FileDeleteIcon size="small" onClick={this.handleFileDelete( f )} name={f.name} />
90
+ </Row>
91
+ </Paper>
92
+ )
93
+ } )
94
+ }
95
+ </div>
96
+ }
97
+ </div >
98
+ )
99
+ }
100
+
101
+
102
+ }
103
+
104
+
105
+ const filesOnly = memoizee( ( files ) => {
106
+ return sortByProp( files.filter( ( f ) => f.mimeType.indexOf( "image" ) < 0 ), "name" ).reverse();
107
+ } )
108
+
109
+
110
+
111
+ export default Connect( PhotoGallery );
@@ -0,0 +1,6 @@
1
+ import SRC from '../../img/excel-filetype.png';
2
+ import React from "react";
3
+
4
+ const ExcelFileTypeImage = ( props ) => ( <img alt="Excel" src={SRC} {...props} /> )
5
+
6
+ export default ExcelFileTypeImage;
@@ -0,0 +1,5 @@
1
+ import SRC from '../../img/html-filetype.png';
2
+
3
+ const HTMLFileTypeImage = ( props ) => ( <img alt="HTML" src={SRC} {...props} /> )
4
+
5
+ export default HTMLFileTypeImage;
@@ -0,0 +1,5 @@
1
+ import SRC from '../../img/json-filetype.png';
2
+
3
+ const JsonFileTypeImage = ( props ) => ( <img alt="JSON" src={SRC} {...props} /> )
4
+
5
+ export default JsonFileTypeImage;
@@ -0,0 +1,5 @@
1
+ import SRC from '../../img/pdf-filetype.png';
2
+
3
+ const PDFMimeTypeImage = ( props ) => ( <img alt="PDF" src={SRC} {...props} /> )
4
+
5
+ export default PDFMimeTypeImage;
@@ -0,0 +1,5 @@
1
+ import SRC from '../../img/photo-filetype.png';
2
+
3
+ const PhotoFileTypeImage = ( props ) => ( <img src={SRC} {...props} /> )
4
+
5
+ export default PhotoFileTypeImage;
@@ -0,0 +1,5 @@
1
+ import SRC from '../../img/PowerPoint-filetype.png';
2
+
3
+ const PowerPointTypeImage = ( props ) => ( <img alt="Power Point" src={SRC} {...props} /> )
4
+
5
+ export default PowerPointTypeImage;
@@ -0,0 +1,5 @@
1
+ import SRC from '../../img/txt-filetype.png';
2
+
3
+ const TextFileTypeImage = ( props ) => ( <img alt="Text" src={SRC} {...props} /> )
4
+
5
+ export default TextFileTypeImage;
@@ -0,0 +1,5 @@
1
+ import SRC from '../../img/unknown-filetype.png';
2
+
3
+ const UnknownFileTypeImage = ( props ) => ( <img alt="Unknown" src={SRC} {...props} /> )
4
+
5
+ export default UnknownFileTypeImage;
@@ -0,0 +1,5 @@
1
+ import SRC from '../../img/word-filetype.png';
2
+
3
+ const WordFileTypeImage = ( props ) => ( <img alt="Word" src={SRC} {...props} /> )
4
+
5
+ export default WordFileTypeImage;
@@ -0,0 +1,5 @@
1
+ import SRC from '../../img/zip-filetype.png';
2
+
3
+ const ZipFileTypeImage = ( props ) => ( <img alt="Zip" src={SRC} {...props} /> )
4
+
5
+ export default ZipFileTypeImage;
@@ -0,0 +1,72 @@
1
+ import * as React from 'react';
2
+ import { deleteImage } from '../actions/PhotoActions';
3
+ import PhotosStore from '../stores/PhotosStore';
4
+ import { Connect } from '@selkirk-systems/state-management';
5
+ import { Dialog } from 'primereact/dialog';
6
+ import { Trash2, XIcon } from 'lucide-react';
7
+ import { Button } from 'primereact/button';
8
+ import { ProgressSpinner, Typography } from '@selkirk-systems/selkirk-components';
9
+
10
+ import '../css/image-viewer.css';
11
+ import { Row } from '@selkirk-systems/layout';
12
+ import { hideImageViewerDialog } from '../actions/AttachmentActions';
13
+
14
+ class ImageViewerDialog extends React.Component {
15
+
16
+
17
+ static subscribe = [PhotosStore];
18
+
19
+
20
+ static defaultProps = {
21
+ imageViewer: {},
22
+ deleting: false
23
+ }
24
+
25
+
26
+ static storeStateToProps = {
27
+ imageViewer: ( props, state ) => state.imageViewer,
28
+ deleting: ( props, state ) => state.deleting
29
+ }
30
+
31
+
32
+ render() {
33
+
34
+ const { imageViewer, deleting, ...other } = this.props;
35
+
36
+ return (
37
+ <Dialog
38
+ visible={imageViewer.name}
39
+ maximized
40
+ onHide={hideImageViewerDialog}
41
+ transitionOptions={
42
+ {
43
+ onExited: this.handledExited
44
+ }
45
+ }
46
+ {...other}
47
+ >
48
+ <div className="image-viewer">
49
+ <Row className="top actions" align="center" xs="1fr auto" gap="md" fill={false}>
50
+ <Typography ml='sm' className="title" variant="body1">{imageViewer.name}</Typography>
51
+ <Button mr='-sm' type='button' style={{ color: 'inherit' }} onClick={hideImageViewerDialog} text><XIcon /></Button>
52
+ </Row>
53
+ <Row className="bottom actions" center fill={false}>
54
+ <Button disabled={deleting} type='button' onClick={() => deleteImage( imageViewer.url, imageViewer.name )} text className="delete icon">
55
+ {deleting ?
56
+ <ProgressSpinner style={{ width: 18, height: 18, color: 'white' }} />
57
+ :
58
+ <Trash2 />
59
+ }
60
+ </Button>
61
+ </Row>
62
+ <img alt="test" src={imageViewer.url} />
63
+ </div>
64
+ </Dialog>
65
+ )
66
+ }
67
+
68
+
69
+ }
70
+
71
+
72
+ export default Connect( ImageViewerDialog );
@@ -0,0 +1,30 @@
1
+ import PDFFileTypeImage from "./Icons/PDFFileTypeImage";
2
+ import TextFileTypeImage from "./Icons/TextFileTypeImage";
3
+ import WordFileTypeImage from "./Icons/WordFileTypeImage";
4
+ import ExcelFileTypeImage from "./Icons/ExcelFileTypeImage";
5
+ import PowerPointTypeImage from "./Icons/PowerPointTypeImage";
6
+ import HTMLFileTypeImage from "./Icons/HTMLFileTypeImage";
7
+ import JsonFileTypeImage from "./Icons/JSONFileTypeImage";
8
+ import ZipFileTypeImage from "./Icons/ZipFileTypeImage";
9
+ import React from "react";
10
+
11
+ const MIME_TYPE_ICONS = {
12
+ 'application/pdf': <PDFFileTypeImage />,
13
+ 'application/msword': <WordFileTypeImage />,
14
+ 'application/vnd.ms-word': <WordFileTypeImage />,
15
+ 'application/vnd.oasis.opendocument.text': <WordFileTypeImage />,
16
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml': <WordFileTypeImage />,
17
+ 'application/vnd.ms-excel': <ExcelFileTypeImage />,
18
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml': <ExcelFileTypeImage />,
19
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': <ExcelFileTypeImage />,
20
+ 'application/vnd.oasis.opendocument.spreadsheet': <ExcelFileTypeImage />,
21
+ 'application/vnd.ms-powerpoint': <PowerPointTypeImage />,
22
+ 'application/vnd.openxmlformats-officedocument.presentationml': <PowerPointTypeImage />,
23
+ 'application/vnd.oasis.opendocument.presentation': <PowerPointTypeImage />,
24
+ 'text/plain': <TextFileTypeImage />,
25
+ 'text/html': <HTMLFileTypeImage />,
26
+ 'application/json': <JsonFileTypeImage />,
27
+ 'application/zip': <ZipFileTypeImage />
28
+ }
29
+
30
+ export default MIME_TYPE_ICONS;