@monolith-forensics/monolith-ui 1.2.50 → 1.2.52

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.
@@ -3,10 +3,11 @@ export type File = {
3
3
  ext: string;
4
4
  size: number;
5
5
  type?: string;
6
- url: string;
6
+ url?: string;
7
7
  };
8
8
  export declare const FileViewer: React.FC<{
9
9
  file: File;
10
10
  open: boolean;
11
+ isPending?: boolean;
11
12
  onClose: () => void;
12
13
  }>;
@@ -151,7 +151,7 @@ const resolveViewerType = (file) => {
151
151
  }
152
152
  return ViewerTypes.Code;
153
153
  };
154
- export const FileViewer = ({ file, open, onClose }) => {
154
+ export const FileViewer = ({ file, open, isPending, onClose }) => {
155
155
  const [zoomFactor, setZoomFactor] = useState(1);
156
156
  if (!open)
157
157
  return null;
@@ -160,8 +160,8 @@ export const FileViewer = ({ file, open, onClose }) => {
160
160
  onClose === null || onClose === void 0 ? void 0 : onClose();
161
161
  setZoomFactor(1);
162
162
  };
163
- return (_jsx(FloatingPortal, { preserveTabOrder: true, children: _jsxs(StyledContainer, { className: "mfui-FileViewer", children: [_jsxs(StyledMenu, { className: "FileViewer-menu", children: [_jsx(Button, { variant: "text", onClick: () => {
163
+ return (_jsx(FloatingPortal, { preserveTabOrder: true, children: _jsxs(StyledContainer, { className: "mfui-FileViewer", children: [file.url && (_jsxs(StyledMenu, { className: "FileViewer-menu", children: [_jsx(Button, { variant: "text", onClick: () => {
164
164
  onClose === null || onClose === void 0 ? void 0 : onClose();
165
165
  setZoomFactor(1);
166
- }, children: _jsx(XIcon, { size: 18 }) }), _jsx("div", { children: file.name }), _jsxs(StyledActionsMenu, { children: [ZoomableViewerTypes.includes(viewerType) && (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "text", children: _jsx(ZoomInIcon, { size: 18, onClick: () => setZoomFactor((prev) => prev * 1.1) }) }), _jsx(Button, { variant: "text", children: _jsx(ZoomOutIcon, { size: 18, onClick: () => setZoomFactor((prev) => prev * 0.9) }) })] })), _jsx("a", { href: file.url, download: file.name, children: _jsx(Button, { variant: "text", children: _jsx(DownloadIcon, { size: 18 }) }) })] })] }), _jsxs(StyledInnerContainer, { onClick: handleBackgroundClick, "data-type": viewerType, children: [viewerType === ViewerTypes.PDF && (_jsx(PdfViewer, { file: file, zoomFactor: zoomFactor })), viewerType === ViewerTypes.Image && (_jsx(ImageViewer, { file: file, zoomFactor: zoomFactor })), viewerType === ViewerTypes.Video && (_jsx(VideoViewer, { file: file, zoomFactor: zoomFactor })), viewerType === ViewerTypes.Audio && (_jsx(VideoViewer, { file: file, zoomFactor: zoomFactor })), viewerType === ViewerTypes.Office && _jsx(OfficeViewer, { file: file }), viewerType === ViewerTypes.Text && (_jsx(CodeViewer, { file: file, zoomFactor: zoomFactor })), viewerType === ViewerTypes.Code && (_jsx(CodeViewer, { file: file, zoomFactor: zoomFactor }))] })] }) }));
166
+ }, children: _jsx(XIcon, { size: 18 }) }), _jsx("div", { children: file.name }), _jsxs(StyledActionsMenu, { children: [ZoomableViewerTypes.includes(viewerType) && (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "text", children: _jsx(ZoomInIcon, { size: 18, onClick: () => setZoomFactor((prev) => prev * 1.1) }) }), _jsx(Button, { variant: "text", children: _jsx(ZoomOutIcon, { size: 18, onClick: () => setZoomFactor((prev) => prev * 0.9) }) })] })), _jsx("a", { href: file.url, download: file.name, children: _jsx(Button, { variant: "text", children: _jsx(DownloadIcon, { size: 18 }) }) })] })] })), _jsxs(StyledInnerContainer, { onClick: handleBackgroundClick, "data-type": viewerType, children: [viewerType === ViewerTypes.PDF && (_jsx(PdfViewer, { file: file, zoomFactor: zoomFactor, isPending: isPending })), viewerType === ViewerTypes.Image && (_jsx(ImageViewer, { file: file, zoomFactor: zoomFactor, isPending: isPending })), viewerType === ViewerTypes.Video && (_jsx(VideoViewer, { file: file, zoomFactor: zoomFactor, isPending: isPending })), viewerType === ViewerTypes.Audio && (_jsx(VideoViewer, { file: file, zoomFactor: zoomFactor, isPending: isPending })), viewerType === ViewerTypes.Office && (_jsx(OfficeViewer, { file: file, isPending: isPending })), viewerType === ViewerTypes.Text && (_jsx(CodeViewer, { file: file, zoomFactor: zoomFactor, isPending: isPending })), viewerType === ViewerTypes.Code && (_jsx(CodeViewer, { file: file, zoomFactor: zoomFactor, isPending: isPending }))] })] }) }));
167
167
  };
