@zauru-sdk/components 1.0.13 → 1.0.15

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 (94) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/Chat/ChatLayout.d.ts +17 -0
  3. package/dist/Chat/ChatLayout.js +28 -0
  4. package/dist/Chat/ChatMessageHistory.d.ts +12 -0
  5. package/dist/Chat/ChatMessageHistory.js +53 -0
  6. package/dist/Chat/index.d.ts +2 -0
  7. package/dist/Chat/index.js +2 -0
  8. package/dist/ConnectionState/ConnectionState.d.ts +2 -0
  9. package/dist/ConnectionState/ConnectionState.js +22 -0
  10. package/dist/ConnectionState/index.d.ts +1 -0
  11. package/dist/ConnectionState/index.js +1 -0
  12. package/dist/DynamicTable/BasicPrintDynamicTable.d.ts +10 -0
  13. package/dist/DynamicTable/BasicPrintDynamicTable.js +27 -0
  14. package/dist/DynamicTable/DynamicPrintTable.d.ts +23 -0
  15. package/dist/DynamicTable/DynamicPrintTable.js +132 -0
  16. package/dist/DynamicTable/GenericDynamicTable.d.ts +21 -0
  17. package/dist/DynamicTable/GenericDynamicTable.js +195 -0
  18. package/dist/DynamicTable/index.d.ts +24 -0
  19. package/dist/DynamicTable/index.js +193 -0
  20. package/dist/Footer/Footer.js +2 -2
  21. package/dist/Form/Checkbox/index.d.ts +17 -0
  22. package/dist/Form/Checkbox/index.js +34 -0
  23. package/dist/Form/Checklist/index.d.ts +14 -0
  24. package/dist/Form/Checklist/index.js +10 -0
  25. package/dist/Form/DatePicker/index.d.ts +18 -0
  26. package/dist/Form/DatePicker/index.js +31 -0
  27. package/dist/Form/DynamicBaculoForm/index.d.ts +18 -0
  28. package/dist/Form/DynamicBaculoForm/index.js +138 -0
  29. package/dist/Form/FieldContainer/DoubleFieldContainer.d.ts +8 -0
  30. package/dist/Form/FieldContainer/DoubleFieldContainer.js +14 -0
  31. package/dist/Form/FieldContainer/QuadrupleFieldContainer.d.ts +7 -0
  32. package/dist/Form/FieldContainer/QuadrupleFieldContainer.js +14 -0
  33. package/dist/Form/FieldContainer/TripleFieldContainer.d.ts +7 -0
  34. package/dist/Form/FieldContainer/TripleFieldContainer.js +14 -0
  35. package/dist/Form/FieldContainer/index.d.ts +3 -0
  36. package/dist/Form/FieldContainer/index.js +3 -0
  37. package/dist/Form/FileUpload/index.d.ts +21 -0
  38. package/dist/Form/FileUpload/index.js +54 -0
  39. package/dist/Form/FormButtons/index.d.ts +16 -0
  40. package/dist/Form/FormButtons/index.js +5 -0
  41. package/dist/Form/FormLayout/index.d.ts +11 -0
  42. package/dist/Form/FormLayout/index.js +7 -0
  43. package/dist/Form/SelectField/index.d.ts +27 -0
  44. package/dist/Form/SelectField/index.js +74 -0
  45. package/dist/Form/TextArea/index.d.ts +23 -0
  46. package/dist/Form/TextArea/index.js +36 -0
  47. package/dist/Form/TextField/index.d.ts +25 -0
  48. package/dist/Form/TextField/index.js +70 -0
  49. package/dist/Form/TimePicker/index.d.ts +16 -0
  50. package/dist/Form/TimePicker/index.js +31 -0
  51. package/dist/Form/YesNo/index.d.ts +12 -0
  52. package/dist/Form/YesNo/index.js +19 -0
  53. package/dist/Form/index.d.ts +13 -0
  54. package/dist/Form/index.js +13 -0
  55. package/dist/Zendesk/Chat.d.ts +14 -0
  56. package/dist/Zendesk/Chat.js +64 -0
  57. package/dist/Zendesk/index.d.ts +2 -0
  58. package/dist/Zendesk/index.js +2 -0
  59. package/dist/Zendesk/zendesk.config.d.ts +9 -0
  60. package/dist/Zendesk/zendesk.config.js +24 -0
  61. package/dist/index.d.ts +4 -0
  62. package/dist/index.js +4 -2
  63. package/package.json +6 -6
  64. package/src/Chat/ChatLayout.tsx +133 -0
  65. package/src/Chat/ChatMessageHistory.tsx +142 -0
  66. package/src/Chat/index.ts +2 -0
  67. package/src/ConnectionState/ConnectionState.tsx +29 -0
  68. package/src/ConnectionState/index.tsx +1 -0
  69. package/src/DynamicTable/BasicPrintDynamicTable.tsx +73 -0
  70. package/src/DynamicTable/DynamicPrintTable.tsx +290 -0
  71. package/src/DynamicTable/GenericDynamicTable.tsx +455 -0
  72. package/src/DynamicTable/index.tsx +407 -0
  73. package/src/Footer/Footer.tsx +3 -3
  74. package/src/Form/Checkbox/index.tsx +96 -0
  75. package/src/Form/Checklist/index.tsx +35 -0
  76. package/src/Form/DatePicker/index.tsx +132 -0
  77. package/src/Form/DynamicBaculoForm/index.tsx +359 -0
  78. package/src/Form/FieldContainer/DoubleFieldContainer.tsx +35 -0
  79. package/src/Form/FieldContainer/QuadrupleFieldContainer.tsx +36 -0
  80. package/src/Form/FieldContainer/TripleFieldContainer.tsx +35 -0
  81. package/src/Form/FieldContainer/index.ts +3 -0
  82. package/src/Form/FileUpload/index.tsx +184 -0
  83. package/src/Form/FormButtons/index.tsx +78 -0
  84. package/src/Form/FormLayout/index.tsx +37 -0
  85. package/src/Form/SelectField/index.tsx +237 -0
  86. package/src/Form/TextArea/index.tsx +125 -0
  87. package/src/Form/TextField/index.tsx +194 -0
  88. package/src/Form/TimePicker/index.tsx +127 -0
  89. package/src/Form/YesNo/index.tsx +79 -0
  90. package/src/Form/index.ts +13 -0
  91. package/src/Zendesk/Chat.tsx +85 -0
  92. package/src/Zendesk/index.ts +2 -0
  93. package/src/Zendesk/zendesk.config.ts +40 -0
  94. package/src/index.ts +4 -2
