From 3029df96a27c73a20ff2fb5ccfe9cc384532a0f8 Mon Sep 17 00:00:00 2001 From: Tudor Stanciu Date: Wed, 14 Dec 2022 18:05:57 +0200 Subject: [PATCH] Add 'download' option for resources --- .../list/components/ResourcesContainer.js | 40 +++++++++++++++++-- src/hooks/index.js | 3 +- src/hooks/useFileDownload.js | 14 +++++++ src/hooks/useResourceSecurity.js | 11 +++-- 4 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 src/hooks/useFileDownload.js diff --git a/src/features/resources/list/components/ResourcesContainer.js b/src/features/resources/list/components/ResourcesContainer.js index 38f3ab2..3e1d059 100644 --- a/src/features/resources/list/components/ResourcesContainer.js +++ b/src/features/resources/list/components/ResourcesContainer.js @@ -11,9 +11,14 @@ import SecondaryActionsGroup from "./SecondaryActionsGroup"; import { EditOutlined, FileCopyOutlined, - OpenInNewOutlined + OpenInNewOutlined, + CloudDownloadOutlined } from "@material-ui/icons"; -import { useToast, useResourceSecurity } from "../../../../hooks"; +import { + useToast, + useResourceSecurity, + useFileDownload +} from "../../../../hooks"; import { useHistory } from "react-router-dom"; const __ROWS_PER_PAGE_OPTIONS = [10, 20, 50, 100]; @@ -34,6 +39,7 @@ const ResourcesContainer = () => { const { getResources } = useResourcesApi(); const { getResourceCategories } = useDictionariesApi(); const { secureUrl } = useResourceSecurity(); + const { download } = useFileDownload(); const history = useHistory(); useEffect(() => { @@ -72,6 +78,21 @@ const ResourcesContainer = () => { [resourceCategories] ); + const prepareUrl = useCallback( + (url, download, secure) => { + if (download) { + url = `${url}?download=${download}`; + } + + if (secure) { + url = secureUrl(url, download); + } + + return url; + }, + [secureUrl] + ); + const actions = useMemo( () => [ { @@ -96,16 +117,27 @@ const ResourcesContainer = () => { { code: "open-in-new-tab", effect: (event, resource) => { - const url = resource.secured ? secureUrl(resource.url) : resource.url; + const url = prepareUrl(resource.url, false, resource.secured); window.open(url, "_blank"); event.preventDefault(); }, icon: OpenInNewOutlined, tooltip: t("Generic.OpenInNewTab"), top: false + }, + { + code: "download", + effect: (event, resource) => { + const url = prepareUrl(resource.url, true, resource.secured); + download(url); + event.preventDefault(); + }, + icon: CloudDownloadOutlined, + tooltip: t("Generic.Download"), + top: false } ], - [t, info, secureUrl, history] + [t, info, secureUrl, history, download, prepareUrl] ); const columns = useMemo( diff --git a/src/hooks/index.js b/src/hooks/index.js index 29909e5..3abb8dc 100644 --- a/src/hooks/index.js +++ b/src/hooks/index.js @@ -1,5 +1,6 @@ import { useToast } from "../contexts/ToastContext"; import useHttpRequest from "./useHttpRequest"; import useResourceSecurity from "./useResourceSecurity"; +import useFileDownload from "./useFileDownload"; -export { useToast, useHttpRequest, useResourceSecurity }; +export { useToast, useHttpRequest, useResourceSecurity, useFileDownload }; diff --git a/src/hooks/useFileDownload.js b/src/hooks/useFileDownload.js new file mode 100644 index 0000000..7ffbd63 --- /dev/null +++ b/src/hooks/useFileDownload.js @@ -0,0 +1,14 @@ +const useFileDownload = () => { + const download = (uri, name = "") => { + const link = document.createElement("a"); + link.setAttribute("download", name); + link.href = uri; + document.body.appendChild(link); + link.click(); + link.remove(); + }; + + return { download }; +}; + +export default useFileDownload; diff --git a/src/hooks/useResourceSecurity.js b/src/hooks/useResourceSecurity.js index 3dc13aa..548e7ed 100644 --- a/src/hooks/useResourceSecurity.js +++ b/src/hooks/useResourceSecurity.js @@ -3,9 +3,14 @@ import { useCallback } from "react"; const useResourceSecurity = () => { const { token } = useUserState(); - const secureUrl = useCallback((url) => `${url}?token=${token.raw}`, [ - token.raw - ]); + const secureUrl = useCallback( + (url, join) => { + const separator = join ? "&" : "?"; + const securedUrl = `${url}${separator}token=${token.raw}`; + return securedUrl; + }, + [token.raw] + ); return { secureUrl }; };