@zauru-sdk/components 6.14.2 → 6.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
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
+ ## [6.15.1](https://github.com/intuitiva/zauru-typescript-sdk/compare/@zauru-sdk/components@6.15.0...@zauru-sdk/components@6.15.1) (2026-10-28)
7
+
8
+ **Note:** Version bump only for package @zauru-sdk/components
9
+
10
+
11
+
12
+
13
+
14
+ # [6.15.0](https://github.com/intuitiva/zauru-typescript-sdk/compare/@zauru-sdk/components@6.14.2...@zauru-sdk/components@6.15.0) (2026-10-28)
15
+
16
+
17
+ ### Features
18
+
19
+ * permitir editar GenericDynamicTable sin agregar o borrar filas ([7fc9b41](https://github.com/intuitiva/zauru-typescript-sdk/commit/7fc9b41a7aebf2627a674bc8d9d70b772c378056))
20
+
21
+
22
+
23
+
24
+
6
25
  ## [6.14.2](https://github.com/intuitiva/zauru-typescript-sdk/compare/@zauru-sdk/components@6.14.1...@zauru-sdk/components@6.14.2) (2026-10-26)
7
26
 
8
27
 
@@ -15,8 +15,13 @@ type Props = {
15
15
  footerRow?: FooterColumnConfig[];
16
16
  thCSSProperties?: React.CSSProperties;
17
17
  thElementsClassName?: string;
18
- /** Controla si se pueden o no editar los campos (oculta botones y/o deshabilita campos). */
18
+ /** Controla si se pueden editar los campos. */
19
19
  editable?: boolean;
20
+ /**
21
+ * Si es false, no muestra agregar/eliminar filas aunque `editable` esté activo.
22
+ * Útil para catálogos fijos cuyos valores sí se editan.
23
+ */
24
+ rowActions?: boolean;
20
25
  /** Opciones de búsqueda. */
21
26
  searcheables?: SelectFieldOption[];
22
27
  /** Activa o desactiva el “skeleton” de carga. */
@@ -97,12 +97,13 @@ const GenericDynamicTableErrorComponent = ({ name }) => {
97
97
  */
98
98
  export const GenericDynamicTable = (props) => {
99
99
  const { columns, onChange, className, footerRow, defaultValue = [], thCSSProperties, thElementsClassName = "", editable = true, readOnly = false, // Nuevo prop
100
- searcheables = [], loading = false, paginated = true, defaultItemsPerPage = 10, itemsPerPageOptions = [10, 50, 100], name, withoutBg = false, orientation = "horizontal", maxRows, confirmDelete = true, addRowButtonHandler, rowSummary, } = props;
100
+ rowActions = true, searcheables = [], loading = false, paginated = true, defaultItemsPerPage = 10, itemsPerPageOptions = [10, 50, 100], name, withoutBg = false, orientation = "horizontal", maxRows, confirmDelete = true, addRowButtonHandler, rowSummary, } = props;
101
101
  /**
102
102
  * Definimos una variable interna para saber si los campos son
103
103
  * efectivamente editables: solo si `editable` es true y `readOnly` es false.
104
104
  */
105
105
  const isEditable = editable && !readOnly;
106
+ const showRowActions = isEditable && rowActions;
106
107
  try {
107
108
  const [tableData, setTableData] = useState(defaultValue);
108
109
  const [deletedData, setDeletedData] = useState([]);
@@ -174,9 +175,9 @@ export const GenericDynamicTable = (props) => {
174
175
  if (orientation === "horizontal") {
175
176
  return (_jsxs("tr", { style: { ...thCSSProperties }, children: [rendereableColumns.map((column, index) => {
176
177
  const ancho = column.width ??
177
- (isEditable ? 94 : 100) / (rendereableColumns.length ?? 1);
178
+ (showRowActions ? 94 : 100) / (rendereableColumns.length ?? 1);
178
179
  return (_jsx("th", { className: `text-left align-middle p-2 ${thElementsClassName} ${column.headerClassName || ""}`, style: { width: `${ancho}%` }, children: column.label }, index));
179
- }), isEditable && _jsx("th", { style: { width: "4%" } })] }));
180
+ }), showRowActions && _jsx("th", { style: { width: "4%" } })] }));
180
181
  }
