@movalib/movalib-commons 1.55.5 → 1.55.7
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/PV_README.md +1 -1
- package/dist/src/components/QrCodePLVContainer/PLVComponent.d.ts +3 -0
- package/dist/src/components/QrCodePLVContainer/PLVComponent.js +16 -2
- package/dist/src/components/QrCodePLVContainer/QrCodePLVContainer.js +82 -10
- package/dist/src/helpers/ApiHelper.d.ts +0 -1
- package/dist/src/helpers/ApiHelper.js +2 -3
- package/dist/src/utils/DialogPrint.js +2 -1
- package/package.json +4 -2
- package/public/pdf.worker.mjs +56401 -0
- package/src/components/QrCodePLVContainer/PLVComponent.tsx +35 -0
- package/src/components/QrCodePLVContainer/QrCodePLVContainer.tsx +84 -13
- package/src/helpers/ApiHelper.ts +4 -7
- package/src/utils/DialogPrint.tsx +2 -1
- package/movalib-movalib-commons-1.55.36.tgz +0 -0
- package/movalib-movalib-commons-1.55.37.tgz +0 -0
|
@@ -179,8 +179,35 @@ export class PLVComponent extends React.Component<PLVComponentProps> {
|
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
export class PLVComponentV2 extends React.Component<PLVComponentProps> {
|
|
185
|
+
render() {
|
|
186
|
+
return (
|
|
187
|
+
<div
|
|
188
|
+
className='printable-content'
|
|
189
|
+
style={{
|
|
190
|
+
width:
|
|
191
|
+
this.props.printSize === PrintSize.A4 ? '210mm' : this.props.printSize === PrintSize.A3 ? '297mm' : '0mm',
|
|
192
|
+
height:
|
|
193
|
+
this.props.printSize === PrintSize.A4 ? '297mm' : this.props.printSize === PrintSize.A3 ? '420mm' : '0mm',
|
|
194
|
+
}}
|
|
195
|
+
>
|
|
196
|
+
<Grid container>
|
|
197
|
+
<Grid item xs={12}>
|
|
198
|
+
<img src={this.props.url} style={{ display: 'block', width: '100%', height: '100%', objectFit: 'cover' }} />
|
|
199
|
+
</Grid>
|
|
200
|
+
</Grid>
|
|
201
|
+
</div>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
182
206
|
// CSS pour cacher le contenu à l'écran mais le rendre imprimable
|
|
183
207
|
const css = `
|
|
208
|
+
body {
|
|
209
|
+
margin: 0;
|
|
210
|
+
}
|
|
184
211
|
.highlight {
|
|
185
212
|
background-color: #BCD46C; /* Couleur de surlignage */
|
|
186
213
|
margin: 4px 4px; /* Espacement autour du texte surligné */
|
|
@@ -197,13 +224,21 @@ const css = `
|
|
|
197
224
|
}
|
|
198
225
|
|
|
199
226
|
.printable-content {
|
|
227
|
+
margin: 0;
|
|
228
|
+
padding: 0;
|
|
200
229
|
visibility: hidden;
|
|
201
230
|
position: absolute;
|
|
202
231
|
left: -10000px;
|
|
203
232
|
top: -10000px;
|
|
233
|
+
|
|
204
234
|
}
|
|
205
235
|
@media print {
|
|
236
|
+
body {
|
|
237
|
+
margin: 0;
|
|
238
|
+
}
|
|
206
239
|
.printable-content {
|
|
240
|
+
margin: 0;
|
|
241
|
+
padding: 0;
|
|
207
242
|
visibility: visible;
|
|
208
243
|
position: static;
|
|
209
244
|
}
|
|
@@ -2,6 +2,7 @@ import { DocumentScanner, QrCode2 } from '@mui/icons-material';
|
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
4
|
Button,
|
|
5
|
+
CircularProgress,
|
|
5
6
|
FormControl,
|
|
6
7
|
Grid,
|
|
7
8
|
InputLabel,
|
|
@@ -20,21 +21,24 @@ import { useReactToPrint } from 'react-to-print';
|
|
|
20
21
|
import { DownloadedQRCode } from '../../DownloadedQRCode';
|
|
21
22
|
import QRCodeImage from '../../assets/images/leaf_yellow_small.png';
|
|
22
23
|
import { flexCenter } from '../../helpers/Tools';
|
|
23
|
-
import { PLVComponent, PrintSize } from './PLVComponent';
|
|
24
24
|
import { PDFDocument } from 'pdf-lib';
|
|
25
|
-
import {
|
|
25
|
+
import { PLVComponentV2, PrintSize } from './PLVComponent';
|
|
26
|
+
import * as pdfjsLib from 'pdfjs-dist';
|
|
27
|
+
pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.mjs';
|
|
26
28
|
|
|
27
29
|
type SelectChoice = null | 'A3' | 'A4' | 'QR_Headless' | 'QR_Google';
|
|
28
|
-
|
|
29
30
|
export const QrCodePLVContainer = ({ data }: { data: string }) => {
|
|
30
31
|
const [selectedChoice, setSelectedChoice] = useState<SelectChoice>(null);
|
|
32
|
+
const [urlA4, setUrlA4] = useState<string>('');
|
|
33
|
+
const [urlA3, setUrlA3] = useState<string>('');
|
|
34
|
+
const [isReady, setIsReady] = useState(false);
|
|
31
35
|
|
|
32
36
|
const qrCodeRef = useRef<HTMLDivElement>(null);
|
|
33
37
|
const theme = useTheme();
|
|
34
|
-
|
|
38
|
+
const PLVrefA4 = useRef<PLVComponentV2>(null);
|
|
39
|
+
const PLVrefA3 = useRef<PLVComponentV2>(null);
|
|
35
40
|
//si sur l'impression des PLV en A4 ou A3 le Qrcode est flou,
|
|
36
41
|
//il faut modifier la width et height, imageSize du qrCodeOptions et mettre les mêmes valeurs que dans le optionQrcode de la fonction printPLV
|
|
37
|
-
//
|
|
38
42
|
const qrCodeOptions: Options = useMemo(
|
|
39
43
|
() => ({
|
|
40
44
|
width: 300,
|
|
@@ -79,6 +83,24 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
|
|
|
79
83
|
qrCode.append(qrCodeRef.current);
|
|
80
84
|
}
|
|
81
85
|
}, [qrCode]);
|
|
86
|
+
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
const urlA4 = printPLV('A4').then((url) => {
|
|
89
|
+
setUrlA4(url);
|
|
90
|
+
});
|
|
91
|
+
const urlA3 = printPLV('A3').then((url) => {
|
|
92
|
+
setUrlA3(url);
|
|
93
|
+
});
|
|
94
|
+
}, [data]);
|
|
95
|
+
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (PLVrefA4.current || PLVrefA3.current) {
|
|
98
|
+
setIsReady(true);
|
|
99
|
+
} else {
|
|
100
|
+
setIsReady(false);
|
|
101
|
+
}
|
|
102
|
+
}, [PLVrefA4.current, PLVrefA3.current]);
|
|
103
|
+
|
|
82
104
|
async function printPLV(format: string) {
|
|
83
105
|
// Chemin du fichier PDF
|
|
84
106
|
const pdfUrl = `/Movalib_${format}.pdf`;
|
|
@@ -97,7 +119,7 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
|
|
|
97
119
|
const qrImage = await pdfDoc.embedPng(qrImageBytes!);
|
|
98
120
|
|
|
99
121
|
const pages = pdfDoc.getPages();
|
|
100
|
-
const firstPage = pages[0];
|
|
122
|
+
const firstPage = pages[0];
|
|
101
123
|
const { width, height } = firstPage.getSize();
|
|
102
124
|
|
|
103
125
|
let optionQrcode = {};
|
|
@@ -126,8 +148,38 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
|
|
|
126
148
|
const blob = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
|
|
127
149
|
const url = URL.createObjectURL(blob);
|
|
128
150
|
|
|
129
|
-
//
|
|
130
|
-
|
|
151
|
+
// étape nécesssaire pour utiliser reactToPrint pour pouvoir nommer le document
|
|
152
|
+
// reactToPrint fonctionne uniquement avec le HTML
|
|
153
|
+
// donc il faut convertir le PDF en image
|
|
154
|
+
// puis convertir l'image en URL
|
|
155
|
+
// et enfin integrer l'image dans le HTML via la balise <img>
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
// Convertir le PDF en image
|
|
159
|
+
const loadingTask = pdfjsLib.getDocument(url);
|
|
160
|
+
const pdf = await loadingTask.promise;
|
|
161
|
+
|
|
162
|
+
// Récupérer la première page
|
|
163
|
+
const page = await pdf.getPage(1);
|
|
164
|
+
|
|
165
|
+
// Créer un canvas pour afficher la page
|
|
166
|
+
const canvas = document.createElement('canvas');
|
|
167
|
+
const context = canvas.getContext('2d');
|
|
168
|
+
|
|
169
|
+
const viewport = page.getViewport({ scale: 4});
|
|
170
|
+
canvas.width = viewport.width;
|
|
171
|
+
canvas.height = viewport.height;
|
|
172
|
+
|
|
173
|
+
// Rendu de la page dans le canvas
|
|
174
|
+
const renderContext = {
|
|
175
|
+
canvasContext: context!,
|
|
176
|
+
viewport: viewport,
|
|
177
|
+
};
|
|
178
|
+
await page.render(renderContext).promise;
|
|
179
|
+
|
|
180
|
+
// Convertir le canvas en URL d'image (data URL)
|
|
181
|
+
const imageUrl = canvas.toDataURL('image/png');
|
|
182
|
+
return imageUrl;
|
|
131
183
|
}
|
|
132
184
|
|
|
133
185
|
const downloadQRCodeHeadless = useCallback(() => {
|
|
@@ -176,13 +228,23 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
|
|
|
176
228
|
const onChangeSelectedChoice: SelectProps<SelectChoice>['onChange'] = (e) => {
|
|
177
229
|
setSelectedChoice(e.target.value as SelectChoice);
|
|
178
230
|
};
|
|
231
|
+
|
|
232
|
+
const printA3PLV = useReactToPrint({
|
|
233
|
+
content: () => PLVrefA3.current,
|
|
234
|
+
documentTitle: 'Movalib_PLV_A3',
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const printA4PLV = useReactToPrint({
|
|
238
|
+
content: () => PLVrefA4.current,
|
|
239
|
+
documentTitle: 'Movalib_PLV_A4',
|
|
240
|
+
});
|
|
179
241
|
|
|
180
242
|
const onClickDownload = useMemo(() => {
|
|
181
243
|
switch (selectedChoice) {
|
|
182
244
|
case 'A3':
|
|
183
|
-
return
|
|
245
|
+
return printA3PLV;
|
|
184
246
|
case 'A4':
|
|
185
|
-
return
|
|
247
|
+
return printA4PLV;
|
|
186
248
|
case 'QR_Headless':
|
|
187
249
|
return downloadQRCodeHeadless;
|
|
188
250
|
case 'QR_Google':
|
|
@@ -190,9 +252,12 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
|
|
|
190
252
|
default:
|
|
191
253
|
return () => {};
|
|
192
254
|
}
|
|
193
|
-
}, [selectedChoice, downloadQRCodeHeadless, downloadQrCodeWithCTA]);
|
|
255
|
+
}, [selectedChoice, downloadQRCodeHeadless, downloadQrCodeWithCTA, printA3PLV, printA4PLV]);
|
|
194
256
|
return (
|
|
195
257
|
<Box display='flex' flexDirection='column' alignItems='center' gap='24px'>
|
|
258
|
+
{urlA4 && <PLVComponentV2 ref={PLVrefA4} url={urlA4} printSize={PrintSize.A4} />}
|
|
259
|
+
{urlA3 &&<PLVComponentV2 ref={PLVrefA3} url={urlA3} printSize={PrintSize.A3} />}
|
|
260
|
+
|
|
196
261
|
<Grid container justifyContent='center' alignItems='center'>
|
|
197
262
|
<Grid item xs={7}>
|
|
198
263
|
<FormControl fullWidth size='small'>
|
|
@@ -212,15 +277,21 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
|
|
|
212
277
|
</FormControl>
|
|
213
278
|
</Grid>
|
|
214
279
|
<Grid item xs={4} marginLeft={3}>
|
|
280
|
+
|
|
281
|
+
{(selectedChoice === 'A3' || selectedChoice === 'A4') && !isReady ? (
|
|
282
|
+
<CircularProgress />
|
|
283
|
+
) : (
|
|
215
284
|
<Button
|
|
216
285
|
startIcon={selectedChoice === 'A3' || selectedChoice === 'A4' ? <DocumentScanner /> : <QrCode2 />}
|
|
217
286
|
onClick={onClickDownload}
|
|
218
287
|
variant='outlined'
|
|
219
|
-
disabled={!selectedChoice}
|
|
288
|
+
disabled={!selectedChoice || ((selectedChoice === 'A3' || selectedChoice === 'A4') && !isReady)}
|
|
220
289
|
sx={{ color: darken(theme.palette.primary.main, 0.2), borderRadius: '10rem' }}
|
|
221
290
|
>
|
|
222
291
|
{selectedChoice === 'A3' || selectedChoice === 'A4' ? 'Imprimer' : 'Télécharger'}
|
|
223
|
-
|
|
292
|
+
</Button>
|
|
293
|
+
)}
|
|
294
|
+
|
|
224
295
|
</Grid>
|
|
225
296
|
</Grid>
|
|
226
297
|
<div id='qr-code-container' style={flexCenter}>
|
package/src/helpers/ApiHelper.ts
CHANGED
|
@@ -7,7 +7,6 @@ export const API_BASE_URL = process.env.REACT_APP_API_URL || 'https://localhost:
|
|
|
7
7
|
type APISuccess<T> = {
|
|
8
8
|
success: true;
|
|
9
9
|
data: T;
|
|
10
|
-
location: string
|
|
11
10
|
};
|
|
12
11
|
|
|
13
12
|
type APIError = {
|
|
@@ -21,8 +20,8 @@ type APIError = {
|
|
|
21
20
|
export type APIResponse<T> = {
|
|
22
21
|
success: boolean,
|
|
23
22
|
data?: T,
|
|
24
|
-
error?: string
|
|
25
|
-
|
|
23
|
+
error?: string
|
|
24
|
+
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
export type APIRequest = {
|
|
@@ -36,7 +35,7 @@ function handleError(error: Error): APIResponse<null> {
|
|
|
36
35
|
let msg = error.message.includes('fetch') ? "Connexion impossible" : error.message;
|
|
37
36
|
return {
|
|
38
37
|
success: false,
|
|
39
|
-
error: msg
|
|
38
|
+
error: msg
|
|
40
39
|
};
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -45,8 +44,6 @@ function handleResponse(response: Response): Promise<APIResponse<any>> {
|
|
|
45
44
|
const contentType = response.headers.get("content-type");
|
|
46
45
|
const isJson = contentType && contentType.includes("application/json");
|
|
47
46
|
const dataPromise = isJson ? response.json() : response.text();
|
|
48
|
-
const location = response.headers.get('Location');
|
|
49
|
-
|
|
50
47
|
|
|
51
48
|
return dataPromise.then(data => {
|
|
52
49
|
|
|
@@ -70,7 +67,7 @@ function handleResponse(response: Response): Promise<APIResponse<any>> {
|
|
|
70
67
|
return { success: false, error: errorMsg };
|
|
71
68
|
}
|
|
72
69
|
|
|
73
|
-
return { success: true, data
|
|
70
|
+
return { success: true, data };
|
|
74
71
|
});
|
|
75
72
|
}
|
|
76
73
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export function openDialogPrint(url: string) {
|
|
2
|
+
// Créer un iframe pour charger le document Blob => url
|
|
2
3
|
const iframe = document.createElement('iframe');
|
|
3
4
|
iframe.style.position = 'absolute';
|
|
4
5
|
iframe.style.width = '0px';
|
|
@@ -10,7 +11,7 @@ export function openDialogPrint(url: string) {
|
|
|
10
11
|
iframe.onload = () => {
|
|
11
12
|
iframe?.contentWindow?.print();
|
|
12
13
|
};
|
|
13
|
-
// Supprimer l'iframe une fois
|
|
14
|
+
// Supprimer l'iframe une fois lque la dialog est fermer
|
|
14
15
|
iframe.onclose = () => {
|
|
15
16
|
document.body.removeChild(iframe);
|
|
16
17
|
URL.revokeObjectURL(url);
|
|
Binary file
|
|
Binary file
|