@bigbinary/neeto-pdf-frontend 1.0.1

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.
Files changed (82) hide show
  1. package/README.md +413 -0
  2. package/app/javascript/src/translations/ar.json +5 -0
  3. package/app/javascript/src/translations/bg.json +5 -0
  4. package/app/javascript/src/translations/ca.json +5 -0
  5. package/app/javascript/src/translations/cs.json +5 -0
  6. package/app/javascript/src/translations/da.json +5 -0
  7. package/app/javascript/src/translations/de.json +5 -0
  8. package/app/javascript/src/translations/en.json +109 -0
  9. package/app/javascript/src/translations/es-MX.json +5 -0
  10. package/app/javascript/src/translations/es.json +5 -0
  11. package/app/javascript/src/translations/et.json +5 -0
  12. package/app/javascript/src/translations/fi.json +5 -0
  13. package/app/javascript/src/translations/fil.json +5 -0
  14. package/app/javascript/src/translations/fr.json +5 -0
  15. package/app/javascript/src/translations/he.json +5 -0
  16. package/app/javascript/src/translations/hi.json +5 -0
  17. package/app/javascript/src/translations/hr.json +5 -0
  18. package/app/javascript/src/translations/hu.json +5 -0
  19. package/app/javascript/src/translations/id.json +5 -0
  20. package/app/javascript/src/translations/index.js +3 -0
  21. package/app/javascript/src/translations/it.json +5 -0
  22. package/app/javascript/src/translations/ja.json +5 -0
  23. package/app/javascript/src/translations/ko.json +5 -0
  24. package/app/javascript/src/translations/nl.json +5 -0
  25. package/app/javascript/src/translations/pl.json +5 -0
  26. package/app/javascript/src/translations/pt-BR.json +5 -0
  27. package/app/javascript/src/translations/pt.json +5 -0
  28. package/app/javascript/src/translations/ro.json +5 -0
  29. package/app/javascript/src/translations/ru.json +5 -0
  30. package/app/javascript/src/translations/sk.json +5 -0
  31. package/app/javascript/src/translations/sl.json +5 -0
  32. package/app/javascript/src/translations/sv.json +5 -0
  33. package/app/javascript/src/translations/th.json +5 -0
  34. package/app/javascript/src/translations/tr.json +5 -0
  35. package/app/javascript/src/translations/uk.json +5 -0
  36. package/app/javascript/src/translations/vi.json +5 -0
  37. package/app/javascript/src/translations/zh-CN.json +5 -0
  38. package/app/javascript/src/translations/zh-TW.json +5 -0
  39. package/dist/.ready +1 -0
  40. package/dist/AttachmentCard-75GY2Thb.js +64 -0
  41. package/dist/AttachmentCard-75GY2Thb.js.map +1 -0
  42. package/dist/AttachmentCard-D_Gp0f5r.js +67 -0
  43. package/dist/AttachmentCard-D_Gp0f5r.js.map +1 -0
  44. package/dist/FilenameUtilities-Cw9Tvd6k.js +329 -0
  45. package/dist/FilenameUtilities-Cw9Tvd6k.js.map +1 -0
  46. package/dist/FilenameUtilities-De2k_NXh.js +318 -0
  47. package/dist/FilenameUtilities-De2k_NXh.js.map +1 -0
  48. package/dist/IconBlock-BTPLDDiO.js +15 -0
  49. package/dist/IconBlock-BTPLDDiO.js.map +1 -0
  50. package/dist/IconBlock-hZ_gOnb1.js +17 -0
  51. package/dist/IconBlock-hZ_gOnb1.js.map +1 -0
  52. package/dist/PdfAttachmentSelector.js +94 -0
  53. package/dist/PdfAttachmentSelector.js.map +1 -0
  54. package/dist/PdfAttachmentsPreview.js +43 -0
  55. package/dist/PdfAttachmentsPreview.js.map +1 -0
  56. package/dist/PdfDocumentsPage.js +555 -0
  57. package/dist/PdfDocumentsPage.js.map +1 -0
  58. package/dist/PdfEditorPage.js +2051 -0
  59. package/dist/PdfEditorPage.js.map +1 -0
  60. package/dist/cjs/PdfAttachmentSelector.js +96 -0
  61. package/dist/cjs/PdfAttachmentSelector.js.map +1 -0
  62. package/dist/cjs/PdfAttachmentsPreview.js +45 -0
  63. package/dist/cjs/PdfAttachmentsPreview.js.map +1 -0
  64. package/dist/cjs/PdfDocumentsPage.js +557 -0
  65. package/dist/cjs/PdfDocumentsPage.js.map +1 -0
  66. package/dist/cjs/PdfEditorPage.js +2072 -0
  67. package/dist/cjs/PdfEditorPage.js.map +1 -0
  68. package/dist/cjs/index.js +75 -0
  69. package/dist/cjs/index.js.map +1 -0
  70. package/dist/constants-CTDOz942.js +5 -0
  71. package/dist/constants-CTDOz942.js.map +1 -0
  72. package/dist/constants-DvvJYjxW.js +8 -0
  73. package/dist/constants-DvvJYjxW.js.map +1 -0
  74. package/dist/index.js +66 -0
  75. package/dist/index.js.map +1 -0
  76. package/package.json +240 -0
  77. package/types/PdfAttachmentSelector.d.ts +2 -0
  78. package/types/PdfAttachmentsPreview.d.ts +2 -0
  79. package/types/PdfDocumentsPage.d.ts +6 -0
  80. package/types/PdfEditorPage.d.ts +7 -0
  81. package/types/index.d.ts +88 -0
  82. package/types.d.ts +1 -0