181
182
  else {
182
183
  return null;
@@ -186,13 +187,13 @@ export const GenericDynamicTable = (props) => {
186
187
  const rendereableColumns = columns.filter((column) => column.type !== "hidden");
187
188
  if (orientation === "horizontal") {
188
189
  const rowClassName = index % 2 === 0 ? `${withoutBg ? "" : "bg-gray-200"}` : "";
189
- const summaryColSpan = rendereableColumns.length + (isEditable ? 1 : 0);
190
+ const summaryColSpan = rendereableColumns.length + (showRowActions ? 1 : 0);
190
191
  const summaryContent = rowSummary?.(rowData);
191
- return (_jsxs(React.Fragment, { children: [_jsxs("tr", { className: rowClassName, children: [rendereableColumns.map((column) => renderCell(rowData, column)), isEditable && renderDeleteButton(rowData)] }), summaryContent ? (_jsx("tr", { className: rowClassName, children: _jsxs("td", { colSpan: summaryColSpan, className: "px-2 pb-3 pt-0 text-sm text-gray-700 border-b border-gray-300", children: [_jsx("span", { className: "font-medium text-gray-500", children: "Resumen: " }), summaryContent] }) })) : null] }, rowData.id));
192
+ return (_jsxs(React.Fragment, { children: [_jsxs("tr", { className: rowClassName, children: [rendereableColumns.map((column) => renderCell(rowData, column)), showRowActions && renderDeleteButton(rowData)] }), summaryContent ? (_jsx("tr", { className: rowClassName, children: _jsxs("td", { colSpan: summaryColSpan, className: "px-2 pb-3 pt-0 text-sm text-gray-700 border-b border-gray-300", children: [_jsx("span", { className: "font-medium text-gray-500", children: "Resumen: " }), summaryContent] }) })) : null] }, rowData.id));
192
193
  }
193
194
  else {
194
195
  // Orientación vertical
195
- return rendereableColumns.map((column) => (_jsxs("tr", { className: index % 2 === 0 ? `${withoutBg ? "" : "bg-gray-200"}` : "", children: [_jsx("th", { className: `text-left align-middle p-2 ${thElementsClassName} ${column.headerClassName || ""}`, children: column.label }), renderCell(rowData, column), isEditable &&
196
+ return rendereableColumns.map((column) => (_jsxs("tr", { className: index % 2 === 0 ? `${withoutBg ? "" : "bg-gray-200"}` : "", children: [_jsx("th", { className: `text-left align-middle p-2 ${thElementsClassName} ${column.headerClassName || ""}`, children: column.label }), renderCell(rowData, column), showRowActions &&
196
197
  column === rendereableColumns[rendereableColumns.length - 1] &&
197
198
  renderDeleteButton(rowData)] }, `${rowData.id}-${column.name}`)));
198
199
  }
@@ -303,7 +304,7 @@ export const GenericDynamicTable = (props) => {
303
304
  };
304
305
  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(TextField, { className: "mb-2", name: "search", title: `Buscar por: ${searcheables
305
306
  .map((x) => x.label)
306
- .join(", ")}`, onChange: handleChangeSearch, disabled: loading || readOnly }) })), _jsxs("table", { className: "w-full", children: [orientation === "horizontal" && _jsx("thead", { children: renderHeader() }), _jsx("tbody", { children: renderRows() }), isEditable && (_jsx("tfoot", { children: _jsx("tr", { children: _jsx("td", { colSpan: orientation === "horizontal" ? columns.length + 1 : 2, className: "align-middle text-right", children: (!maxRows || tableData.length < maxRows) && (_jsx("button", { className: "bg-blue-500 hover:bg-blue-600 font-bold py-2 px-4 rounded", onClick: (event) => {
307
+ .join(", ")}`, onChange: handleChangeSearch, disabled: loading || readOnly }) })), _jsxs("table", { className: "w-full", children: [orientation === "horizontal" && _jsx("thead", { children: renderHeader() }), _jsx("tbody", { children: renderRows() }), showRowActions && (_jsx("tfoot", { children: _jsx("tr", { children: _jsx("td", { colSpan: orientation === "horizontal" ? columns.length + 1 : 2, className: "align-middle text-right", children: (!maxRows || tableData.length < maxRows) && (_jsx("button", { className: "bg-blue-500 hover:bg-blue-600 font-bold py-2 px-4 rounded", onClick: (event) => {
307
308
  event.preventDefault();
308
309
  event.stopPropagation();
309
310
  if (addRowButtonHandler) {
@@ -317,7 +318,7 @@ export const GenericDynamicTable = (props) => {
317
318
  .map((column, index) => {
318
319
  const footerCell = footerRow.find((fc) => fc.name === column.name);
319
320
  return (_jsx("td", { colSpan: orientation === "vertical" ? 2 : 1, className: `align-middle ${footerCell?.className || ""}`, children: footerCell ? (footerCell.cell ? (footerCell.cell(tableData)) : (footerCell.content)) : (_jsx(_Fragment, {})) }, index));
320
- }), isEditable && _jsx("td", {})] }) }))] }), 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 || readOnly, 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() || readOnly, onClickSave: () => setCurrentPage((old) => Math.min(old + 1, totalPages())), children: "Siguiente" })] }), _jsx("div", { children: _jsx("select", { value: itemsPerPage, onChange: (e) => {
321
+ }), showRowActions && _jsx("td", {})] }) }))] }), 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 || readOnly, 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() || readOnly, onClickSave: () => setCurrentPage((old) => Math.min(old + 1, totalPages())), children: "Siguiente" })] }), _jsx("div", { children: _jsx("select", { value: itemsPerPage, onChange: (e) => {
321
322
  setItemsPerPage(Number(e.target.value));
322
323
  setCurrentPage(1); // resetear la página al cambiar los elementos por página
323
324
  }, children: itemsPerPageOptions.map((option) => (_jsxs("option", { value: option, children: [option, " elementos por p\u00E1gina"] }, option))) }) })] }))] })] }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zauru-sdk/components",
3
- "version": "6.14.2",
3
+ "version": "6.15.1",
4
4
  "description": "Componentes reutilizables en las WebApps de Zauru.",
5
5
  "main": "./dist/esm/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -10,6 +10,13 @@
10
10
  "access": "public",
11
11
  "registry": "https://registry.npmjs.org/"
12
12
  },
13
+ "scripts": {
14
+ "build": "npm run build:esm",
15
+ "build:esm": "tsc -p tsconfig.esm.json",
16
+ "play": "ladle serve --port 61000",
17
+ "play:build": "ladle build",
18
+ "test": "echo \"Error: no test specified\" && exit 1"
19
+ },
13
20
  "author": {
14
21
  "name": "Oscar Cuellar",
15
22
  "email": "usackoka@gmail.com"
@@ -37,6 +44,12 @@
37
44
  "@reduxjs/toolkit": "^2.2.1",
38
45
  "@remix-run/node": "^2.8.1",
39
46
  "@remix-run/react": "^2.8.1",
47
+ "@zauru-sdk/common": "^6.12.0",
48
+ "@zauru-sdk/hooks": "^6.4.1",
49
+ "@zauru-sdk/icons": "^6.2.0",
50
+ "@zauru-sdk/redux": "^6.8.2",
51
+ "@zauru-sdk/types": "^6.28.0",
52
+ "@zauru-sdk/utils": "^6.27.0",
40
53
  "browser-image-compression": "^2.0.2",
41
54
  "framer-motion": "^12.0.0",
42
55
  "jsonwebtoken": "^9.0.2",
@@ -47,20 +60,7 @@
47
60
  "react-is": "^18.2.0",
48
61
  "react-select": "^5.8.0",
49
62
  "styled-components": "^5.3.5",
50
- "zod": "^3.23.8",
51
- "@zauru-sdk/common": "^6.12.0",
52
- "@zauru-sdk/icons": "^6.1.0",
53
- "@zauru-sdk/hooks": "^6.3.23",
54
- "@zauru-sdk/redux": "^6.7.2",
55
- "@zauru-sdk/types": "^6.28.0",
56
- "@zauru-sdk/utils": "^6.26.1"
63
+ "zod": "^3.23.8"
57
64
  },
58
- "gitHead": "57c966c16b47b52c32e72d40ccd7c76d9aaba247",
59
- "scripts": {
60
- "build": "npm run build:esm",
61
- "build:esm": "tsc -p tsconfig.esm.json",
62
- "play": "ladle serve --port 61000",
63
- "play:build": "ladle build",
64
- "test": "echo \"Error: no test specified\" && exit 1"
65
- }
66
- }
65
+ "gitHead": "fdcb2feac6e49fb6803a4eadea73d063ca3cfe0a"
66
+ }
@@ -31,8 +31,13 @@ type Props = {
31
31
  footerRow?: FooterColumnConfig[];
32
32
  thCSSProperties?: React.CSSProperties;
33
33
  thElementsClassName?: string;
34
- /** Controla si se pueden o no editar los campos (oculta botones y/o deshabilita campos). */
34
+ /** Controla si se pueden editar los campos. */
35
35
  editable?: boolean;
36
+ /**
37
+ * Si es false, no muestra agregar/eliminar filas aunque `editable` esté activo.
38
+ * Útil para catálogos fijos cuyos valores sí se editan.
39
+ */
40
+ rowActions?: boolean;
36
41
  /** Opciones de búsqueda. */
37
42
  searcheables?: SelectFieldOption[];
38
43
  /** Activa o desactiva el “skeleton” de carga. */
@@ -169,6 +174,7 @@ export const GenericDynamicTable = (props: Props) => {
169
174
  thElementsClassName = "",
170
175
  editable = true,
171
176
  readOnly = false, // Nuevo prop
177
+ rowActions = true,
172
178
  searcheables = [],
173
179
  loading = false,
174
180
  paginated = true,
@@ -188,6 +194,7 @@ export const GenericDynamicTable = (props: Props) => {
188
194
  * efectivamente editables: solo si `editable` es true y `readOnly` es false.
189
195
  */
190
196
  const isEditable = editable && !readOnly;
197
+ const showRowActions = isEditable && rowActions;
191
198
 
192
199
  try {
193
200
  const [tableData, setTableData] = useState<RowDataType[]>(defaultValue);
@@ -276,7 +283,7 @@ export const GenericDynamicTable = (props: Props) => {
276
283
  {rendereableColumns.map((column, index) => {
277
284
  const ancho =
278
285
  column.width ??
279
- (isEditable ? 94 : 100) / (rendereableColumns.length ?? 1);
286
+ (showRowActions ? 94 : 100) / (rendereableColumns.length ?? 1);
280
287
  return (
281
288
  <th
282
289
  key={index}
@@ -289,7 +296,7 @@ export const GenericDynamicTable = (props: Props) => {
289
296
  </th>
290
297
  );
291
298
  })}
292
- {isEditable && <th style={{ width: "4%" }}></th>}
299
+ {showRowActions && <th style={{ width: "4%" }}></th>}
293
300
  </tr>
294
301
  );
295
302
  } else {
@@ -306,14 +313,14 @@ export const GenericDynamicTable = (props: Props) => {
306
313
  const rowClassName =
307
314
  index % 2 === 0 ? `${withoutBg ? "" : "bg-gray-200"}` : "";
308
315
  const summaryColSpan =
309
- rendereableColumns.length + (isEditable ? 1 : 0);
316
+ rendereableColumns.length + (showRowActions ? 1 : 0);
310
317
  const summaryContent = rowSummary?.(rowData);
311
318
 
312
319
  return (
313
320
  <React.Fragment key={rowData.id}>
314
321
  <tr className={rowClassName}>
315
322
  {rendereableColumns.map((column) => renderCell(rowData, column))}
316
- {isEditable && renderDeleteButton(rowData)}
323
+ {showRowActions && renderDeleteButton(rowData)}
317
324
  </tr>
318
325
  {summaryContent ? (
319
326
  <tr className={rowClassName}>
@@ -345,7 +352,7 @@ export const GenericDynamicTable = (props: Props) => {
345
352
  {column.label}
346
353
  </th>
347
354
  {renderCell(rowData, column)}
348
- {isEditable &&
355
+ {showRowActions &&
349
356
  column === rendereableColumns[rendereableColumns.length - 1] &&
350
357
  renderDeleteButton(rowData)}
351
358
  </tr>
@@ -572,7 +579,7 @@ export const GenericDynamicTable = (props: Props) => {
572
579
  <table className="w-full">
573
580
  {orientation === "horizontal" && <thead>{renderHeader()}</thead>}
574
581
  <tbody>{renderRows()}</tbody>
575
- {isEditable && (
582
+ {showRowActions && (
576
583
  <tfoot>
577
584
  <tr>
578
585
  <td
@@ -633,7 +640,7 @@ export const GenericDynamicTable = (props: Props) => {
633
640
  </td>
634
641
  );
635
642
  })}
636
- {isEditable && <td></td>}
643
+ {showRowActions && <td></td>}
637
644
  </tr>
638
645
  </tfoot>
639
646
  )}