teraprox-ui-kit 0.1.5 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs DELETED
@@ -1,2198 +0,0 @@
1
- // src/buttons/AddButton.tsx
2
- import { Button } from "react-bootstrap";
3
- import { GrAdd } from "react-icons/gr";
4
- import { jsx } from "react/jsx-runtime";
5
- var AddButton = ({ callback, hiddenBool, size }) => /* @__PURE__ */ jsx(
6
- Button,
7
- {
8
- hidden: hiddenBool || false,
9
- variant: "outline-primary",
10
- onClick: () => callback(),
11
- children: /* @__PURE__ */ jsx(GrAdd, { size: size || 25 })
12
- }
13
- );
14
- var AddButton_default = AddButton;
15
-
16
- // src/buttons/DeleteButton.tsx
17
- import { Button as Button2 } from "react-bootstrap";
18
- import { jsx as jsx2 } from "react/jsx-runtime";
19
- var DeleteButton = ({ title, onDeleteClick }) => {
20
- return /* @__PURE__ */ jsx2(Button2, { variant: "danger", onClick: () => onDeleteClick(), children: title });
21
- };
22
- var DeleteButton_default = DeleteButton;
23
-
24
- // src/buttons/ActionButtons.tsx
25
- import { useState as useState2, useRef } from "react";
26
- import { Button as Button4, Form as Form2, ProgressBar } from "react-bootstrap";
27
- import { FiSave, FiTrash2, FiRotateCcw, FiCopy, FiChevronLeft } from "react-icons/fi";
28
-
29
- // src/forms/DeleteConfirm.tsx
30
- import { useState } from "react";
31
- import { Button as Button3, Modal, Form } from "react-bootstrap";
32
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
33
- var DeleteConfirm = ({
34
- show,
35
- onHide,
36
- onConfirm,
37
- title = "Confirma\xE7\xE3o de Exclus\xE3o",
38
- dialogText,
39
- payload,
40
- needExclusionDetails = false
41
- }) => {
42
- const [exclusionDetails, setExclusionDetails] = useState("");
43
- const getDialogContent = () => {
44
- if (typeof dialogText === "function" && payload) {
45
- return dialogText(payload);
46
- }
47
- return dialogText || "Voc\xEA tem certeza que deseja excluir este item?";
48
- };
49
- const isConfirmEnabled = () => {
50
- if (!needExclusionDetails) return true;
51
- return exclusionDetails.length >= 8;
52
- };
53
- return /* @__PURE__ */ jsxs(Modal, { show, onHide: () => onHide(false), centered: true, children: [
54
- /* @__PURE__ */ jsx3(Modal.Header, { closeButton: true, children: /* @__PURE__ */ jsx3(Modal.Title, { children: title }) }),
55
- /* @__PURE__ */ jsx3(Modal.Body, { children: /* @__PURE__ */ jsxs("div", { className: "d-flex flex-column gap-3", children: [
56
- /* @__PURE__ */ jsx3("div", { children: /* @__PURE__ */ jsx3("strong", { children: getDialogContent() }) }),
57
- needExclusionDetails && /* @__PURE__ */ jsxs(Form.Group, { children: [
58
- /* @__PURE__ */ jsx3(Form.Label, { children: "Motivo da Exclus\xE3o (m\xEDn. 8 caracteres)" }),
59
- /* @__PURE__ */ jsx3(
60
- Form.Control,
61
- {
62
- as: "textarea",
63
- rows: 3,
64
- value: exclusionDetails,
65
- onChange: (e) => setExclusionDetails(e.target.value),
66
- placeholder: "Descreva o motivo...",
67
- autoFocus: true
68
- }
69
- )
70
- ] })
71
- ] }) }),
72
- /* @__PURE__ */ jsxs(Modal.Footer, { children: [
73
- /* @__PURE__ */ jsx3(Button3, { variant: "secondary", onClick: () => onHide(false), children: "Cancelar" }),
74
- /* @__PURE__ */ jsx3(
75
- Button3,
76
- {
77
- variant: "danger",
78
- disabled: !isConfirmEnabled(),
79
- onClick: () => {
80
- onConfirm(exclusionDetails);
81
- onHide(false);
82
- },
83
- children: "Confirmar Exclus\xE3o"
84
- }
85
- )
86
- ] })
87
- ] });
88
- };
89
-
90
- // src/buttons/ActionButtons.tsx
91
- import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
92
- var ActionButtons = ({
93
- onSave,
94
- saveLabel = "Salvar",
95
- saveVariant = "primary",
96
- disabled = false,
97
- onDelete,
98
- deleteLabel = "Excluir",
99
- deleteConfirmMsg,
100
- needExclusionDetails = false,
101
- onBack,
102
- backLabel = "Voltar",
103
- onCancelEdit,
104
- cancelEditLabel = "Cancelar",
105
- onCopy,
106
- copyLabel = "Copiar Formul\xE1rio",
107
- isEditing = false,
108
- useDelayedDelete = false,
109
- delayedDeleteTimeout = 3e3,
110
- PermissionWrapper = ({ children }) => /* @__PURE__ */ jsx4(Fragment, { children })
111
- }) => {
112
- const [showConfirm, setShowConfirm] = useState2(false);
113
- const [isHolding, setIsHolding] = useState2(false);
114
- const [progress, setProgress] = useState2(0);
115
- const timeoutRef = useRef(null);
116
- const intervalRef = useRef(null);
117
- const startHold = () => {
118
- if (disabled || !onDelete) return;
119
- setIsHolding(true);
120
- setProgress(0);
121
- const step = 2;
122
- const tickTime = delayedDeleteTimeout / (100 / step);
123
- intervalRef.current = setInterval(() => {
124
- setProgress((prev) => prev >= 100 ? 100 : prev + step);
125
- }, tickTime);
126
- timeoutRef.current = setTimeout(() => {
127
- stopHold();
128
- onDelete();
129
- }, delayedDeleteTimeout);
130
- };
131
- const stopHold = () => {
132
- setIsHolding(false);
133
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
134
- if (intervalRef.current) clearInterval(intervalRef.current);
135
- setProgress(0);
136
- };
137
- const renderDeleteButton = () => {
138
- if (!onDelete || !isEditing) return null;
139
- if (useDelayedDelete) {
140
- return /* @__PURE__ */ jsxs2("div", { style: { position: "relative", display: "inline-block", margin: 2 }, children: [
141
- /* @__PURE__ */ jsxs2(
142
- Button4,
143
- {
144
- variant: "outline-danger",
145
- onMouseDown: startHold,
146
- onMouseUp: stopHold,
147
- onMouseLeave: stopHold,
148
- onTouchStart: startHold,
149
- onTouchEnd: stopHold,
150
- disabled,
151
- style: { minWidth: "120px" },
152
- children: [
153
- /* @__PURE__ */ jsx4(FiTrash2, { className: "me-2" }),
154
- isHolding ? "Segure..." : deleteLabel
155
- ]
156
- }
157
- ),
158
- isHolding && /* @__PURE__ */ jsx4(
159
- ProgressBar,
160
- {
161
- now: progress,
162
- style: {
163
- position: "absolute",
164
- bottom: 0,
165
- left: 0,
166
- right: 0,
167
- height: "4px",
168
- borderRadius: "0 0 4px 4px"
169
- },
170
- variant: "danger"
171
- }
172
- )
173
- ] });
174
- }
175
- return /* @__PURE__ */ jsxs2(
176
- Button4,
177
- {
178
- variant: "danger",
179
- onClick: () => setShowConfirm(true),
180
- disabled,
181
- style: { margin: 2 },
182
- children: [
183
- /* @__PURE__ */ jsx4(FiTrash2, { className: "me-2" }),
184
- deleteLabel
185
- ]
186
- }
187
- );
188
- };
189
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
190
- /* @__PURE__ */ jsx4(
191
- DeleteConfirm,
192
- {
193
- show: showConfirm,
194
- onHide: setShowConfirm,
195
- onConfirm: (details) => onDelete && onDelete(details),
196
- dialogText: deleteConfirmMsg,
197
- needExclusionDetails
198
- }
199
- ),
200
- /* @__PURE__ */ jsxs2(Form2.Group, { className: "d-flex flex-wrap align-items-center mt-3 gap-1", children: [
201
- onBack && /* @__PURE__ */ jsxs2(Button4, { variant: "outline-secondary", onClick: onBack, disabled, style: { margin: 2 }, children: [
202
- /* @__PURE__ */ jsx4(FiChevronLeft, { className: "me-2" }),
203
- backLabel
204
- ] }),
205
- isEditing && onCancelEdit && /* @__PURE__ */ jsxs2(Button4, { variant: "warning", onClick: onCancelEdit, disabled, style: { margin: 2 }, children: [
206
- /* @__PURE__ */ jsx4(FiRotateCcw, { className: "me-2" }),
207
- cancelEditLabel
208
- ] }),
209
- /* @__PURE__ */ jsx4(PermissionWrapper, { children: renderDeleteButton() }),
210
- onSave && /* @__PURE__ */ jsxs2(Button4, { variant: saveVariant, onClick: onSave, disabled, style: { margin: 2 }, children: [
211
- /* @__PURE__ */ jsx4(FiSave, { className: "me-2" }),
212
- saveLabel
213
- ] }),
214
- isEditing && onCopy && /* @__PURE__ */ jsxs2(Button4, { variant: "outline-primary", onClick: onCopy, disabled, style: { margin: 2 }, children: [
215
- /* @__PURE__ */ jsx4(FiCopy, { className: "me-2" }),
216
- copyLabel
217
- ] })
218
- ] })
219
- ] });
220
- };
221
-
222
- // src/buttons/ApproveAndReproveButtons.tsx
223
- import { useEffect } from "react";
224
- import { Button as Button5 } from "react-bootstrap";
225
- import { GrCheckmark, GrClose } from "react-icons/gr";
226
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
227
- var ApproveAndReproveButtons = ({
228
- buttonSize = 25,
229
- approveCallback,
230
- reproveCallback,
231
- cancelCallback,
232
- headerText = "Aprovar?",
233
- approveText,
234
- repproveText
235
- }) => {
236
- useEffect(() => {
237
- const keyboardHandler = (e) => {
238
- if (e.key === "Escape") {
239
- cancelCallback();
240
- }
241
- };
242
- window.document.addEventListener("keydown", keyboardHandler);
243
- return () => window.document.removeEventListener("keydown", keyboardHandler);
244
- }, [cancelCallback]);
245
- return /* @__PURE__ */ jsxs3("div", { children: [
246
- /* @__PURE__ */ jsx5("strong", { children: headerText }),
247
- /* @__PURE__ */ jsx5("br", {}),
248
- /* @__PURE__ */ jsx5(Button5, { onClick: approveCallback, variant: "success", className: "me-1", children: approveText ? approveText : /* @__PURE__ */ jsx5(GrCheckmark, { size: buttonSize }) }),
249
- /* @__PURE__ */ jsx5(Button5, { onClick: reproveCallback, variant: "danger", children: repproveText ? repproveText : /* @__PURE__ */ jsx5(GrClose, { size: buttonSize }) })
250
- ] });
251
- };
252
-
253
- // src/buttons/AsyncButton.tsx
254
- import { useState as useState3, useRef as useRef2 } from "react";
255
- import { Button as Button6 } from "react-bootstrap";
256
-
257
- // src/progress/LoadingProgress.tsx
258
- import { Spinner } from "react-bootstrap";
259
- import { jsx as jsx6 } from "react/jsx-runtime";
260
- var LoadingProgress = ({ hidden }) => {
261
- return /* @__PURE__ */ jsx6(Spinner, { hidden, animation: "border", role: "status", children: /* @__PURE__ */ jsx6("span", { className: "visually-hidden", children: "Carregando..." }) });
262
- };
263
-
264
- // src/buttons/AsyncButton.tsx
265
- import { jsx as jsx7 } from "react/jsx-runtime";
266
- var useAsyncAction = () => {
267
- const [loading, setLoading] = useState3(false);
268
- const isMounted = useRef2(true);
269
- const isProcessing = useRef2(false);
270
- const execute = async (action) => {
271
- if (typeof action !== "function") {
272
- throw new Error("A\xE7\xE3o inv\xE1lida: n\xE3o \xE9 uma fun\xE7\xE3o");
273
- }
274
- if (!action || isProcessing.current) return;
275
- isProcessing.current = true;
276
- setLoading(true);
277
- try {
278
- await action();
279
- } catch (error) {
280
- console.error("Async operation failed:", error);
281
- } finally {
282
- if (isMounted.current) {
283
- setLoading(false);
284
- isProcessing.current = false;
285
- }
286
- }
287
- };
288
- return { loading, execute };
289
- };
290
- var AsyncButton = ({
291
- onClick,
292
- children,
293
- loadingComponent = /* @__PURE__ */ jsx7(LoadingProgress, {}),
294
- buttonProps
295
- }) => {
296
- const { loading, execute } = useAsyncAction();
297
- return /* @__PURE__ */ jsx7(
298
- Button6,
299
- {
300
- ...buttonProps,
301
- onClick: () => execute(onClick),
302
- disabled: loading || buttonProps && buttonProps.disabled,
303
- children: loading ? loadingComponent : children
304
- }
305
- );
306
- };
307
-
308
- // src/buttons/Generic3DotMenu.tsx
309
- import { useState as useState4 } from "react";
310
- import { Button as Button7, Modal as Modal2 } from "react-bootstrap";
311
- import { CiMenuKebab } from "react-icons/ci";
312
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
313
- var MenuEvent = class {
314
- /**
315
- * @param label - O texto que aparecerá no botão.
316
- * @param callback - A função a ser chamada quando o botão for clicado.
317
- * @param variant - A variante do botão (padrão: 'primary').
318
- * @param renderCondition - Condição para renderizar o botão.
319
- * @param section - A seção para organizar os botões (padrão: 'default').
320
- */
321
- constructor(label, callback, variant = "primary", renderCondition = true, section = "default") {
322
- this.label = label;
323
- this.callback = callback;
324
- this.variant = variant;
325
- this.renderCondition = renderCondition;
326
- this.section = section;
327
- }
328
- };
329
- var Generic3DotMenu = ({
330
- events,
331
- tittle = "Op\xE7\xF5es de Controle"
332
- }) => {
333
- const [show, setShow] = useState4(false);
334
- const handleClose = () => setShow(false);
335
- const handleShow = () => setShow(true);
336
- const shouldRender = (event) => {
337
- return typeof event.renderCondition === "function" ? event.renderCondition() : event.renderCondition;
338
- };
339
- const groupedEvents = events.reduce((sections, event) => {
340
- const section = event.section || "default";
341
- if (!sections[section]) {
342
- sections[section] = [];
343
- }
344
- if (shouldRender(event)) {
345
- sections[section].push(event);
346
- }
347
- return sections;
348
- }, {});
349
- return /* @__PURE__ */ jsxs4(Fragment2, { children: [
350
- /* @__PURE__ */ jsx8(CiMenuKebab, { onClick: handleShow, style: { cursor: "pointer" }, size: 25, title: tittle }),
351
- /* @__PURE__ */ jsxs4(Modal2, { show, onHide: handleClose, centered: true, children: [
352
- /* @__PURE__ */ jsx8(Modal2.Header, { closeButton: true, children: /* @__PURE__ */ jsx8(Modal2.Title, { children: tittle }) }),
353
- /* @__PURE__ */ jsxs4(Modal2.Body, { children: [
354
- Object.keys(groupedEvents).length === 0 && /* @__PURE__ */ jsx8("div", { className: "text-center text-muted", children: "Nenhuma op\xE7\xE3o dispon\xEDvel." }),
355
- Object.keys(groupedEvents).map((section, sectionIndex) => /* @__PURE__ */ jsxs4("div", { className: "mb-4", children: [
356
- /* @__PURE__ */ jsx8("h6", { className: "border-bottom pb-2 mb-3", children: section !== "default" ? section : "Op\xE7\xF5es Principais" }),
357
- /* @__PURE__ */ jsx8("div", { className: "d-grid gap-2", children: groupedEvents[section].map((event, index) => /* @__PURE__ */ jsx8(
358
- Button7,
359
- {
360
- variant: event.variant || "primary",
361
- onClick: () => {
362
- event.callback();
363
- handleClose();
364
- },
365
- children: event.label
366
- },
367
- index
368
- )) })
369
- ] }, sectionIndex))
370
- ] }),
371
- /* @__PURE__ */ jsx8(Modal2.Footer, { children: /* @__PURE__ */ jsx8(Button7, { variant: "secondary", onClick: handleClose, children: "Fechar" }) })
372
- ] })
373
- ] });
374
- };
375
-
376
- // src/buttons/LoadingButton.tsx
377
- import { Button as Button8, Spinner as Spinner2 } from "react-bootstrap";
378
- import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
379
- var LoadingButton = ({
380
- onClick,
381
- loading = false,
382
- label = "Enviar",
383
- variant = "primary",
384
- size = "md",
385
- disabled = false,
386
- icon = null,
387
- className = "",
388
- loadingLabel = "Carregando...",
389
- ...props
390
- }) => {
391
- return /* @__PURE__ */ jsx9(
392
- Button8,
393
- {
394
- variant,
395
- size,
396
- disabled: disabled || loading,
397
- onClick,
398
- className: `loading-button ${className}`,
399
- style: { cursor: loading ? "not-allowed" : "pointer" },
400
- ...props,
401
- children: loading ? /* @__PURE__ */ jsxs5("div", { className: "align-items-center", children: [
402
- /* @__PURE__ */ jsx9(
403
- Spinner2,
404
- {
405
- as: "span",
406
- animation: "border",
407
- size: "sm",
408
- role: "status",
409
- "aria-hidden": "true",
410
- className: "me-2"
411
- }
412
- ),
413
- /* @__PURE__ */ jsx9("span", { children: loadingLabel })
414
- ] }) : /* @__PURE__ */ jsxs5("div", { className: "align-items-center", children: [
415
- icon && /* @__PURE__ */ jsx9("span", { className: "me-2 d-flex", children: icon }),
416
- /* @__PURE__ */ jsx9("span", { children: label })
417
- ] })
418
- }
419
- );
420
- };
421
-
422
- // src/buttons/NavigateButton.tsx
423
- import { Button as Button9 } from "react-bootstrap";
424
- import { jsx as jsx10 } from "react/jsx-runtime";
425
- var NavigateButton = ({
426
- displayName,
427
- path,
428
- config,
429
- pageName,
430
- navigator: navigator2,
431
- onBeforeNavigate,
432
- variant = "outline-primary",
433
- style,
434
- ...props
435
- }) => {
436
- const handleClick = () => {
437
- if (onBeforeNavigate) {
438
- onBeforeNavigate();
439
- }
440
- navigator2(path, config, pageName);
441
- };
442
- return /* @__PURE__ */ jsx10(
443
- Button9,
444
- {
445
- style,
446
- variant,
447
- onClick: handleClick,
448
- ...props,
449
- children: displayName
450
- }
451
- );
452
- };
453
-
454
- // src/buttons/StatusBadge.tsx
455
- import { Form as Form3, Spinner as Spinner3 } from "react-bootstrap";
456
- import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
457
- var StatusBadge = ({
458
- status,
459
- showCheckbox = false,
460
- checked = false,
461
- onToggle = () => {
462
- },
463
- loading = false,
464
- customStatusClasses
465
- }) => {
466
- const statusClasses = customStatusClasses || {
467
- PENDENTE: "bg-warning text-dark",
468
- EXECUTANDO: "bg-success text-white",
469
- CONCLUIDO: "bg-secondary text-white",
470
- CANCELED: "bg-danger text-white"
471
- };
472
- const badgeClass = statusClasses[status] || "bg-secondary text-white";
473
- return /* @__PURE__ */ jsx11("div", { className: "d-flex align-items-center gap-2", children: loading ? /* @__PURE__ */ jsx11(Spinner3, { animation: "border", size: "sm" }) : /* @__PURE__ */ jsxs6(Fragment3, { children: [
474
- showCheckbox && /* @__PURE__ */ jsx11(
475
- Form3.Check,
476
- {
477
- type: "checkbox",
478
- checked,
479
- onChange: onToggle,
480
- className: "me-1"
481
- }
482
- ),
483
- /* @__PURE__ */ jsx11("span", { className: `badge ${badgeClass}`, children: status })
484
- ] }) });
485
- };
486
-
487
- // src/buttons/SwitchOnClick.tsx
488
- import { useEffect as useEffect2, useState as useState5 } from "react";
489
- import { FaTimes } from "react-icons/fa";
490
- import { GrAddCircle } from "react-icons/gr";
491
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
492
- var SwitchOnClick = ({
493
- children,
494
- placeHolder = /* @__PURE__ */ jsx12(
495
- "div",
496
- {
497
- className: "text-center zoom-container",
498
- style: {
499
- fontSize: "1.2rem",
500
- color: "#666"
501
- },
502
- children: /* @__PURE__ */ jsx12(
503
- GrAddCircle,
504
- {
505
- size: 25,
506
- className: "mb-2",
507
- style: { cursor: "pointer" }
508
- }
509
- )
510
- }
511
- ),
512
- onSwitchClick,
513
- onCancel,
514
- containerClassName = ""
515
- }) => {
516
- const [clicked, setClicked] = useState5(false);
517
- const handleClick = () => {
518
- onSwitchClick && onSwitchClick();
519
- setClicked(!clicked);
520
- };
521
- const handleClose = () => {
522
- setClicked(false);
523
- onCancel && onCancel();
524
- };
525
- useEffect2(() => {
526
- const handleEscape = (event) => {
527
- if (event.key === "Escape") {
528
- handleClose();
529
- }
530
- };
531
- window.addEventListener("keydown", handleEscape);
532
- return () => window.removeEventListener("keydown", handleEscape);
533
- }, []);
534
- if (!clicked) {
535
- return /* @__PURE__ */ jsx12("div", { onClick: handleClick, style: { cursor: "pointer" }, children: placeHolder });
536
- }
537
- return /* @__PURE__ */ jsxs7("div", { className: `switch-on-click-container ${containerClassName}`, children: [
538
- /* @__PURE__ */ jsx12("div", { className: "close-icon", onClick: handleClose, children: /* @__PURE__ */ jsx12(FaTimes, { title: "Fechar" }) }),
539
- children({ handleClose })
540
- ] });
541
- };
542
-
543
- // src/containers/ResponsiveContainer.tsx
544
- import { Modal as Modal3, ModalBody } from "react-bootstrap";
545
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
546
- var ResponsiveContainer = ({
547
- title,
548
- show,
549
- setShow,
550
- children,
551
- onClose,
552
- scrollable = false
553
- }) => {
554
- const handleClose = () => {
555
- setShow(false);
556
- if (onClose) onClose();
557
- };
558
- return /* @__PURE__ */ jsxs8(Modal3, { size: "lg", show, onHide: handleClose, scrollable, children: [
559
- /* @__PURE__ */ jsx13(Modal3.Header, { closeButton: true, onClick: handleClose }),
560
- /* @__PURE__ */ jsx13(ModalBody, { children })
561
- ] });
562
- };
563
- var ResponsiveContainer_default = ResponsiveContainer;
564
-
565
- // src/displays/UuidPill.tsx
566
- import { useState as useState6, useRef as useRef3 } from "react";
567
- import { Badge, Overlay, Tooltip } from "react-bootstrap";
568
- import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
569
- var UuidPill = ({ uuid, bg = "light", textColor = "dark", short = 8 }) => {
570
- const [copied, setCopied] = useState6(false);
571
- const ref = useRef3(null);
572
- const [showTooltip, setShowTooltip] = useState6(false);
573
- if (!uuid) return /* @__PURE__ */ jsx14("span", { className: "text-muted", children: "\u2014" });
574
- const shortId = String(uuid).substring(0, short);
575
- const handleCopy = async (e) => {
576
- e.stopPropagation();
577
- try {
578
- await navigator.clipboard.writeText(uuid);
579
- } catch (e2) {
580
- const ta = document.createElement("textarea");
581
- ta.value = uuid;
582
- document.body.appendChild(ta);
583
- ta.select();
584
- document.execCommand("copy");
585
- document.body.removeChild(ta);
586
- }
587
- setCopied(true);
588
- setTimeout(() => setCopied(false), 1500);
589
- };
590
- return /* @__PURE__ */ jsxs9(Fragment4, { children: [
591
- /* @__PURE__ */ jsxs9(
592
- Badge,
593
- {
594
- ref,
595
- bg,
596
- text: textColor,
597
- pill: true,
598
- className: "border px-2 py-1",
599
- style: { cursor: "pointer", fontFamily: "monospace", fontSize: "0.8rem", userSelect: "none" },
600
- onClick: handleCopy,
601
- onMouseEnter: () => setShowTooltip(true),
602
- onMouseLeave: () => {
603
- setShowTooltip(false);
604
- setCopied(false);
605
- },
606
- children: [
607
- shortId,
608
- "\u2026"
609
- ]
610
- }
611
- ),
612
- /* @__PURE__ */ jsx14(Overlay, { target: ref.current, show: showTooltip, placement: "top", children: (props) => /* @__PURE__ */ jsx14(Tooltip, { ...props, children: copied ? /* @__PURE__ */ jsx14("span", { style: { color: "#6f6" }, children: "Copiado!" }) : /* @__PURE__ */ jsxs9("span", { style: { fontFamily: "monospace", fontSize: "0.75rem" }, children: [
613
- uuid,
614
- /* @__PURE__ */ jsx14("br", {}),
615
- /* @__PURE__ */ jsx14("small", { className: "text-muted", children: "Clique para copiar" })
616
- ] }) }) })
617
- ] });
618
- };
619
- var UuidPill_default = UuidPill;
620
-
621
- // src/displays/GenericDisplay.tsx
622
- import React8, { useState as useState7, useEffect as useEffect3 } from "react";
623
- import { Col, Container, Row } from "react-bootstrap";
624
- import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
625
- var ConfigObject = class {
626
- constructor(dotNotation, style, onClick, onBlur, onHideClick, hidden, mapData, additionalComponents) {
627
- this.dotNotation = dotNotation;
628
- this.style = style;
629
- this.onClick = onClick;
630
- this.onBlur = onBlur;
631
- this.onHideClick = onHideClick;
632
- this.hidden = hidden;
633
- this.mapData = mapData;
634
- this.additionalComponents = additionalComponents || [];
635
- }
636
- };
637
- var getRightConfigObjects = (currentPropertieMap, configObjects) => {
638
- const curreDotNotation = currentPropertieMap.join(".");
639
- if (!configObjects) return [];
640
- return configObjects.filter((configObject) => configObject.dotNotation === curreDotNotation);
641
- };
642
- var getStyle = (configObjects) => {
643
- let styleObject = {};
644
- configObjects.forEach((configObject) => {
645
- styleObject = { ...styleObject, ...configObject.style };
646
- });
647
- return styleObject;
648
- };
649
- var getAdditionalComponentes = (configObjects) => {
650
- const components = [];
651
- configObjects.forEach((configObject) => {
652
- if (configObject.additionalComponents) {
653
- components.push(...configObject.additionalComponents);
654
- }
655
- });
656
- return components;
657
- };
658
- var getOnClick = (configObjects) => {
659
- return () => {
660
- configObjects.forEach((configObject) => {
661
- configObject.onClick && configObject.onClick();
662
- });
663
- };
664
- };
665
- var buildData = (obj, propertiesMap, configObjects, opn, innerArray, dispatch, isRoot, editButtonRenderer) => {
666
- const newPropertiesMap = [];
667
- if (opn) newPropertiesMap.push(...propertiesMap, opn);
668
- else newPropertiesMap.push(...propertiesMap);
669
- const innerConfigs = getRightConfigObjects(newPropertiesMap, configObjects);
670
- const styles = getStyle(innerConfigs);
671
- const onClick = getOnClick(innerConfigs);
672
- const extraComponents = getAdditionalComponentes(innerConfigs);
673
- if (Array.isArray(obj)) {
674
- return /* @__PURE__ */ jsxs10(Container, { onClick, style: { ...styles }, children: [
675
- opn && /* @__PURE__ */ jsx15("div", { style: { textAlign: "center" }, children: /* @__PURE__ */ jsx15("strong", { children: opn }) }),
676
- obj.map((o, index) => {
677
- const mapCopy = [...newPropertiesMap, `[${index}]`];
678
- return /* @__PURE__ */ jsx15(Row, { style: { padding: 4, ...styles }, children: buildData(o, mapCopy, configObjects, null, true, null, false, editButtonRenderer) }, index);
679
- })
680
- ] });
681
- }
682
- if (typeof obj === "object" && obj != null) {
683
- return /* @__PURE__ */ jsxs10(
684
- Container,
685
- {
686
- onClick,
687
- style: {
688
- border: innerArray ? "solid" : void 0,
689
- borderColor: "lightgray",
690
- borderRadius: innerArray ? 4 : 2,
691
- borderWidth: 1,
692
- padding: 4,
693
- ...styles
694
- },
695
- children: [
696
- opn && /* @__PURE__ */ jsx15("strong", { children: opn }),
697
- Object.entries(obj).map(
698
- ([key, value]) => buildData(value, newPropertiesMap, configObjects, key, false, null, false, editButtonRenderer)
699
- ),
700
- extraComponents.length > 0 ? extraComponents.map((comp, i) => /* @__PURE__ */ jsx15(React8.Fragment, { children: comp() }, i)) : isRoot && editButtonRenderer ? editButtonRenderer(obj, opn) : null
701
- ]
702
- }
703
- );
704
- }
705
- return /* @__PURE__ */ jsxs10(Col, { children: [
706
- /* @__PURE__ */ jsxs10("strong", { children: [
707
- opn,
708
- ": "
709
- ] }),
710
- String(obj)
711
- ] });
712
- };
713
- var GenericDisplay = ({
714
- ops = [],
715
- loadFunc,
716
- configObjects,
717
- rootName,
718
- context,
719
- onRefresh,
720
- editButtonRenderer
721
- }) => {
722
- const [innerOptions, setInnerOptions] = useState7();
723
- const refreshFunc = () => {
724
- if (loadFunc) {
725
- loadFunc().then((res) => {
726
- if (Array.isArray(res)) {
727
- setInnerOptions(res);
728
- } else {
729
- setInnerOptions([res]);
730
- }
731
- });
732
- } else {
733
- setInnerOptions(ops);
734
- }
735
- };
736
- useEffect3(() => {
737
- if (onRefresh) {
738
- onRefresh(refreshFunc);
739
- } else {
740
- refreshFunc();
741
- }
742
- }, [context]);
743
- return /* @__PURE__ */ jsx15(Fragment5, { children: innerOptions && innerOptions.map((cObj, index) => /* @__PURE__ */ jsx15(Container, { style: { padding: 4, border: "solid" }, children: buildData(cObj, [], configObjects, rootName || null, false, null, true, editButtonRenderer) }, index)) });
744
- };
745
- var GenericDisplay_default = GenericDisplay;
746
-
747
- // src/displays/StatusIndicator.tsx
748
- import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
749
- var StatusIndicator = ({
750
- status,
751
- count,
752
- containerClassName = "",
753
- customLabels
754
- }) => {
755
- const statusLabels = customLabels || {
756
- pendente: "PENDENTE",
757
- executando: "EXECUTANDO",
758
- concluido: "CONCLU\xCDDA",
759
- canceled: "CANCELADA",
760
- naoAtribuida: "N\xC3O ATRIBUIDA"
761
- };
762
- const label = statusLabels[status] || status.toUpperCase();
763
- return /* @__PURE__ */ jsxs11("div", { className: `status-flag ${status} ${containerClassName}`, children: [
764
- /* @__PURE__ */ jsx16("div", { className: "status-label", children: label }),
765
- /* @__PURE__ */ jsx16("div", { className: "status-count", children: count })
766
- ] });
767
- };
768
-
769
- // src/displays/VerticalItemsDisplay.tsx
770
- import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
771
- var VerticalItemsDisplay = ({
772
- item1 = "",
773
- item2 = "",
774
- item3 = "",
775
- className = "",
776
- style
777
- }) => {
778
- return /* @__PURE__ */ jsxs12("div", { className, style, children: [
779
- /* @__PURE__ */ jsx17("div", { children: item1 }),
780
- /* @__PURE__ */ jsx17("div", { children: item2 }),
781
- /* @__PURE__ */ jsx17("div", { children: item3 })
782
- ] });
783
- };
784
-
785
- // src/forms/MailSender.tsx
786
- import { useState as useState8 } from "react";
787
- import {
788
- Button as Button10,
789
- Card,
790
- Col as Col2,
791
- Form as Form4,
792
- Row as Row2,
793
- Spinner as Spinner4,
794
- Badge as Badge2,
795
- InputGroup
796
- } from "react-bootstrap";
797
- import { FiMail, FiSearch, FiUser, FiX, FiPlus, FiSend } from "react-icons/fi";
798
- import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
799
- var MailSender = ({
800
- htmlContent,
801
- companyName,
802
- onFetchEmails,
803
- onSendEmail,
804
- hide = false,
805
- renderTrigger
806
- }) => {
807
- const [opened, setOpened] = useState8(false);
808
- const [addingEmail, setAddingEmail] = useState8(false);
809
- const [selectedEmails, setSelectedEmails] = useState8([]);
810
- const [emails, setEmails] = useState8([]);
811
- const [loading, setLoading] = useState8(false);
812
- const [postLoading, setPostLoading] = useState8(false);
813
- const [customEmail, setCustomEmail] = useState8("");
814
- const [emailError, setEmailError] = useState8("");
815
- const [searchFilter, setSearchFilter] = useState8("");
816
- const handleOpen = async () => {
817
- setLoading(true);
818
- try {
819
- const data = await onFetchEmails();
820
- setEmails(data || []);
821
- setOpened(true);
822
- } catch (err) {
823
- console.error("Erro ao buscar e-mails:", err);
824
- } finally {
825
- setLoading(false);
826
- }
827
- };
828
- const mailListLinter = () => {
829
- const result = [];
830
- const seen = /* @__PURE__ */ new Set();
831
- if (emails) {
832
- for (const item of emails) {
833
- if (item.email && !seen.has(item.email)) {
834
- seen.add(item.email);
835
- result.push({ email: item.email });
836
- }
837
- }
838
- }
839
- return result;
840
- };
841
- const filteredEmails = emails ? mailListLinter().filter(
842
- (email) => email.email.toLowerCase().includes(searchFilter.toLowerCase()) && !selectedEmails.some((selected) => (selected.email || selected) === email.email)
843
- ) : [];
844
- const sendEmail = async () => {
845
- const emailString = selectedEmails.map((email) => email.email ? email.email : email).join(", ");
846
- const emailData = {
847
- to: emailString,
848
- subject: `Relat\xF3rio - ${companyName}`,
849
- text: `Relat\xF3rio de processo da empresa ${companyName}`,
850
- html: htmlContent
851
- };
852
- setPostLoading(true);
853
- try {
854
- await onSendEmail(emailData);
855
- setSelectedEmails([]);
856
- setCustomEmail("");
857
- setOpened(false);
858
- } catch (err) {
859
- console.error("Erro ao enviar e-mail:", err);
860
- } finally {
861
- setPostLoading(false);
862
- }
863
- };
864
- const validateEmail = (email) => {
865
- const re = /\S+@\S+\.\S+/;
866
- return re.test(email);
867
- };
868
- const handleEmailAdd = () => {
869
- if (!customEmail.trim()) {
870
- setEmailError("Por favor, digite um e-mail");
871
- return;
872
- }
873
- if (!validateEmail(customEmail)) {
874
- setEmailError("Formato de e-mail inv\xE1lido");
875
- return;
876
- }
877
- if (selectedEmails.some((email) => (email.email || email) === customEmail)) {
878
- setEmailError("Este e-mail j\xE1 foi selecionado");
879
- return;
880
- }
881
- setSelectedEmails([...selectedEmails, customEmail]);
882
- setCustomEmail("");
883
- setEmailError("");
884
- setAddingEmail(false);
885
- };
886
- const handleEmailRemove = (emailToRemove) => {
887
- setSelectedEmails(
888
- selectedEmails.filter(
889
- (email) => (email.email || email) !== (emailToRemove.email || emailToRemove)
890
- )
891
- );
892
- };
893
- if (hide) return null;
894
- if (!opened) {
895
- if (renderTrigger) {
896
- return renderTrigger({ onClick: handleOpen, loading });
897
- }
898
- return /* @__PURE__ */ jsx18(Button10, { disabled: loading, className: "w-100", onClick: handleOpen, children: loading ? "Carregando..." : "Enviar por E-mail" });
899
- }
900
- return /* @__PURE__ */ jsxs13(
901
- "div",
902
- {
903
- style: {
904
- backgroundColor: "#f8f9fa",
905
- borderRadius: "12px",
906
- overflow: "hidden",
907
- border: "1px solid #dee2e6",
908
- boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)"
909
- },
910
- children: [
911
- /* @__PURE__ */ jsx18(
912
- "div",
913
- {
914
- style: {
915
- background: "linear-gradient(135deg, #28a745 0%, #20c997 100%)",
916
- color: "white",
917
- padding: "25px"
918
- },
919
- children: /* @__PURE__ */ jsxs13("div", { className: "d-flex justify-content-between align-items-center", children: [
920
- /* @__PURE__ */ jsxs13("div", { children: [
921
- /* @__PURE__ */ jsxs13("h4", { className: "mb-1", style: { fontWeight: "600", fontSize: "22px" }, children: [
922
- /* @__PURE__ */ jsx18(FiMail, { className: "me-2", size: 20 }),
923
- "Enviar Relat\xF3rio por E-mail"
924
- ] }),
925
- /* @__PURE__ */ jsxs13("small", { style: { opacity: "0.9", fontSize: "14px" }, children: [
926
- "Selecione os destinat\xE1rios para envio do relat\xF3rio de ",
927
- companyName
928
- ] })
929
- ] }),
930
- /* @__PURE__ */ jsxs13("div", { className: "d-flex gap-2", children: [
931
- /* @__PURE__ */ jsx18(
932
- Button10,
933
- {
934
- variant: "light",
935
- onClick: sendEmail,
936
- disabled: selectedEmails.length === 0 || postLoading,
937
- style: {
938
- borderRadius: "8px",
939
- fontWeight: "600",
940
- minWidth: "130px",
941
- height: "40px"
942
- },
943
- children: postLoading ? /* @__PURE__ */ jsxs13(Fragment6, { children: [
944
- /* @__PURE__ */ jsx18(Spinner4, { size: "sm", className: "me-2" }),
945
- "Enviando..."
946
- ] }) : /* @__PURE__ */ jsxs13(Fragment6, { children: [
947
- /* @__PURE__ */ jsx18(FiSend, { className: "me-2", size: 14 }),
948
- "Enviar E-mail"
949
- ] })
950
- }
951
- ),
952
- /* @__PURE__ */ jsx18(
953
- Button10,
954
- {
955
- variant: "outline-light",
956
- onClick: () => setOpened(false),
957
- disabled: postLoading,
958
- style: { borderRadius: "8px", width: "40px", height: "40px" },
959
- children: /* @__PURE__ */ jsx18(FiX, { size: 16 })
960
- }
961
- )
962
- ] })
963
- ] })
964
- }
965
- ),
966
- /* @__PURE__ */ jsxs13("div", { style: { padding: "25px" }, children: [
967
- /* @__PURE__ */ jsx18(Card, { className: "mb-4", style: { border: "none", boxShadow: "0 2px 8px rgba(0,0,0,0.05)" }, children: /* @__PURE__ */ jsxs13(Card.Body, { style: { padding: "20px" }, children: [
968
- /* @__PURE__ */ jsxs13(Row2, { className: "align-items-center", children: [
969
- /* @__PURE__ */ jsxs13(Col2, { md: 6, children: [
970
- /* @__PURE__ */ jsx18("h6", { className: "mb-2", style: { color: "#495057", fontWeight: "600" }, children: "\u{1F527} Filtros e A\xE7\xF5es" }),
971
- /* @__PURE__ */ jsxs13(InputGroup, { style: { maxWidth: "300px" }, children: [
972
- /* @__PURE__ */ jsx18(InputGroup.Text, { style: { backgroundColor: "#f8f9fa", border: "1px solid #dee2e6" }, children: /* @__PURE__ */ jsx18(FiSearch, { size: 14, color: "#6c757d" }) }),
973
- /* @__PURE__ */ jsx18(
974
- Form4.Control,
975
- {
976
- type: "text",
977
- placeholder: "Buscar e-mails...",
978
- value: searchFilter,
979
- onChange: (e) => setSearchFilter(e.target.value),
980
- style: { border: "1px solid #dee2e6" }
981
- }
982
- )
983
- ] })
984
- ] }),
985
- /* @__PURE__ */ jsx18(Col2, { md: 6, className: "text-end", children: /* @__PURE__ */ jsx18(
986
- Button10,
987
- {
988
- variant: addingEmail ? "outline-secondary" : "outline-primary",
989
- size: "sm",
990
- onClick: () => setAddingEmail(!addingEmail),
991
- disabled: postLoading,
992
- style: { borderRadius: "8px" },
993
- children: addingEmail ? /* @__PURE__ */ jsxs13(Fragment6, { children: [
994
- /* @__PURE__ */ jsx18(FiX, { className: "me-1", size: 14 }),
995
- "Cancelar"
996
- ] }) : /* @__PURE__ */ jsxs13(Fragment6, { children: [
997
- /* @__PURE__ */ jsx18(FiPlus, { className: "me-1", size: 14 }),
998
- "E-mail Personalizado"
999
- ] })
1000
- }
1001
- ) })
1002
- ] }),
1003
- addingEmail && /* @__PURE__ */ jsxs13(
1004
- "div",
1005
- {
1006
- style: {
1007
- marginTop: "20px",
1008
- padding: "20px",
1009
- backgroundColor: "#f8f9ff",
1010
- borderRadius: "8px",
1011
- border: "1px solid #e3f2fd"
1012
- },
1013
- children: [
1014
- /* @__PURE__ */ jsx18("h6", { className: "mb-3", style: { color: "#1976d2", fontWeight: "600" }, children: "\u2709\uFE0F Adicionar E-mail Personalizado" }),
1015
- /* @__PURE__ */ jsxs13(Row2, { className: "align-items-end", children: [
1016
- /* @__PURE__ */ jsxs13(Col2, { md: 8, children: [
1017
- /* @__PURE__ */ jsx18(Form4.Label, { style: { fontSize: "13px", color: "#6c757d", fontWeight: "500" }, children: "Endere\xE7o de E-mail" }),
1018
- /* @__PURE__ */ jsx18(
1019
- Form4.Control,
1020
- {
1021
- type: "email",
1022
- placeholder: "exemplo@empresa.com",
1023
- value: customEmail,
1024
- onChange: (e) => {
1025
- setCustomEmail(e.target.value);
1026
- if (emailError) setEmailError("");
1027
- },
1028
- isInvalid: !!emailError,
1029
- disabled: postLoading,
1030
- style: { borderRadius: "8px" },
1031
- onKeyPress: (e) => e.key === "Enter" && handleEmailAdd()
1032
- }
1033
- ),
1034
- /* @__PURE__ */ jsx18(Form4.Control.Feedback, { type: "invalid", children: emailError })
1035
- ] }),
1036
- /* @__PURE__ */ jsx18(Col2, { md: 4, children: /* @__PURE__ */ jsxs13(
1037
- Button10,
1038
- {
1039
- variant: "success",
1040
- onClick: handleEmailAdd,
1041
- disabled: postLoading,
1042
- style: { borderRadius: "8px", width: "100%" },
1043
- children: [
1044
- /* @__PURE__ */ jsx18(FiPlus, { className: "me-1", size: 14 }),
1045
- "Adicionar"
1046
- ]
1047
- }
1048
- ) })
1049
- ] })
1050
- ]
1051
- }
1052
- )
1053
- ] }) }),
1054
- selectedEmails.length > 0 && /* @__PURE__ */ jsx18(Card, { className: "mb-4", style: { border: "none", boxShadow: "0 2px 8px rgba(0,0,0,0.05)" }, children: /* @__PURE__ */ jsxs13(Card.Body, { style: { padding: "20px" }, children: [
1055
- /* @__PURE__ */ jsxs13("div", { className: "d-flex justify-content-between align-items-center mb-3", children: [
1056
- /* @__PURE__ */ jsx18("h6", { className: "mb-0", style: { color: "#495057", fontWeight: "600" }, children: "\u{1F4CB} Destinat\xE1rios Selecionados" }),
1057
- /* @__PURE__ */ jsxs13(Badge2, { bg: "primary", style: { fontSize: "12px", padding: "6px 12px" }, children: [
1058
- selectedEmails.length,
1059
- " selecionado",
1060
- selectedEmails.length > 1 ? "s" : ""
1061
- ] })
1062
- ] }),
1063
- /* @__PURE__ */ jsx18("div", { className: "d-flex flex-wrap gap-2", children: selectedEmails.map((email, index) => /* @__PURE__ */ jsxs13(
1064
- "div",
1065
- {
1066
- style: {
1067
- background: "linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%)",
1068
- border: "1px solid #bbdefb",
1069
- borderRadius: "20px",
1070
- padding: "8px 15px",
1071
- display: "flex",
1072
- alignItems: "center",
1073
- fontSize: "14px",
1074
- fontWeight: "500"
1075
- },
1076
- children: [
1077
- /* @__PURE__ */ jsx18(FiUser, { size: 12, className: "me-2", color: "#1976d2" }),
1078
- /* @__PURE__ */ jsx18("span", { children: email.email || email }),
1079
- /* @__PURE__ */ jsx18(
1080
- Button10,
1081
- {
1082
- variant: "link",
1083
- size: "sm",
1084
- onClick: () => handleEmailRemove(email),
1085
- disabled: postLoading,
1086
- style: {
1087
- padding: "0 0 0 8px",
1088
- color: "#dc3545",
1089
- textDecoration: "none",
1090
- fontSize: "16px"
1091
- },
1092
- children: /* @__PURE__ */ jsx18(FiX, { size: 14 })
1093
- }
1094
- )
1095
- ]
1096
- },
1097
- index
1098
- )) })
1099
- ] }) }),
1100
- /* @__PURE__ */ jsx18(Card, { style: { border: "none", boxShadow: "0 2px 8px rgba(0,0,0,0.05)" }, children: /* @__PURE__ */ jsxs13(Card.Body, { style: { padding: "20px" }, children: [
1101
- /* @__PURE__ */ jsxs13("h6", { className: "mb-3", style: { color: "#495057", fontWeight: "600" }, children: [
1102
- /* @__PURE__ */ jsx18(FiUser, { className: "me-2", size: 16 }),
1103
- "E-mails de ",
1104
- companyName
1105
- ] }),
1106
- loading ? /* @__PURE__ */ jsxs13("div", { className: "text-center py-4", children: [
1107
- /* @__PURE__ */ jsx18(Spinner4, {}),
1108
- /* @__PURE__ */ jsx18("p", { className: "mt-2 text-muted", children: "Carregando e-mails..." })
1109
- ] }) : filteredEmails.length === 0 ? /* @__PURE__ */ jsx18("div", { className: "text-center py-4", children: /* @__PURE__ */ jsx18("p", { className: "text-muted mb-0", children: searchFilter ? "Nenhum e-mail encontrado com esse filtro" : "Nenhum e-mail dispon\xEDvel" }) }) : /* @__PURE__ */ jsx18(Row2, { children: filteredEmails.map((email) => /* @__PURE__ */ jsx18(Col2, { xs: 12, sm: 6, lg: 4, className: "mb-3", children: /* @__PURE__ */ jsx18(
1110
- Card,
1111
- {
1112
- onClick: () => setSelectedEmails([...selectedEmails, email]),
1113
- style: {
1114
- cursor: "pointer",
1115
- border: "1px solid #e9ecef",
1116
- borderRadius: "10px",
1117
- transition: "all 0.2s ease",
1118
- backgroundColor: "#fff"
1119
- },
1120
- onMouseEnter: (e) => {
1121
- e.currentTarget.style.transform = "translateY(-2px)";
1122
- e.currentTarget.style.boxShadow = "0 4px 12px rgba(0,0,0,0.1)";
1123
- e.currentTarget.style.borderColor = "#007bff";
1124
- },
1125
- onMouseLeave: (e) => {
1126
- e.currentTarget.style.transform = "translateY(0)";
1127
- e.currentTarget.style.boxShadow = "none";
1128
- e.currentTarget.style.borderColor = "#e9ecef";
1129
- },
1130
- children: /* @__PURE__ */ jsxs13(Card.Body, { style: { padding: "15px", textAlign: "center" }, children: [
1131
- /* @__PURE__ */ jsx18(FiMail, { size: 20, color: "#007bff", className: "mb-2" }),
1132
- /* @__PURE__ */ jsx18(
1133
- "div",
1134
- {
1135
- style: {
1136
- fontSize: "14px",
1137
- fontWeight: "500",
1138
- color: "#2c3e50",
1139
- wordBreak: "break-word"
1140
- },
1141
- children: email.email
1142
- }
1143
- )
1144
- ] })
1145
- }
1146
- ) }, email.email)) })
1147
- ] }) })
1148
- ] })
1149
- ]
1150
- }
1151
- );
1152
- };
1153
-
1154
- // src/forms/AutoComplete.tsx
1155
- import { useEffect as useEffect4, useMemo, useState as useState9 } from "react";
1156
- import { FloatingLabel, Form as Form5, InputGroup as InputGroup2, ListGroup, Spinner as Spinner5 } from "react-bootstrap";
1157
- import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
1158
- var AutoComplete = ({
1159
- className,
1160
- ops = [],
1161
- sortKey,
1162
- displayKey,
1163
- displayKeys,
1164
- onValueChanged,
1165
- onSelectedClick,
1166
- value,
1167
- actionButton,
1168
- actionButton2,
1169
- placeH,
1170
- title,
1171
- filter,
1172
- filterField,
1173
- loadFunc,
1174
- loadCondition,
1175
- onBlurEvent,
1176
- formatationFunc,
1177
- onEscKeyDown,
1178
- onEnterKeyDown,
1179
- margT,
1180
- margB,
1181
- hideComponent,
1182
- disableComponent = false,
1183
- disableSelect = false,
1184
- autoFocusConfig,
1185
- onLoad,
1186
- cacheKey,
1187
- minChars = 0,
1188
- maxItems,
1189
- showListOnFocus = true,
1190
- lazyLoad = false
1191
- }) => {
1192
- const [liItem, setListItem] = useState9([]);
1193
- const [options, setOptions] = useState9([]);
1194
- const [input, setInput] = useState9("");
1195
- const [hide, setHide] = useState9(true);
1196
- const [onLoaded, setOnLoaded] = useState9(false);
1197
- const [loading, setLoading] = useState9(false);
1198
- const cacheStore = useMemo(() => {
1199
- const win = window;
1200
- if (!win.__AUTO_COMPLETE_CACHE__) {
1201
- win.__AUTO_COMPLETE_CACHE__ = /* @__PURE__ */ new Map();
1202
- }
1203
- return win.__AUTO_COMPLETE_CACHE__;
1204
- }, []);
1205
- const sortOptions = (data, key) => {
1206
- if (!key || !Array.isArray(data)) return data;
1207
- return [...data].sort((a, b) => String(a[key]).localeCompare(String(b[key])));
1208
- };
1209
- useEffect4(() => {
1210
- setInput(value || "");
1211
- }, [value]);
1212
- useEffect4(() => {
1213
- const sortedOptions = sortOptions(ops, sortKey);
1214
- setListItem(sortedOptions);
1215
- setOptions(sortedOptions);
1216
- }, [ops, sortKey]);
1217
- useEffect4(() => {
1218
- const loadData = async () => {
1219
- if (!(loadCondition && loadFunc)) return;
1220
- if (lazyLoad && minChars > 0 && !showListOnFocus && (!value || String(value).length < minChars)) {
1221
- return;
1222
- }
1223
- const key = cacheKey ? `${cacheKey}${filter ? `:${filterField}:${filter}` : ""}` : null;
1224
- if (key && cacheStore.has(key)) {
1225
- const cacheEntry = cacheStore.get(key);
1226
- const data = cacheEntry.promise ? await cacheEntry.promise : cacheEntry.data || cacheEntry;
1227
- setListItem(data);
1228
- setOptions(data);
1229
- triggerOnLoad(data);
1230
- return;
1231
- }
1232
- setLoading(true);
1233
- try {
1234
- const requestPromise = loadFunc().then((res) => {
1235
- let newOps = (res == null ? void 0 : res.content) || res;
1236
- newOps = Array.isArray(newOps) ? newOps.filter((op) => op != null) : [];
1237
- if (filter && filterField) {
1238
- newOps = newOps.filter((op) => op[filterField] === filter);
1239
- }
1240
- return sortOptions(newOps, sortKey);
1241
- });
1242
- if (key) cacheStore.set(key, { promise: requestPromise });
1243
- const sortedOptions = await requestPromise;
1244
- setListItem(sortedOptions);
1245
- setOptions(sortedOptions);
1246
- if (key) cacheStore.set(key, { data: sortedOptions });
1247
- triggerOnLoad(sortedOptions);
1248
- } catch (error) {
1249
- if (key) cacheStore.delete(key);
1250
- setListItem([]);
1251
- } finally {
1252
- setLoading(false);
1253
- }
1254
- };
1255
- loadData();
1256
- }, [loadCondition, filter, filterField, sortKey, cacheKey, lazyLoad, minChars, showListOnFocus]);
1257
- const triggerOnLoad = (data) => {
1258
- if (onLoad && !onLoaded) {
1259
- setOnLoaded(true);
1260
- onLoad(data);
1261
- }
1262
- };
1263
- const keysJoinner = (li) => {
1264
- if (!displayKeys || !Array.isArray(displayKeys)) return "";
1265
- return displayKeys.map((key) => `${li[key]} `).join("").trim();
1266
- };
1267
- const getDisplayText = (item) => {
1268
- if (formatationFunc) return formatationFunc(item);
1269
- if (displayKey) return item[displayKey];
1270
- if (displayKeys) return keysJoinner(item);
1271
- return String(item);
1272
- };
1273
- const onFieldUpdate = (val) => {
1274
- const search = val.toLowerCase();
1275
- const canSearch = search.length >= minChars;
1276
- if (canSearch && Array.isArray(options)) {
1277
- const filtered = options.filter((item) => {
1278
- const text = getDisplayText(item);
1279
- return String(text).toLowerCase().includes(search);
1280
- });
1281
- setListItem(filtered);
1282
- } else {
1283
- setListItem(options || []);
1284
- }
1285
- onValueChanged == null ? void 0 : onValueChanged(val);
1286
- setInput(val);
1287
- setHide(!canSearch && options.length === 0);
1288
- };
1289
- return /* @__PURE__ */ jsxs14(
1290
- "div",
1291
- {
1292
- className,
1293
- style: { marginTop: margT != null ? margT : 4, marginBottom: margB != null ? margB : 4, position: "relative" },
1294
- onBlur: (e) => {
1295
- setTimeout(() => {
1296
- onBlurEvent == null ? void 0 : onBlurEvent(e, input);
1297
- setHide(true);
1298
- }, 200);
1299
- },
1300
- onKeyDown: (e) => {
1301
- if (e.key === "Escape") {
1302
- setHide(true);
1303
- onEscKeyDown == null ? void 0 : onEscKeyDown();
1304
- }
1305
- if (e.key === "Enter" && onEnterKeyDown) {
1306
- onEnterKeyDown(input);
1307
- }
1308
- },
1309
- onMouseLeave: () => setHide(true),
1310
- children: [
1311
- !hideComponent && /* @__PURE__ */ jsxs14(InputGroup2, { children: [
1312
- /* @__PURE__ */ jsx19(FloatingLabel, { controlId: "floatingInput", label: title, style: { zIndex: 0, flex: 1 }, children: /* @__PURE__ */ jsx19(
1313
- Form5.Control,
1314
- {
1315
- autoFocus: autoFocusConfig,
1316
- disabled: disableComponent || disableSelect,
1317
- placeholder: placeH,
1318
- autoComplete: "off",
1319
- value: input,
1320
- onClickCapture: () => {
1321
- const canOpen = showListOnFocus && input.length >= minChars;
1322
- setHide(!canOpen);
1323
- },
1324
- onChange: (e) => onFieldUpdate(e.currentTarget.value),
1325
- type: "text"
1326
- }
1327
- ) }),
1328
- loading && /* @__PURE__ */ jsx19(InputGroup2.Text, { children: /* @__PURE__ */ jsx19(Spinner5, { animation: "border", size: "sm" }) }),
1329
- !disableComponent && (actionButton == null ? void 0 : actionButton(() => setInput(""))),
1330
- !disableComponent && (actionButton2 == null ? void 0 : actionButton2(input))
1331
- ] }),
1332
- /* @__PURE__ */ jsx19(
1333
- ListGroup,
1334
- {
1335
- className: "listgroup-autocomplete shadow-sm",
1336
- hidden: hide || liItem.length === 0,
1337
- style: {
1338
- position: "absolute",
1339
- top: "100%",
1340
- left: 0,
1341
- width: "100%",
1342
- maxHeight: "250px",
1343
- overflowY: "auto",
1344
- zIndex: 1050,
1345
- backgroundColor: "#fff"
1346
- },
1347
- children: (maxItems ? liItem.slice(0, maxItems) : liItem).map((li, index) => /* @__PURE__ */ jsx19(
1348
- ListGroup.Item,
1349
- {
1350
- action: true,
1351
- onClick: () => {
1352
- const text = getDisplayText(li);
1353
- setInput(text);
1354
- onSelectedClick(li, index, liItem);
1355
- setHide(true);
1356
- },
1357
- children: getDisplayText(li)
1358
- },
1359
- index
1360
- ))
1361
- }
1362
- )
1363
- ]
1364
- }
1365
- );
1366
- };
1367
-
1368
- // src/forms/GenericForm.tsx
1369
- import { useState as useState10 } from "react";
1370
- import { Button as Button11, Form as Form6 } from "react-bootstrap";
1371
- import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
1372
- var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
1373
- const [formValues, setFormValues] = useState10({});
1374
- const [errors, setErrors] = useState10({});
1375
- const handleChange = (key, value) => {
1376
- setFormValues({
1377
- ...formValues,
1378
- [key]: value
1379
- });
1380
- };
1381
- const validate = () => {
1382
- const newErrors = {};
1383
- fields.forEach((field) => {
1384
- if (field.required && !formValues[field.key]) {
1385
- newErrors[field.key] = `${field.label} \xE9 obrigat\xF3rio`;
1386
- }
1387
- });
1388
- setErrors(newErrors);
1389
- return Object.keys(newErrors).length === 0;
1390
- };
1391
- const handleSubmit = (e) => {
1392
- e.preventDefault();
1393
- if (validate()) {
1394
- onSubmit(formValues);
1395
- }
1396
- };
1397
- const renderField = (field) => {
1398
- const { label, key, type, options, placeholder } = field;
1399
- const value = formValues[key] || "";
1400
- switch (type) {
1401
- case "text":
1402
- case "number":
1403
- return /* @__PURE__ */ jsxs15(Form6.Group, { className: "mb-3", children: [
1404
- /* @__PURE__ */ jsx20(Form6.Label, { children: label }),
1405
- /* @__PURE__ */ jsx20(
1406
- Form6.Control,
1407
- {
1408
- type,
1409
- placeholder,
1410
- value,
1411
- onChange: (e) => handleChange(key, e.target.value),
1412
- isInvalid: !!errors[key]
1413
- }
1414
- ),
1415
- /* @__PURE__ */ jsx20(Form6.Control.Feedback, { type: "invalid", children: errors[key] })
1416
- ] }, key);
1417
- case "select": {
1418
- const orderedOptions = (options || []).filter((opt) => opt && opt.value !== void 0 && opt.label !== void 0).sort((a, b) => a.label.localeCompare(b.label));
1419
- return /* @__PURE__ */ jsxs15(Form6.Group, { className: "mb-3", children: [
1420
- /* @__PURE__ */ jsx20(Form6.Label, { children: label }),
1421
- /* @__PURE__ */ jsxs15(
1422
- Form6.Select,
1423
- {
1424
- value,
1425
- onChange: (e) => handleChange(key, e.target.value),
1426
- isInvalid: !!errors[key],
1427
- children: [
1428
- /* @__PURE__ */ jsx20("option", { value: "", children: "Selecione..." }),
1429
- orderedOptions.map((option) => /* @__PURE__ */ jsx20("option", { value: option.value, children: option.label }, String(option.value)))
1430
- ]
1431
- }
1432
- ),
1433
- /* @__PURE__ */ jsx20(Form6.Control.Feedback, { type: "invalid", children: errors[key] })
1434
- ] }, key);
1435
- }
1436
- case "custom-select":
1437
- if (renderCustomSelect) {
1438
- return /* @__PURE__ */ jsxs15("div", { children: [
1439
- renderCustomSelect({
1440
- label,
1441
- value,
1442
- options,
1443
- onChange: (v) => handleChange(key, v),
1444
- placeholder
1445
- }),
1446
- errors[key] && /* @__PURE__ */ jsx20("div", { className: "invalid-feedback d-block", children: errors[key] })
1447
- ] }, key);
1448
- }
1449
- return null;
1450
- case "date":
1451
- return /* @__PURE__ */ jsxs15(Form6.Group, { className: "mb-3", children: [
1452
- /* @__PURE__ */ jsx20(Form6.Label, { children: label }),
1453
- /* @__PURE__ */ jsx20(
1454
- Form6.Control,
1455
- {
1456
- type: "date",
1457
- value,
1458
- onChange: (e) => handleChange(key, e.target.value),
1459
- isInvalid: !!errors[key]
1460
- }
1461
- ),
1462
- /* @__PURE__ */ jsx20(Form6.Control.Feedback, { type: "invalid", children: errors[key] })
1463
- ] }, key);
1464
- default:
1465
- return null;
1466
- }
1467
- };
1468
- return /* @__PURE__ */ jsxs15(Form6, { onSubmit: handleSubmit, children: [
1469
- fields.map((field) => renderField(field)),
1470
- /* @__PURE__ */ jsx20("div", { className: "d-grid", children: /* @__PURE__ */ jsx20(Button11, { variant: "primary", type: "submit", children: "Salvar" }) })
1471
- ] });
1472
- };
1473
- var GenericForm_default = GenericForm;
1474
-
1475
- // src/forms/GenericSelect.tsx
1476
- import { useEffect as useEffect5, useState as useState11 } from "react";
1477
- import { Form as Form7, InputGroup as InputGroup3 } from "react-bootstrap";
1478
- import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
1479
- var GenericSelectOps = class {
1480
- constructor(noLabel, title, onChange, ops, selection, returnType, displayType, filter, filterField, valueType, loadFunc, loadCondition, actionClick, locked) {
1481
- this.noLabel = noLabel;
1482
- this.title = title;
1483
- this.onChange = onChange;
1484
- this.ops = ops;
1485
- this.selection = selection;
1486
- this.returnType = returnType;
1487
- this.displayType = displayType;
1488
- this.filter = filter;
1489
- this.filterField = filterField;
1490
- this.valueType = valueType;
1491
- this.loadFunc = loadFunc;
1492
- this.loadCondition = loadCondition;
1493
- this.actionClick = actionClick;
1494
- this.locked = locked;
1495
- }
1496
- };
1497
- var GenericSelect = ({
1498
- noLabel,
1499
- title,
1500
- onChange,
1501
- ops,
1502
- selection,
1503
- returnType,
1504
- displayType,
1505
- filter,
1506
- filterField,
1507
- valueType,
1508
- loadFunc,
1509
- loadCondition = true,
1510
- actionClick,
1511
- locked,
1512
- isBold,
1513
- ...restProps
1514
- }) => {
1515
- const [options, setOptions] = useState11(ops || []);
1516
- useEffect5(() => {
1517
- const loadFunction = async () => {
1518
- if (loadCondition && loadFunc) {
1519
- loadFunc().then((res) => {
1520
- let newOps = res.content ? res.content : res;
1521
- if (filter && filterField) {
1522
- newOps = res.filter((op) => op[filterField] == filter);
1523
- }
1524
- setOptions(newOps);
1525
- });
1526
- }
1527
- };
1528
- loadFunction().catch((error) => console.log(error));
1529
- }, [loadCondition]);
1530
- const getTrueValue = (clickedIndex) => {
1531
- const returnValue = options.filter((_op, index) => index == clickedIndex - 1)[0];
1532
- if (returnType == "index") {
1533
- onChange(clickedIndex);
1534
- } else if (returnType) {
1535
- onChange(returnValue[returnType]);
1536
- } else {
1537
- onChange(returnValue);
1538
- }
1539
- };
1540
- const defaultPlaceholder = (restProps == null ? void 0 : restProps.default) || "Seleciona uma Op\xE7\xE3o";
1541
- const selectContent = /* @__PURE__ */ jsxs16(
1542
- Form7.Control,
1543
- {
1544
- disabled: locked,
1545
- as: "select",
1546
- value: selection,
1547
- onChange: (event) => getTrueValue(event.target.selectedIndex),
1548
- children: [
1549
- /* @__PURE__ */ jsxs16("option", { value: void 0, children: [
1550
- "-- ",
1551
- defaultPlaceholder,
1552
- " --"
1553
- ] }, 0),
1554
- (options == null ? void 0 : options.length) > 0 && options.map((op, index) => {
1555
- const val = valueType && op[valueType] || op.id || op;
1556
- let fill = displayType && op[displayType] || op;
1557
- if (typeof fill == "object") fill = "";
1558
- return /* @__PURE__ */ jsx21("option", { value: val, children: fill }, op.id || index);
1559
- })
1560
- ]
1561
- }
1562
- );
1563
- if (actionClick) {
1564
- return /* @__PURE__ */ jsxs16(Fragment7, { children: [
1565
- /* @__PURE__ */ jsx21(Form7.Label, { style: { fontWeight: isBold ? "bold" : void 0 }, hidden: noLabel, children: title }),
1566
- /* @__PURE__ */ jsxs16(InputGroup3, { children: [
1567
- selectContent,
1568
- actionClick()
1569
- ] })
1570
- ] });
1571
- }
1572
- return /* @__PURE__ */ jsxs16(Fragment7, { children: [
1573
- /* @__PURE__ */ jsx21(Form7.Label, { style: { fontWeight: isBold ? "bold" : void 0 }, hidden: noLabel, children: title }),
1574
- selectContent
1575
- ] });
1576
- };
1577
- var GenericSelect_default = GenericSelect;
1578
-
1579
- // src/forms/FormField.tsx
1580
- import { FloatingLabel as FloatingLabel2, Form as Form8, InputGroup as InputGroup4 } from "react-bootstrap";
1581
- import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
1582
- var FormField = ({
1583
- val,
1584
- onValueUpdate,
1585
- onBlur,
1586
- label,
1587
- ty,
1588
- actionClick,
1589
- actionClick2,
1590
- reference,
1591
- others,
1592
- styleObj,
1593
- locked,
1594
- hide,
1595
- onMouseLv,
1596
- onEnterPress,
1597
- className,
1598
- isInvalid,
1599
- feedback,
1600
- onFocus,
1601
- rows,
1602
- asTextArea,
1603
- controlId
1604
- }) => {
1605
- const onKeyDownHandler = (event) => {
1606
- if (event.code === "Enter" || event.key === "Enter") {
1607
- onEnterPress && onEnterPress(event.target.value);
1608
- }
1609
- };
1610
- const onFocusHandler = (value) => {
1611
- onFocus && onFocus(value);
1612
- };
1613
- const renderField = () => {
1614
- const fieldProps = {
1615
- autoComplete: "off",
1616
- isInvalid,
1617
- className,
1618
- ...others,
1619
- onBlur: (event) => onBlur && onBlur(event.target.value, event),
1620
- disabled: locked,
1621
- style: styleObj,
1622
- ref: reference,
1623
- placeholder: (others == null ? void 0 : others.placeholder) || label,
1624
- type: ty || "text",
1625
- value: val != null ? val : "",
1626
- onChange: (event) => onValueUpdate && onValueUpdate(event.target.value, event)
1627
- };
1628
- if (asTextArea) {
1629
- fieldProps.as = "textarea";
1630
- fieldProps.rows = rows || 3;
1631
- }
1632
- return /* @__PURE__ */ jsx22(Form8.Control, { ...fieldProps });
1633
- };
1634
- if (hide) return null;
1635
- return /* @__PURE__ */ jsxs17(
1636
- Form8.Group,
1637
- {
1638
- onFocusCapture: (e) => onFocusHandler(e.target.value),
1639
- onMouseLeave: onMouseLv,
1640
- onKeyDown: onKeyDownHandler,
1641
- style: { marginTop: 4, marginBottom: 4, width: "100%" },
1642
- children: [
1643
- /* @__PURE__ */ jsxs17(InputGroup4, { children: [
1644
- asTextArea ? renderField() : /* @__PURE__ */ jsx22(FloatingLabel2, { style: { zIndex: 0, flex: 1 }, label, controlId: controlId || "floatingInput", children: renderField() }),
1645
- actionClick && actionClick(),
1646
- actionClick2 && actionClick2()
1647
- ] }),
1648
- feedback && isInvalid && /* @__PURE__ */ jsx22(Form8.Control.Feedback, { type: "invalid", style: { display: "block" }, children: feedback })
1649
- ]
1650
- }
1651
- );
1652
- };
1653
-
1654
- // src/forms/ClickToWriteField.tsx
1655
- import { useState as useState12, useEffect as useEffect6, useRef as useRef4 } from "react";
1656
- import { Button as Button12 } from "react-bootstrap";
1657
- import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
1658
- var ClickToWriteField = ({
1659
- buttonDisplay,
1660
- fieldType = "text",
1661
- fieldLabel = "",
1662
- buttonProps,
1663
- fieldProps,
1664
- onFieldValueUpdate,
1665
- enableFieldActionButton = false,
1666
- fieldActionButtonIcon,
1667
- fieldActionButtonProps,
1668
- fieldActionButtonCallback = () => {
1669
- },
1670
- onEnterPress,
1671
- cleanRef
1672
- }) => {
1673
- const [showClick, setShowClick] = useState12(false);
1674
- const inputRef = useRef4(null);
1675
- useEffect6(() => {
1676
- if (showClick) {
1677
- setTimeout(() => {
1678
- if (inputRef.current) {
1679
- inputRef.current.focus();
1680
- cleanRef && cleanRef(inputRef);
1681
- }
1682
- }, 100);
1683
- }
1684
- }, [showClick, cleanRef]);
1685
- const handleShowClick = () => {
1686
- setShowClick(!showClick);
1687
- };
1688
- const resolveButtonDisplay = () => {
1689
- if (typeof buttonDisplay === "function") return buttonDisplay();
1690
- return buttonDisplay;
1691
- };
1692
- const renderFieldActionButtonIcon = () => {
1693
- if (fieldActionButtonIcon) return fieldActionButtonIcon();
1694
- return "OK";
1695
- };
1696
- const closeOnEscape = (e) => {
1697
- if (e.key === "Escape") {
1698
- setShowClick(false);
1699
- }
1700
- if (e.key === "Enter" && onEnterPress) {
1701
- onEnterPress(inputRef);
1702
- }
1703
- };
1704
- return /* @__PURE__ */ jsxs18("div", { style: { display: "flex", width: "100%", margin: 0, padding: 0 }, children: [
1705
- !showClick && /* @__PURE__ */ jsx23(
1706
- Button12,
1707
- {
1708
- style: { flexGrow: 1 },
1709
- onClick: handleShowClick,
1710
- ...buttonProps,
1711
- children: resolveButtonDisplay()
1712
- }
1713
- ),
1714
- showClick && /* @__PURE__ */ jsx23(
1715
- FormField,
1716
- {
1717
- reference: inputRef,
1718
- others: { ...fieldProps, onKeyUp: closeOnEscape },
1719
- hide: !showClick,
1720
- ty: fieldType,
1721
- label: fieldLabel,
1722
- onValueUpdate: onFieldValueUpdate,
1723
- onBlur: () => setShowClick(false),
1724
- actionClick: () => enableFieldActionButton ? /* @__PURE__ */ jsx23(
1725
- Button12,
1726
- {
1727
- ...fieldActionButtonProps,
1728
- onClick: () => fieldActionButtonCallback(inputRef),
1729
- children: renderFieldActionButtonIcon()
1730
- }
1731
- ) : null
1732
- }
1733
- )
1734
- ] });
1735
- };
1736
-
1737
- // src/forms/ColorPicker.tsx
1738
- import { Card as Card2, Form as Form9, Row as Row3, Col as Col3 } from "react-bootstrap";
1739
- import { FaPalette } from "react-icons/fa";
1740
- import { jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
1741
- var ColorPicker = ({
1742
- selectedColor,
1743
- onColorChange,
1744
- presetColors = ["#ff0000", "#ffd700", "#008000", "#0000ff", "#800080"],
1745
- title = "Cor de Identifica\xE7\xE3o"
1746
- }) => {
1747
- return /* @__PURE__ */ jsxs19(
1748
- Card2,
1749
- {
1750
- className: "shadow-sm border-primary-hover mb-3",
1751
- style: { maxWidth: "320px", transition: "0.3s" },
1752
- children: [
1753
- /* @__PURE__ */ jsxs19(Card2.Header, { className: "bg-light d-flex align-items-center", children: [
1754
- /* @__PURE__ */ jsx24(FaPalette, { className: "me-2 text-primary" }),
1755
- /* @__PURE__ */ jsx24("span", { className: "fw-medium", children: title })
1756
- ] }),
1757
- /* @__PURE__ */ jsxs19(Card2.Body, { children: [
1758
- /* @__PURE__ */ jsxs19(Row3, { className: "g-3 align-items-center mb-3", children: [
1759
- /* @__PURE__ */ jsx24(Col3, { xs: "auto", children: /* @__PURE__ */ jsx24(
1760
- "div",
1761
- {
1762
- className: "rounded-circle shadow-sm border",
1763
- style: {
1764
- width: "40px",
1765
- height: "40px",
1766
- backgroundColor: selectedColor,
1767
- cursor: "pointer",
1768
- border: "2px solid #dee2e6"
1769
- },
1770
- onClick: () => {
1771
- const el = document.getElementById("color-input-hidden");
1772
- if (el) el.click();
1773
- },
1774
- title: "Clique para abrir o seletor"
1775
- }
1776
- ) }),
1777
- /* @__PURE__ */ jsx24(Col3, { children: /* @__PURE__ */ jsx24(
1778
- Form9.Control,
1779
- {
1780
- type: "color",
1781
- id: "color-input-hidden",
1782
- value: selectedColor,
1783
- onChange: (e) => onColorChange(e.target.value),
1784
- className: "form-control-color-lg",
1785
- style: { width: "100%", height: "40px", cursor: "pointer" }
1786
- }
1787
- ) })
1788
- ] }),
1789
- /* @__PURE__ */ jsx24(Row3, { className: "g-2 justify-content-start", children: presetColors.map((cor) => /* @__PURE__ */ jsx24(Col3, { xs: "auto", children: /* @__PURE__ */ jsx24(
1790
- "div",
1791
- {
1792
- className: "rounded-1 shadow-sm",
1793
- style: {
1794
- width: "28px",
1795
- height: "28px",
1796
- backgroundColor: cor,
1797
- cursor: "pointer",
1798
- border: cor.toLowerCase() === selectedColor.toLowerCase() ? "2px solid #0d6efd" : "1px solid #dee2e6"
1799
- },
1800
- onClick: () => onColorChange(cor)
1801
- }
1802
- ) }, cor)) })
1803
- ] })
1804
- ]
1805
- }
1806
- );
1807
- };
1808
-
1809
- // src/forms/Switch.tsx
1810
- import { Form as Form10 } from "react-bootstrap";
1811
- import { jsx as jsx25 } from "react/jsx-runtime";
1812
- var Switch = ({
1813
- label,
1814
- onSwitchChange,
1815
- value,
1816
- disabled = false,
1817
- defaultChecked,
1818
- ...props
1819
- }) => {
1820
- return /* @__PURE__ */ jsx25(
1821
- Form10.Check,
1822
- {
1823
- ...props,
1824
- disabled,
1825
- type: "switch",
1826
- label,
1827
- checked: value,
1828
- defaultChecked,
1829
- onChange: (event) => onSwitchChange && onSwitchChange(event.target.checked)
1830
- }
1831
- );
1832
- };
1833
-
1834
- // src/forms/UploadArea.tsx
1835
- import { useCallback } from "react";
1836
- import { useDropzone } from "react-dropzone";
1837
- import { FiUploadCloud, FiCheckCircle } from "react-icons/fi";
1838
- import { Fragment as Fragment8, jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
1839
- var UploadArea = ({
1840
- onFilePut,
1841
- anexo,
1842
- accept = { "image/jpeg": [], "image/png": [] },
1843
- maxSize = 50 * 1024 * 1024
1844
- }) => {
1845
- const onDrop = useCallback(
1846
- (acceptedFiles) => {
1847
- const file = acceptedFiles[0];
1848
- if (file && typeof onFilePut === "function") {
1849
- onFilePut(file);
1850
- }
1851
- },
1852
- [onFilePut]
1853
- );
1854
- const { getRootProps, getInputProps, isDragActive } = useDropzone({
1855
- onDrop,
1856
- maxSize,
1857
- accept
1858
- });
1859
- const hasAnexo = Boolean(anexo);
1860
- return /* @__PURE__ */ jsxs20(
1861
- "div",
1862
- {
1863
- ...getRootProps(),
1864
- className: `upload-area
1865
- ${isDragActive ? "drag-active" : ""}
1866
- ${hasAnexo ? "upload-has-file" : ""}
1867
- `,
1868
- children: [
1869
- /* @__PURE__ */ jsx26("input", { ...getInputProps() }),
1870
- /* @__PURE__ */ jsxs20("div", { className: "upload-content", children: [
1871
- /* @__PURE__ */ jsx26("span", { className: "upload-icon", children: hasAnexo ? /* @__PURE__ */ jsx26(FiCheckCircle, { size: 24 }) : /* @__PURE__ */ jsx26(FiUploadCloud, { size: 24 }) }),
1872
- hasAnexo ? /* @__PURE__ */ jsxs20(Fragment8, { children: [
1873
- /* @__PURE__ */ jsx26("p", { className: "upload-link", children: "Arquivo anexado" }),
1874
- /* @__PURE__ */ jsx26("p", { className: "upload-info", children: anexo == null ? void 0 : anexo.name })
1875
- ] }) : /* @__PURE__ */ jsxs20(Fragment8, { children: [
1876
- /* @__PURE__ */ jsxs20("p", { children: [
1877
- /* @__PURE__ */ jsx26("span", { className: "upload-link", children: "Adicione" }),
1878
- " ou arraste arquivos aqui"
1879
- ] }),
1880
- /* @__PURE__ */ jsxs20("p", { className: "upload-info", children: [
1881
- "Formatos aceitos: ",
1882
- /* @__PURE__ */ jsx26("b", { children: Object.keys(accept).map((t) => t.split("/")[1].toUpperCase()).join(", ") }),
1883
- " | Tamanho m\xE1ximo:",
1884
- " ",
1885
- /* @__PURE__ */ jsxs20("b", { children: [
1886
- (maxSize / (1024 * 1024)).toFixed(0),
1887
- "MB"
1888
- ] })
1889
- ] })
1890
- ] })
1891
- ] })
1892
- ]
1893
- }
1894
- );
1895
- };
1896
-
1897
- // src/forms/FindRecursoByTagField.tsx
1898
- import { useState as useState15 } from "react";
1899
- import { GrCheckmark as GrCheckmark2 } from "react-icons/gr";
1900
-
1901
- // src/qr/QrCodeScanButton.tsx
1902
- import { useState as useState14 } from "react";
1903
- import { BsQrCode } from "react-icons/bs";
1904
-
1905
- // src/qr/QrReader.tsx
1906
- import QrScanner from "qr-scanner";
1907
- import { useEffect as useEffect7, useRef as useRef5, useState as useState13 } from "react";
1908
- import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
1909
- var QrReader = ({ callback }) => {
1910
- const scanner = useRef5(null);
1911
- const videoEl = useRef5(null);
1912
- const qrBoxEl = useRef5(null);
1913
- const [qrOn, setQrOn] = useState13(true);
1914
- const [scannedResult, setScannedResult] = useState13("");
1915
- const onScanSuccess = (result) => {
1916
- setScannedResult(result.data);
1917
- callback(result.data);
1918
- };
1919
- const onScanFail = (err) => {
1920
- if (typeof err === "string" && !err.includes("No QR code found")) {
1921
- console.error("QR Scanner Error:", err);
1922
- }
1923
- };
1924
- useEffect7(() => {
1925
- if (videoEl.current && !scanner.current) {
1926
- scanner.current = new QrScanner(videoEl.current, onScanSuccess, {
1927
- onDecodeError: onScanFail,
1928
- preferredCamera: "environment",
1929
- highlightScanRegion: true,
1930
- highlightCodeOutline: true,
1931
- overlay: qrBoxEl.current || void 0
1932
- });
1933
- scanner.current.start().then(() => setQrOn(true)).catch((err) => {
1934
- console.error("Failed to start QR Scanner:", err);
1935
- setQrOn(false);
1936
- });
1937
- }
1938
- return () => {
1939
- if (scanner.current) {
1940
- scanner.current.stop();
1941
- scanner.current.destroy();
1942
- scanner.current = null;
1943
- }
1944
- };
1945
- }, []);
1946
- useEffect7(() => {
1947
- if (!qrOn) {
1948
- alert(
1949
- "C\xE2mera est\xE1 bloqueada ou inacess\xEDvel. Por favor, habilite a c\xE2mera nas permiss\xF5es do seu navegador e recarregue a p\xE1gina."
1950
- );
1951
- }
1952
- }, [qrOn]);
1953
- return /* @__PURE__ */ jsxs21("div", { className: "qr-reader", style: { position: "relative", width: "100%", maxWidth: "500px", margin: "0 auto" }, children: [
1954
- /* @__PURE__ */ jsx27("video", { ref: videoEl, style: { width: "100%", borderRadius: "8px" } }),
1955
- /* @__PURE__ */ jsx27("div", { ref: qrBoxEl, className: "qr-box" }),
1956
- scannedResult && /* @__PURE__ */ jsxs21(
1957
- "div",
1958
- {
1959
- style: {
1960
- position: "absolute",
1961
- top: 10,
1962
- left: 10,
1963
- zIndex: 10,
1964
- background: "rgba(0,0,0,0.6)",
1965
- color: "white",
1966
- padding: "4px 8px",
1967
- borderRadius: "4px",
1968
- fontSize: "0.8rem"
1969
- },
1970
- children: [
1971
- "Lido: ",
1972
- scannedResult
1973
- ]
1974
- }
1975
- )
1976
- ] });
1977
- };
1978
-
1979
- // src/qr/QrCodeScanButton.tsx
1980
- import { jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
1981
- var QrCodeScanButton = ({ callback, size = 25 }) => {
1982
- const [showQr, setShowQr] = useState14(false);
1983
- const toggleQr = () => {
1984
- setShowQr((prev) => !prev);
1985
- };
1986
- return /* @__PURE__ */ jsxs22(
1987
- "div",
1988
- {
1989
- className: "hoverable-div",
1990
- style: {
1991
- border: "solid",
1992
- borderTopRightRadius: "3px",
1993
- borderBottomRightRadius: "3px",
1994
- padding: "8px",
1995
- borderLeft: "none",
1996
- borderColor: "#ccc",
1997
- borderWidth: "1px",
1998
- cursor: "pointer",
1999
- display: "flex",
2000
- alignItems: "center"
2001
- },
2002
- onClick: toggleQr,
2003
- children: [
2004
- /* @__PURE__ */ jsx28(BsQrCode, { size }),
2005
- showQr && /* @__PURE__ */ jsx28(
2006
- "div",
2007
- {
2008
- style: {
2009
- position: "fixed",
2010
- top: 0,
2011
- left: 0,
2012
- right: 0,
2013
- bottom: 0,
2014
- backgroundColor: "rgba(0,0,0,0.8)",
2015
- zIndex: 9999,
2016
- display: "flex",
2017
- flexDirection: "column",
2018
- alignItems: "center",
2019
- justifyContent: "center",
2020
- padding: "20px"
2021
- },
2022
- onClick: (e) => e.stopPropagation(),
2023
- children: /* @__PURE__ */ jsxs22("div", { style: { width: "100%", maxWidth: "500px", backgroundColor: "#fff", borderRadius: "12px", padding: "20px", position: "relative" }, children: [
2024
- /* @__PURE__ */ jsx28(
2025
- "div",
2026
- {
2027
- onClick: toggleQr,
2028
- style: { position: "absolute", top: "10px", right: "15px", fontSize: "1.5rem", cursor: "pointer", zIndex: 10001 },
2029
- children: "\xD7"
2030
- }
2031
- ),
2032
- /* @__PURE__ */ jsx28("h5", { className: "mb-3 text-center", children: "Escaneie o QR Code" }),
2033
- /* @__PURE__ */ jsx28(
2034
- QrReader,
2035
- {
2036
- callback: (v) => {
2037
- toggleQr();
2038
- callback(v);
2039
- }
2040
- }
2041
- ),
2042
- /* @__PURE__ */ jsx28("p", { className: "mt-3 text-muted text-center small", children: "Aponte a c\xE2mera para o c\xF3digo" })
2043
- ] })
2044
- }
2045
- )
2046
- ]
2047
- }
2048
- );
2049
- };
2050
-
2051
- // src/forms/FindRecursoByTagField.tsx
2052
- import { jsx as jsx29 } from "react/jsx-runtime";
2053
- var FindRecursoByTagField = ({ callback, recursoController }) => {
2054
- const [selectedTag, setSelectedTag] = useState15("");
2055
- const [reachedRecurso, setReachedRecurso] = useState15(null);
2056
- const findRecursoByTagIdHandler = async (tagId) => {
2057
- try {
2058
- const r = await recursoController.read("findRecursoByTagId", tagId);
2059
- setReachedRecurso(r);
2060
- } catch (error) {
2061
- console.error("Erro ao buscar recurso por tag ID:", error);
2062
- }
2063
- };
2064
- const findRecursoByTagDescriptionHandler = async (description) => {
2065
- try {
2066
- const formattedDescription = description.replace(/\s/g, "");
2067
- const recurso = await recursoController.read(
2068
- `recurso/findByTagDescription`,
2069
- formattedDescription
2070
- );
2071
- if (!callback) {
2072
- console.log("Recurso encontrado (sem callback):", recurso);
2073
- } else {
2074
- callback(recurso, true);
2075
- }
2076
- } catch (error) {
2077
- console.error("Erro ao buscar recurso por descri\xE7\xE3o de tag:", error);
2078
- }
2079
- };
2080
- const confirmRecursoSelectionButton = () => {
2081
- return /* @__PURE__ */ jsx29(
2082
- "div",
2083
- {
2084
- className: "hoverable-div",
2085
- style: {
2086
- border: "solid",
2087
- borderTopRightRadius: "3px",
2088
- borderBottomRightRadius: "3px",
2089
- padding: "8px",
2090
- borderLeft: "none",
2091
- borderColor: "#ccc",
2092
- borderWidth: "1px",
2093
- cursor: "pointer",
2094
- display: "flex",
2095
- alignItems: "center"
2096
- },
2097
- children: /* @__PURE__ */ jsx29(
2098
- GrCheckmark2,
2099
- {
2100
- size: 25,
2101
- onClick: () => reachedRecurso && callback(reachedRecurso, true)
2102
- }
2103
- )
2104
- }
2105
- );
2106
- };
2107
- return /* @__PURE__ */ jsx29("div", { children: /* @__PURE__ */ jsx29(
2108
- AutoComplete,
2109
- {
2110
- sortKey: "id",
2111
- loadCondition: true,
2112
- loadFunc: () => recursoController.get("findActiveRecursosTags"),
2113
- displayKey: "descricao",
2114
- title: "Selecione ou Digite a TAG",
2115
- isBold: true,
2116
- actionButton: confirmRecursoSelectionButton,
2117
- actionButton2: () => /* @__PURE__ */ jsx29(
2118
- QrCodeScanButton,
2119
- {
2120
- callback: (description) => findRecursoByTagDescriptionHandler(description)
2121
- }
2122
- ),
2123
- onSelectedClick: (v) => {
2124
- setSelectedTag(v);
2125
- findRecursoByTagIdHandler(v.id);
2126
- },
2127
- value: (selectedTag == null ? void 0 : selectedTag.descricao) || ""
2128
- }
2129
- ) });
2130
- };
2131
-
2132
- // src/icons/IconLabelItem.tsx
2133
- import { jsx as jsx30, jsxs as jsxs23 } from "react/jsx-runtime";
2134
- var IconLabelItem = ({
2135
- icon,
2136
- label,
2137
- containerClassName = "",
2138
- labelClassName = "",
2139
- onClick,
2140
- style
2141
- }) => {
2142
- return /* @__PURE__ */ jsxs23("div", { className: containerClassName, onClick, style: { ...style, cursor: onClick ? "pointer" : "default" }, children: [
2143
- icon,
2144
- /* @__PURE__ */ jsx30("span", { className: labelClassName, children: label })
2145
- ] });
2146
- };
2147
-
2148
- // src/icons/IconLabelList.tsx
2149
- import { jsx as jsx31 } from "react/jsx-runtime";
2150
- var IconLabelList = ({ items, className = "" }) => {
2151
- return /* @__PURE__ */ jsx31("div", { className: `icon-label-list ${className}`, children: items.map((item, index) => /* @__PURE__ */ jsx31(
2152
- IconLabelItem,
2153
- {
2154
- labelClassName: "icon-label",
2155
- containerClassName: "icon-label-item",
2156
- icon: item.icon,
2157
- label: item.label,
2158
- onClick: item.onClick
2159
- },
2160
- index
2161
- )) });
2162
- };
2163
- export {
2164
- ActionButtons,
2165
- AddButton_default as AddButton,
2166
- ApproveAndReproveButtons,
2167
- AsyncButton,
2168
- AutoComplete,
2169
- ClickToWriteField,
2170
- ColorPicker,
2171
- ConfigObject,
2172
- DeleteButton_default as DeleteButton,
2173
- DeleteConfirm,
2174
- FindRecursoByTagField,
2175
- FormField,
2176
- Generic3DotMenu,
2177
- GenericDisplay_default as GenericDisplay,
2178
- GenericForm_default as GenericForm,
2179
- GenericSelect_default as GenericSelect,
2180
- GenericSelectOps,
2181
- IconLabelItem,
2182
- IconLabelList,
2183
- LoadingButton,
2184
- LoadingProgress,
2185
- MailSender,
2186
- MenuEvent,
2187
- NavigateButton,
2188
- QrCodeScanButton,
2189
- QrReader,
2190
- ResponsiveContainer_default as ResponsiveContainer,
2191
- StatusBadge,
2192
- StatusIndicator,
2193
- Switch,
2194
- SwitchOnClick,
2195
- UploadArea,
2196
- UuidPill_default as UuidPill,
2197
- VerticalItemsDisplay
2198
- };