From 4b100cd7fcce2f134d9c0a8f3aa580066e9f6100 Mon Sep 17 00:00:00 2001 From: Chengxun Lee <24319042+bclswl0827@users.noreply.github.com> Date: Sat, 12 Oct 2024 11:58:24 +0800 Subject: [PATCH] feat: Support previewing helicorder in frontend --- CHANGELOG.md | 16 +++++ VERSION | 2 +- frontend/src/package-lock.json | 6 ++ frontend/src/package.json | 1 + .../src/helpers/request/requestRestApi.tsx | 9 ++- frontend/src/src/locales/en-US.json | 4 ++ frontend/src/src/locales/zh-CN.json | 4 ++ frontend/src/src/locales/zh-TW.json | 4 ++ frontend/src/src/views/Export/index.tsx | 62 ++++++++++++++++++- 9 files changed, 103 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 819803e2..57e8ae51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ Starting from v2.2.5, all notable changes to this project will be documented in this file. +## v3.4.1 + +### New Features + +- Support previewing helicorder images in frontend. +- Added earthquake event source API of KNDC. + +### Bug Fixes + +- Fixed channel names in inventory response. + +### Refactor + +- Cache parsed results instead of crawler response. +- Return nil directly for API endpoints if miniSEED or helicorder service is disabled. + ## v3.4.0 ### New Features diff --git a/VERSION b/VERSION index c219f723..3d67a549 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.4.0 +v3.4.1 diff --git a/frontend/src/package-lock.json b/frontend/src/package-lock.json index 7be3a3c5..44727078 100644 --- a/frontend/src/package-lock.json +++ b/frontend/src/package-lock.json @@ -9,6 +9,7 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", + "@fancyapps/ui": "^5.0.36", "@mdi/js": "^7.4.47", "@mdi/react": "^1.6.1", "@mui/material": "^5.14.14", @@ -2796,6 +2797,11 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fancyapps/ui": { + "version": "5.0.36", + "resolved": "https://registry.npmmirror.com/@fancyapps/ui/-/ui-5.0.36.tgz", + "integrity": "sha512-GMygQzp1MBTFNTT6AzpbL6pXTD6bTxwjmmpI1fe8Ozmmiseu8/g82Sudl1YhcbZmS4bJgaBOF5THDFGpXQ1fDw==" + }, "node_modules/@floating-ui/core": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", diff --git a/frontend/src/package.json b/frontend/src/package.json index 7b9a3461..6825dce7 100644 --- a/frontend/src/package.json +++ b/frontend/src/package.json @@ -5,6 +5,7 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", + "@fancyapps/ui": "^5.0.36", "@mdi/js": "^7.4.47", "@mdi/react": "^1.6.1", "@mui/material": "^5.14.14", diff --git a/frontend/src/src/helpers/request/requestRestApi.tsx b/frontend/src/src/helpers/request/requestRestApi.tsx index f97c1708..c6621f81 100644 --- a/frontend/src/src/helpers/request/requestRestApi.tsx +++ b/frontend/src/src/helpers/request/requestRestApi.tsx @@ -19,7 +19,8 @@ interface Options { readonly abortController?: AbortController; readonly endpoint: Endpoint; readonly blobOptions?: { - readonly fileName: string; + readonly fileName?: string; + readonly onComplete?: (response: Blob) => void; readonly onDownload?: (progressEvent: AxiosProgressEvent) => void; }; } @@ -87,7 +88,7 @@ export const requestRestApi = async { const { endpoints, backend } = apiConfig; const miniSeedRes = await requestRestApi({ backend, + throwError: true, endpoint: endpoints.miniseed, payload: { action: "list", name: "" } }); @@ -63,6 +67,7 @@ const Export = ({ locale }: RouterComponentProps) => { const { endpoints, backend } = apiConfig; const heliCorderRes = await requestRestApi({ backend, + throwError: true, endpoint: endpoints.helicorder, payload: { action: "list", name: "" } }); @@ -186,6 +191,43 @@ const Export = ({ locale }: RouterComponentProps) => { forceUpdateComponent(); }; + // Handler for previewing helicorder + const handlePreviewHeliCorder = async (fileName: string) => { + const { backend, endpoints } = apiConfig; + await sendPromiseAlert( + requestRestApi< + typeof endpoints.helicorder.model.request, + typeof endpoints.helicorder.model.response.common, + typeof endpoints.helicorder.model.response.error + >({ + throwError: true, + payload: { action: "export", name: fileName }, + endpoint: endpoints.helicorder, + timeout: 3600, + backend, + blobOptions: { + onComplete: async (response) => { + const imageData = await response.text(); + const blob = new Blob([imageData], { type: "image/svg+xml" }); + const blobUrl = URL.createObjectURL(blob); + Fancybox.show([{ src: blobUrl, type: "image" }], { + on: { close: () => URL.revokeObjectURL(blobUrl) } + }); + } + } + }), + t("views.export.toasts.is_previewing_helicorder"), + t("views.export.toasts.preview_helicorder_success"), + t("views.export.toasts.preview_helicorder_error") + ); + }; + useEffect( + () => () => { + Fancybox.destroy(); + }, + [] + ); + // Handler for downloading helicorder const handleDownloadHeliCorder = async (fileName: string) => { const { backend, endpoints } = apiConfig; @@ -195,6 +237,7 @@ const Export = ({ locale }: RouterComponentProps) => { typeof endpoints.helicorder.model.response.common, typeof endpoints.helicorder.model.response.error >({ + throwError: true, blobOptions: { fileName }, payload: { action: "export", name: fileName }, endpoint: endpoints.helicorder, @@ -421,7 +464,16 @@ const Export = ({ locale }: RouterComponentProps) => { headerName: t("views.export.table.columns.ttl"), hideable: true, sortable: false, - minWidth: 200 + minWidth: 200, + renderCell: ({ value }) => { + if (value === -1) { + return "∞"; + } + if (value < 0) { + return "0"; + } + return String(value); + } }, { field: "actions", @@ -431,6 +483,14 @@ const Export = ({ locale }: RouterComponentProps) => { minWidth: 150, renderCell: ({ row }) => (
+