@bit.rhplus/data 0.0.26 → 0.0.27

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.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,4 @@
1
- export default function useData(): {
2
- fetchData: (api: any, data: any, accessToken: any) => Promise<any>;
3
- fetchDataUIAsync: (api: any, data: any, accessToken: any) => Promise<any>;
4
- getFileURL: (content: any, type: any) => string;
5
- downloadFileURL: (content: any, type: any, fileName: any) => void;
6
- };
1
+ export default useData;
2
+ export { useFileDownload } from "./useFileDownload";
3
+ import useData from './useData';
7
4
  export { useApiQuery, useApiQuerySilence, useStaticQuery } from "./reactQuery";
package/dist/index.js CHANGED
@@ -1,66 +1,5 @@
1
- import { FetchData, errorNotification } from '@bit.rhplus/api';
2
- // import { useOidcAccessToken } from "@axa-fr/react-oidc";
3
- export default function useData() {
4
- // let accessToken = null;
5
- // try {
6
- // const oidcToken = useOidcAccessToken();
7
- // accessToken = oidcToken?.accessToken || null;
8
- // console.log("🚀 ~ useData ~ accessToken:", accessToken)
9
- // } catch (err) {
10
- // // Kontext OIDC není dostupný – pokračujeme bez tokenu
11
- // errorNotification('OIDC není dostupné. Pravděpodobně chybí OidcProvider.', err);
12
- // }
13
- /* eslint-disable */
14
- const fetchData = (api, data, accessToken) => FetchData(api, data, accessToken);
15
- const fetchDataUIAsync = async (api, data, accessToken) => {
16
- try {
17
- const result = await fetchData(api, data, accessToken);
18
- return {
19
- ...result,
20
- result: 'success',
21
- success: true
22
- };
23
- }
24
- catch (error) {
25
- errorNotification(error);
26
- return {
27
- result: 'fail',
28
- success: false,
29
- error
30
- };
31
- }
32
- };
33
- const getFileURL = (content, type) => {
34
- const isBase64 = typeof content === 'string' && /^[A-Za-z0-9+/=]+$/.test(content);
35
- let byteArray;
36
- if (isBase64) {
37
- const byteCharacters = atob(content);
38
- const byteNumbers = new Array(byteCharacters.length);
39
- for (let i = 0; i < byteCharacters.length; i += 1) {
40
- byteNumbers[i] = byteCharacters.charCodeAt(i);
41
- }
42
- byteArray = new Uint8Array(byteNumbers);
43
- }
44
- else {
45
- byteArray = new Uint8Array(content);
46
- }
47
- const blob = new Blob([byteArray], { type });
48
- const fileUrl = window.URL.createObjectURL(blob);
49
- return fileUrl;
50
- };
51
- const downloadFileURL = (content, type, fileName) => {
52
- const fileURL = getFileURL(content, type);
53
- const tempLink = document.createElement("a");
54
- tempLink.href = fileURL;
55
- tempLink.download = fileName;
56
- tempLink.click();
57
- };
58
- return {
59
- fetchData,
60
- fetchDataUIAsync,
61
- getFileURL,
62
- downloadFileURL
63
- };
64
- }
1
+ import useData from './useData';
2
+ export default useData;
3
+ export { useFileDownload } from './useFileDownload';
65
4
  export { useApiQuery, useApiQuerySilence, useStaticQuery } from './reactQuery';
