@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.
@@ -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 { openDialogPrint } from '../../utils/DialogPrint';
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]; // Ajouter le QR code à la première page
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
- // Ouvrir la page d'impression
130
- openDialogPrint(url);
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 () => {printPLV('A3')};
245
+ return printA3PLV;
184
246
  case 'A4':
185
- return () => {printPLV('A4')};
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
- </Button>
292
+ </Button>
293
+ )}
294
+
224
295
  </Grid>
225
296
  </Grid>
226
297
  <div id='qr-code-container' style={flexCenter}>
@@ -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
- location?: string | null
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, location: location };
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 l'impression terminée
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