@bit.rhplus/data 0.0.25 → 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 +3 -6
- package/dist/index.js +3 -64
- package/dist/index.js.map +1 -1
- package/dist/useData.d.ts +7 -0
- package/dist/useData.js +124 -0
- package/dist/useData.js.map +1 -0
- package/dist/useFileDownload.d.ts +24 -0
- package/dist/useFileDownload.js +130 -0
- package/dist/useFileDownload.js.map +1 -0
- package/index.js +4 -72
- package/package.json +4 -3
- package/useData.js +141 -0
- package/useFileDownload.js +156 -0
- /package/dist/{preview-1748847865447.js → preview-1748944094527.js} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
export default
|
|
2
|
-
|
|
3
|
-
|
|
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
|
|
2
|
-
|
|
3
|
-
export
|
|
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,
|
|
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";
|
package/dist/useData.js
ADDED
|
@@ -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,73 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
// import { useOidcAccessToken } from "@axa-fr/react-oidc";
|
|
1
|
+
import useData from './useData';
|
|
3
2
|
|
|
4
|
-
export default
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
/* eslint-disable */
|
|
17
|
-
const fetchData = (api, data, accessToken) => FetchData(api, data, accessToken);
|
|
18
|
-
|
|
19
|
-
const fetchDataUIAsync = async (api, data, accessToken) => {
|
|
20
|
-
try {
|
|
21
|
-
const result = await fetchData(api, data, accessToken);
|
|
22
|
-
return {
|
|
23
|
-
...result,
|
|
24
|
-
result: 'success',
|
|
25
|
-
success: true
|
|
26
|
-
};
|
|
27
|
-
} catch (error) {
|
|
28
|
-
errorNotification(error);
|
|
29
|
-
return {
|
|
30
|
-
result: 'fail',
|
|
31
|
-
success: false,
|
|
32
|
-
error
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const getFileURL = (content, type) => {
|
|
38
|
-
const isBase64 = typeof content === 'string' && /^[A-Za-z0-9+/=]+$/.test(content);
|
|
39
|
-
|
|
40
|
-
let byteArray;
|
|
41
|
-
if (isBase64) {
|
|
42
|
-
const byteCharacters = atob(content);
|
|
43
|
-
const byteNumbers = new Array(byteCharacters.length);
|
|
44
|
-
for (let i = 0; i < byteCharacters.length; i += 1) {
|
|
45
|
-
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
|
46
|
-
}
|
|
47
|
-
byteArray = new Uint8Array(byteNumbers);
|
|
48
|
-
} else {
|
|
49
|
-
byteArray = new Uint8Array(content);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const blob = new Blob([byteArray], { type });
|
|
53
|
-
const fileUrl = window.URL.createObjectURL(blob);
|
|
54
|
-
return fileUrl;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const downloadFileURL = (content, type, fileName) => {
|
|
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
|
-
|
|
65
|
-
return {
|
|
66
|
-
fetchData,
|
|
67
|
-
fetchDataUIAsync,
|
|
68
|
-
getFileURL,
|
|
69
|
-
downloadFileURL
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
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.
|
|
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.
|
|
9
|
+
"version": "0.0.27"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@tanstack/react-query": "^5.66.9",
|
|
13
|
-
"@bit.rhplus/api": "0.0.
|
|
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
|
+
};
|
|
File without changes
|