66
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,2DAA2D;AAE3D,MAAM,CAAC,OAAO,UAAU,OAAO;IAE7B,0BAA0B;IAE1B,QAAQ;IACR,4CAA4C;IAC5C,kDAAkD;IAClD,4DAA4D;IAC5D,kBAAkB;IAClB,2DAA2D;IAC3D,qFAAqF;IACrF,IAAI;IAEJ,oBAAoB;IACpB,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IAEhF,MAAM,gBAAgB,GAAG,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE;QACxD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;YACvD,OAAO;gBACL,GAAG,MAAM;gBACT,MAAM,EAAE,SAAS;gBACjB,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACzB,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,KAAK;gBACd,KAAK;aACN,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QACnC,MAAM,QAAQ,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAElF,IAAI,SAAS,CAAC;QACd,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YACrD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClD,WAAW,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAChD,CAAC;YACD,SAAS,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,SAAS,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QAClD,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC7C,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC;QACxB,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC7B,QAAQ,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC,CAAC;IAEF,OAAO;QACL,SAAS;QACT,gBAAgB;QAChB,UAAU;QACV,eAAe;KAChB,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.js"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,WAAW,CAAC;AAEhC,eAAe,OAAO,CAAC;AACvB,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAE,cAAc,EAAC,MAAM,cAAc,CAAC"}
@@ -0,0 +1,7 @@
1
+ export default function useData(): {
2
+ fetchData: (api: any, data: any, accessToken: any) => Promise<any>;
3
+ fetchDataUIAsync: (api: any, data: any, accessToken: any) => Promise<any>;
4
+ getFileURL: (content: any, type: any) => string;
5
+ downloadFileURL: (content: any, type: any, fileName: any) => void;
6
+ };
7
+ export { useApiQuery, useApiQuerySilence, useStaticQuery } from "./reactQuery";
@@ -0,0 +1,124 @@
1
+ import { useState } from 'react';
2
+ import { FetchData, errorNotification } from '@bit.rhplus/api';
3
+ // import { useOidcAccessToken } from "@axa-fr/react-oidc";
4
+ export default function useData() {
5
+ const [isDownloading, setIsDownloading] = useState(false);
6
+ const [error, setError] = useState('');
7
+ // let accessToken = null;
8
+ // try {
9
+ // const oidcToken = useOidcAccessToken();
10
+ // accessToken = oidcToken?.accessToken || null;
11
+ // console.log("🚀 ~ useData ~ accessToken:", accessToken)
12
+ // } catch (err) {
13
+ // // Kontext OIDC není dostupný – pokračujeme bez tokenu
14
+ // errorNotification('OIDC není dostupné. Pravděpodobně chybí OidcProvider.', err);
15
+ // }
16
+ /* eslint-disable */
17
+ const fetchData = (api, data, accessToken) => FetchData(api, data, accessToken);
18
+ const fetchDataUIAsync = async (api, data, accessToken) => {
19
+ try {
20
+ const result = await fetchData(api, data, accessToken);
21
+ return {
22
+ ...result,
23
+ result: 'success',
24
+ success: true,
25
+ };
26
+ }
27
+ catch (error) {
28
+ errorNotification(error);
29
+ return {
30
+ result: 'fail',
31
+ success: false,
32
+ error,
33
+ };
34
+ }
35
+ };
36
+ const getFileURL = (content, type) => {
37
+ const isBase64 = typeof content === 'string' && /^[A-Za-z0-9+/=]+$/.test(content);
38
+ let byteArray;
39
+ if (isBase64) {
40
+ const byteCharacters = atob(content);
41
+ const byteNumbers = new Array(byteCharacters.length);
42
+ for (let i = 0; i < byteCharacters.length; i += 1) {
43
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
44
+ }
45
+ byteArray = new Uint8Array(byteNumbers);
46
+ }
47
+ else {
48
+ byteArray = new Uint8Array(content);
49
+ }
50
+ const blob = new Blob([byteArray], { type });
51
+ const fileUrl = window.URL.createObjectURL(blob);
52
+ return fileUrl;
53
+ };
54
+ const downloadFileURL = (content, type, fileName) => {
55
+ setIsDownloading(true);
56
+ setError('');
57
+ try {
58
+ const fileURL = getFileURL(content, type);
59
+ const tempLink = document.createElement('a');
60
+ tempLink.href = fileURL;
61
+ tempLink.download = fileName;
62
+ tempLink.click();
63
+ }
64
+ catch (err) {
65
+ console.error('Chyba při stahování:', err);
66
+ setError(`Chyba při stahování souboru: ${err.message}`);
67
+ }
68
+ finally {
69
+ setIsDownloading(false);
70
+ }
71
+ };
72
+ // const downloadFile = async () => {
73
+ // setIsDownloading(true);
74
+ // setError('');
75
+ // try {
76
+ // const response = await fetch(`/api/document/download/${documentId}`, {
77
+ // method: 'GET',
78
+ // headers: {
79
+ // Accept: '*/*',
80
+ // },
81
+ // });
82
+ // if (!response.ok) {
83
+ // throw new Error(`Chyba serveru: ${response.status}`);
84
+ // }
85
+ // // Získáme blob z odpovědi
86
+ // const blob = await response.blob();
87
+ // // Získáme název souboru z Content-Disposition hlavičky nebo použijeme předaný název
88
+ // const contentDisposition = response.headers.get('content-disposition');
89
+ // let downloadFileName = fileName;
90
+ // if (contentDisposition) {
91
+ // const fileNameMatch = contentDisposition.match(
92
+ // /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
93
+ // );
94
+ // if (fileNameMatch && fileNameMatch[1]) {
95
+ // // Odstraníme uvozovky pokud jsou
96
+ // downloadFileName = fileNameMatch[1].replace(/['"]/g, '');
97
+ // }
98
+ // }
99
+ // // Vytvoříme URL pro blob a spustíme stahování
100
+ // const url = window.URL.createObjectURL(blob);
101
+ // const link = document.createElement('a');
102
+ // link.href = url;
103
+ // link.download = downloadFileName || `soubor_${documentId}`;
104
+ // document.body.appendChild(link);
105
+ // link.click();
106
+ // // Vyčistíme po sobě
107
+ // window.URL.revokeObjectURL(url);
108
+ // document.body.removeChild(link);
109
+ // } catch (err) {
110
+ // console.error('Chyba při stahování:', err);
111
+ // setError(`Chyba při stahování souboru: ${err.message}`);
112
+ // } finally {
113
+ // setIsDownloading(false);
114
+ // }
115
+ // };
116
+ return {
117
+ fetchData,
118
+ fetchDataUIAsync,
119
+ getFileURL,
120
+ downloadFileURL,
121
+ };
122
+ }
123
+ export { useApiQuery, useApiQuerySilence, useStaticQuery } from './reactQuery';
124
+ //# sourceMappingURL=useData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useData.js","sourceRoot":"","sources":["../useData.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export function useFileDownload(options?: {}): {
2
+ isDownloading: boolean;
3
+ error: string;
4
+ downloadFile: (api: any, data: any, fileName?: null) => Promise<{
5
+ success: boolean;
6
+ error: string;
7
+ fileName?: undefined;
8
+ size?: undefined;
9
+ errorMessage?: undefined;
10
+ } | {
11
+ success: boolean;
12
+ fileName: null;
13
+ size: any;
14
+ error?: undefined;
15
+ errorMessage?: undefined;
16
+ } | {
17
+ success: boolean;
18
+ error: unknown;
19
+ errorMessage: string;
20
+ fileName?: undefined;
21
+ size?: undefined;
22
+ }>;
23
+ reset: () => void;
24
+ };
@@ -0,0 +1,130 @@
1
+ // hooks/useFileDownload.js
2
+ import { useState, useCallback } from 'react';
3
+ import useData from '.';
4
+ export const useFileDownload = (options = {}) => {
5
+ const { onDownloadStart, onDownloadEnd, onDownloadSuccess, onDownloadError, onLoadingChange, accessToken, } = options;
6
+ const { fetchData } = useData();
7
+ const [isDownloading, setIsDownloading] = useState(false);
8
+ const [error, setError] = useState('');
9
+ const downloadFile = useCallback(async (api, data, fileName = null) => {
10
+ if (isDownloading) {
11
+ console.warn('Download already in progress');
12
+ return { success: false, error: 'Download already in progress' };
13
+ }
14
+ setIsDownloading(true);
15
+ setError('');
16
+ // Notify o začátku stahování
17
+ onDownloadStart?.();
18
+ onLoadingChange?.(true);
19
+ try {
20
+ const response = await fetchData(api, data, accessToken);
21
+ const blob = response.data;
22
+ // Získáme název souboru z Content-Disposition hlavičky nebo použijeme předaný název
23
+ let downloadFileName = fileName;
24
+ // Zkus získat filename ze serverových headers
25
+ if (response.headers) {
26
+ let contentDisposition;
27
+ // Různé způsoby jak získat header (záleží na struktuře response)
28
+ if (typeof response.headers.get === 'function') {
29
+ contentDisposition = response.headers.get('content-disposition');
30
+ }
31
+ else if (response.headers['content-disposition']) {
32
+ contentDisposition = response.headers['content-disposition'];
33
+ }
34
+ if (contentDisposition) {
35
+ const fileNameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
36
+ if (fileNameMatch && fileNameMatch[1]) {
37
+ downloadFileName = fileNameMatch[1].replace(/['"]/g, '');
38
+ }
39
+ }
40
+ }
41
+ // Vytvoříme URL pro blob
42
+ const objectUrl = window.URL.createObjectURL(blob);
43
+ // METODA: Pouze Save As dialog bez otevření PDF
44
+ const newWindow = window.open('', '_blank');
45
+ if (newWindow) {
46
+ // Okamžitě vytvoř download link v prázdném okně
47
+ const link = newWindow.document.createElement('a');
48
+ link.href = objectUrl;
49
+ link.download = downloadFileName || 'soubor.pdf';
50
+ newWindow.document.body.appendChild(link);
51
+ link.click();
52
+ // Zavři prázdné okno okamžitě
53
+ setTimeout(() => {
54
+ newWindow.close();
55
+ }, 100);
56
+ }
57
+ else {
58
+ // Fallback pokud jsou zablokovány popup okna
59
+ console.warn('⚠️ Popup blokováno, zkouším fallback metodu');
60
+ const link = document.createElement('a');
61
+ link.style.display = 'none';
62
+ link.href = objectUrl;
63
+ link.download = downloadFileName || 'soubor.pdf';
64
+ document.body.appendChild(link);
65
+ // Zkus více způsobů kliknutí
66
+ try {
67
+ link.click();
68
+ }
69
+ catch (e) {
70
+ const event = new MouseEvent('click', {
71
+ view: window,
72
+ bubbles: true,
73
+ cancelable: true,
74
+ });
75
+ link.dispatchEvent(event);
76
+ }
77
+ // Cleanup
78
+ setTimeout(() => {
79
+ document.body.removeChild(link);
80
+ }, 100);
81
+ }
82
+ // Cleanup URL s kratším delayem
83
+ setTimeout(() => {
84
+ window.URL.revokeObjectURL(objectUrl);
85
+ }, 1000);
86
+ // Success callback
87
+ onDownloadSuccess?.(downloadFileName, blob.size);
88
+ return {
89
+ success: true,
90
+ fileName: downloadFileName,
91
+ size: blob.size,
92
+ };
93
+ }
94
+ catch (err) {
95
+ console.error('Chyba při stahování:', err);
96
+ const errorMessage = `Chyba při stahování souboru: ${err.message}`;
97
+ setError(errorMessage);
98
+ onDownloadError?.(err, errorMessage);
99
+ return {
100
+ success: false,
101
+ error: err,
102
+ errorMessage,
103
+ };
104
+ }
105
+ finally {
106
+ setIsDownloading(false);
107
+ onDownloadEnd?.();
108
+ onLoadingChange?.(false);
109
+ }
110
+ }, [
111
+ isDownloading,
112
+ onDownloadStart,
113
+ onDownloadEnd,
114
+ onDownloadSuccess,
115
+ onDownloadError,
116
+ onLoadingChange,
117
+ accessToken,
118
+ fetchData,
119
+ ]);
120
+ const reset = useCallback(() => {
121
+ setError('');
122
+ }, []);
123
+ return {
124
+ isDownloading,
125
+ error,
126
+ downloadFile,
127
+ reset,
128
+ };
129
+ };
130
+ //# sourceMappingURL=useFileDownload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFileDownload.js","sourceRoot":"","sources":["../useFileDownload.js"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -1,74 +1,5 @@
1
- import { FetchData, errorNotification } from '@bit.rhplus/api';
2
- // import { useOidcAccessToken } from "@axa-fr/react-oidc";
1
+ import useData from './useData';
3
2
 
4
- export default function useData() {
5
-
6
- // let accessToken = null;
7
-
8
- // try {
9
- // const oidcToken = useOidcAccessToken();
10
- // accessToken = oidcToken?.accessToken || null;
11
- // console.log("🚀 ~ useData ~ accessToken:", accessToken)
12
- // } catch (err) {
13
- // // Kontext OIDC není dostupný – pokračujeme bez tokenu
14
- // errorNotification('OIDC není dostupné. Pravděpodobně chybí OidcProvider.', err);
15
- // }
16
-
17
- /* eslint-disable */
18
- const fetchData = (api, data, accessToken) => FetchData(api, data, accessToken);
19
-
20
- const fetchDataUIAsync = async (api, data, accessToken) => {
21
- try {
22
- const result = await fetchData(api, data, accessToken);
23
- return {
24
- ...result,
25
- result: 'success',
26
- success: true
27
- };
28
- } catch (error) {
29
- errorNotification(error);
30
- return {
31
- result: 'fail',
32
- success: false,
33
- error
34
- };
35
- }
36
- };
37
-
38
- const getFileURL = (content, type) => {
39
- const isBase64 = typeof content === 'string' && /^[A-Za-z0-9+/=]+$/.test(content);
40
-
41
- let byteArray;
42
- if (isBase64) {
43
- const byteCharacters = atob(content);
44
- const byteNumbers = new Array(byteCharacters.length);
45
- for (let i = 0; i < byteCharacters.length; i += 1) {
46
- byteNumbers[i] = byteCharacters.charCodeAt(i);
47
- }
48
- byteArray = new Uint8Array(byteNumbers);
49
- } else {
50
- byteArray = new Uint8Array(content);
51
- }
52
-
53
- const blob = new Blob([byteArray], { type });
54
- const fileUrl = window.URL.createObjectURL(blob);
55
- return fileUrl;
56
- };
57
-
58
- const downloadFileURL = (content, type, fileName) => {
59
- const fileURL = getFileURL(content, type);
60
- const tempLink = document.createElement("a");
61
- tempLink.href = fileURL;
62
- tempLink.download = fileName;
63
- tempLink.click();
64
- };
65
-
66
- return {
67
- fetchData,
68
- fetchDataUIAsync,
69
- getFileURL,
70
- downloadFileURL
71
- };
72
- }
73
-
74
- export { useApiQuery, useApiQuerySilence, useStaticQuery } from './reactQuery';
3
+ export default useData;
4
+ export {useFileDownload} from './useFileDownload';
5
+ export {useApiQuery, useApiQuerySilence, useStaticQuery} from './reactQuery';
package/package.json CHANGED
@@ -1,21 +1,22 @@
1
1
  {
2
2
  "name": "@bit.rhplus/data",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "homepage": "https://bit.cloud/remote-scope/data",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "remote-scope",
8
8
  "name": "data",
9
- "version": "0.0.26"
9
+ "version": "0.0.27"
10
10
  },
11
11
  "dependencies": {
12
12
  "@tanstack/react-query": "^5.66.9",
13
- "@bit.rhplus/api": "0.0.2"
13
+ "@bit.rhplus/api": "0.0.26"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@teambit/react.react-env": "1.0.129"
17
17
  },
18
18
  "peerDependencies": {
19
+ "react": "^17.0.0 || ^18.0.0",
19
20
  "@axa-fr/react-oidc": "7.24.1"
20
21
  },
21
22
  "license": "SEE LICENSE IN UNLICENSED",
package/useData.js ADDED
@@ -0,0 +1,141 @@
1
+ import { useState } from 'react';
2
+ import { FetchData, errorNotification } from '@bit.rhplus/api';
3
+ // import { useOidcAccessToken } from "@axa-fr/react-oidc";
4
+
5
+ export default function useData() {
6
+ const [isDownloading, setIsDownloading] = useState(false);
7
+ const [error, setError] = useState('');
8
+
9
+ // let accessToken = null;
10
+
11
+ // try {
12
+ // const oidcToken = useOidcAccessToken();
13
+ // accessToken = oidcToken?.accessToken || null;
14
+ // console.log("🚀 ~ useData ~ accessToken:", accessToken)
15
+ // } catch (err) {
16
+ // // Kontext OIDC není dostupný – pokračujeme bez tokenu
17
+ // errorNotification('OIDC není dostupné. Pravděpodobně chybí OidcProvider.', err);
18
+ // }
19
+
20
+ /* eslint-disable */
21
+ const fetchData = (api, data, accessToken) =>
22
+ FetchData(api, data, accessToken);
23
+
24
+ const fetchDataUIAsync = async (api, data, accessToken) => {
25
+ try {
26
+ const result = await fetchData(api, data, accessToken);
27
+ return {
28
+ ...result,
29
+ result: 'success',
30
+ success: true,
31
+ };
32
+ } catch (error) {
33
+ errorNotification(error);
34
+ return {
35
+ result: 'fail',
36
+ success: false,
37
+ error,
38
+ };
39
+ }
40
+ };
41
+
42
+ const getFileURL = (content, type) => {
43
+ const isBase64 =
44
+ typeof content === 'string' && /^[A-Za-z0-9+/=]+$/.test(content);
45
+
46
+ let byteArray;
47
+ if (isBase64) {
48
+ const byteCharacters = atob(content);
49
+ const byteNumbers = new Array(byteCharacters.length);
50
+ for (let i = 0; i < byteCharacters.length; i += 1) {
51
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
52
+ }
53
+ byteArray = new Uint8Array(byteNumbers);
54
+ } else {
55
+ byteArray = new Uint8Array(content);
56
+ }
57
+
58
+ const blob = new Blob([byteArray], { type });
59
+ const fileUrl = window.URL.createObjectURL(blob);
60
+ return fileUrl;
61
+ };
62
+
63
+ const downloadFileURL = (content, type, fileName) => {
64
+ setIsDownloading(true);
65
+ setError('');
66
+
67
+ try {
68
+ const fileURL = getFileURL(content, type);
69
+ const tempLink = document.createElement('a');
70
+ tempLink.href = fileURL;
71
+ tempLink.download = fileName;
72
+ tempLink.click();
73
+ } catch (err) {
74
+ console.error('Chyba při stahování:', err);
75
+ setError(`Chyba při stahování souboru: ${err.message}`);
76
+ } finally {
77
+ setIsDownloading(false);
78
+ }
79
+ };
80
+
81
+ // const downloadFile = async () => {
82
+ // setIsDownloading(true);
83
+ // setError('');
84
+
85
+ // try {
86
+ // const response = await fetch(`/api/document/download/${documentId}`, {
87
+ // method: 'GET',
88
+ // headers: {
89
+ // Accept: '*/*',
90
+ // },
91
+ // });
92
+
93
+ // if (!response.ok) {
94
+ // throw new Error(`Chyba serveru: ${response.status}`);
95
+ // }
96
+
97
+ // // Získáme blob z odpovědi
98
+ // const blob = await response.blob();
99
+
100
+ // // Získáme název souboru z Content-Disposition hlavičky nebo použijeme předaný název
101
+ // const contentDisposition = response.headers.get('content-disposition');
102
+ // let downloadFileName = fileName;
103
+
104
+ // if (contentDisposition) {
105
+ // const fileNameMatch = contentDisposition.match(
106
+ // /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
107
+ // );
108
+ // if (fileNameMatch && fileNameMatch[1]) {
109
+ // // Odstraníme uvozovky pokud jsou
110
+ // downloadFileName = fileNameMatch[1].replace(/['"]/g, '');
111
+ // }
112
+ // }
113
+
114
+ // // Vytvoříme URL pro blob a spustíme stahování
115
+ // const url = window.URL.createObjectURL(blob);
116
+ // const link = document.createElement('a');
117
+ // link.href = url;
118
+ // link.download = downloadFileName || `soubor_${documentId}`;
119
+ // document.body.appendChild(link);
120
+ // link.click();
121
+
122
+ // // Vyčistíme po sobě
123
+ // window.URL.revokeObjectURL(url);
124
+ // document.body.removeChild(link);
125
+ // } catch (err) {
126
+ // console.error('Chyba při stahování:', err);
127
+ // setError(`Chyba při stahování souboru: ${err.message}`);
128
+ // } finally {
129
+ // setIsDownloading(false);
130
+ // }
131
+ // };
132
+
133
+ return {
134
+ fetchData,
135
+ fetchDataUIAsync,
136
+ getFileURL,
137
+ downloadFileURL,
138
+ };
139
+ }
140
+
141
+ export { useApiQuery, useApiQuerySilence, useStaticQuery } from './reactQuery';
@@ -0,0 +1,156 @@
1
+ // hooks/useFileDownload.js
2
+ import { useState, useCallback } from 'react';
3
+ import useData from '.';
4
+
5
+ export const useFileDownload = (options = {}) => {
6
+ const {
7
+ onDownloadStart,
8
+ onDownloadEnd,
9
+ onDownloadSuccess,
10
+ onDownloadError,
11
+ onLoadingChange,
12
+ accessToken,
13
+ } = options;
14
+ const { fetchData } = useData();
15
+ const [isDownloading, setIsDownloading] = useState(false);
16
+ const [error, setError] = useState('');
17
+
18
+ const downloadFile = useCallback(
19
+ async (api, data, fileName = null) => {
20
+ if (isDownloading) {
21
+ console.warn('Download already in progress');
22
+ return { success: false, error: 'Download already in progress' };
23
+ }
24
+ setIsDownloading(true);
25
+ setError('');
26
+ // Notify o začátku stahování
27
+ onDownloadStart?.();
28
+ onLoadingChange?.(true);
29
+
30
+ try {
31
+ const response = await fetchData(api, data, accessToken);
32
+ const blob = response.data;
33
+
34
+ // Získáme název souboru z Content-Disposition hlavičky nebo použijeme předaný název
35
+ let downloadFileName = fileName;
36
+
37
+ // Zkus získat filename ze serverových headers
38
+ if (response.headers) {
39
+ let contentDisposition;
40
+
41
+ // Různé způsoby jak získat header (záleží na struktuře response)
42
+ if (typeof response.headers.get === 'function') {
43
+ contentDisposition = response.headers.get('content-disposition');
44
+ } else if (response.headers['content-disposition']) {
45
+ contentDisposition = response.headers['content-disposition'];
46
+ }
47
+
48
+ if (contentDisposition) {
49
+ const fileNameMatch = contentDisposition.match(
50
+ /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
51
+ );
52
+ if (fileNameMatch && fileNameMatch[1]) {
53
+ downloadFileName = fileNameMatch[1].replace(/['"]/g, '');
54
+ }
55
+ }
56
+ }
57
+ // Vytvoříme URL pro blob
58
+ const objectUrl = window.URL.createObjectURL(blob);
59
+
60
+ // METODA: Pouze Save As dialog bez otevření PDF
61
+ const newWindow = window.open('', '_blank');
62
+
63
+ if (newWindow) {
64
+ // Okamžitě vytvoř download link v prázdném okně
65
+ const link = newWindow.document.createElement('a');
66
+ link.href = objectUrl;
67
+ link.download = downloadFileName || 'soubor.pdf';
68
+ newWindow.document.body.appendChild(link);
69
+ link.click();
70
+
71
+ // Zavři prázdné okno okamžitě
72
+ setTimeout(() => {
73
+ newWindow.close();
74
+ }, 100);
75
+ } else {
76
+ // Fallback pokud jsou zablokovány popup okna
77
+ console.warn('⚠️ Popup blokováno, zkouším fallback metodu');
78
+
79
+ const link = document.createElement('a');
80
+ link.style.display = 'none';
81
+ link.href = objectUrl;
82
+ link.download = downloadFileName || 'soubor.pdf';
83
+
84
+ document.body.appendChild(link);
85
+
86
+ // Zkus více způsobů kliknutí
87
+ try {
88
+ link.click();
89
+ } catch (e) {
90
+ const event = new MouseEvent('click', {
91
+ view: window,
92
+ bubbles: true,
93
+ cancelable: true,
94
+ });
95
+ link.dispatchEvent(event);
96
+ }
97
+
98
+ // Cleanup
99
+ setTimeout(() => {
100
+ document.body.removeChild(link);
101
+ }, 100);
102
+ }
103
+
104
+ // Cleanup URL s kratším delayem
105
+ setTimeout(() => {
106
+ window.URL.revokeObjectURL(objectUrl);
107
+ }, 1000);
108
+
109
+ // Success callback
110
+ onDownloadSuccess?.(downloadFileName, blob.size);
111
+
112
+ return {
113
+ success: true,
114
+ fileName: downloadFileName,
115
+ size: blob.size,
116
+ };
117
+ } catch (err) {
118
+ console.error('Chyba při stahování:', err);
119
+ const errorMessage = `Chyba při stahování souboru: ${err.message}`;
120
+ setError(errorMessage);
121
+ onDownloadError?.(err, errorMessage);
122
+
123
+ return {
124
+ success: false,
125
+ error: err,
126
+ errorMessage,
127
+ };
128
+ } finally {
129
+ setIsDownloading(false);
130
+ onDownloadEnd?.();
131
+ onLoadingChange?.(false);
132
+ }
133
+ },
134
+ [
135
+ isDownloading,
136
+ onDownloadStart,
137
+ onDownloadEnd,
138
+ onDownloadSuccess,
139
+ onDownloadError,
140
+ onLoadingChange,
141
+ accessToken,
142
+ fetchData,
143
+ ]
144
+ );
145
+
146
+ const reset = useCallback(() => {
147
+ setError('');
148
+ }, []);
149
+
150
+ return {
151
+ isDownloading,
152
+ error,
153
+ downloadFile,
154
+ reset,
155
+ };
156
+ };