package/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.0.15](https://github.com/intuitiva/zauru-typescript-sdk/compare/v1.0.14...v1.0.15) (2024-03-21)
7
+
8
+ **Note:** Version bump only for package @zauru-sdk/components
9
+
10
+
11
+
12
+
13
+
14
+ ## [1.0.14](https://github.com/intuitiva/zauru-typescript-sdk/compare/v1.0.13...v1.0.14) (2024-03-21)
15
+
16
+ **Note:** Version bump only for package @zauru-sdk/components
17
+
18
+
19
+
20
+
21
+
6
22
  ## [1.0.13](https://github.com/intuitiva/zauru-typescript-sdk/compare/v1.0.12...v1.0.13) (2024-03-21)
7
23
 
8
24
  **Note:** Version bump only for package @zauru-sdk/components
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import { FormDocumentType } from "@zauru-sdk/types";
3
+ interface ChatLayoutProps {
4
+ children?: React.ReactNode;
5
+ sendingMessage?: boolean;
6
+ formConfig?: {
7
+ document_type: FormDocumentType;
8
+ form_id: number;
9
+ document_id: number;
10
+ id_number?: string;
11
+ reference?: string;
12
+ attachmentFieldId: number;
13
+ messageFieldId: number;
14
+ };
15
+ }
16
+ declare const ChatLayout: React.FC<ChatLayoutProps>;
17
+ export default ChatLayout;
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useRef, useState } from "react";
3
+ import { TextField } from "../Form";
4
+ import { Form } from "@remix-run/react";
5
+ import { LoadingInputSkeleton } from "src";
6
+ import { AttachmentIconSVG, SendMessageIcon, SpinnerSvg, } from "@zauru-sdk/icons";
7
+ const ChatLayout = ({ children, sendingMessage = false, formConfig = undefined, }) => {
8
+ const refAttachment = useRef(null);
9
+ const [formValues, setFormValues] = useState({ image: null });
10
+ const handleAttachmentClick = () => {
11
+ if (refAttachment.current) {
12
+ refAttachment.current.click();
13
+ }
14
+ };
15
+ return (_jsxs("div", { className: "flex flex-col h-full", children: [_jsx("div", { className: "flex flex-col-reverse overflow-y-auto p-4 bg-gray-100 border border-gray-200 rounded-lg grow max-h-[65vh]", children: children }), _jsxs(Form, { id: "formRef", encType: "multipart/form-data", method: "post", children: [formConfig ? (_jsxs(_Fragment, { children: [_jsx(TextField, { hidden: true, name: "reference", defaultValue: formConfig.reference ?? "" }), _jsx(TextField, { hidden: true, name: "form_id", defaultValue: formConfig.form_id }), _jsx(TextField, { hidden: true, name: "document_id", defaultValue: formConfig.document_id }), _jsx(TextField, { hidden: true, name: "document_type", defaultValue: formConfig.document_type }), _jsx(TextField, { hidden: true, name: "id_number", defaultValue: formConfig?.id_number ?? "" })] })) : (_jsx(_Fragment, {})), _jsxs("div", { className: "mt-4 flex", children: [sendingMessage ? (_jsx(LoadingInputSkeleton, {})) : (_jsx("input", { name: `message${formConfig?.messageFieldId
16
+ ? `_${formConfig?.messageFieldId}`
17
+ : ""}`, type: "text", placeholder: "Escribe un mensaje...", className: "form-input px-4 py-2 border border-gray-300 rounded-l-lg grow" })), _jsx("button", { onClick: handleAttachmentClick, className: `${formValues?.image ? "bg-blue-500" : ""} hover:bg-blue-700 text-white font-bold py-2 px-4`, type: "button", children: _jsx(AttachmentIconSVG, {}) }), _jsx("button", { className: "bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded-r-lg", type: "submit", name: "action", value: "sendMessage", children: sendingMessage ? _jsx(SpinnerSvg, {}) : _jsx(SendMessageIcon, {}) })] }), _jsx("input", { ref: refAttachment, hidden: true, name: `attachment${formConfig?.attachmentFieldId
18
+ ? `_${formConfig?.attachmentFieldId}`
19
+ : ""}`, type: "file", accept: ".jpg, .png, .jpeg, .png", onChange: (e) => {
20
+ if (e.target.value && e.target.value !== "") {
21
+ setFormValues({ ...formValues, image: e.target.value });
22
+ }
23
+ else {
24
+ setFormValues({ ...formValues, image: null });
25
+ }
26
+ } })] })] }));
27
+ };
28
+ export default ChatLayout;
@@ -0,0 +1,12 @@
1
+ type Props = {
2
+ author: string;
3
+ content: string;
4
+ date?: string;
5
+ onLike?: (like: boolean) => void;
6
+ onUpdateComment?: (text: string, itsNew?: boolean) => void;
7
+ id: string;
8
+ commentOwner?: boolean;
9
+ imageLink?: string;
10
+ };
11
+ export declare const ChatMessageHistory: (props: Props) => import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CheckIconSVG, PencilSvg } from "@zauru-sdk/icons";
3
+ import { useState, useEffect, useRef } from "react";
4
+ export const ChatMessageHistory = (props) => {
5
+ const { author, content, onLike, onUpdateComment, id, commentOwner = false, date, imageLink, } = props;
6
+ const initials = author ? author[0].toUpperCase() : "A";
7
+ const [isUpdating, setIsUpdating] = useState(false);
8
+ const [updatedContent, setUpdatedContent] = useState(content);
9
+ const textAreaRef = useRef(null);
10
+ const [shouldPulse, setShouldPulse] = useState(false);
11
+ useEffect(() => {
12
+ if (isUpdating && textAreaRef.current) {
13
+ textAreaRef.current.style.height = "auto";
14
+ textAreaRef.current.style.height = `${textAreaRef.current.scrollHeight}px`;
15
+ textAreaRef.current.focus();
16
+ }
17
+ }, [isUpdating]);
18
+ // Efecto secundario que se ejecuta cada vez que 'isUpdating' cambia
19
+ useEffect(() => {
20
+ // Activar la animación
21
+ setShouldPulse(true);
22
+ // Establecer un temporizador para eliminar la clase después de que la animación se haya completado
23
+ const timer = setTimeout(() => {
24
+ setShouldPulse(false);
25
+ }, 15000); // Tiempo total de la animación
26
+ // Limpiar el temporizador si el componente se desmonta o si 'isUpdating' cambia de nuevo antes de que la animación se complete
27
+ return () => clearTimeout(timer);
28
+ }, [isUpdating]);
29
+ const handleUpdate = (e) => {
30
+ if (e.target.value.length <= 254) {
31
+ setUpdatedContent(e.target.value);
32
+ }
33
+ };
34
+ const handleUpdateClick = () => {
35
+ if (isUpdating) {
36
+ if (textAreaRef.current) {
37
+ textAreaRef.current.blur();
38
+ }
39
+ //onUpdateComment && onUpdateComment(updatedContent, itsNew);
40
+ }
41
+ setIsUpdating(!isUpdating);
42
+ };
43
+ return (_jsxs("div", { className: "p-1 rounded-xl flex items-center space-x-4 relative", children: [commentOwner && (_jsx("div", { className: "absolute top-2 right-2", children: _jsx("button", { onClick: handleUpdateClick, className: `${shouldPulse ? "animate-custom-pulse" : ""}`, children: isUpdating ? _jsx(CheckIconSVG, {}) : _jsx(PencilSvg, {}) }) })), _jsx("div", { className: `w-[0%] lg:w-[8%] h-16 bg-purple-300 rounded-full flex items-center justify-center overflow-hidden text-white text-xl font-bold`, children: initials }), _jsxs("div", { className: "flex flex-col justify-between h-full w-[92%]", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex flex-row space-x-2", children: [_jsx("div", { className: "text-xl font-medium text-black", children: author }), _jsx("div", { className: "text-xl font-medium text-gray-500", children: date && _jsxs(_Fragment, { children: [" - ", date] }) })] }), isUpdating ? (_jsx("textarea", { ref: textAreaRef, className: "bg-gray-100 rounded p-2 w-full resize-none", value: updatedContent, onChange: handleUpdate, maxLength: 254, placeholder: "Deja tus buenos deseos..." })) : (_jsx("p", { className: "text-gray-500", children: updatedContent }))] }), _jsx("div", { className: "flex justify-end items-center", children: _jsx("button", { onClick: () => { }, children: _jsx(_Fragment, {}) }) })] }), imageLink && (_jsx("div", { className: `w-[25%] flex items-center justify-center overflow-hidden text-white text-xl font-bold`, children: _jsx("div", { onClick: () => {
44
+ return window.open(imageLink, "_blank");
45
+ }, children: _jsx("img", { src: imageLink, alt: "IMG_CHAT", className: `h-48 w-48 inline mr-1 pb-1`, style: {
46
+ stroke: "currentColor",
47
+ strokeWidth: 2,
48
+ strokeLinecap: "round",
49
+ strokeLinejoin: "round",
50
+ fill: "none",
51
+ backgroundColor: "transparent",
52
+ } }) }) }))] }));
53
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./ChatLayout";
2
+ export * from "./ChatMessageHistory";
@@ -0,0 +1,2 @@
1
+ export * from "./ChatLayout";
2
+ export * from "./ChatMessageHistory";
@@ -0,0 +1,2 @@
1
+ declare const ConnectionState: () => import("react/jsx-runtime").JSX.Element;
2
+ export default ConnectionState;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useIsOnline } from "@zauru-sdk/hooks";
3
+ const ConnectionState = () => {
4
+ const isOnline = useIsOnline();
5
+ // Definir estilos
6
+ const styles = {
7
+ container: {
8
+ padding: "10px",
9
+ borderRadius: "5px",
10
+ backgroundColor: isOnline ? "#d4edda" : "#f8d7da",
11
+ color: isOnline ? "#155724" : "#721c24",
12
+ fontWeight: "bold",
13
+ },
14
+ text: {
15
+ fontSize: "16px",
16
+ margin: 0,
17
+ },
18
+ };
19
+ // Renderizar el estado de conexión
20
+ return (_jsx("div", { style: styles.container, children: _jsx("p", { style: styles.text, children: isOnline ? "ONLINE ✅🌐" : "OFFLINE ❌🌐" }) }));
21
+ };
22
+ export default ConnectionState;
@@ -0,0 +1 @@
1
+ export * from "./ConnectionState";
@@ -0,0 +1 @@
1
+ export * from "./ConnectionState";
@@ -0,0 +1,10 @@
1
+ import { GenericDynamicTableColumn } from "@zauru-sdk/types";
2
+ export declare const BasicTableHTML: (props: {
3
+ data: {
4
+ [key: string]: string;
5
+ }[];
6
+ headers: GenericDynamicTableColumn[];
7
+ footer: {
8
+ [key: string]: string;
9
+ };
10
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { isNumeric } from "@zauru-sdk/common";
3
+ //TABLA PARA LA IMPRESION:
4
+ export const BasicTableHTML = (props) => {
5
+ const { data, footer, headers } = props;
6
+ return (_jsxs("table", { style: { borderCollapse: "collapse", width: "100%" }, children: [_jsx("thead", { children: _jsx("tr", { children: headers?.map((titulo, index) => (_jsx("th", { style: {
7
+ border: "1px solid black",
8
+ padding: "10px",
9
+ textAlign: "center",
10
+ whiteSpace: "normal",
11
+ }, children: titulo.label }, index))) }) }), _jsx("tbody", { children: data?.map((fila, index) => (_jsx("tr", { children: headers?.map((titulo, index) => (_jsx("td", { style: {
12
+ border: "1px solid black",
13
+ padding: "1px",
14
+ textAlign: "center",
15
+ whiteSpace: "normal",
16
+ fontSize: isNumeric(fila[titulo.name])
17
+ ? "2em"
18
+ : "1em",
19
+ }, children: fila[titulo.name] }, index))) }, index))) }), _jsx("tfoot", { children: _jsx("tr", { children: headers?.map((titulo, index) => (_jsx("td", { style: {
20
+ padding: "10px",
21
+ textAlign: "center",
22
+ whiteSpace: "normal",
23
+ fontSize: isNumeric(footer[titulo.name])
24
+ ? "2em"
25
+ : "1em",
26
+ }, children: footer[titulo.name] }, index))) }) })] }));
27
+ };
@@ -0,0 +1,23 @@
1
+ import React, { type ReactNode } from "react";
2
+ export type TableStateItem = {
3
+ item_id: string | undefined;
4
+ quantity: number | undefined;
5
+ };
6
+ export type FormatedItem = {
7
+ label: string;
8
+ value: number;
9
+ template: string;
10
+ };
11
+ type Props = {
12
+ name: string;
13
+ formName?: string;
14
+ className?: string;
15
+ items: FormatedItem[];
16
+ onChange?: (tableState?: TableStateItem[]) => void;
17
+ forwardedRef?: React.RefObject<{
18
+ insertItems: (items: FormatedItem[]) => void;
19
+ getTableState: (updatedData?: ReactNode[][]) => TableStateItem[] | undefined;
20
+ }>;
21
+ };
22
+ declare const _default: React.ForwardRefExoticComponent<Props & React.RefAttributes<unknown>>;
23
+ export default _default;
@@ -0,0 +1,132 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useEffect, useCallback, useState } from "react";
3
+ import { TextFieldWithoutValidation } from "src";
4
+ import { SelectFieldWithoutValidation } from "src";
5
+ import { useAppSelector } from "@zauru-sdk/redux";
6
+ const errorAnimation = {
7
+ hidden: { opacity: 0, y: -10 },
8
+ visible: { opacity: 1, y: 0 },
9
+ };
10
+ const DynamicPrintTable = ({ forwardedRef, ...props }) => {
11
+ const { items, onChange, className } = props;
12
+ const { formValidations } = useAppSelector((state) => state.formValidation);
13
+ const createItemSelect = (rowIndex, defaultValue) => (_jsx(SelectFieldWithoutValidation, { name: "item_select", isClearable: true, onChange: (value) => {
14
+ const selectedItem = items?.find((x) => x.value === value?.value);
15
+ updateRow(rowIndex, selectedItem);
16
+ }, options: items, defaultValue: defaultValue }, rowIndex));
17
+ const createItemQuantity = (rowIndex, defaultValue) => (_jsx(TextFieldWithoutValidation, { name: "item_quantity", type: "number", integer: true, defaultValue: defaultValue ?? 1, min: 1, onChange: (value) => {
18
+ updateRow(rowIndex, undefined, Number(value));
19
+ } }, rowIndex));
20
+ const createTemplateName = (rowIndex, defaultValue) => (_jsx("div", { children: defaultValue != "" ? defaultValue : "No hay etiqueta" }, rowIndex));
21
+ const createRow = (rowIndex, item, quantity) => {
22
+ const itemCreated = createItemSelect(rowIndex, item ?? undefined);
23
+ const quantityCreated = createItemQuantity(rowIndex, quantity ?? 1);
24
+ const templateCreated = createTemplateName(rowIndex, item ? item.template : "Seleccione un item para visualizar su etiqueta.");
25
+ return [itemCreated, quantityCreated, templateCreated];
26
+ };
27
+ const [tableData, setTableData] = useState([]);
28
+ const [isInitialItemAdded, setIsInitialItemAdded] = useState(false);
29
+ const insertItems = useCallback((newItems) => {
30
+ setTableData((prevData) => [
31
+ ...(prevData ?? []),
32
+ ...newItems.map((item, index) => {
33
+ const rowIndex = (prevData?.length ?? 0) + index;
34
+ const [itemCreated, quantityCreated, templateCreated] = createRow(rowIndex, item);
35
+ updateRow(rowIndex, item, 1);
36
+ return [itemCreated, quantityCreated, templateCreated];
37
+ }),
38
+ ]);
39
+ }, [items]);
40
+ const getTableState = (temp) => {
41
+ const updatedData = temp ?? tableData;
42
+ const tableState = updatedData?.map((rowData) => {
43
+ const firstElement = rowData[0];
44
+ const item_id = React.isValidElement(firstElement)
45
+ ? firstElement.props.defaultValue?.value
46
+ : undefined;
47
+ const secondElement = rowData[1];
48
+ const quantity = React.isValidElement(secondElement)
49
+ ? secondElement.props.defaultValue
50
+ : undefined;
51
+ return {
52
+ item_id,
53
+ quantity,
54
+ };
55
+ });
56
+ return tableState;
57
+ };
58
+ const updateRow = (rowIndex, item, quantity) => {
59
+ setTableData((prevData) => {
60
+ const updatedData = prevData?.map((_, index) => {
61
+ if (index === rowIndex) {
62
+ const firstElement = prevData[index][0];
63
+ const selectedItem = item ??
64
+ (React.isValidElement(firstElement)
65
+ ? items?.find((x) => x.value === firstElement.props.defaultValue?.value)
66
+ : undefined);
67
+ const secondElement = prevData[index][1];
68
+ const newQuantity = quantity
69
+ ? quantity
70
+ : React.isValidElement(secondElement)
71
+ ? secondElement.props.defaultValue
72
+ : undefined;
73
+ return createRow(rowIndex, selectedItem, newQuantity);
74
+ }
75
+ else {
76
+ return prevData[index];
77
+ }
78
+ });
79
+ if (onChange) {
80
+ const tableState = getTableState(updatedData);
81
+ onChange(tableState);
82
+ }
83
+ return updatedData;
84
+ });
85
+ };
86
+ const addRow = () => {
87
+ setTableData((prevData) => [
88
+ ...(prevData ?? []),
89
+ createRow(prevData?.length ?? 0),
90
+ ]);
91
+ };
92
+ const removeRow = (rowIndex) => {
93
+ setTableData((prevData) => prevData?.filter((_, index) => index !== rowIndex));
94
+ };
95
+ React.useImperativeHandle(forwardedRef, () => ({
96
+ insertItems,
97
+ getTableState,
98
+ }));
99
+ const pastelGrayBackground = {
100
+ backgroundColor: "#B69E99",
101
+ };
102
+ const renderHeader = () => (_jsxs("tr", { style: { ...pastelGrayBackground }, children: [_jsx("th", { className: "text-left align-middle p-2", children: "Item" }), _jsx("th", { className: "text-left align-middle p-2", children: "Cantidad" }), _jsx("th", { className: "text-left align-middle p-2", children: "Etiqueta" }), _jsx("th", { className: "w-16" })] }));
103
+ const renderRow = (rowData, rowIndex) => (_jsxs("tr", { children: [rowData.map((cellData, cellIndex) => (_jsx("td", { className: "align-middle p-2", children: cellData }, cellIndex))), rowIndex !== 0 && (_jsx("td", { className: "align-middle w-16", children: _jsx("button", { className: "bg-red-500 hover:bg-red-600 font-bold py-1 px-2 rounded ml-2", onClick: (event) => {
104
+ event.preventDefault();
105
+ event.stopPropagation();
106
+ removeRow(rowIndex);
107
+ }, type: "button", children: "x" }) }))] }, rowIndex));
108
+ const renderRows = () => {
109
+ return tableData?.map((rowData, rowIndex) => renderRow(rowData, rowIndex));
110
+ };
111
+ const error = formValidations[props.formName ?? "-1"][props.name];
112
+ const borderColor = error ? "border-red-500" : "border-transparent";
113
+ useEffect(() => {
114
+ if (!isInitialItemAdded && items?.length > 0) {
115
+ insertItems([items[0]]);
116
+ setIsInitialItemAdded(true);
117
+ }
118
+ }, [isInitialItemAdded, items, insertItems]);
119
+ return (_jsxs("div", { className: `${className} ${borderColor} border-2`, style: { overflowX: "auto" }, children: [!!error && _jsx("div", { className: "text-red-500 text-sm mb-2", children: error }), _jsxs("table", { className: "w-full", children: [_jsx("thead", { children: renderHeader() }), _jsx("tbody", { children: renderRows() }), _jsx("tfoot", { children: _jsxs("tr", { children: [_jsx("td", { className: "align-middle", children: _jsx("button", { className: "bg-blue-500 hover:bg-blue-600 font-bold py-2 px-4 rounded", onClick: (event) => {
120
+ event.preventDefault();
121
+ event.stopPropagation();
122
+ addRow();
123
+ }, type: "button", children: "+" }) }), _jsxs("td", { colSpan: 2, children: ["Total de etiquetas a imprimir:", " ", tableData?.reduce((sum, x) => {
124
+ const val = React.isValidElement(x[1])
125
+ ? x[1]?.props?.defaultValue
126
+ : undefined;
127
+ if (!sum)
128
+ return val;
129
+ return sum + val;
130
+ }, 0)] })] }) })] })] }));
131
+ };
132
+ export default React.forwardRef(DynamicPrintTable);
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { GenericDynamicTableColumn, RowDataType, SelectFieldOption } from "@zauru-sdk/types";
3
+ type Props = {
4
+ name?: string;
5
+ className?: string;
6
+ columns: GenericDynamicTableColumn[];
7
+ onChange?: (tableState?: any[]) => void;
8
+ defaultValue?: RowDataType[];
9
+ footerRow?: RowDataType;
10
+ thCSSProperties?: React.CSSProperties;
11
+ thElementsClassName?: string;
12
+ editable?: boolean;
13
+ searcheables?: SelectFieldOption[];
14
+ loading?: boolean;
15
+ paginated?: boolean;
16
+ defaultItemsPerPage?: number;
17
+ itemsPerPageOptions?: number[];
18
+ withoutBg?: boolean;
19
+ };
20
+ export declare const GenericDynamicTable: (props: Props) => import("react/jsx-runtime").JSX.Element;
21
+ export {};
@@ -0,0 +1,195 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import { SelectFieldWithoutValidation } from "../Form/SelectField";
4
+ import { TextFieldWithoutValidation } from "../Form/TextField";
5
+ import { CheckboxWithoutValidation } from "../Form/Checkbox";
6
+ import { createModal } from "../Modal";
7
+ import { Button } from "../Buttons/Button";
8
+ import { useAppSelector } from "@zauru-sdk/redux";
9
+ import { generateClientUUID } from "@zauru-sdk/common";
10
+ import { LoadingInputSkeleton, WithTooltip } from "src";
11
+ import { TrashSvg } from "@zauru-sdk/icons";
12
+ const GenericDynamicTableErrorComponent = ({ name, formName, }) => {
13
+ const { formValidations } = useAppSelector((state) => state.formValidation);
14
+ const error = formValidations[formName ?? "-1"]?.[name ?? "-1"];
15
+ return error ? (_jsxs("p", { className: `mt-2 text-sm text-red-600 dark:text-red-500`, children: [_jsx("span", { className: "font-medium", children: "Oops!" }), " ", error] })) : (_jsx(_Fragment, {}));
16
+ };
17
+ export const GenericDynamicTable = (props) => {
18
+ const { columns, onChange, className, footerRow, defaultValue = [], thCSSProperties, thElementsClassName = "", editable = true, searcheables = [], loading = false, paginated = true, defaultItemsPerPage = 10, itemsPerPageOptions = [10, 50, 100], name, withoutBg = false, } = props;
19
+ const [tableData, setTableData] = useState(defaultValue);
20
+ const [deletedData, setDeletedData] = useState([]);
21
+ const [search, setSearch] = useState("");
22
+ const [filteredTableData, setFilteredTableData] = useState(tableData);
23
+ const [currentPage, setCurrentPage] = useState(1);
24
+ const [itemsPerPage, setItemsPerPage] = useState(defaultItemsPerPage);
25
+ useEffect(() => {
26
+ if (defaultValue.length) {
27
+ setTableData(defaultValue);
28
+ }
29
+ }, []);
30
+ useEffect(() => {
31
+ setFilteredTableData(tableData);
32
+ }, [tableData]);
33
+ useEffect(() => {
34
+ changeFilteredData();
35
+ }, [tableData, search]);
36
+ const totalPages = () => {
37
+ return Math.ceil(filteredTableData.length / itemsPerPage);
38
+ };
39
+ const addRow = () => {
40
+ const defs = {};
41
+ columns.forEach((x) => {
42
+ defs[`${x.name}`] =
43
+ x.type == "label" || x.type == "textField"
44
+ ? ""
45
+ : x.type == "selectField"
46
+ ? 0
47
+ : x.type == "checkbox"
48
+ ? false
49
+ : 0;
50
+ });
51
+ setTableData((prevData) => [
52
+ ...prevData,
53
+ { id: generateClientUUID(), ...defs },
54
+ ]);
55
+ };
56
+ const removeRow = (rowId) => {
57
+ const newDeletedData = [...deletedData];
58
+ const deletedItem = tableData?.find((x) => x.id === rowId);
59
+ if (deletedItem && !isNaN(deletedItem.id)) {
60
+ newDeletedData.push(deletedItem);
61
+ }
62
+ setDeletedData(newDeletedData);
63
+ setTableData((prevData) => prevData?.filter((x) => x.id !== rowId));
64
+ };
65
+ const handleChange = (name, value, rowId) => {
66
+ // Encontrar el índice de la fila que está cambiando
67
+ const rowIndex = tableData.findIndex((x) => x.id === rowId);
68
+ // Crear una copia del objeto en esa fila
69
+ const updatedRow = { ...tableData[rowIndex], [name]: value };
70
+ // Copiar todo el array
71
+ const updatedData = [...tableData];
72
+ // Reemplazar el objeto en la fila que cambió
73
+ updatedData[rowIndex] = updatedRow;
74
+ // Actualizar el estado con el nuevo array
75
+ setTableData(updatedData);
76
+ onChange && onChange(updatedData);
77
+ };
78
+ const renderHeader = () => (_jsxs("tr", { style: { ...thCSSProperties }, children: [columns.map((column, index) => {
79
+ const ancho = column.width ?? (editable ? 94 : 100) / (columns.length ?? 1);
80
+ return (_jsx("th", { className: `text-left align-middle p-2 ${thElementsClassName}`, style: { width: `${ancho}%` }, children: column.label }, index));
81
+ }), editable && _jsx("th", { style: { width: "4%" } })] }));
82
+ const renderRow = (rowData, index) => {
83
+ return (_jsxs("tr", { className: index % 2 === 0 ? `${withoutBg ? "" : "bg-gray-200"}` : "", children: [columns.map((column) => {
84
+ if (loading) {
85
+ return (_jsx("td", { className: "align-middle p-1", children: _jsx(LoadingInputSkeleton, {}) }, `${rowData.id}-${column.name}`));
86
+ }
87
+ const tempVal = rowData[column.name];
88
+ const defaultVal = column.type === "selectField"
89
+ ? column.options?.find((x) => x.value === tempVal)
90
+ : tempVal;
91
+ if (column.type === "label") {
92
+ return (_jsx("td", { className: "align-middle p-1", children: _jsx("div", { children: defaultVal }) }, `${rowData.id}-${column.name}`));
93
+ }
94
+ const FieldComponent = column.type === "textField"
95
+ ? TextFieldWithoutValidation
96
+ : column.type === "checkbox"
97
+ ? CheckboxWithoutValidation
98
+ : SelectFieldWithoutValidation;
99
+ const setTableValue = (columnName, newValue) => {
100
+ setTableData((prevState) => {
101
+ // Encontrar el índice de la fila que está cambiando
102
+ const rowIndex = prevState.findIndex((x) => x.id === rowData.id);
103
+ // Crear una copia del objeto en esa fila
104
+ const updatedRow = {
105
+ ...prevState[rowIndex],
106
+ [columnName]: newValue,
107
+ };
108
+ // Copiar todo el array
109
+ const updatedData = [...prevState];
110
+ // Reemplazar el objeto en la fila que cambió
111
+ updatedData[rowIndex] = updatedRow;
112
+ return updatedData;
113
+ });
114
+ };
115
+ return (_jsx("td", { className: "align-middle p-1", children: column.loadingOptions ? (_jsx(LoadingInputSkeleton, {})) : (_jsx(FieldComponent, {
116
+ //name={column.name}
117
+ type: column.textFieldType, integer: !!column.integer, disabled: column.disabled, isClearable: true, onChange: (value) => {
118
+ const sendValue = value?.value ?? value;
119
+ handleChange(column.name, sendValue, rowData.id);
120
+ column.onChange &&
121
+ column.onChange(rowData, sendValue, setTableValue);
122
+ }, defaultValue: defaultVal, options: column.options ?? [] }, `${rowData.id}-${column.name}`)) }, `${rowData.id}-${column.name}`));
123
+ }), editable && (_jsx("td", { className: "align-middle w-16", children: _jsx(WithTooltip, { text: "Eliminar", children: _jsx("button", { className: "bg-red-500 hover:bg-red-600 font-bold py-1 px-2 rounded ml-2", onClick: (event) => {
124
+ event.preventDefault();
125
+ event.stopPropagation();
126
+ createModal({
127
+ title: "¿Está seguro que quiere eliminar este registro?",
128
+ description: "Una vez eliminada la información no podrá ser recuperada.",
129
+ }).then((response) => {
130
+ if (response === "OK") {
131
+ removeRow(rowData.id);
132
+ }
133
+ });
134
+ }, type: "button", children: _jsx(TrashSvg, {}) }) }) }))] }, rowData.id));
135
+ };
136
+ const renderRows = () => {
137
+ let mapeable = filteredTableData.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);
138
+ if (loading) {
139
+ mapeable = [
140
+ { id: 1 },
141
+ { id: 2 },
142
+ { id: 3 },
143
+ { id: 4 },
144
+ { id: 5 },
145
+ { id: 6 },
146
+ { id: 7 },
147
+ { id: 8 },
148
+ { id: 9 },
149
+ { id: 10 },
150
+ ];
151
+ }
152
+ return mapeable.map((rowData, index) => renderRow(rowData, index));
153
+ };
154
+ const handleChangeSearch = (newSearch) => {
155
+ setSearch(newSearch);
156
+ };
157
+ const changeFilteredData = () => {
158
+ if (search) {
159
+ const filteredData = tableData.filter((rowData) => {
160
+ for (const searchable of searcheables) {
161
+ const column = columns.find((col) => col.name === searchable.value);
162
+ if (column) {
163
+ const tempVal = rowData[column.name];
164
+ const defaultVal = column.type === "selectField"
165
+ ? column.options?.find((x) => x.value === tempVal)?.label
166
+ : tempVal;
167
+ if (defaultVal
168
+ ?.toString()
169
+ .toLowerCase()
170
+ .includes(search.toLowerCase())) {
171
+ return true;
172
+ }
173
+ }
174
+ }
175
+ return false;
176
+ });
177
+ setFilteredTableData(filteredData);
178
+ }
179
+ else {
180
+ setFilteredTableData(tableData);
181
+ }
182
+ };
183
+ return (_jsxs(_Fragment, { children: [name && (_jsxs(_Fragment, { children: [_jsx(GenericDynamicTableErrorComponent, { name: name }), _jsx("input", { name: name, type: "hidden", value: JSON.stringify(tableData), hidden: true }), _jsx("input", { name: `deleted_${name}`, type: "hidden", value: JSON.stringify(deletedData), hidden: true })] })), _jsxs("div", { className: `${className}`, children: [searcheables.length > 0 && (_jsx("div", { children: _jsx(TextFieldWithoutValidation, { className: "mb-2", name: "search", title: `Buscar por: ${searcheables
184
+ .map((x) => x.label)
185
+ .join(", ")}`, onChange: handleChangeSearch, disabled: loading }) })), _jsxs("table", { className: "w-full", children: [_jsx("thead", { children: renderHeader() }), _jsx("tbody", { children: renderRows() }), footerRow && !editable ? (_jsx("tfoot", { className: "border-t-2 border-black", children: _jsx("tr", { children: Object.keys(footerRow ?? {})?.map((x, indx) => {
186
+ return (_jsx("td", { className: "align-middle", children: footerRow[x] }, indx));
187
+ }) }) })) : editable ? (_jsx("tfoot", { children: _jsx("tr", { children: _jsx("td", { className: "align-middle", children: _jsx("button", { className: "bg-blue-500 hover:bg-blue-600 font-bold py-2 px-4 rounded", onClick: (event) => {
188
+ event.preventDefault();
189
+ event.stopPropagation();
190
+ addRow();
191
+ }, type: "button", children: "+" }) }) }) })) : (_jsx(_Fragment, {}))] }), paginated && totalPages() > 1 && (_jsxs("div", { className: "flex justify-between items-center mt-4", children: [_jsxs("div", { className: "flex items-center", children: [_jsx(Button, { type: "button", disabled: currentPage === 1, onClickSave: () => setCurrentPage((old) => Math.max(old - 1, 1)), children: "Anterior" }), _jsx("span", { className: "mx-2", children: `Página ${currentPage} de ${totalPages()}` }), _jsx(Button, { type: "button", disabled: currentPage === totalPages(), onClickSave: () => setCurrentPage((old) => Math.min(old + 1, totalPages())), children: "Siguiente" })] }), _jsx("div", { children: _jsx("select", { value: itemsPerPage, onChange: (e) => {
192
+ setItemsPerPage(Number(e.target.value));
193
+ setCurrentPage(1); // resetear la página al cambiar los elementos por página
194
+ }, children: itemsPerPageOptions.map((option) => (_jsxs("option", { value: option, children: [option, " elementos por p\u00E1gina"] }, option))) }) })] }))] })] }));
195
+ };
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ type Props = {
3
+ cellInputs?: boolean;
4
+ intersectionTitle?: string;
5
+ className?: string;
6
+ onChange?: (data: string) => void;
7
+ defaultValue?: string;
8
+ onValidate?: (headerValue: string, rowValue: string) => boolean;
9
+ onRemove?: () => void;
10
+ margins?: {
11
+ marginLeft?: number;
12
+ marginTop?: number;
13
+ verticalGap?: number;
14
+ horizontalGap?: number;
15
+ };
16
+ forwardedRef?: React.RefObject<{
17
+ getTotalForRows: () => number;
18
+ getTotalForColumns: () => number;
19
+ getColumnsCount: () => number;
20
+ getRowsCount: () => number;
21
+ }>;
22
+ };
23
+ declare const _default: React.ForwardRefExoticComponent<Props & React.RefAttributes<any>>;
24
+ export default _default;