@@ -0,0 +1,2051 @@
1
+ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
2
+ import { useRef, useState, useMemo, useEffect, createElement } from 'react';
3
+ import Spinner from '@bigbinary/neetoui/Spinner';
4
+ import { createPortal } from 'react-dom';
5
+ import { useTranslation } from 'react-i18next';
6
+ import Typography from '@bigbinary/neetoui/Typography';
7
+ import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
8
+ import _regeneratorRuntime from '@babel/runtime/regenerator';
9
+ import _defineProperty from '@babel/runtime/helpers/defineProperty';
10
+ import classNames from 'classnames';
11
+ import { findBy, findById, removeById } from '@bigbinary/neeto-cist';
12
+ import Calendar from '@bigbinary/neeto-icons/Calendar';
13
+ import Hash from '@bigbinary/neeto-icons/Hash';
14
+ import TextLines from '@bigbinary/neeto-icons/TextLines';
15
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
16
+ import * as pdfjsLib from 'pdfjs-dist';
17
+ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
18
+ import { withT } from '@bigbinary/neeto-commons-frontend/react-utils';
19
+ import CenterAlign from '@bigbinary/neeto-icons/CenterAlign';
20
+ import Delete from '@bigbinary/neeto-icons/Delete';
21
+ import Folder from '@bigbinary/neeto-icons/Folder';
22
+ import LeftAlign from '@bigbinary/neeto-icons/LeftAlign';
23
+ import RightAlign from '@bigbinary/neeto-icons/RightAlign';
24
+ import Button from '@bigbinary/neetoui/Button';
25
+ import ColorPicker from '@bigbinary/neetoui/ColorPicker';
26
+ import Input from '@bigbinary/neetoui/Input';
27
+ import Select from '@bigbinary/neetoui/Select';
28
+ import Search from '@bigbinary/neeto-icons/Search';
29
+ import Drag from '@bigbinary/neeto-icons/Drag';
30
+ import logger from 'js-logger';
31
+ import Toastr from '@bigbinary/neetoui/Toastr';
32
+ import { h as buildOutputFilename, i as useFetchPdfDocument, u as useUpdatePdfDocument, g as getPdfDocumentApiErrorMessage, d as buildOutputFilenameTemplate } from './FilenameUtilities-De2k_NXh.js';
33
+ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
34
+ import { append } from 'ramda';
35
+ import Left from '@bigbinary/neeto-icons/Left';
36
+ import Right from '@bigbinary/neeto-icons/Right';
37
+ import _typeof from '@babel/runtime/helpers/typeof';
38
+ import { dateFormat } from '@bigbinary/neeto-commons-frontend/utils';
39
+ import Download from '@bigbinary/neeto-icons/Download';
40
+ import LeftArrow from '@bigbinary/neeto-icons/LeftArrow';
41
+ import Minus from '@bigbinary/neeto-icons/Minus';
42
+ import Plus from '@bigbinary/neeto-icons/Plus';
43
+ import NavigationHeader from '@bigbinary/neeto-molecules/NavigationHeader';
44
+ import '@tanstack/react-query';
45
+ import 'axios';
46
+
47
+ var enums = {
48
+ sources: [
49
+ "answer",
50
+ "system"
51
+ ],
52
+ alignments: [
53
+ "left",
54
+ "center",
55
+ "right"
56
+ ]
57
+ };
58
+ var fonts = [
59
+ {
60
+ value: "Helvetica",
61
+ label: "Helvetica",
62
+ stack: "Helvetica, Arial, sans-serif",
63
+ client_variants: [
64
+ "Helvetica",
65
+ "HelveticaBold",
66
+ "HelveticaOblique",
67
+ "HelveticaBoldOblique"
68
+ ],
69
+ server_variants: [
70
+ "Helvetica",
71
+ "Helvetica-Bold",
72
+ "Helvetica-Oblique",
73
+ "Helvetica-BoldOblique"
74
+ ]
75
+ },
76
+ {
77
+ value: "Arial",
78
+ label: "Arial",
79
+ stack: "Arial, Helvetica, sans-serif",
80
+ client_variants: [
81
+ "Helvetica",
82
+ "HelveticaBold",
83
+ "HelveticaOblique",
84
+ "HelveticaBoldOblique"
85
+ ],
86
+ server_variants: [
87
+ "Helvetica",
88
+ "Helvetica-Bold",
89
+ "Helvetica-Oblique",
90
+ "Helvetica-BoldOblique"
91
+ ]
92
+ },
93
+ {
94
+ value: "Times New Roman",
95
+ label: "Times New Roman",
96
+ stack: "'Times New Roman', Times, serif",
97
+ client_variants: [
98
+ "TimesRoman",
99
+ "TimesRomanBold",
100
+ "TimesRomanItalic",
101
+ "TimesRomanBoldItalic"
102
+ ],
103
+ server_variants: [
104
+ "Times-Roman",
105
+ "Times-Bold",
106
+ "Times-Italic",
107
+ "Times-BoldItalic"
108
+ ]
109
+ },
110
+ {
111
+ value: "Georgia",
112
+ label: "Georgia",
113
+ stack: "Georgia, 'Times New Roman', serif",
114
+ client_variants: [
115
+ "TimesRoman",
116
+ "TimesRomanBold",
117
+ "TimesRomanItalic",
118
+ "TimesRomanBoldItalic"
119
+ ],
120
+ server_variants: [
121
+ "Times-Roman",
122
+ "Times-Bold",
123
+ "Times-Italic",
124
+ "Times-BoldItalic"
125
+ ]
126
+ },
127
+ {
128
+ value: "Courier",
129
+ label: "Courier",
130
+ stack: "'Courier New', Courier, monospace",
131
+ client_variants: [
132
+ "Courier",
133
+ "CourierBold",
134
+ "CourierOblique",
135
+ "CourierBoldOblique"
136
+ ],
137
+ server_variants: [
138
+ "Courier",
139
+ "Courier-Bold",
140
+ "Courier-Oblique",
141
+ "Courier-BoldOblique"
142
+ ]
143
+ },
144
+ {
145
+ value: "Verdana",
146
+ label: "Verdana",
147
+ stack: "Verdana, Geneva, sans-serif",
148
+ client_variants: [
149
+ "Helvetica",
150
+ "HelveticaBold",
151
+ "HelveticaOblique",
152
+ "HelveticaBoldOblique"
153
+ ],
154
+ server_variants: [
155
+ "Helvetica",
156
+ "Helvetica-Bold",
157
+ "Helvetica-Oblique",
158
+ "Helvetica-BoldOblique"
159
+ ]
160
+ }
161
+ ];
162
+ var ranges = {
163
+ font_size: {
164
+ min: 4,
165
+ max: 200
166
+ }
167
+ };
168
+ var defaults = {
169
+ box: {
170
+ x: 0.1,
171
+ y: 0.1,
172
+ width: 0.35,
173
+ height: 0.035
174
+ },
175
+ style: {
176
+ font: "Helvetica",
177
+ font_size: 12,
178
+ color: "#1F2937",
179
+ bold: false,
180
+ italic: false,
181
+ underline: false,
182
+ align: "left"
183
+ }
184
+ };
185
+ var pdfMappingSchema = {
186
+ enums: enums,
187
+ fonts: fonts,
188
+ ranges: ranges,
189
+ defaults: defaults
190
+ };
191
+
192
+ var mappingDefaults = pdfMappingSchema.defaults;
193
+
194
+ // CSS pixels per PDF point (96dpi / 72dpi). `renderScale = CSS_PX_PER_PT * zoom`
195
+ // maps a page's intrinsic point dimensions to on-screen pixels, and font sizes
196
+ // (stored in points) to pixels. Keeping geometry in point-fractions keeps
197
+ // mappings resolution independent.
198
+ var CSS_PX_PER_PT = 96 / 72;
199
+ var ZOOM = {
200
+ MIN: 0.5,
201
+ MAX: 2,
202
+ STEP: 0.1,
203
+ DEFAULT: 1
204
+ };
205
+ var PDF_CANVAS = {
206
+ MAX_DISPLAY_SIZE: 1400,
207
+ MAX_RENDER_SIZE: 8192,
208
+ MAX_RENDER_PIXELS: 16000000
209
+ };
210
+ var EDITOR_MODES = {
211
+ MAP: "map",
212
+ PREVIEW: "preview"
213
+ };
214
+ var PDF_LOAD_INITIAL_STATE = {
215
+ pages: [],
216
+ isLoading: true,
217
+ error: null
218
+ };
219
+ var EMPTY_MAPPINGS = [];
220
+ var FIELD_SOURCES = {
221
+ ANSWER: pdfMappingSchema.enums.sources[0],
222
+ SYSTEM: pdfMappingSchema.enums.sources[1]
223
+ };
224
+ var DRAG_KINDS = {
225
+ MOVE: "move",
226
+ RESIZE: "resize"
227
+ };
228
+ var ALIGNMENTS = {
229
+ LEFT: pdfMappingSchema.enums.alignments[0],
230
+ CENTER: pdfMappingSchema.enums.alignments[1],
231
+ RIGHT: pdfMappingSchema.enums.alignments[2]
232
+ };
233
+ var FORM_THEME_COLOR = "rgb(var(--neeto-form-answer-color, var(--neeto-ui-primary-500)))";
234
+ var FORM_THEME_BACKGROUND = "rgba(var(--neeto-form-answer-color, var(--neeto-ui-primary-500)), 0.08)";
235
+ var RESIZE_HANDLES = [{
236
+ key: "top-left",
237
+ x: "left",
238
+ y: "top",
239
+ className: "-left-1.5 -top-1.5 cursor-nwse-resize"
240
+ }, {
241
+ key: "top-right",
242
+ x: "right",
243
+ y: "top",
244
+ className: "-right-1.5 -top-1.5 cursor-nesw-resize"
245
+ }, {
246
+ key: "bottom-left",
247
+ x: "left",
248
+ y: "bottom",
249
+ className: "-left-1.5 -bottom-1.5 cursor-nesw-resize"
250
+ }, {
251
+ key: "bottom-right",
252
+ x: "right",
253
+ y: "bottom",
254
+ className: "-right-1.5 -bottom-1.5 cursor-nwse-resize"
255
+ }];
256
+
257
+ // Curated, PDF/web-safe fonts. The JSON schema also supplies the server-side
258
+ // variants so client/server rendering cannot drift when the list changes.
259
+ var FONTS = pdfMappingSchema.fonts.map(function (_ref) {
260
+ var label = _ref.label,
261
+ stack = _ref.stack,
262
+ value = _ref.value;
263
+ return {
264
+ value: value,
265
+ label: label,
266
+ stack: stack
267
+ };
268
+ });
269
+
270
+ // Maps a curated font to pdf-lib StandardFont variant names, indexed by
271
+ // (bold ? 1 : 0) + (italic ? 2 : 0).
272
+ var STANDARD_FONT_VARIANTS = Object.fromEntries(pdfMappingSchema.fonts.map(function (_ref2) {
273
+ var clientVariants = _ref2.client_variants,
274
+ value = _ref2.value;
275
+ return [value, clientVariants];
276
+ }));
277
+ var DEFAULT_FONT_SIZE = mappingDefaults.style.font_size;
278
+ var DEFAULT_DISPLAY_FONT_SIZE = DEFAULT_FONT_SIZE * CSS_PX_PER_PT;
279
+ var FONT_SIZE_LIMITS = pdfMappingSchema.ranges.font_size;
280
+ var DEFAULT_STYLE = {
281
+ font: mappingDefaults.style.font,
282
+ fontSize: DEFAULT_FONT_SIZE,
283
+ color: mappingDefaults.style.color,
284
+ bold: mappingDefaults.style.bold,
285
+ italic: mappingDefaults.style.italic,
286
+ underline: mappingDefaults.style.underline,
287
+ align: mappingDefaults.style.align
288
+ };
289
+
290
+ // Default placement box as a fraction of the page (top-left origin).
291
+ var DEFAULT_BOX = mappingDefaults.box;
292
+ var MIN_BOX = {
293
+ width: 0.03,
294
+ height: 0.012
295
+ };
296
+ var SYSTEM_FIELD_KEYS = {
297
+ FORM_NAME: "form_name",
298
+ SUBMISSION_ID: "submission_id",
299
+ SUBMISSION_DATE: "submission_date"
300
+ };
301
+
302
+ // System fields are not form questions; they resolve from submission metadata.
303
+ var SYSTEM_FIELDS = [{
304
+ key: SYSTEM_FIELD_KEYS.FORM_NAME,
305
+ labelKey: "neetoPdf.pdfDocuments.editor.systemFields.formName",
306
+ icon: TextLines
307
+ }, {
308
+ key: SYSTEM_FIELD_KEYS.SUBMISSION_ID,
309
+ labelKey: "neetoPdf.pdfDocuments.editor.systemFields.submissionId",
310
+ icon: Hash
311
+ }, {
312
+ key: SYSTEM_FIELD_KEYS.SUBMISSION_DATE,
313
+ labelKey: "neetoPdf.pdfDocuments.editor.systemFields.submissionDate",
314
+ icon: Calendar
315
+ }];
316
+
317
+ var clamp = function clamp(value, min, max) {
318
+ return Math.min(Math.max(value, min), max);
319
+ };
320
+ var getPdfPageDisplayScale = function getPdfPageDisplayScale(_ref) {
321
+ var heightPt = _ref.heightPt,
322
+ rawScale = _ref.rawScale,
323
+ widthPt = _ref.widthPt;
324
+ var maxPageSize = Math.max(widthPt, heightPt);
325
+ if (!maxPageSize) return rawScale;
326
+ var zoom = rawScale / CSS_PX_PER_PT;
327
+ var baseScale = Math.min(CSS_PX_PER_PT, PDF_CANVAS.MAX_DISPLAY_SIZE / maxPageSize);
328
+ return baseScale * zoom;
329
+ };
330
+ var getDefaultFontSizeForScale = function getDefaultFontSizeForScale(scale) {
331
+ if (!scale || Number.isNaN(scale)) return DEFAULT_STYLE.fontSize;
332
+ return clamp(Math.round(DEFAULT_DISPLAY_FONT_SIZE / scale), FONT_SIZE_LIMITS.min, FONT_SIZE_LIMITS.max);
333
+ };
334
+ var getFontStack = function getFontStack(font) {
335
+ var _findBy;
336
+ return ((_findBy = findBy({
337
+ value: font
338
+ }, FONTS)) === null || _findBy === void 0 ? void 0 : _findBy.stack) || FONTS[0].stack;
339
+ };
340
+
341
+ function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
342
+ function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
343
+ var getJustifyContent = function getJustifyContent(align) {
344
+ if (align === "center") return "center";
345
+ if (align === "right") return "flex-end";
346
+ return "flex-start";
347
+ };
348
+ var PlacedField = function PlacedField(_ref) {
349
+ var mapping = _ref.mapping,
350
+ mode = _ref.mode,
351
+ isSelected = _ref.isSelected,
352
+ scale = _ref.scale,
353
+ pageWidthPx = _ref.pageWidthPx,
354
+ pageHeightPx = _ref.pageHeightPx,
355
+ previewValue = _ref.previewValue,
356
+ onSelect = _ref.onSelect,
357
+ onChange = _ref.onChange;
358
+ var dragRef = useRef(null);
359
+ var draftPatchRef = useRef(null);
360
+ var _useState = useState(null),
361
+ _useState2 = _slicedToArray(_useState, 2),
362
+ draftPatch = _useState2[0],
363
+ setDraftPatch = _useState2[1];
364
+ var isPreview = mode === EDITOR_MODES.PREVIEW;
365
+ var displayMapping = draftPatch ? _objectSpread$3(_objectSpread$3({}, mapping), draftPatch) : mapping;
366
+ var style = {
367
+ left: "".concat(displayMapping.x * pageWidthPx, "px"),
368
+ top: "".concat(displayMapping.y * pageHeightPx, "px"),
369
+ width: "".concat(displayMapping.width * pageWidthPx, "px"),
370
+ height: "".concat(displayMapping.height * pageHeightPx, "px")
371
+ };
372
+ var selectedStyle = isSelected ? {
373
+ borderColor: FORM_THEME_COLOR,
374
+ backgroundColor: FORM_THEME_BACKGROUND
375
+ } : {};
376
+ var textStyle = {
377
+ fontFamily: getFontStack(displayMapping.font),
378
+ fontSize: "".concat(displayMapping.fontSize * scale, "px"),
379
+ color: displayMapping.color,
380
+ fontWeight: displayMapping.bold ? 700 : 400,
381
+ fontStyle: displayMapping.italic ? "italic" : "normal",
382
+ textDecoration: displayMapping.underline ? "underline" : "none",
383
+ textAlign: displayMapping.align,
384
+ justifyContent: getJustifyContent(displayMapping.align)
385
+ };
386
+ var getResizePatch = function getResizePatch(_ref2) {
387
+ var drag = _ref2.drag,
388
+ dxFrac = _ref2.dxFrac,
389
+ dyFrac = _ref2.dyFrac;
390
+ var patch = {};
391
+ var originRight = drag.originX + drag.originWidth;
392
+ var originBottom = drag.originY + drag.originHeight;
393
+ if (drag.handle.x === "left") {
394
+ var x = clamp(drag.originX + dxFrac, 0, originRight - MIN_BOX.width);
395
+ patch.x = x;
396
+ patch.width = originRight - x;
397
+ } else {
398
+ patch.width = clamp(drag.originWidth + dxFrac, MIN_BOX.width, 1 - drag.originX);
399
+ }
400
+ if (drag.handle.y === "top") {
401
+ var y = clamp(drag.originY + dyFrac, 0, originBottom - MIN_BOX.height);
402
+ patch.y = y;
403
+ patch.height = originBottom - y;
404
+ } else {
405
+ patch.height = clamp(drag.originHeight + dyFrac, MIN_BOX.height, 1 - drag.originY);
406
+ }
407
+ return patch;
408
+ };
409
+ var handlePointerMove = function handlePointerMove(event) {
410
+ var drag = dragRef.current;
411
+ if (!drag) return;
412
+ var dxFrac = (event.clientX - drag.startX) / pageWidthPx;
413
+ var dyFrac = (event.clientY - drag.startY) / pageHeightPx;
414
+ var patch = drag.kind === DRAG_KINDS.MOVE ? {
415
+ x: clamp(drag.originX + dxFrac, 0, 1 - mapping.width),
416
+ y: clamp(drag.originY + dyFrac, 0, 1 - mapping.height)
417
+ } : getResizePatch({
418
+ drag: drag,
419
+ dxFrac: dxFrac,
420
+ dyFrac: dyFrac
421
+ });
422
+ draftPatchRef.current = patch;
423
+ setDraftPatch(patch);
424
+ };
425
+ var startDrag = function startDrag(event, kind) {
426
+ var handle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
427
+ if (isPreview) return;
428
+ event.stopPropagation();
429
+ event.preventDefault();
430
+ onSelect(mapping.id);
431
+ event.currentTarget.setPointerCapture(event.pointerId);
432
+ dragRef.current = {
433
+ kind: kind,
434
+ handle: handle,
435
+ startX: event.clientX,
436
+ startY: event.clientY,
437
+ originX: mapping.x,
438
+ originY: mapping.y,
439
+ originWidth: mapping.width,
440
+ originHeight: mapping.height
441
+ };
442
+ draftPatchRef.current = null;
443
+ setDraftPatch(null);
444
+ };
445
+ var endDrag = function endDrag(event) {
446
+ var _event$currentTarget$, _event$currentTarget;
447
+ if (!dragRef.current) return;
448
+ (_event$currentTarget$ = (_event$currentTarget = event.currentTarget).releasePointerCapture) === null || _event$currentTarget$ === void 0 || _event$currentTarget$.call(_event$currentTarget, event.pointerId);
449
+ dragRef.current = null;
450
+ if (draftPatchRef.current) onChange(mapping.id, draftPatchRef.current);
451
+ draftPatchRef.current = null;
452
+ setDraftPatch(null);
453
+ };
454
+ var renderResizeHandle = function renderResizeHandle(handle) {
455
+ return /*#__PURE__*/jsx("span", {
456
+ style: {
457
+ backgroundColor: FORM_THEME_COLOR
458
+ },
459
+ className: classNames("neeto-ui-rounded-full neeto-ui-border-white absolute h-3 w-3 border-2", handle.className),
460
+ onPointerCancel: endDrag,
461
+ onPointerDown: function onPointerDown(event) {
462
+ return startDrag(event, DRAG_KINDS.RESIZE, handle);
463
+ },
464
+ onPointerMove: handlePointerMove,
465
+ onPointerUp: endDrag
466
+ }, handle.key);
467
+ };
468
+ if (isPreview) {
469
+ return /*#__PURE__*/jsx("div", {
470
+ style: style,
471
+ className: "pointer-events-none absolute flex items-center",
472
+ children: /*#__PURE__*/jsx("span", {
473
+ className: "w-full overflow-hidden leading-tight whitespace-pre-wrap",
474
+ style: textStyle,
475
+ children: previewValue
476
+ })
477
+ });
478
+ }
479
+ return /*#__PURE__*/jsxs("div", {
480
+ style: _objectSpread$3(_objectSpread$3({}, style), selectedStyle),
481
+ className: classNames("neeto-ui-rounded-sm absolute flex cursor-move items-center border transition-colors select-none", {
482
+ "z-10": isSelected,
483
+ "neeto-ui-border-gray-400 bg-opacity-40 neeto-ui-bg-white border-dashed": !isSelected
484
+ }),
485
+ onPointerCancel: endDrag,
486
+ onPointerDown: function onPointerDown(event) {
487
+ return startDrag(event, DRAG_KINDS.MOVE);
488
+ },
489
+ onPointerMove: handlePointerMove,
490
+ onPointerUp: endDrag,
491
+ children: [/*#__PURE__*/jsx("span", {
492
+ className: "flex w-full items-center gap-1 overflow-hidden px-1 leading-tight",
493
+ style: textStyle,
494
+ children: /*#__PURE__*/jsx("span", {
495
+ className: "truncate",
496
+ children: displayMapping.label
497
+ })
498
+ }), isSelected && RESIZE_HANDLES.map(renderResizeHandle)]
499
+ });
500
+ };
501
+
502
+ var getRenderPixelRatio = function getRenderPixelRatio(viewport) {
503
+ var dpr = window.devicePixelRatio || 1;
504
+ var widthRatio = PDF_CANVAS.MAX_RENDER_SIZE / viewport.width;
505
+ var heightRatio = PDF_CANVAS.MAX_RENDER_SIZE / viewport.height;
506
+ var pixelRatio = Math.sqrt(PDF_CANVAS.MAX_RENDER_PIXELS / (viewport.width * viewport.height));
507
+ return Math.min(dpr, widthRatio, heightRatio, pixelRatio);
508
+ };
509
+ var PdfPage = function PdfPage(_ref) {
510
+ var pageDescriptor = _ref.pageDescriptor,
511
+ rawScale = _ref.scale,
512
+ mappings = _ref.mappings,
513
+ selectedId = _ref.selectedId,
514
+ mode = _ref.mode,
515
+ resolveValue = _ref.resolveValue,
516
+ onSelect = _ref.onSelect,
517
+ onChange = _ref.onChange,
518
+ onDropField = _ref.onDropField,
519
+ onScaleChange = _ref.onScaleChange;
520
+ var page = pageDescriptor.page,
521
+ pageNumber = pageDescriptor.pageNumber,
522
+ widthPt = pageDescriptor.widthPt,
523
+ heightPt = pageDescriptor.heightPt;
524
+ var canvasRef = useRef(null);
525
+ var overlayRef = useRef(null);
526
+ var scale = useMemo(function () {
527
+ return getPdfPageDisplayScale({
528
+ heightPt: heightPt,
529
+ rawScale: rawScale,
530
+ widthPt: widthPt
531
+ });
532
+ }, [heightPt, rawScale, widthPt]);
533
+ var defaultMappingScale = useMemo(function () {
534
+ return getPdfPageDisplayScale({
535
+ heightPt: heightPt,
536
+ rawScale: CSS_PX_PER_PT,
537
+ widthPt: widthPt
538
+ });
539
+ }, [heightPt, widthPt]);
540
+ var viewport = useMemo(function () {
541
+ return page.getViewport({
542
+ scale: scale
543
+ });
544
+ }, [page, scale]);
545
+ var pageWidthPx = viewport.width;
546
+ var pageHeightPx = viewport.height;
547
+ useEffect(function () {
548
+ onScaleChange(pageNumber, defaultMappingScale);
549
+ }, [defaultMappingScale, onScaleChange, pageNumber]);
550
+ useEffect(function () {
551
+ var canvas = canvasRef.current;
552
+ if (!canvas) return undefined;
553
+ var renderPixelRatio = getRenderPixelRatio(viewport);
554
+ canvas.width = Math.floor(viewport.width * renderPixelRatio);
555
+ canvas.height = Math.floor(viewport.height * renderPixelRatio);
556
+ canvas.style.width = "".concat(viewport.width, "px");
557
+ canvas.style.height = "".concat(viewport.height, "px");
558
+ var renderTask = page.render({
559
+ canvasContext: canvas.getContext("2d"),
560
+ viewport: viewport,
561
+ transform: renderPixelRatio !== 1 ? [renderPixelRatio, 0, 0, renderPixelRatio, 0, 0] : undefined
562
+ });
563
+ var render = /*#__PURE__*/function () {
564
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
565
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
566
+ while (1) switch (_context.prev = _context.next) {
567
+ case 0:
568
+ _context.prev = 0;
569
+ _context.next = 3;
570
+ return renderTask.promise;
571
+ case 3:
572
+ _context.next = 7;
573
+ break;
574
+ case 5:
575
+ _context.prev = 5;
576
+ _context.t0 = _context["catch"](0);
577
+ case 7:
578
+ case "end":
579
+ return _context.stop();
580
+ }
581
+ }, _callee, null, [[0, 5]]);
582
+ }));
583
+ return function render() {
584
+ return _ref2.apply(this, arguments);
585
+ };
586
+ }();
587
+ render();
588
+ return function () {
589
+ return renderTask.cancel();
590
+ };
591
+ }, [page, scale, viewport]);
592
+ var handleDrop = function handleDrop(event) {
593
+ event.preventDefault();
594
+ var rect = overlayRef.current.getBoundingClientRect();
595
+ var xFrac = clamp((event.clientX - rect.left) / rect.width, 0, 1);
596
+ var yFrac = clamp((event.clientY - rect.top) / rect.height, 0, 1);
597
+ onDropField({
598
+ pageNumber: pageNumber,
599
+ scale: defaultMappingScale,
600
+ x: xFrac,
601
+ y: yFrac
602
+ });
603
+ };
604
+ var handleDragOver = function handleDragOver(event) {
605
+ event.preventDefault();
606
+ event.dataTransfer.dropEffect = "copy";
607
+ };
608
+ return /*#__PURE__*/jsxs("div", {
609
+ className: "neeto-ui-shadow-md neeto-ui-bg-white relative",
610
+ style: {
611
+ width: "".concat(pageWidthPx, "px"),
612
+ height: "".concat(pageHeightPx, "px")
613
+ },
614
+ children: [/*#__PURE__*/jsx("canvas", {
615
+ ref: canvasRef
616
+ }), /*#__PURE__*/jsx("div", {
617
+ className: "absolute inset-0",
618
+ ref: overlayRef,
619
+ onDragOver: handleDragOver,
620
+ onDrop: handleDrop,
621
+ onPointerDown: function onPointerDown() {
622
+ return onSelect(null);
623
+ },
624
+ children: mappings.map(function (mapping) {
625
+ return /*#__PURE__*/createElement(PlacedField, {
626
+ mapping: mapping,
627
+ mode: mode,
628
+ onChange: onChange,
629
+ onSelect: onSelect,
630
+ pageHeightPx: pageHeightPx,
631
+ pageWidthPx: pageWidthPx,
632
+ scale: scale,
633
+ isSelected: mapping.id === selectedId,
634
+ key: mapping.id,
635
+ previewValue: mode === EDITOR_MODES.PREVIEW ? resolveValue(mapping) : null
636
+ });
637
+ })
638
+ })]
639
+ });
640
+ };
641
+
642
+ // The worker is vendored into public/ (see the sync:pdf-worker script) so it is
643
+ // served as a static asset with a JS MIME type. pdf.js always loads it as a
644
+ // module worker. Its version must stay in sync with pdfjs-dist.
645
+ pdfjsLib.GlobalWorkerOptions.workerSrc = "/pdf.worker.min.js";
646
+
647
+ // Loads a PDF via pdf.js and returns one descriptor per page:
648
+ // { pageNumber, page (PDFPageProxy), widthPt, heightPt }. Dimensions are in PDF
649
+ // points (viewport scale 1), which the canvas scales by CSS_PX_PER_PT * zoom.
650
+ var usePdfDocument = function usePdfDocument(url) {
651
+ var _useState = useState(PDF_LOAD_INITIAL_STATE),
652
+ _useState2 = _slicedToArray(_useState, 2),
653
+ state = _useState2[0],
654
+ setState = _useState2[1];
655
+ useEffect(function () {
656
+ if (!url) return undefined;
657
+ var isCancelled = false;
658
+ var pdf;
659
+ setState(PDF_LOAD_INITIAL_STATE);
660
+ var loadingTask = pdfjsLib.getDocument({
661
+ url: url
662
+ });
663
+ var loadPages = /*#__PURE__*/function () {
664
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
665
+ var pages, pageNumber, page, viewport;
666
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
667
+ while (1) switch (_context.prev = _context.next) {
668
+ case 0:
669
+ _context.prev = 0;
670
+ _context.next = 3;
671
+ return loadingTask.promise;
672
+ case 3:
673
+ pdf = _context.sent;
674
+ pages = [];
675
+ pageNumber = 1;
676
+ case 6:
677
+ if (!(pageNumber <= pdf.numPages)) {
678
+ _context.next = 15;
679
+ break;
680
+ }
681
+ _context.next = 9;
682
+ return pdf.getPage(pageNumber);
683
+ case 9:
684
+ page = _context.sent;
685
+ viewport = page.getViewport({
686
+ scale: 1
687
+ });
688
+ pages.push({
689
+ pageNumber: pageNumber,
690
+ page: page,
691
+ widthPt: viewport.width,
692
+ heightPt: viewport.height
693
+ });
694
+ case 12:
695
+ pageNumber += 1;
696
+ _context.next = 6;
697
+ break;
698
+ case 15:
699
+ if (!isCancelled) setState({
700
+ pages: pages,
701
+ isLoading: false,
702
+ error: null
703
+ });
704
+ _context.next = 21;
705
+ break;
706
+ case 18:
707
+ _context.prev = 18;
708
+ _context.t0 = _context["catch"](0);
709
+ if (!isCancelled) setState({
710
+ pages: [],
711
+ isLoading: false,
712
+ error: _context.t0
713
+ });
714
+ case 21:
715
+ case "end":
716
+ return _context.stop();
717
+ }
718
+ }, _callee, null, [[0, 18]]);
719
+ }));
720
+ return function loadPages() {
721
+ return _ref.apply(this, arguments);
722
+ };
723
+ }();
724
+ loadPages();
725
+ return function () {
726
+ var _loadingTask$destroy, _pdf, _pdf$destroy;
727
+ isCancelled = true;
728
+ (_loadingTask$destroy = loadingTask.destroy) === null || _loadingTask$destroy === void 0 || _loadingTask$destroy.call(loadingTask);
729
+ (_pdf = pdf) === null || _pdf === void 0 || (_pdf$destroy = _pdf.destroy) === null || _pdf$destroy === void 0 || _pdf$destroy.call(_pdf);
730
+ };
731
+ }, [url]);
732
+ return state;
733
+ };
734
+
735
+ var Canvas = function Canvas(_ref) {
736
+ var templateUrl = _ref.templateUrl,
737
+ zoom = _ref.zoom,
738
+ mappings = _ref.mappings,
739
+ selectedId = _ref.selectedId,
740
+ mode = _ref.mode,
741
+ resolveValue = _ref.resolveValue,
742
+ onSelect = _ref.onSelect,
743
+ onChange = _ref.onChange,
744
+ onDropField = _ref.onDropField,
745
+ onPageScaleChange = _ref.onPageScaleChange;
746
+ var _useTranslation = useTranslation(),
747
+ t = _useTranslation.t;
748
+ var _usePdfDocument = usePdfDocument(templateUrl),
749
+ pages = _usePdfDocument.pages,
750
+ isLoading = _usePdfDocument.isLoading,
751
+ error = _usePdfDocument.error;
752
+ var scale = CSS_PX_PER_PT * zoom;
753
+ var mappingsByPage = useMemo(function () {
754
+ return mappings.reduce(function (groupedMappings, mapping) {
755
+ var pageMappings = groupedMappings.get(mapping.page) || [];
756
+ pageMappings.push(mapping);
757
+ groupedMappings.set(mapping.page, pageMappings);
758
+ return groupedMappings;
759
+ }, new Map());
760
+ }, [mappings]);
761
+ if (isLoading) {
762
+ return /*#__PURE__*/jsx("div", {
763
+ className: "flex h-full w-full items-center justify-center",
764
+ children: /*#__PURE__*/jsx(Spinner, {})
765
+ });
766
+ }
767
+ if (error || !templateUrl) {
768
+ return /*#__PURE__*/jsx("div", {
769
+ className: "flex h-full w-full items-center justify-center p-8",
770
+ children: /*#__PURE__*/jsx(Typography, {
771
+ className: "neeto-ui-text-gray-500",
772
+ style: "body2",
773
+ children: t("neetoPdf.pdfDocuments.editor.renderError")
774
+ })
775
+ });
776
+ }
777
+ return /*#__PURE__*/jsx("div", {
778
+ className: "neeto-ui-bg-gray-200 absolute inset-0 overflow-auto",
779
+ children: /*#__PURE__*/jsx("div", {
780
+ className: "flex min-h-full min-w-full w-max flex-col items-center gap-6 p-8",
781
+ children: pages.map(function (pageDescriptor) {
782
+ return /*#__PURE__*/createElement(PdfPage, {
783
+ mode: mode,
784
+ onChange: onChange,
785
+ onDropField: onDropField,
786
+ onSelect: onSelect,
787
+ pageDescriptor: pageDescriptor,
788
+ resolveValue: resolveValue,
789
+ scale: scale,
790
+ selectedId: selectedId,
791
+ key: pageDescriptor.pageNumber,
792
+ mappings: mappingsByPage.get(pageDescriptor.pageNumber) || EMPTY_MAPPINGS,
793
+ onScaleChange: onPageScaleChange
794
+ });
795
+ })
796
+ })
797
+ });
798
+ };
799
+
800
+ var _excluded = ["isActive", "onClick", "className", "children"];
801
+ function ownKeys$2(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
802
+ function _objectSpread$2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$2(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$2(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
803
+ var ToggleButton = function ToggleButton(_ref) {
804
+ var isActive = _ref.isActive,
805
+ onClick = _ref.onClick,
806
+ className = _ref.className,
807
+ children = _ref.children,
808
+ rest = _objectWithoutProperties(_ref, _excluded);
809
+ return /*#__PURE__*/jsx("button", _objectSpread$2(_objectSpread$2({
810
+ onClick: onClick,
811
+ type: "button",
812
+ className: classNames("neeto-ui-border-gray-300 flex h-8 items-center justify-center border text-sm first:rounded-l-md last:rounded-r-md", className, {
813
+ "neeto-ui-bg-gray-800 neeto-ui-text-white": isActive,
814
+ "neeto-ui-bg-white neeto-ui-text-gray-700 hover:neeto-ui-bg-gray-100": !isActive
815
+ })
816
+ }, rest), {}, {
817
+ children: children
818
+ }));
819
+ };
820
+ var EmptyState = withT(function (_ref2) {
821
+ var t = _ref2.t;
822
+ return /*#__PURE__*/jsxs("div", {
823
+ className: "flex h-full flex-col items-center justify-center gap-2 p-8 text-center",
824
+ children: [/*#__PURE__*/jsx(Folder, {
825
+ className: "neeto-ui-text-gray-400",
826
+ size: 32
827
+ }), /*#__PURE__*/jsx(Typography, {
828
+ style: "body2",
829
+ weight: "medium",
830
+ children: t("neetoPdf.pdfDocuments.editor.field.emptyTitle")
831
+ }), /*#__PURE__*/jsx(Typography, {
832
+ className: "neeto-ui-text-gray-500",
833
+ style: "body3",
834
+ children: t("neetoPdf.pdfDocuments.editor.field.emptyDescription")
835
+ })]
836
+ });
837
+ });
838
+ var renderFontOptionLabel = function renderFontOptionLabel(_ref3) {
839
+ var label = _ref3.label,
840
+ stack = _ref3.stack;
841
+ return /*#__PURE__*/jsx("span", {
842
+ style: {
843
+ fontFamily: stack
844
+ },
845
+ children: label
846
+ });
847
+ };
848
+ var sanitizeFontSize = function sanitizeFontSize(value) {
849
+ var fontSize = Number(value);
850
+ if (Number.isNaN(fontSize)) return FONT_SIZE_LIMITS.min;
851
+ return Math.min(Math.max(fontSize, FONT_SIZE_LIMITS.min), FONT_SIZE_LIMITS.max);
852
+ };
853
+ var FieldPanel = withT(function (_ref4) {
854
+ var t = _ref4.t,
855
+ mapping = _ref4.mapping,
856
+ _onChange = _ref4.onChange,
857
+ onRemove = _ref4.onRemove;
858
+ return mapping ? /*#__PURE__*/jsxs("div", {
859
+ className: "neeto-ui-border-gray-200 neeto-ui-bg-white flex h-full w-72 shrink-0 flex-col overflow-y-auto border-l p-4",
860
+ children: [/*#__PURE__*/jsx("div", {
861
+ className: "mb-4 flex place-content-between items-center gap-2",
862
+ children: /*#__PURE__*/jsx(Typography, {
863
+ className: "truncate",
864
+ "data-testid": "field-header",
865
+ style: "h3",
866
+ children: mapping.label
867
+ })
868
+ }), /*#__PURE__*/jsxs("div", {
869
+ className: "grow space-y-5",
870
+ children: [/*#__PURE__*/jsxs("div", {
871
+ className: "space-y-1",
872
+ children: [/*#__PURE__*/jsx(Typography, {
873
+ className: "neeto-ui-text-gray-700",
874
+ style: "body3",
875
+ children: t("neetoPdf.pdfDocuments.editor.field.font")
876
+ }), /*#__PURE__*/jsx(Select, {
877
+ formatOptionLabel: renderFontOptionLabel,
878
+ isSearchable: false,
879
+ options: FONTS,
880
+ size: "small",
881
+ strategy: "fixed",
882
+ value: findBy({
883
+ value: mapping.font
884
+ }, FONTS),
885
+ onChange: function onChange(option) {
886
+ return _onChange(mapping.id, {
887
+ font: option.value
888
+ });
889
+ }
890
+ })]
891
+ }), /*#__PURE__*/jsxs("div", {
892
+ className: "flex gap-4",
893
+ children: [/*#__PURE__*/jsxs("div", {
894
+ className: "min-w-0 flex-1 space-y-1",
895
+ children: [/*#__PURE__*/jsx(Typography, {
896
+ className: "neeto-ui-text-gray-700",
897
+ style: "body3",
898
+ children: t("neetoPdf.pdfDocuments.editor.field.size")
899
+ }), /*#__PURE__*/jsx(Input, {
900
+ max: FONT_SIZE_LIMITS.max,
901
+ min: FONT_SIZE_LIMITS.min,
902
+ size: "small",
903
+ type: "number",
904
+ value: mapping.fontSize,
905
+ onChange: function onChange(event) {
906
+ return _onChange(mapping.id, {
907
+ fontSize: sanitizeFontSize(event.target.value)
908
+ });
909
+ }
910
+ })]
911
+ }), /*#__PURE__*/jsxs("div", {
912
+ className: "space-y-1",
913
+ children: [/*#__PURE__*/jsx(Typography, {
914
+ className: "neeto-ui-text-gray-700",
915
+ style: "body3",
916
+ children: t("neetoPdf.pdfDocuments.editor.field.format")
917
+ }), /*#__PURE__*/jsxs("div", {
918
+ className: "flex",
919
+ children: [/*#__PURE__*/jsx(ToggleButton, {
920
+ "aria-label": "bold",
921
+ className: "w-9",
922
+ isActive: mapping.bold,
923
+ onClick: function onClick() {
924
+ return _onChange(mapping.id, {
925
+ bold: !mapping.bold
926
+ });
927
+ },
928
+ children: /*#__PURE__*/jsx("span", {
929
+ className: "font-bold",
930
+ children: "B"
931
+ })
932
+ }), /*#__PURE__*/jsx(ToggleButton, {
933
+ "aria-label": "italic",
934
+ className: "w-9",
935
+ isActive: mapping.italic,
936
+ onClick: function onClick() {
937
+ return _onChange(mapping.id, {
938
+ italic: !mapping.italic
939
+ });
940
+ },
941
+ children: /*#__PURE__*/jsx("span", {
942
+ className: "italic",
943
+ children: "I"
944
+ })
945
+ }), /*#__PURE__*/jsx(ToggleButton, {
946
+ "aria-label": "underline",
947
+ className: "w-9",
948
+ isActive: mapping.underline,
949
+ onClick: function onClick() {
950
+ return _onChange(mapping.id, {
951
+ underline: !mapping.underline
952
+ });
953
+ },
954
+ children: /*#__PURE__*/jsx("span", {
955
+ className: "underline",
956
+ children: "U"
957
+ })
958
+ })]
959
+ })]
960
+ })]
961
+ }), /*#__PURE__*/jsxs("div", {
962
+ className: "space-y-1",
963
+ children: [/*#__PURE__*/jsx(Typography, {
964
+ className: "neeto-ui-text-gray-700",
965
+ style: "body3",
966
+ children: t("neetoPdf.pdfDocuments.editor.field.fontColor")
967
+ }), /*#__PURE__*/jsx(ColorPicker, {
968
+ showHexValue: true,
969
+ color: mapping.color,
970
+ size: "small",
971
+ onChange: function onChange(_ref5) {
972
+ var hex = _ref5.hex;
973
+ return _onChange(mapping.id, {
974
+ color: hex
975
+ });
976
+ }
977
+ })]
978
+ }), /*#__PURE__*/jsxs("div", {
979
+ className: "space-y-1",
980
+ children: [/*#__PURE__*/jsx(Typography, {
981
+ className: "neeto-ui-text-gray-700",
982
+ style: "body3",
983
+ children: t("neetoPdf.pdfDocuments.editor.field.alignment")
984
+ }), /*#__PURE__*/jsxs("div", {
985
+ className: "flex w-full",
986
+ children: [/*#__PURE__*/jsx(ToggleButton, {
987
+ "aria-label": "align-left",
988
+ className: "flex-1",
989
+ isActive: mapping.align === ALIGNMENTS.LEFT,
990
+ onClick: function onClick() {
991
+ return _onChange(mapping.id, {
992
+ align: ALIGNMENTS.LEFT
993
+ });
994
+ },
995
+ children: /*#__PURE__*/jsx(LeftAlign, {
996
+ size: 16
997
+ })
998
+ }), /*#__PURE__*/jsx(ToggleButton, {
999
+ "aria-label": "align-center",
1000
+ className: "flex-1",
1001
+ isActive: mapping.align === ALIGNMENTS.CENTER,
1002
+ onClick: function onClick() {
1003
+ return _onChange(mapping.id, {
1004
+ align: ALIGNMENTS.CENTER
1005
+ });
1006
+ },
1007
+ children: /*#__PURE__*/jsx(CenterAlign, {
1008
+ size: 16
1009
+ })
1010
+ }), /*#__PURE__*/jsx(ToggleButton, {
1011
+ "aria-label": "align-right",
1012
+ className: "flex-1",
1013
+ isActive: mapping.align === ALIGNMENTS.RIGHT,
1014
+ onClick: function onClick() {
1015
+ return _onChange(mapping.id, {
1016
+ align: ALIGNMENTS.RIGHT
1017
+ });
1018
+ },
1019
+ children: /*#__PURE__*/jsx(RightAlign, {
1020
+ size: 16
1021
+ })
1022
+ })]
1023
+ })]
1024
+ })]
1025
+ }), /*#__PURE__*/jsx(Button, {
1026
+ fullWidth: true,
1027
+ className: "mt-4",
1028
+ icon: Delete,
1029
+ label: t("neetoPdf.pdfDocuments.editor.field.remove"),
1030
+ style: "danger",
1031
+ onClick: function onClick() {
1032
+ return onRemove(mapping.id);
1033
+ }
1034
+ })]
1035
+ }) : /*#__PURE__*/jsx("div", {
1036
+ className: "neeto-ui-border-gray-200 neeto-ui-bg-white flex h-full w-72 shrink-0 flex-col border-l",
1037
+ children: /*#__PURE__*/jsx(EmptyState, {})
1038
+ });
1039
+ });
1040
+
1041
+ var FieldCard = function FieldCard(_ref) {
1042
+ var field = _ref.field,
1043
+ onPlace = _ref.onPlace,
1044
+ onDragStart = _ref.onDragStart,
1045
+ onDragEnd = _ref.onDragEnd;
1046
+ var Icon = field.icon;
1047
+ var handleDragStart = function handleDragStart(event) {
1048
+ event.dataTransfer.effectAllowed = "copy";
1049
+ event.dataTransfer.setData("text/plain", field.key);
1050
+ onDragStart(field);
1051
+ };
1052
+ return /*#__PURE__*/jsxs("div", {
1053
+ onDragEnd: onDragEnd,
1054
+ draggable: true,
1055
+ className: "neeto-ui-border-gray-400 neeto-ui-bg-white hover:neeto-ui-bg-gray-200 neeto-ui-rounded-lg relative mb-2 flex h-10 cursor-pointer items-center gap-2 border p-3 transition-all duration-300 ease-in-out",
1056
+ "data-testid": "add-".concat(field.key, "-field"),
1057
+ onClick: function onClick() {
1058
+ return onPlace(field);
1059
+ },
1060
+ onDragStart: handleDragStart,
1061
+ children: [/*#__PURE__*/jsx("span", {
1062
+ className: "absolute end-full top-1/2 me-0.5 flex-shrink-0 -translate-y-1/2 cursor-grab",
1063
+ "data-testid": "drag-handle",
1064
+ children: /*#__PURE__*/jsx(Drag, {
1065
+ className: "neeto-ui-text-gray-400 hover:neeto-ui-text-gray-500 transition-all duration-300 ease-in-out",
1066
+ size: 16
1067
+ })
1068
+ }), /*#__PURE__*/jsxs("div", {
1069
+ className: "flex flex-grow items-center gap-2 overflow-hidden",
1070
+ children: [Icon && /*#__PURE__*/jsx("div", {
1071
+ className: "flex-shrink-0",
1072
+ children: /*#__PURE__*/jsx(Icon, {})
1073
+ }), /*#__PURE__*/jsx(Typography, {
1074
+ className: "truncate leading-4",
1075
+ style: "body2",
1076
+ children: field.label
1077
+ })]
1078
+ })]
1079
+ });
1080
+ };
1081
+
1082
+ var Section = function Section(_ref) {
1083
+ var title = _ref.title,
1084
+ children = _ref.children;
1085
+ if (!(children !== null && children !== void 0 && children.length)) return null;
1086
+ return /*#__PURE__*/jsxs(Fragment, {
1087
+ children: [/*#__PURE__*/jsx(Typography, {
1088
+ className: "mt-1 mb-3",
1089
+ style: "h3",
1090
+ children: title
1091
+ }), children]
1092
+ });
1093
+ };
1094
+ var FieldsPanel = function FieldsPanel(_ref2) {
1095
+ var answerFields = _ref2.answerFields,
1096
+ systemFields = _ref2.systemFields,
1097
+ onPlace = _ref2.onPlace,
1098
+ onDragStartField = _ref2.onDragStartField,
1099
+ onDragEndField = _ref2.onDragEndField;
1100
+ var _useTranslation = useTranslation(),
1101
+ t = _useTranslation.t;
1102
+ var _useState = useState(""),
1103
+ _useState2 = _slicedToArray(_useState, 2),
1104
+ searchTerm = _useState2[0],
1105
+ setSearchTerm = _useState2[1];
1106
+ var query = searchTerm.trim().toLowerCase();
1107
+ var matches = function matches(field) {
1108
+ return field.label.toLowerCase().includes(query);
1109
+ };
1110
+ var filteredAnswers = query ? answerFields.filter(matches) : answerFields;
1111
+ var filteredSystem = query ? systemFields.filter(matches) : systemFields;
1112
+ var renderField = function renderField(field) {
1113
+ return /*#__PURE__*/createElement(FieldCard, {
1114
+ field: field,
1115
+ onPlace: onPlace,
1116
+ key: "".concat(field.source, "-").concat(field.key),
1117
+ onDragEnd: onDragEndField,
1118
+ onDragStart: onDragStartField
1119
+ });
1120
+ };
1121
+ return /*#__PURE__*/jsxs("div", {
1122
+ className: "neeto-ui-border-gray-200 neeto-ui-bg-gray-50 flex h-full w-[360px] shrink-0 flex-col border-r",
1123
+ children: [/*#__PURE__*/jsx("div", {
1124
+ className: "p-6 pb-1",
1125
+ children: /*#__PURE__*/jsx(Typography, {
1126
+ lineHeight: "normal",
1127
+ style: "h3",
1128
+ weight: "semibold",
1129
+ children: t("neetoPdf.pdfDocuments.editor.addNewElement")
1130
+ })
1131
+ }), /*#__PURE__*/jsxs("div", {
1132
+ className: "mb-1 px-6",
1133
+ children: [/*#__PURE__*/jsx(Typography, {
1134
+ className: "mb-3",
1135
+ style: "body3",
1136
+ children: t("neetoPdf.pdfDocuments.editor.addNewElementDescription")
1137
+ }), /*#__PURE__*/jsx(Input, {
1138
+ autoFocus: true,
1139
+ "data-testid": "elements-panel-search-field",
1140
+ placeholder: t("neetoPdf.pdfDocuments.editor.searchElements"),
1141
+ prefix: /*#__PURE__*/jsx(Search, {}),
1142
+ type: "search",
1143
+ value: searchTerm,
1144
+ onChange: function onChange(event) {
1145
+ return setSearchTerm(event.target.value);
1146
+ }
1147
+ })]
1148
+ }), /*#__PURE__*/jsxs("div", {
1149
+ className: "grow overflow-y-auto px-6 pb-2",
1150
+ "data-testid": "elements-container",
1151
+ children: [/*#__PURE__*/jsx(Section, {
1152
+ title: t("neetoPdf.pdfDocuments.editor.answers"),
1153
+ children: filteredAnswers.map(renderField)
1154
+ }), /*#__PURE__*/jsx(Section, {
1155
+ title: t("neetoPdf.pdfDocuments.editor.system"),
1156
+ children: filteredSystem.map(renderField)
1157
+ }), filteredAnswers.length === 0 && filteredSystem.length === 0 ? /*#__PURE__*/jsx(Typography, {
1158
+ className: "neeto-ui-text-gray-800 text-md flex h-full items-center justify-center",
1159
+ weight: "bold",
1160
+ children: t("neetoPdf.pdfDocuments.editor.noFields")
1161
+ }) : null]
1162
+ })]
1163
+ });
1164
+ };
1165
+
1166
+ // pdf-lib StandardFonts only support WinAnsi encoding and single-line text, so
1167
+ // collapse whitespace and drop characters they cannot encode.
1168
+ var sanitizeForPdf = function sanitizeForPdf(text) {
1169
+ return text.replace(/\s+/g, " ").trim().replace(/[^\x20-\x7E\xA0-\xFF]/g, "").trim();
1170
+ };
1171
+ var hexToRgbComponents = function hexToRgbComponents(hex) {
1172
+ var value = (hex || DEFAULT_STYLE.color).replace("#", "");
1173
+ var full = value.length === 3 ? value.split("").map(function (_char) {
1174
+ return _char + _char;
1175
+ }).join("") : value;
1176
+ var _int = parseInt(full, 16);
1177
+ return {
1178
+ r: (_int >> 16 & 255) / 255,
1179
+ g: (_int >> 8 & 255) / 255,
1180
+ b: (_int & 255) / 255
1181
+ };
1182
+ };
1183
+ var standardFontName = function standardFontName(font, bold, italic) {
1184
+ var variants = STANDARD_FONT_VARIANTS[font] || STANDARD_FONT_VARIANTS.Helvetica;
1185
+ return variants[(bold ? 1 : 0) + (italic ? 2 : 0)];
1186
+ };
1187
+ var triggerBlobDownload = function triggerBlobDownload(bytes, fileName) {
1188
+ var blob = new Blob([bytes], {
1189
+ type: "application/pdf"
1190
+ });
1191
+ var url = URL.createObjectURL(blob);
1192
+ var link = window.document.createElement("a");
1193
+ link.href = url;
1194
+ link.download = fileName;
1195
+ window.document.body.appendChild(link);
1196
+ link.click();
1197
+ link.remove();
1198
+ URL.revokeObjectURL(url);
1199
+ };
1200
+
1201
+ // Stamp the resolved values for one submission onto the template PDF (client
1202
+ // side, via pdf-lib) and trigger a browser download. pdf-lib is imported lazily
1203
+ // so it only loads on the first download.
1204
+ var downloadFilledPdf = /*#__PURE__*/function () {
1205
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(_ref) {
1206
+ var templateUrl, mappings, valueFor, fileName, pdfLibModule, PDFDocument, StandardFonts, rgb, response, bytes, pdfDoc, pages, fontNames, embeddedFonts;
1207
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
1208
+ while (1) switch (_context2.prev = _context2.next) {
1209
+ case 0:
1210
+ templateUrl = _ref.templateUrl, mappings = _ref.mappings, valueFor = _ref.valueFor, fileName = _ref.fileName;
1211
+ _context2.next = 3;
1212
+ return import('pdf-lib');
1213
+ case 3:
1214
+ pdfLibModule = _context2.sent;
1215
+ PDFDocument = pdfLibModule.PDFDocument, StandardFonts = pdfLibModule.StandardFonts, rgb = pdfLibModule.rgb;
1216
+ _context2.next = 7;
1217
+ return fetch(templateUrl);
1218
+ case 7:
1219
+ response = _context2.sent;
1220
+ if (response.ok) {
1221
+ _context2.next = 10;
1222
+ break;
1223
+ }
1224
+ throw new Error("Failed to fetch template PDF (".concat(response.status, ")"));
1225
+ case 10:
1226
+ _context2.next = 12;
1227
+ return response.arrayBuffer();
1228
+ case 12:
1229
+ bytes = _context2.sent;
1230
+ _context2.next = 15;
1231
+ return PDFDocument.load(bytes, {
1232
+ ignoreEncryption: true
1233
+ });
1234
+ case 15:
1235
+ pdfDoc = _context2.sent;
1236
+ pages = pdfDoc.getPages();
1237
+ fontNames = _toConsumableArray(new Set(mappings.map(function (mapping) {
1238
+ return standardFontName(mapping.font, mapping.bold, mapping.italic);
1239
+ })));
1240
+ _context2.t0 = Object;
1241
+ _context2.next = 21;
1242
+ return Promise.all(fontNames.map(/*#__PURE__*/function () {
1243
+ var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(name) {
1244
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
1245
+ while (1) switch (_context.prev = _context.next) {
1246
+ case 0:
1247
+ _context.t0 = name;
1248
+ _context.next = 3;
1249
+ return pdfDoc.embedFont(StandardFonts[name]);
1250
+ case 3:
1251
+ _context.t1 = _context.sent;
1252
+ return _context.abrupt("return", [_context.t0, _context.t1]);
1253
+ case 5:
1254
+ case "end":
1255
+ return _context.stop();
1256
+ }
1257
+ }, _callee);
1258
+ }));
1259
+ return function (_x2) {
1260
+ return _ref3.apply(this, arguments);
1261
+ };
1262
+ }()));
1263
+ case 21:
1264
+ _context2.t1 = _context2.sent;
1265
+ embeddedFonts = _context2.t0.fromEntries.call(_context2.t0, _context2.t1);
1266
+ mappings.forEach(function (mapping) {
1267
+ var page = pages[mapping.page - 1];
1268
+ if (!page) return;
1269
+ var text = sanitizeForPdf(valueFor(mapping) || "");
1270
+ if (!text) return;
1271
+ var _page$getSize = page.getSize(),
1272
+ pageWidth = _page$getSize.width,
1273
+ pageHeight = _page$getSize.height;
1274
+ var font = embeddedFonts[standardFontName(mapping.font, mapping.bold, mapping.italic)];
1275
+ var size = mapping.fontSize;
1276
+ var _hexToRgbComponents = hexToRgbComponents(mapping.color),
1277
+ r = _hexToRgbComponents.r,
1278
+ g = _hexToRgbComponents.g,
1279
+ b = _hexToRgbComponents.b;
1280
+ var color = rgb(r, g, b);
1281
+ var boxLeft = mapping.x * pageWidth;
1282
+ var boxWidth = mapping.width * pageWidth;
1283
+ var textWidth = font.widthOfTextAtSize(text, size);
1284
+ var x = boxLeft;
1285
+ if (mapping.align === "center") x = boxLeft + (boxWidth - textWidth) / 2;else if (mapping.align === "right") x = boxLeft + boxWidth - textWidth;
1286
+ var y = pageHeight - mapping.y * pageHeight - size;
1287
+ page.drawText(text, {
1288
+ x: x,
1289
+ y: y,
1290
+ size: size,
1291
+ font: font,
1292
+ color: color
1293
+ });
1294
+ if (mapping.underline) {
1295
+ var lineY = y - size * 0.1;
1296
+ page.drawLine({
1297
+ start: {
1298
+ x: x,
1299
+ y: lineY
1300
+ },
1301
+ end: {
1302
+ x: x + textWidth,
1303
+ y: lineY
1304
+ },
1305
+ thickness: Math.max(0.5, size * 0.06),
1306
+ color: color
1307
+ });
1308
+ }
1309
+ });
1310
+ _context2.t2 = triggerBlobDownload;
1311
+ _context2.next = 27;
1312
+ return pdfDoc.save();
1313
+ case 27:
1314
+ _context2.t3 = _context2.sent;
1315
+ _context2.t4 = fileName;
1316
+ (0, _context2.t2)(_context2.t3, _context2.t4);
1317
+ case 30:
1318
+ case "end":
1319
+ return _context2.stop();
1320
+ }
1321
+ }, _callee2);
1322
+ }));
1323
+ return function downloadFilledPdf(_x) {
1324
+ return _ref2.apply(this, arguments);
1325
+ };
1326
+ }();
1327
+
1328
+ var usePdfDownload = function usePdfDownload(_ref) {
1329
+ var mappings = _ref.mappings,
1330
+ pdfDocument = _ref.pdfDocument,
1331
+ previewRecord = _ref.previewRecord,
1332
+ resolveValue = _ref.resolveValue,
1333
+ t = _ref.t;
1334
+ var _useState = useState(false),
1335
+ _useState2 = _slicedToArray(_useState, 2),
1336
+ isDownloading = _useState2[0],
1337
+ setIsDownloading = _useState2[1];
1338
+ var downloadPdf = /*#__PURE__*/function () {
1339
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
1340
+ var _pdfDocument$template;
1341
+ var templateUrl;
1342
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
1343
+ while (1) switch (_context.prev = _context.next) {
1344
+ case 0:
1345
+ templateUrl = pdfDocument === null || pdfDocument === void 0 || (_pdfDocument$template = pdfDocument.templateFile) === null || _pdfDocument$template === void 0 ? void 0 : _pdfDocument$template.url;
1346
+ if (!(!templateUrl || !previewRecord)) {
1347
+ _context.next = 3;
1348
+ break;
1349
+ }
1350
+ return _context.abrupt("return");
1351
+ case 3:
1352
+ setIsDownloading(true);
1353
+ _context.prev = 4;
1354
+ _context.next = 7;
1355
+ return downloadFilledPdf({
1356
+ templateUrl: templateUrl,
1357
+ mappings: mappings,
1358
+ valueFor: resolveValue,
1359
+ fileName: buildOutputFilename(pdfDocument, previewRecord)
1360
+ });
1361
+ case 7:
1362
+ _context.next = 13;
1363
+ break;
1364
+ case 9:
1365
+ _context.prev = 9;
1366
+ _context.t0 = _context["catch"](4);
1367
+ logger.error(_context.t0);
1368
+ Toastr.error(t("neetoPdf.pdfDocuments.editor.downloadError"));
1369
+ case 13:
1370
+ _context.prev = 13;
1371
+ setIsDownloading(false);
1372
+ return _context.finish(13);
1373
+ case 16:
1374
+ case "end":
1375
+ return _context.stop();
1376
+ }
1377
+ }, _callee, null, [[4, 9, 13, 16]]);
1378
+ }));
1379
+ return function downloadPdf() {
1380
+ return _ref2.apply(this, arguments);
1381
+ };
1382
+ }();
1383
+ return {
1384
+ downloadPdf: downloadPdf,
1385
+ isDownloading: isDownloading
1386
+ };
1387
+ };
1388
+
1389
+ var usePdfEditorDocument = function usePdfEditorDocument(_ref) {
1390
+ var _pdfDocument$template;
1391
+ var apiBaseUrl = _ref.apiBaseUrl,
1392
+ documentId = _ref.documentId,
1393
+ ownerId = _ref.ownerId,
1394
+ t = _ref.t;
1395
+ var _useFetchPdfDocument = useFetchPdfDocument({
1396
+ apiBaseUrl: apiBaseUrl,
1397
+ ownerId: ownerId,
1398
+ documentId: documentId
1399
+ }),
1400
+ documentResponse = _useFetchPdfDocument.data,
1401
+ isDocumentLoading = _useFetchPdfDocument.isLoading;
1402
+ var pdfDocument = documentResponse === null || documentResponse === void 0 ? void 0 : documentResponse.document;
1403
+ var _useUpdatePdfDocument = useUpdatePdfDocument({
1404
+ apiBaseUrl: apiBaseUrl,
1405
+ ownerId: ownerId,
1406
+ options: {
1407
+ onSuccess: function onSuccess() {
1408
+ return Toastr.success(t("neetoPdf.pdfDocuments.editor.saveSuccess"));
1409
+ },
1410
+ onError: function onError(error) {
1411
+ return Toastr.error(getPdfDocumentApiErrorMessage(error, t("neetoPdf.pdfDocuments.editor.saveError")));
1412
+ }
1413
+ }
1414
+ }),
1415
+ saveMappings = _useUpdatePdfDocument.mutate,
1416
+ isSaving = _useUpdatePdfDocument.isPending;
1417
+ var _useUpdatePdfDocument2 = useUpdatePdfDocument({
1418
+ apiBaseUrl: apiBaseUrl,
1419
+ ownerId: ownerId,
1420
+ options: {
1421
+ onSuccess: function onSuccess() {
1422
+ return Toastr.success(t("neetoPdf.pdfDocuments.rename.success"));
1423
+ },
1424
+ onError: function onError(error) {
1425
+ return Toastr.error(getPdfDocumentApiErrorMessage(error, t("neetoPdf.pdfDocuments.rename.error")));
1426
+ }
1427
+ }
1428
+ }),
1429
+ renameDocument = _useUpdatePdfDocument2.mutate;
1430
+ var saveDocumentMappings = function saveDocumentMappings(_ref2) {
1431
+ var mappings = _ref2.mappings,
1432
+ onSuccess = _ref2.onSuccess;
1433
+ saveMappings({
1434
+ documentId: documentId,
1435
+ payload: {
1436
+ mappings: mappings
1437
+ }
1438
+ }, {
1439
+ onSuccess: onSuccess
1440
+ });
1441
+ };
1442
+ var renamePdfDocument = function renamePdfDocument(name) {
1443
+ var trimmedName = name.trim();
1444
+ renameDocument({
1445
+ documentId: documentId,
1446
+ payload: {
1447
+ name: trimmedName,
1448
+ outputFilename: buildOutputFilenameTemplate(trimmedName)
1449
+ }
1450
+ });
1451
+ };
1452
+ return {
1453
+ documentName: (pdfDocument === null || pdfDocument === void 0 ? void 0 : pdfDocument.name) || "",
1454
+ isDocumentLoading: isDocumentLoading,
1455
+ isSaving: isSaving,
1456
+ pdfDocument: pdfDocument,
1457
+ renamePdfDocument: renamePdfDocument,
1458
+ saveDocumentMappings: saveDocumentMappings,
1459
+ templateUrl: pdfDocument === null || pdfDocument === void 0 || (_pdfDocument$template = pdfDocument.templateFile) === null || _pdfDocument$template === void 0 ? void 0 : _pdfDocument$template.url
1460
+ };
1461
+ };
1462
+
1463
+ function ownKeys$1(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1464
+ function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$1(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$1(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1465
+ var htmlToPlainText = function htmlToPlainText(value) {
1466
+ var element = window.document.createElement("div");
1467
+ element.innerHTML = value || "";
1468
+ return element.textContent || element.innerText || "";
1469
+ };
1470
+ var generateId = function generateId() {
1471
+ var _window$crypto, _window$crypto$random;
1472
+ return ((_window$crypto = window.crypto) === null || _window$crypto === void 0 || (_window$crypto$random = _window$crypto.randomUUID) === null || _window$crypto$random === void 0 ? void 0 : _window$crypto$random.call(_window$crypto)) || "".concat(Date.now(), "-").concat(Math.random());
1473
+ };
1474
+
1475
+ // Turn the form's records into the "Answers" list shown in the left panel.
1476
+ var buildAnswerFields = function buildAnswerFields() {
1477
+ var fields = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1478
+ return fields.filter(function (field) {
1479
+ return field;
1480
+ }).map(function (field) {
1481
+ return {
1482
+ source: FIELD_SOURCES.ANSWER,
1483
+ key: field.key || field.slug,
1484
+ recordId: field.recordId || field.id || null,
1485
+ slug: field.slug || field.key,
1486
+ label: htmlToPlainText(field.label || ""),
1487
+ kind: field.kind,
1488
+ icon: field.icon,
1489
+ typeLabel: field.typeLabel || field.kind || ""
1490
+ };
1491
+ });
1492
+ };
1493
+ var buildMapping = function buildMapping(_ref) {
1494
+ var _field$recordId;
1495
+ var field = _ref.field,
1496
+ page = _ref.page,
1497
+ scale = _ref.scale;
1498
+ return _objectSpread$1(_objectSpread$1(_objectSpread$1({
1499
+ id: generateId(),
1500
+ source: field.source,
1501
+ fieldSlug: field.key,
1502
+ recordId: (_field$recordId = field.recordId) !== null && _field$recordId !== void 0 ? _field$recordId : null,
1503
+ label: field.label,
1504
+ kind: field.kind,
1505
+ page: page
1506
+ }, DEFAULT_BOX), DEFAULT_STYLE), {}, {
1507
+ fontSize: getDefaultFontSizeForScale(scale)
1508
+ });
1509
+ };
1510
+
1511
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1512
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1513
+ var usePdfMappingsState = function usePdfMappingsState(_ref) {
1514
+ var documentId = _ref.documentId,
1515
+ pdfDocument = _ref.pdfDocument;
1516
+ var _useState = useState([]),
1517
+ _useState2 = _slicedToArray(_useState, 2),
1518
+ mappings = _useState2[0],
1519
+ setMappings = _useState2[1];
1520
+ var _useState3 = useState(null),
1521
+ _useState4 = _slicedToArray(_useState3, 2),
1522
+ selectedId = _useState4[0],
1523
+ setSelectedId = _useState4[1];
1524
+ var _useState5 = useState(function () {
1525
+ return new Map();
1526
+ }),
1527
+ _useState6 = _slicedToArray(_useState5, 2),
1528
+ pageScales = _useState6[0],
1529
+ setPageScales = _useState6[1];
1530
+ var _useState7 = useState(false),
1531
+ _useState8 = _slicedToArray(_useState7, 2),
1532
+ isDirty = _useState8[0],
1533
+ setIsDirty = _useState8[1];
1534
+ var draggedFieldRef = useRef(null);
1535
+ var initializedRef = useRef(null);
1536
+ useEffect(function () {
1537
+ if (!(pdfDocument && initializedRef.current !== documentId)) return;
1538
+ initializedRef.current = documentId;
1539
+ setMappings(pdfDocument.mappings || []);
1540
+ setIsDirty(false);
1541
+ }, [pdfDocument, documentId]);
1542
+ var selectedMapping = findById(selectedId, mappings) || null;
1543
+ var mutateMappings = function mutateMappings(updater) {
1544
+ setMappings(updater);
1545
+ setIsDirty(true);
1546
+ };
1547
+ var handleAddField = function handleAddField(field) {
1548
+ var mapping = buildMapping({
1549
+ field: field,
1550
+ page: 1,
1551
+ scale: pageScales.get(1)
1552
+ });
1553
+ mutateMappings(append(mapping));
1554
+ setSelectedId(mapping.id);
1555
+ };
1556
+ var handleDropField = function handleDropField(_ref2) {
1557
+ var pageNumber = _ref2.pageNumber,
1558
+ scale = _ref2.scale,
1559
+ x = _ref2.x,
1560
+ y = _ref2.y;
1561
+ var field = draggedFieldRef.current;
1562
+ if (!field) return;
1563
+ var mapping = _objectSpread(_objectSpread({}, buildMapping({
1564
+ field: field,
1565
+ page: pageNumber,
1566
+ scale: scale
1567
+ })), {}, {
1568
+ x: clamp(x, 0, 1 - DEFAULT_BOX.width),
1569
+ y: clamp(y, 0, 1 - DEFAULT_BOX.height)
1570
+ });
1571
+ mutateMappings(append(mapping));
1572
+ setSelectedId(mapping.id);
1573
+ };
1574
+ var handleChangeMapping = function handleChangeMapping(id, patch) {
1575
+ return mutateMappings(function (prev) {
1576
+ return prev.map(function (mapping) {
1577
+ return mapping.id === id ? _objectSpread(_objectSpread({}, mapping), patch) : mapping;
1578
+ });
1579
+ });
1580
+ };
1581
+ var handlePageScaleChange = function handlePageScaleChange(pageNumber, scale) {
1582
+ setPageScales(function (prev) {
1583
+ if (prev.get(pageNumber) === scale) return prev;
1584
+ var nextPageScales = new Map(prev);
1585
+ nextPageScales.set(pageNumber, scale);
1586
+ return nextPageScales;
1587
+ });
1588
+ };
1589
+ var handleRemoveMapping = function handleRemoveMapping(id) {
1590
+ mutateMappings(function (prev) {
1591
+ return removeById(id, prev);
1592
+ });
1593
+ setSelectedId(function (current) {
1594
+ return current === id ? null : current;
1595
+ });
1596
+ };
1597
+ var handleDragEndField = function handleDragEndField() {
1598
+ draggedFieldRef.current = null;
1599
+ };
1600
+ var handleDragStartField = function handleDragStartField(field) {
1601
+ draggedFieldRef.current = field;
1602
+ };
1603
+ return {
1604
+ handleAddField: handleAddField,
1605
+ handleChangeMapping: handleChangeMapping,
1606
+ handleDragEndField: handleDragEndField,
1607
+ handleDragStartField: handleDragStartField,
1608
+ handleDropField: handleDropField,
1609
+ handlePageScaleChange: handlePageScaleChange,
1610
+ handleRemoveMapping: handleRemoveMapping,
1611
+ isDirty: isDirty,
1612
+ mappings: mappings,
1613
+ selectedId: selectedId,
1614
+ selectedMapping: selectedMapping,
1615
+ setIsDirty: setIsDirty,
1616
+ setSelectedId: setSelectedId
1617
+ };
1618
+ };
1619
+
1620
+ var usePreviewPagination = function usePreviewPagination(_ref) {
1621
+ var controlledMode = _ref.controlledMode,
1622
+ onModeChange = _ref.onModeChange,
1623
+ onPreviewPageChange = _ref.onPreviewPageChange,
1624
+ previewPage = _ref.previewPage,
1625
+ setSelectedId = _ref.setSelectedId;
1626
+ var _useState = useState(previewPage),
1627
+ _useState2 = _slicedToArray(_useState, 2),
1628
+ localPreviewPage = _useState2[0],
1629
+ setLocalPreviewPage = _useState2[1];
1630
+ var _useState3 = useState(EDITOR_MODES.MAP),
1631
+ _useState4 = _slicedToArray(_useState3, 2),
1632
+ localMode = _useState4[0],
1633
+ setLocalMode = _useState4[1];
1634
+ var mode = controlledMode || localMode;
1635
+ var isPreview = mode === EDITOR_MODES.PREVIEW;
1636
+ var currentPreviewPage = onPreviewPageChange ? previewPage : localPreviewPage;
1637
+ useEffect(function () {
1638
+ if (!isPreview) return;
1639
+ setSelectedId(null);
1640
+ setLocalPreviewPage(1);
1641
+ onPreviewPageChange === null || onPreviewPageChange === void 0 || onPreviewPageChange(1);
1642
+ }, [isPreview, onPreviewPageChange, setSelectedId]);
1643
+ var setPreviewPage = function setPreviewPage(page) {
1644
+ setLocalPreviewPage(page);
1645
+ onPreviewPageChange === null || onPreviewPageChange === void 0 || onPreviewPageChange(page);
1646
+ };
1647
+ var handleModeChange = function handleModeChange(nextMode) {
1648
+ setLocalMode(nextMode);
1649
+ onModeChange === null || onModeChange === void 0 || onModeChange(nextMode);
1650
+ };
1651
+ return {
1652
+ currentPreviewPage: currentPreviewPage,
1653
+ handleModeChange: handleModeChange,
1654
+ isPreview: isPreview,
1655
+ mode: mode,
1656
+ setPreviewPage: setPreviewPage
1657
+ };
1658
+ };
1659
+
1660
+ var PreviewPager = function PreviewPager(_ref) {
1661
+ var page = _ref.page,
1662
+ total = _ref.total,
1663
+ isLoading = _ref.isLoading,
1664
+ onPrev = _ref.onPrev,
1665
+ onNext = _ref.onNext;
1666
+ var _useTranslation = useTranslation(),
1667
+ t = _useTranslation.t;
1668
+ if (!isLoading && total === 0) {
1669
+ return /*#__PURE__*/jsx("div", {
1670
+ className: "neeto-ui-border-gray-200 neeto-ui-bg-white neeto-ui-shadow-md neeto-ui-rounded-lg border px-3 py-1.5",
1671
+ children: /*#__PURE__*/jsx(Typography, {
1672
+ className: "neeto-ui-text-gray-500",
1673
+ style: "body3",
1674
+ children: t("neetoPdf.pdfDocuments.editor.preview.noSubmissions")
1675
+ })
1676
+ });
1677
+ }
1678
+ return /*#__PURE__*/jsxs("div", {
1679
+ className: "neeto-ui-border-gray-200 neeto-ui-bg-white neeto-ui-shadow-md neeto-ui-rounded-lg flex items-center gap-1 border px-1",
1680
+ children: [/*#__PURE__*/jsx(Button, {
1681
+ disabled: page <= 1 || isLoading,
1682
+ icon: Left,
1683
+ size: "small",
1684
+ style: "text",
1685
+ onClick: onPrev
1686
+ }), /*#__PURE__*/jsx(Typography, {
1687
+ className: "px-1 whitespace-nowrap",
1688
+ style: "body3",
1689
+ children: t("neetoPdf.pdfDocuments.editor.preview.counter", {
1690
+ page: page,
1691
+ total: total
1692
+ })
1693
+ }), /*#__PURE__*/jsx(Button, {
1694
+ disabled: page >= total || isLoading,
1695
+ icon: Right,
1696
+ size: "small",
1697
+ style: "text",
1698
+ onClick: onNext
1699
+ })]
1700
+ });
1701
+ };
1702
+
1703
+ var _coerceToText = function coerceToText(value) {
1704
+ if (value === null || value === undefined) return "";
1705
+ if (Array.isArray(value)) {
1706
+ return value.map(_coerceToText).filter(Boolean).join(", ");
1707
+ }
1708
+ if (_typeof(value) === "object") {
1709
+ if ("value" in value) return _coerceToText(value.value);
1710
+ if ("label" in value) return _coerceToText(value.label);
1711
+ return "";
1712
+ }
1713
+ return String(value);
1714
+ };
1715
+
1716
+ // Resolve the text shown for a placement in "Preview with data" mode. Returns
1717
+ // "" (rendered blank) when the current submission has no answer for the field.
1718
+ var resolvePreviewValue = function resolvePreviewValue(_ref) {
1719
+ var mapping = _ref.mapping,
1720
+ _ref$responsesBySlug = _ref.responsesBySlug,
1721
+ responsesBySlug = _ref$responsesBySlug === void 0 ? {} : _ref$responsesBySlug,
1722
+ form = _ref.form,
1723
+ submission = _ref.submission;
1724
+ if (mapping.source === FIELD_SOURCES.SYSTEM) {
1725
+ switch (mapping.fieldSlug) {
1726
+ case SYSTEM_FIELD_KEYS.FORM_NAME:
1727
+ return (form === null || form === void 0 ? void 0 : form.title) || (form === null || form === void 0 ? void 0 : form.name) || "";
1728
+ case SYSTEM_FIELD_KEYS.SUBMISSION_ID:
1729
+ return (submission === null || submission === void 0 ? void 0 : submission.id) || "";
1730
+ case SYSTEM_FIELD_KEYS.SUBMISSION_DATE:
1731
+ return submission !== null && submission !== void 0 && submission.createdAt ? dateFormat.dateTime(submission.createdAt) : "";
1732
+ default:
1733
+ return "";
1734
+ }
1735
+ }
1736
+ return _coerceToText(responsesBySlug[mapping.fieldSlug]);
1737
+ };
1738
+
1739
+ // Build a slug -> value lookup from a single submission's responses array.
1740
+ var buildResponsesBySlug = function buildResponsesBySlug() {
1741
+ var responses = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1742
+ return responses.reduce(function (acc, response) {
1743
+ if ((response === null || response === void 0 ? void 0 : response.slug) !== undefined) acc[response.slug] = response.value;
1744
+ return acc;
1745
+ }, {});
1746
+ };
1747
+
1748
+ var TopBar = function TopBar(_ref) {
1749
+ var name = _ref.name,
1750
+ onRename = _ref.onRename,
1751
+ canManage = _ref.canManage,
1752
+ homeUrl = _ref.homeUrl,
1753
+ isPreview = _ref.isPreview,
1754
+ zoom = _ref.zoom,
1755
+ onZoomIn = _ref.onZoomIn,
1756
+ onZoomOut = _ref.onZoomOut,
1757
+ onDownload = _ref.onDownload,
1758
+ isDownloading = _ref.isDownloading,
1759
+ canDownload = _ref.canDownload,
1760
+ onSave = _ref.onSave,
1761
+ isSaving = _ref.isSaving,
1762
+ isDirty = _ref.isDirty,
1763
+ onBack = _ref.onBack,
1764
+ onModeChange = _ref.onModeChange;
1765
+ var _useTranslation = useTranslation(),
1766
+ t = _useTranslation.t;
1767
+ var headerLinks = [{
1768
+ key: EDITOR_MODES.MAP,
1769
+ label: t("neetoPdf.pdfDocuments.editor.mapFields"),
1770
+ to: "#map",
1771
+ isActive: function isActive() {
1772
+ return !isPreview;
1773
+ },
1774
+ onClick: function onClick(event) {
1775
+ event.preventDefault();
1776
+ onModeChange(EDITOR_MODES.MAP);
1777
+ }
1778
+ }, {
1779
+ key: EDITOR_MODES.PREVIEW,
1780
+ label: t("neetoPdf.pdfDocuments.editor.previewWithData"),
1781
+ to: "#preview",
1782
+ isActive: function isActive() {
1783
+ return isPreview;
1784
+ },
1785
+ onClick: function onClick(event) {
1786
+ event.preventDefault();
1787
+ onModeChange(EDITOR_MODES.PREVIEW);
1788
+ }
1789
+ }];
1790
+ var rightActionBlock = /*#__PURE__*/jsxs("div", {
1791
+ className: "flex w-full items-center justify-end gap-3",
1792
+ children: [/*#__PURE__*/jsxs("div", {
1793
+ className: "flex items-center gap-1",
1794
+ children: [/*#__PURE__*/jsx(Button, {
1795
+ disabled: zoom <= ZOOM.MIN,
1796
+ icon: Minus,
1797
+ size: "small",
1798
+ style: "text",
1799
+ onClick: onZoomOut
1800
+ }), /*#__PURE__*/jsxs(Typography, {
1801
+ className: "w-10 text-center",
1802
+ style: "body3",
1803
+ children: [Math.round(zoom * 100), "%"]
1804
+ }), /*#__PURE__*/jsx(Button, {
1805
+ disabled: zoom >= ZOOM.MAX,
1806
+ icon: Plus,
1807
+ size: "small",
1808
+ style: "text",
1809
+ onClick: onZoomIn
1810
+ })]
1811
+ }), /*#__PURE__*/jsx(Button, {
1812
+ disabled: !canDownload,
1813
+ icon: Download,
1814
+ label: t("neetoPdf.pdfDocuments.editor.downloadPdf"),
1815
+ loading: isDownloading,
1816
+ style: "secondary",
1817
+ tooltipProps: {
1818
+ content: canDownload ? t("neetoPdf.pdfDocuments.editor.downloadTooltip") : t("neetoPdf.pdfDocuments.editor.downloadHint")
1819
+ },
1820
+ onClick: onDownload
1821
+ }), /*#__PURE__*/jsx(Button, {
1822
+ disabled: !isDirty,
1823
+ label: t("neetoPdf.common.save"),
1824
+ loading: isSaving,
1825
+ onClick: onSave
1826
+ })]
1827
+ });
1828
+ return /*#__PURE__*/jsx(NavigationHeader, {
1829
+ rightActionBlock: rightActionBlock,
1830
+ leftActionBlock: /*#__PURE__*/jsx(NavigationHeader.LeftActionBlock, {
1831
+ homeUrl: homeUrl || "#",
1832
+ homeButtonProps: {
1833
+ icon: /*#__PURE__*/jsx(LeftArrow, {}),
1834
+ tooltip: {
1835
+ content: t("neetoPdf.pdfDocuments.editor.back"),
1836
+ position: "bottom"
1837
+ },
1838
+ onClick: onBack
1839
+ },
1840
+ renameProps: {
1841
+ value: name,
1842
+ disabled: !canManage,
1843
+ placeholder: t("neetoPdf.pdfDocuments.rename.placeholder"),
1844
+ onRename: onRename
1845
+ }
1846
+ }),
1847
+ navigationLinks: /*#__PURE__*/jsx(NavigationHeader.NavigationLinks, {
1848
+ headerLinks: headerLinks,
1849
+ maxVisibleLinks: 2
1850
+ })
1851
+ });
1852
+ };
1853
+
1854
+ var FullScreenSpinner = function FullScreenSpinner() {
1855
+ return /*#__PURE__*/jsx("div", {
1856
+ className: "neeto-ui-bg-white fixed inset-0 z-50 flex items-center justify-center",
1857
+ children: /*#__PURE__*/jsx(Spinner, {})
1858
+ });
1859
+ };
1860
+ var PdfEditorPage = function PdfEditorPage(_ref) {
1861
+ var apiBaseUrl = _ref.apiBaseUrl,
1862
+ ownerId = _ref.ownerId,
1863
+ documentId = _ref.documentId,
1864
+ _ref$canManage = _ref.canManage,
1865
+ canManage = _ref$canManage === void 0 ? true : _ref$canManage,
1866
+ _ref$fields = _ref.fields,
1867
+ fields = _ref$fields === void 0 ? [] : _ref$fields,
1868
+ _ref$ownerRecord = _ref.ownerRecord,
1869
+ ownerRecord = _ref$ownerRecord === void 0 ? {} : _ref$ownerRecord,
1870
+ previewRecord = _ref.previewRecord,
1871
+ _ref$previewTotal = _ref.previewTotal,
1872
+ previewTotal = _ref$previewTotal === void 0 ? 0 : _ref$previewTotal,
1873
+ _ref$previewPage = _ref.previewPage,
1874
+ previewPage = _ref$previewPage === void 0 ? 1 : _ref$previewPage,
1875
+ _ref$isPreviewLoading = _ref.isPreviewLoading,
1876
+ isPreviewLoading = _ref$isPreviewLoading === void 0 ? false : _ref$isPreviewLoading,
1877
+ controlledMode = _ref.mode,
1878
+ homeUrl = _ref.homeUrl,
1879
+ onBack = _ref.onBack,
1880
+ onModeChange = _ref.onModeChange,
1881
+ onPreviewPageChange = _ref.onPreviewPageChange;
1882
+ var _useTranslation = useTranslation(),
1883
+ t = _useTranslation.t;
1884
+ var _useState = useState(ZOOM.DEFAULT),
1885
+ _useState2 = _slicedToArray(_useState, 2),
1886
+ zoom = _useState2[0],
1887
+ setZoom = _useState2[1];
1888
+ var _usePdfEditorDocument = usePdfEditorDocument({
1889
+ apiBaseUrl: apiBaseUrl,
1890
+ documentId: documentId,
1891
+ ownerId: ownerId,
1892
+ t: t
1893
+ }),
1894
+ documentName = _usePdfEditorDocument.documentName,
1895
+ isDocumentLoading = _usePdfEditorDocument.isDocumentLoading,
1896
+ isSaving = _usePdfEditorDocument.isSaving,
1897
+ pdfDocument = _usePdfEditorDocument.pdfDocument,
1898
+ renamePdfDocument = _usePdfEditorDocument.renamePdfDocument,
1899
+ saveDocumentMappings = _usePdfEditorDocument.saveDocumentMappings,
1900
+ templateUrl = _usePdfEditorDocument.templateUrl;
1901
+ var _usePdfMappingsState = usePdfMappingsState({
1902
+ documentId: documentId,
1903
+ pdfDocument: pdfDocument
1904
+ }),
1905
+ handleAddField = _usePdfMappingsState.handleAddField,
1906
+ handleChangeMapping = _usePdfMappingsState.handleChangeMapping,
1907
+ handleDragEndField = _usePdfMappingsState.handleDragEndField,
1908
+ handleDragStartField = _usePdfMappingsState.handleDragStartField,
1909
+ handleDropField = _usePdfMappingsState.handleDropField,
1910
+ handlePageScaleChange = _usePdfMappingsState.handlePageScaleChange,
1911
+ handleRemoveMapping = _usePdfMappingsState.handleRemoveMapping,
1912
+ isDirty = _usePdfMappingsState.isDirty,
1913
+ mappings = _usePdfMappingsState.mappings,
1914
+ selectedId = _usePdfMappingsState.selectedId,
1915
+ selectedMapping = _usePdfMappingsState.selectedMapping,
1916
+ setIsDirty = _usePdfMappingsState.setIsDirty,
1917
+ setSelectedId = _usePdfMappingsState.setSelectedId;
1918
+ var _usePreviewPagination = usePreviewPagination({
1919
+ controlledMode: controlledMode,
1920
+ onModeChange: onModeChange,
1921
+ onPreviewPageChange: onPreviewPageChange,
1922
+ previewPage: previewPage,
1923
+ setSelectedId: setSelectedId
1924
+ }),
1925
+ currentPreviewPage = _usePreviewPagination.currentPreviewPage,
1926
+ handleModeChange = _usePreviewPagination.handleModeChange,
1927
+ isPreview = _usePreviewPagination.isPreview,
1928
+ mode = _usePreviewPagination.mode,
1929
+ setPreviewPage = _usePreviewPagination.setPreviewPage;
1930
+ var answerFields = useMemo(function () {
1931
+ return buildAnswerFields(fields);
1932
+ }, [fields]);
1933
+ var systemFields = useMemo(function () {
1934
+ return SYSTEM_FIELDS.map(function (_ref2) {
1935
+ var key = _ref2.key,
1936
+ labelKey = _ref2.labelKey,
1937
+ icon = _ref2.icon;
1938
+ return {
1939
+ source: FIELD_SOURCES.SYSTEM,
1940
+ key: key,
1941
+ label: t(labelKey),
1942
+ typeLabel: t("neetoPdf.pdfDocuments.editor.system"),
1943
+ kind: key,
1944
+ icon: icon
1945
+ };
1946
+ });
1947
+ }, [t]);
1948
+ var responsesBySlug = useMemo(function () {
1949
+ return buildResponsesBySlug(previewRecord === null || previewRecord === void 0 ? void 0 : previewRecord.responses);
1950
+ }, [previewRecord]);
1951
+ var resolveValue = function resolveValue(mapping) {
1952
+ return resolvePreviewValue({
1953
+ mapping: mapping,
1954
+ responsesBySlug: responsesBySlug,
1955
+ form: ownerRecord,
1956
+ submission: previewRecord
1957
+ });
1958
+ };
1959
+ var _usePdfDownload = usePdfDownload({
1960
+ mappings: mappings,
1961
+ pdfDocument: pdfDocument,
1962
+ previewRecord: previewRecord,
1963
+ resolveValue: resolveValue,
1964
+ t: t
1965
+ }),
1966
+ downloadPdf = _usePdfDownload.downloadPdf,
1967
+ isDownloading = _usePdfDownload.isDownloading;
1968
+ var handleSave = function handleSave() {
1969
+ return saveDocumentMappings({
1970
+ mappings: mappings,
1971
+ onSuccess: function onSuccess() {
1972
+ return setIsDirty(false);
1973
+ }
1974
+ });
1975
+ };
1976
+ if (isDocumentLoading) return /*#__PURE__*/jsx(FullScreenSpinner, {});
1977
+ return /*#__PURE__*/createPortal(/*#__PURE__*/jsxs("div", {
1978
+ className: "neeto-ui-bg-white fixed inset-0 z-50 flex flex-col",
1979
+ children: [/*#__PURE__*/jsx(TopBar, {
1980
+ canManage: canManage,
1981
+ documentId: documentId,
1982
+ homeUrl: homeUrl,
1983
+ isDirty: isDirty,
1984
+ isDownloading: isDownloading,
1985
+ isPreview: isPreview,
1986
+ isSaving: isSaving,
1987
+ mode: mode,
1988
+ onBack: onBack,
1989
+ zoom: zoom,
1990
+ canDownload: isPreview && Boolean(previewRecord),
1991
+ name: documentName,
1992
+ onDownload: downloadPdf,
1993
+ onModeChange: handleModeChange,
1994
+ onRename: renamePdfDocument,
1995
+ onSave: handleSave,
1996
+ onZoomIn: function onZoomIn() {
1997
+ return setZoom(function (value) {
1998
+ return clamp(value + ZOOM.STEP, ZOOM.MIN, ZOOM.MAX);
1999
+ });
2000
+ },
2001
+ onZoomOut: function onZoomOut() {
2002
+ return setZoom(function (value) {
2003
+ return clamp(value - ZOOM.STEP, ZOOM.MIN, ZOOM.MAX);
2004
+ });
2005
+ }
2006
+ }), /*#__PURE__*/jsxs("div", {
2007
+ className: "flex min-h-0 grow overflow-hidden",
2008
+ children: [!isPreview && /*#__PURE__*/jsx(FieldsPanel, {
2009
+ answerFields: answerFields,
2010
+ systemFields: systemFields,
2011
+ onDragEndField: handleDragEndField,
2012
+ onDragStartField: handleDragStartField,
2013
+ onPlace: handleAddField
2014
+ }), /*#__PURE__*/jsxs("div", {
2015
+ className: "relative h-full min-w-0 flex-1 overflow-hidden",
2016
+ children: [isPreview && /*#__PURE__*/jsx("div", {
2017
+ className: "absolute top-4 left-1/2 z-10 -translate-x-1/2",
2018
+ children: /*#__PURE__*/jsx(PreviewPager, {
2019
+ isLoading: isPreviewLoading,
2020
+ page: currentPreviewPage,
2021
+ total: previewTotal,
2022
+ onNext: function onNext() {
2023
+ return setPreviewPage(Math.min(currentPreviewPage + 1, previewTotal));
2024
+ },
2025
+ onPrev: function onPrev() {
2026
+ return setPreviewPage(Math.max(currentPreviewPage - 1, 1));
2027
+ }
2028
+ })
2029
+ }), /*#__PURE__*/jsx(Canvas, {
2030
+ mappings: mappings,
2031
+ mode: mode,
2032
+ resolveValue: resolveValue,
2033
+ selectedId: selectedId,
2034
+ templateUrl: templateUrl,
2035
+ zoom: zoom,
2036
+ onChange: handleChangeMapping,
2037
+ onDropField: handleDropField,
2038
+ onPageScaleChange: handlePageScaleChange,
2039
+ onSelect: setSelectedId
2040
+ })]
2041
+ }), !isPreview && /*#__PURE__*/jsx(FieldPanel, {
2042
+ mapping: selectedMapping,
2043
+ onChange: handleChangeMapping,
2044
+ onRemove: handleRemoveMapping
2045
+ })]
2046
+ })]
2047
+ }), window.document.body);
2048
+ };
2049
+
2050
+ export { PdfEditorPage as default };
2051
+ //# sourceMappingURL=PdfEditorPage.js.map