@@ -2,4 +2,5 @@ import { File } from "../FileViewer";
2
2
  export declare const CodeViewer: React.FC<{
3
3
  file: File;
4
4
  zoomFactor?: number;
5
+ isPending?: boolean;
5
6
  }>;
@@ -27,6 +27,8 @@ const resolveLanguage = (file) => __awaiter(void 0, void 0, void 0, function* ()
27
27
  return null;
28
28
  });
29
29
  const getFileData = (file) => __awaiter(void 0, void 0, void 0, function* () {
30
+ if (!file.url)
31
+ return "";
30
32
  const response = yield fetch(file.url);
31
33
  const text = yield response.text();
32
34
  return text;
@@ -62,7 +64,7 @@ const StyledLoader = styled.div `
62
64
  align-items: center;
63
65
  gap: 10px;
64
66
  `;
65
- export const CodeViewer = ({ file, zoomFactor }) => {
67
+ export const CodeViewer = ({ file, zoomFactor, isPending }) => {
66
68
  const [CodeMirror, setCodeMirror] = useState(null);
67
69
  const [language, setLanguage] = useState(null);
68
70
  const [theme, setTheme] = useState(null);
@@ -93,6 +95,9 @@ export const CodeViewer = ({ file, zoomFactor }) => {
93
95
  if (CodeMirror) {
94
96
  extensions.push(CodeMirror.EditorView.lineWrapping);
95
97
  }
98
+ if (isPending) {
99
+ return (_jsxs(StyledLoader, { children: [_jsx(Loader, { size: 50 }), _jsx("div", { children: "Loading Image..." })] }));
100
+ }
96
101
  return (_jsxs(StyledContainer, { zoomFactor: zoomFactor, children: [loading && (_jsxs(StyledLoader, { children: [_jsx(Loader, { size: 50 }), _jsx("div", { children: "Loading File..." })] })), !loading && (_jsx(CodeMirror.default, { value: query.data || "", theme: theme, extensions: extensions, readOnly: true, editable: false, onClick: (event) => {
97
102
  event.stopPropagation();
98
103
  } }))] }));
@@ -2,4 +2,5 @@ import { File } from "../FileViewer";
2
2
  export declare const ImageViewer: React.FC<{
3
3
  file: File;
4
4
  zoomFactor?: number;
5
+ isPending?: boolean;
5
6
  }>;
@@ -24,7 +24,7 @@ const StyledLoader = styled.div `
24
24
  align-items: center;
25
25
  gap: 10px;
26
26
  `;
27
- export const ImageViewer = ({ file, zoomFactor = 1, }) => {
27
+ export const ImageViewer = ({ file, zoomFactor = 1, isPending }) => {
28
28
  const [imageLoaded, setImageLoaded] = useState(false);
29
29
  const [originalDimensions, setOriginalDimensions] = useState({
30
30
  naturalWidth: 0,
@@ -36,6 +36,8 @@ export const ImageViewer = ({ file, zoomFactor = 1, }) => {
36
36
  setOriginalDimensions((prev) => (Object.assign(Object.assign({}, prev), { width: e.target.clientWidth, height: e.target.offsetHeight })));
37
37
  };
38
38
  const loadImage = () => {
39
+ if (!file.url)
40
+ return;
39
41
  const img = document.createElement("img");
40
42
  img.src = file.url;
41
43
  img.onload = () => {
@@ -46,6 +48,9 @@ export const ImageViewer = ({ file, zoomFactor = 1, }) => {
46
48
  useEffect(() => {
47
49
  loadImage();
48
50
  }, [file.url]);
51
+ if (isPending) {
52
+ return (_jsxs(StyledLoader, { children: [_jsx(Loader, { size: 50 }), _jsx("div", { children: "Loading Image..." })] }));
53
+ }
49
54
  return (_jsxs(ImageViewerContainer, { className: "mfui-ImageViewer", children: [!imageLoaded && (_jsxs(StyledLoader, { children: [_jsx(Loader, { size: 50 }), _jsx("div", { children: "Loading Image..." })] })), imageLoaded && (_jsx(Image, { src: file.url, alt: file.name ? file.name : "Image", zoomFactor: zoomFactor, onLoad: handleImageLoad, height: zoomFactor === 1 ? "100%" : originalDimensions.height * zoomFactor, onClick: (e) => {
50
55
  e.stopPropagation();
51
56
  } }))] }));
@@ -1,4 +1,5 @@
1
1
  import { File } from "../FileViewer";
2
2
  export declare const OfficeViewer: React.FC<{
3
3
  file: File;
4
+ isPending?: boolean;
4
5
  }>;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import styled from "styled-components";
3
3
  import Loader from "../../Loader";
4
4
  const StyledContainer = styled.div `
@@ -32,6 +32,13 @@ const StyledIframe = styled.iframe `
32
32
  height: 100%;
33
33
  border: none;
34
34
  `;
35
+ const StyledLoader = styled.div `
36
+ display: flex;
37
+ flex-direction: column;
38
+ justify-content: center;
39
+ align-items: center;
40
+ gap: 10px;
41
+ `;
35
42
  const resolveOfficeType = (file) => {
36
43
  let ext = file.ext;
37
44
  if (!ext) {
@@ -54,7 +61,10 @@ const resolveOfficeType = (file) => {
54
61
  return null;
55
62
  }
56
63
  };
57
- export const OfficeViewer = ({ file }) => {
64
+ export const OfficeViewer = ({ file, isPending }) => {
58
65
  const type = resolveOfficeType(file);
66
+ if (isPending) {
67
+ return (_jsxs(StyledLoader, { children: [_jsx(Loader, { size: 50 }), _jsx("div", { children: "Loading Image..." })] }));
68
+ }
59
69
  return (_jsx(StyledContainer, { children: _jsx(StyledInnerContainer, { "data-type": type, children: !(file === null || file === void 0 ? void 0 : file.url) ? (_jsx(Loader, {})) : (_jsx(StyledIframe, { id: "office-iframe", title: "office-iframe", src: `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(file.url)}` })) }) }));
60
70
  };
@@ -3,5 +3,6 @@ import "react-pdf/dist/esm/Page/TextLayer.css";
3
3
  import { File } from "../FileViewer";
4
4
  export declare const PdfViewer: React.FC<{
5
5
  file: File;
6
+ isPending?: boolean;
6
7
  zoomFactor?: number;
7
8
  }>;
@@ -39,7 +39,7 @@ const StyledLoader = styled.div `
39
39
  left: 50%;
40
40
  transform: translate(-50%, -50%);
41
41
  `;
42
- export const PdfViewer = ({ file, zoomFactor = 1, }) => {
42
+ export const PdfViewer = ({ file, zoomFactor = 1, isPending }) => {
43
43
  const [loading, setLoading] = useState(true);
44
44
  const [numPages, setNumPages] = useState();
45
45
  const [pageNumber, setPageNumber] = useState(1);
@@ -51,6 +51,9 @@ export const PdfViewer = ({ file, zoomFactor = 1, }) => {
51
51
  }
52
52
  // viewport width
53
53
  const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0) / 1.15;
54
+ if (isPending) {
55
+ return (_jsxs(StyledLoader, { children: [_jsx(Loader, { size: 50 }), _jsx("div", { children: "Loading PDF..." })] }));
56
+ }
54
57
  return (_jsx(StyledContainer, { className: "PdfViewer", children: _jsx(StyledDocument, { file: file.url, onLoadSuccess: onDocumentLoadSuccess, loading: _jsxs(StyledLoader, { children: [_jsx(Loader, { size: 50 }), _jsx("div", { children: "Loading PDF..." })] }), onClick: (e) => {
55
58
  e.stopPropagation();
56
59
  }, children: Array.from(new Array(numPages), (el, index) => (_jsx(StyledPage, { pageNumber: index + 1, scale: zoomFactor, width: vw }, `page_${index + 1}`))) }) }));
@@ -12,6 +12,8 @@ import styled from "styled-components";
12
12
  import { useState } from "react";
13
13
  import Loader from "../../Loader";
14
14
  const getFileData = (file) => __awaiter(void 0, void 0, void 0, function* () {
15
+ if (!file.url)
16
+ return "";
15
17
  const response = yield fetch(file.url);
16
18
  const text = yield response.text();
17
19
  return text;
@@ -2,4 +2,5 @@ import { File } from "../FileViewer";
2
2
  export declare const VideoViewer: React.FC<{
3
3
  file: File;
4
4
  zoomFactor?: number;
5
+ isPending?: boolean;
5
6
  }>;
@@ -1,5 +1,6 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import styled from "styled-components";
3
+ import Loader from "../../Loader";
3
4
  const StyledContainer = styled.div `
4
5
  display: flex;
5
6
  justify-content: center;
@@ -12,7 +13,17 @@ const StyledVideo = styled.video `
12
13
  max-height: 100%;
13
14
  object-fit: contain;
14
15
  `;
15
- export const VideoViewer = ({ file }) => {
16
+ const StyledLoader = styled.div `
17
+ display: flex;
18
+ flex-direction: column;
19
+ justify-content: center;
20
+ align-items: center;
21
+ gap: 10px;
22
+ `;
23
+ export const VideoViewer = ({ file, isPending }) => {
24
+ if (isPending) {
25
+ return (_jsxs(StyledLoader, { children: [_jsx(Loader, { size: 50 }), _jsx("div", { children: "Loading Image..." })] }));
26
+ }
16
27
  return (_jsx(StyledContainer, { className: "mfui-VideoViewer", children: _jsx(StyledVideo, { src: file.url, controls: true, autoPlay: true, onClick: (e) => {
17
28
  e.stopPropagation();
18
29
  } }) }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monolith-forensics/monolith-ui",
3
- "version": "1.2.50",
3
+ "version": "1.2.52",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Matt Danner (Monolith Forensics LLC)",