@m4l/components 9.3.21 → 9.3.22-JT22102025.beta.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/components/DataGrid/DataGrid.js +9 -4
- package/components/DataGrid/Datagrid.styles.js +270 -0
- package/components/DataGrid/constants.js +2 -2
- package/components/DataGrid/contexts/DataGridContext/index.js +322 -112
- package/components/DataGrid/contexts/DataGridContext/types.d.ts +63 -4
- package/components/DataGrid/dictionary.d.ts +5 -0
- package/components/DataGrid/dictionary.js +6 -1
- package/components/DataGrid/formatters/ColumnSetCheckFormatter/formatter.js +2 -2
- package/components/DataGrid/hooks/useModalCardDetail.d.ts +6 -0
- package/components/DataGrid/hooks/useModalCardDetail.js +74 -0
- package/components/DataGrid/hooks/useProcessedColumns.d.ts +50 -0
- package/components/DataGrid/hooks/useProcessedColumns.js +44 -0
- package/components/DataGrid/icons.d.ts +7 -0
- package/components/DataGrid/icons.js +5 -1
- package/components/DataGrid/index.d.ts +1 -1
- package/components/DataGrid/slots/DataGridEnum.d.ts +22 -1
- package/components/DataGrid/slots/DataGridEnum.js +21 -0
- package/components/DataGrid/slots/DataGridSlot.d.ts +24 -0
- package/components/DataGrid/slots/DataGridSlot.js +123 -21
- package/components/DataGrid/subcomponents/Cards/hooks/useCardContent.d.ts +9 -0
- package/components/DataGrid/subcomponents/Cards/hooks/useCardContent.js +91 -0
- package/components/DataGrid/subcomponents/Cards/index.d.ts +5 -0
- package/components/DataGrid/subcomponents/Cards/index.js +40 -0
- package/components/DataGrid/subcomponents/Cards/subcomponents/CardDetails/index.d.ts +8 -0
- package/components/DataGrid/subcomponents/Cards/subcomponents/CardDetails/index.js +79 -0
- package/components/DataGrid/subcomponents/Cards/subcomponents/CardHeader/index.d.ts +7 -0
- package/components/DataGrid/subcomponents/Cards/subcomponents/CardHeader/index.js +98 -0
- package/components/DataGrid/subcomponents/Cards/subcomponents/CardRow/index.d.ts +6 -0
- package/components/DataGrid/subcomponents/Cards/subcomponents/CardRow/index.js +71 -0
- package/components/DataGrid/subcomponents/Cards/subcomponents/IntersectCard/index.d.ts +20 -0
- package/components/DataGrid/subcomponents/Cards/subcomponents/IntersectCard/index.js +46 -0
- package/components/DataGrid/subcomponents/Cards/subcomponents/LazyLoadCard/index.d.ts +17 -0
- package/components/DataGrid/subcomponents/Cards/subcomponents/LazyLoadCard/index.js +34 -0
- package/components/DataGrid/subcomponents/Cards/types.d.ts +118 -0
- package/components/DataGrid/subcomponents/CheckboxCellAdapter/index.d.ts +7 -0
- package/components/DataGrid/subcomponents/CheckboxCellAdapter/index.js +43 -0
- package/components/DataGrid/subcomponents/CheckboxCellAdapter/types.d.ts +7 -0
- package/components/DataGrid/subcomponents/ControlNavigate/ControlNavigate.js +1 -1
- package/components/DataGrid/subcomponents/HeaderActions/index.js +5 -3
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/RowsCount/index.js +1 -1
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/Settings/index.js +11 -2
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/Settings/subcomponents/ColumnsConfig/index.js +1 -1
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/Settings/subcomponents/ColumnsConfigCards/index.d.ts +2 -0
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/Settings/subcomponents/ColumnsConfigCards/index.js +304 -0
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/Settings/subcomponents/ColumnsConfigCards/types.d.ts +31 -0
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/ViewMode/index.d.ts +4 -0
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/ViewMode/index.js +125 -0
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/hooks/useModalSettings/index.js +2 -2
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/hooks/useModalSettingsCards/index.d.ts +7 -0
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/hooks/useModalSettingsCards/index.js +74 -0
- package/components/DataGrid/subcomponents/HeaderActions/subcomponents/hooks/useModalSettingsCards/types.d.ts +4 -0
- package/components/DataGrid/subcomponents/RenderContent/index.d.ts +5 -0
- package/components/DataGrid/subcomponents/RenderContent/index.js +11 -0
- package/components/DataGrid/subcomponents/Table/hooks/useHeaderMenuActions.js +2 -2
- package/components/DataGrid/subcomponents/Table/hooks/useSortColumnsRows.js +1 -1
- package/components/DataGrid/subcomponents/Table/index.js +1 -1
- package/components/DataGrid/subcomponents/Table/subcomponents/ActionsColumn.js +1 -1
- package/components/DataGrid/subcomponents/Table/subcomponents/DraggableHeaderRenderer.js +1 -1
- package/components/DataGrid/subcomponents/Table/subcomponents/HeaderRenderClick/HeaderRenderClick.js +1 -1
- package/components/DataGrid/subcomponents/editors/TextEditor/index.js +1 -1
- package/components/DataGrid/tests/components/CardDetails.test.d.ts +1 -0
- package/components/DataGrid/tests/components/CardHeader.test.d.ts +1 -0
- package/components/DataGrid/tests/components/CardRow.test.d.ts +1 -0
- package/components/DataGrid/tests/components/Cards.test.d.ts +1 -0
- package/components/DataGrid/tests/components/CheckboxCellAdapter.test.d.ts +1 -0
- package/components/DataGrid/tests/components/ColumnsConfigCards.test.d.ts +1 -0
- package/components/DataGrid/tests/components/IntersectCard.test.d.ts +1 -0
- package/components/DataGrid/tests/components/ViewMode.test.d.ts +1 -0
- package/components/DataGrid/tests/helpers/types.d.ts +1 -0
- package/components/DataGrid/tests/helpers/useCardsViewConfig.d.ts +24 -0
- package/components/DataGrid/tests/helpers/useCustomCardExample.d.ts +7 -0
- package/components/DataGrid/tests/hooks/useCardContent.test.d.ts +1 -0
- package/components/DataGrid/tests/hooks/useModalDetail.test.d.ts +1 -0
- package/components/DataGrid/tests/hooks/useModalSettingsCards.test.d.ts +1 -0
- package/components/DataGrid/tests/hooks/useProcessedColumns.test.d.ts +1 -0
- package/components/DataGrid/types.d.ts +87 -5
- package/components/MFIsolationAppStorybook/MFIsolationAppStorybook.d.ts +5 -0
- package/components/MFIsolationAppStorybook/constants.d.ts +1 -0
- package/components/MFIsolationAppStorybook/icons.d.ts +3 -0
- package/components/MFIsolationAppStorybook/index.d.ts +1 -0
- package/components/MFIsolationAppStorybook/subcomponents/AppBarSettings/AppBarSettings.d.ts +4 -0
- package/components/MFIsolationAppStorybook/subcomponents/AppBarSettings/index.d.ts +1 -0
- package/components/MFIsolationAppStorybook/subcomponents/MFAuthAppStorybook/MFAuthAppStorybook.d.ts +5 -0
- package/components/MFIsolationAppStorybook/subcomponents/MFAuthAppStorybook/index.d.ts +1 -0
- package/components/MFIsolationAppStorybook/subcomponents/MFAuthAppStorybook/types.d.ts +4 -0
- package/components/MFIsolationAppStorybook/types.d.ts +31 -0
- package/components/MenuActions/MenuActions.js +105 -55
- package/components/areas/contexts/AreasContext/store.js +2 -2
- package/components/hook-form/RHFormContext/index.d.ts +1 -1
- package/hooks/useDataGridPersistence/helpers.d.ts +2 -2
- package/hooks/useDataGridPersistence/useDataGridPersistence.d.ts +2 -2
- package/hooks/useDataGridPersistence/useDataGridPersistence.js +5 -0
- package/index.js +8 -8
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CardDetailsProps } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Componente genérico que renderiza TODAS las columnas de una fila
|
|
4
|
+
* en formato detalle dentro del modal.
|
|
5
|
+
*
|
|
6
|
+
* A diferencia del componente Cards, este muestra TODAS las columnas
|
|
7
|
+
*/
|
|
8
|
+
export declare function CardDetails<TRow>({ row, columns, viewColumnsConfig, onRowsChange, size, }: CardDetailsProps<TRow>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { f as CardDetailContainerStyled, c as ContainerLabelValueColumnStyled, d as ContentWrapperColumnStyled, L as LabelHeaderColumnStyled, E as EditorCellWrapperStyled, V as ValueColumnStyled } from "../../../../slots/DataGridSlot.js";
|
|
4
|
+
function CardDetails({
|
|
5
|
+
row,
|
|
6
|
+
columns,
|
|
7
|
+
viewColumnsConfig,
|
|
8
|
+
onRowsChange,
|
|
9
|
+
size = "medium"
|
|
10
|
+
}) {
|
|
11
|
+
const [editingColumnKey, setEditingColumnKey] = useState(null);
|
|
12
|
+
return /* @__PURE__ */ jsx(CardDetailContainerStyled, { children: columns.map((column, index) => {
|
|
13
|
+
const configColumn = viewColumnsConfig.find(
|
|
14
|
+
(config) => config.key === column.key
|
|
15
|
+
);
|
|
16
|
+
const shouldShowTitle = configColumn?.showTitle !== false;
|
|
17
|
+
return /* @__PURE__ */ jsx(ContainerLabelValueColumnStyled, { children: /* @__PURE__ */ jsxs(
|
|
18
|
+
ContentWrapperColumnStyled,
|
|
19
|
+
{
|
|
20
|
+
"data-testid": `card-detail-column-${column.key}`,
|
|
21
|
+
onDoubleClick: column.renderEditCell && editingColumnKey !== column.key ? () => {
|
|
22
|
+
setEditingColumnKey(column.key);
|
|
23
|
+
} : void 0,
|
|
24
|
+
children: [
|
|
25
|
+
shouldShowTitle && /* @__PURE__ */ jsxs(LabelHeaderColumnStyled, { variant: "body", color: "text.secondary", children: [
|
|
26
|
+
column.name,
|
|
27
|
+
":"
|
|
28
|
+
] }),
|
|
29
|
+
(() => {
|
|
30
|
+
if (column.renderEditCell && editingColumnKey === column.key) {
|
|
31
|
+
return /* @__PURE__ */ jsx(EditorCellWrapperStyled, { ownerState: { size }, children: column.renderEditCell({
|
|
32
|
+
column,
|
|
33
|
+
row,
|
|
34
|
+
rowIdx: index,
|
|
35
|
+
/**
|
|
36
|
+
* onRowChange es una función que se ejecuta cuando el usuario edita una celda.
|
|
37
|
+
*/
|
|
38
|
+
onRowChange: (updatedRow) => {
|
|
39
|
+
if (onRowsChange) {
|
|
40
|
+
onRowsChange([updatedRow], {
|
|
41
|
+
indexes: [index],
|
|
42
|
+
column
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
onClose: () => setEditingColumnKey(null)
|
|
47
|
+
}) });
|
|
48
|
+
}
|
|
49
|
+
if (column.renderCell) {
|
|
50
|
+
const cellContent = column.renderCell({
|
|
51
|
+
column,
|
|
52
|
+
row,
|
|
53
|
+
rowIdx: index,
|
|
54
|
+
isCellSelected: false,
|
|
55
|
+
tabIndex: -1,
|
|
56
|
+
/**
|
|
57
|
+
* onRowChange es una función que se ejecuta cuando el usuario edita una celda.
|
|
58
|
+
*/
|
|
59
|
+
onRowChange: (updatedRow) => {
|
|
60
|
+
if (onRowsChange) {
|
|
61
|
+
onRowsChange([updatedRow], {
|
|
62
|
+
indexes: [index],
|
|
63
|
+
column
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
return /* @__PURE__ */ jsx(ValueColumnStyled, { variant: "body", color: "text.primary", children: cellContent });
|
|
69
|
+
}
|
|
70
|
+
return /* @__PURE__ */ jsx(ValueColumnStyled, { variant: "body", color: "text.primary", children: row[column.key] ?? "-" });
|
|
71
|
+
})()
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
) }, column.key);
|
|
75
|
+
}) });
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
CardDetails as C
|
|
79
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CardHeaderProps } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Componente CardHeader que renderiza el header de cada card con:
|
|
4
|
+
* - Checkbox en el lado izquierdo (solo si existen checkedRows/onCheckedRowsChange)
|
|
5
|
+
* - Botones de acción en el lado derecho (IconButton + MenuActions)
|
|
6
|
+
*/
|
|
7
|
+
export declare function CardHeader<TRow>({ row, onOpenDetail }: CardHeaderProps<TRow>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useCallback } from "react";
|
|
3
|
+
import { useEnvironment } from "@m4l/core";
|
|
4
|
+
import { u as useDataGrid } from "../../../../hooks/useDataGrid.js";
|
|
5
|
+
import { g as CardHeaderStyled, h as CardHeaderLeftStyled, i as CardHeaderRightStyled } from "../../../../slots/DataGridSlot.js";
|
|
6
|
+
import { p as pathIcons } from "../../../../icons.js";
|
|
7
|
+
import { C as CheckboxCellAdapter } from "../../../CheckboxCellAdapter/index.js";
|
|
8
|
+
import { I as IconButton } from "../../../../../mui_extended/IconButton/IconButton.js";
|
|
9
|
+
import { M as MenuActions } from "../../../../../MenuActions/MenuActions.js";
|
|
10
|
+
function CardHeader({ row, onOpenDetail }) {
|
|
11
|
+
const {
|
|
12
|
+
rowKeyGetter,
|
|
13
|
+
checkedRows,
|
|
14
|
+
onCheckedRowsChange,
|
|
15
|
+
rowActionsGetter,
|
|
16
|
+
size
|
|
17
|
+
} = useDataGrid();
|
|
18
|
+
const { host_static_assets, environment_assets } = useEnvironment();
|
|
19
|
+
const rowKey = useMemo(() => rowKeyGetter(row), [rowKeyGetter, row]);
|
|
20
|
+
const showCheckbox = useMemo(
|
|
21
|
+
() => checkedRows !== void 0 && onCheckedRowsChange !== void 0,
|
|
22
|
+
[checkedRows, onCheckedRowsChange]
|
|
23
|
+
);
|
|
24
|
+
const isChecked = useMemo(
|
|
25
|
+
() => checkedRows?.has(rowKey) || false,
|
|
26
|
+
[checkedRows, rowKey]
|
|
27
|
+
);
|
|
28
|
+
const onChange = useCallback(
|
|
29
|
+
(checked, _isShiftClick) => {
|
|
30
|
+
if (!onCheckedRowsChange) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const newCheckedRows = new Set(checkedRows);
|
|
34
|
+
if (checked) {
|
|
35
|
+
newCheckedRows.add(rowKey);
|
|
36
|
+
} else {
|
|
37
|
+
newCheckedRows.delete(rowKey);
|
|
38
|
+
}
|
|
39
|
+
onCheckedRowsChange(newCheckedRows);
|
|
40
|
+
},
|
|
41
|
+
[checkedRows, onCheckedRowsChange, rowKey]
|
|
42
|
+
);
|
|
43
|
+
const anchorOrigin = useMemo(
|
|
44
|
+
() => ({
|
|
45
|
+
vertical: "bottom",
|
|
46
|
+
horizontal: "right"
|
|
47
|
+
}),
|
|
48
|
+
[]
|
|
49
|
+
);
|
|
50
|
+
const transformOrigin = useMemo(
|
|
51
|
+
() => ({
|
|
52
|
+
vertical: "top",
|
|
53
|
+
horizontal: "right"
|
|
54
|
+
}),
|
|
55
|
+
[]
|
|
56
|
+
);
|
|
57
|
+
return /* @__PURE__ */ jsxs(CardHeaderStyled, { ownerState: { hasCheckedRows: showCheckbox }, children: [
|
|
58
|
+
showCheckbox && /* @__PURE__ */ jsx(CardHeaderLeftStyled, { children: /* @__PURE__ */ jsx(
|
|
59
|
+
CheckboxCellAdapter,
|
|
60
|
+
{
|
|
61
|
+
value: isChecked,
|
|
62
|
+
tabIndex: -1,
|
|
63
|
+
onChange,
|
|
64
|
+
"aria-label": "Select"
|
|
65
|
+
}
|
|
66
|
+
) }),
|
|
67
|
+
/* @__PURE__ */ jsxs(CardHeaderRightStyled, { children: [
|
|
68
|
+
/* @__PURE__ */ jsx(
|
|
69
|
+
IconButton,
|
|
70
|
+
{
|
|
71
|
+
icon: `${host_static_assets}/${environment_assets}/${pathIcons.expanded}`,
|
|
72
|
+
size,
|
|
73
|
+
variant: "text",
|
|
74
|
+
"data-testid": `card-details-button-${rowKey}`,
|
|
75
|
+
onClick: (e) => {
|
|
76
|
+
e.stopPropagation();
|
|
77
|
+
onOpenDetail();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
rowActionsGetter && /* @__PURE__ */ jsx(
|
|
82
|
+
MenuActions,
|
|
83
|
+
{
|
|
84
|
+
arrowType: "top-left",
|
|
85
|
+
objItem: row,
|
|
86
|
+
menuActions: rowActionsGetter,
|
|
87
|
+
anchorOrigin,
|
|
88
|
+
transformOrigin,
|
|
89
|
+
onClick: (e) => e.stopPropagation(),
|
|
90
|
+
variant: "text"
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
] })
|
|
94
|
+
] });
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
CardHeader as C
|
|
98
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { RowKey } from '../../../../types';
|
|
2
|
+
import { CardRowProps } from '../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Componente que muestra una fila de tarjetas.
|
|
5
|
+
*/
|
|
6
|
+
export declare function CardRow<TRow, TKey extends RowKey = RowKey>({ row, columns, originalColumns, rowKeyGetter, selectedRows, onSelectedRowsChange, onRowsChange, customRender, }: CardRowProps<TRow, TKey>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { j as CardStyled } from "../../../../slots/DataGridSlot.js";
|
|
4
|
+
import { L as LazyLoadCard } from "../LazyLoadCard/index.js";
|
|
5
|
+
import { u as useCardContent } from "../../hooks/useCardContent.js";
|
|
6
|
+
import { C as CardHeader } from "../CardHeader/index.js";
|
|
7
|
+
import { u as useDataGrid } from "../../../../hooks/useDataGrid.js";
|
|
8
|
+
function CardRow({
|
|
9
|
+
row,
|
|
10
|
+
columns,
|
|
11
|
+
originalColumns,
|
|
12
|
+
rowKeyGetter,
|
|
13
|
+
selectedRows,
|
|
14
|
+
onSelectedRowsChange,
|
|
15
|
+
onRowsChange,
|
|
16
|
+
customRender
|
|
17
|
+
}) {
|
|
18
|
+
const { checkedRows } = useDataGrid();
|
|
19
|
+
const hasCustomRender = customRender !== void 0;
|
|
20
|
+
const { cardContent, columnsCount, onOpenDetail } = useCardContent({
|
|
21
|
+
row,
|
|
22
|
+
columns,
|
|
23
|
+
originalColumns,
|
|
24
|
+
onRowsChange
|
|
25
|
+
});
|
|
26
|
+
const isChecked = useMemo(
|
|
27
|
+
() => checkedRows?.has(rowKeyGetter(row)) || false,
|
|
28
|
+
[checkedRows, rowKeyGetter, row]
|
|
29
|
+
);
|
|
30
|
+
const content = useMemo(() => {
|
|
31
|
+
if (hasCustomRender) {
|
|
32
|
+
return customRender.renderContent(row);
|
|
33
|
+
}
|
|
34
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
35
|
+
/* @__PURE__ */ jsx(CardHeader, { row, onOpenDetail }),
|
|
36
|
+
cardContent
|
|
37
|
+
] });
|
|
38
|
+
}, [hasCustomRender, customRender, row, cardContent, onOpenDetail]);
|
|
39
|
+
const onCardClick = () => {
|
|
40
|
+
if (selectedRows && onSelectedRowsChange) {
|
|
41
|
+
if (selectedRows.has(rowKeyGetter(row))) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const mySet = /* @__PURE__ */ new Set([rowKeyGetter(row)]);
|
|
45
|
+
onSelectedRowsChange(mySet);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const dynamicMinHeight = useMemo(() => {
|
|
49
|
+
if (hasCustomRender) {
|
|
50
|
+
return customRender.minHeight;
|
|
51
|
+
}
|
|
52
|
+
return Math.max(120, columnsCount * 32 + 40);
|
|
53
|
+
}, [hasCustomRender, customRender, columnsCount]);
|
|
54
|
+
return /* @__PURE__ */ jsx(LazyLoadCard, { threshold: 200, minHeight: dynamicMinHeight, children: /* @__PURE__ */ jsx(
|
|
55
|
+
CardStyled,
|
|
56
|
+
{
|
|
57
|
+
variant: "outlined",
|
|
58
|
+
selected: selectedRows?.has(rowKeyGetter(row)),
|
|
59
|
+
ownerState: {
|
|
60
|
+
checked: isChecked,
|
|
61
|
+
selected: selectedRows?.has(rowKeyGetter(row))
|
|
62
|
+
},
|
|
63
|
+
onClick: onCardClick,
|
|
64
|
+
"data-testid": "data-grid-card",
|
|
65
|
+
children: content
|
|
66
|
+
}
|
|
67
|
+
) });
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
CardRow as C
|
|
71
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IntersectCardProps } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Componente centinela que detecta cuando una card debe ser renderizada.
|
|
4
|
+
*
|
|
5
|
+
* Utiliza la API IntersectionObserver para detectar cuándo este componente
|
|
6
|
+
* entra en el viewport del usuario, momento en el cual notifica al componente
|
|
7
|
+
* padre para que renderice la card real en lugar del placeholder.
|
|
8
|
+
* @param props - Props del componente IntersectCard
|
|
9
|
+
* @returns Elemento span invisible que actúa como centinela
|
|
10
|
+
*
|
|
11
|
+
* Flujo de funcionamiento:
|
|
12
|
+
* 1. Se renderiza un span invisible en la posición de la card
|
|
13
|
+
* 2. El IntersectionObserver vigila este span
|
|
14
|
+
* 3. Cuando el span entra en el viewport (+ threshold):
|
|
15
|
+
* - Se ejecuta checkIntersections
|
|
16
|
+
* - Se llama a setIsVisible(true)
|
|
17
|
+
* - El componente padre reemplaza este placeholder con la card real
|
|
18
|
+
* 4. El observer deja de observar automáticamente el elemento
|
|
19
|
+
*/
|
|
20
|
+
export declare function IntersectCard(props: IntersectCardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useRef, useEffect } from "react";
|
|
3
|
+
import { styled } from "@mui/material/styles";
|
|
4
|
+
const checkIntersections = (entries) => {
|
|
5
|
+
entries.forEach((entry) => {
|
|
6
|
+
if (entry.isIntersecting) {
|
|
7
|
+
entry.target?.setIsVisible(true);
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
const LAZY_LOAD_OBSERVERS = {};
|
|
12
|
+
const getObserver = (threshold) => {
|
|
13
|
+
LAZY_LOAD_OBSERVERS[threshold] = LAZY_LOAD_OBSERVERS[threshold] || new IntersectionObserver(checkIntersections, {
|
|
14
|
+
rootMargin: threshold + "px"
|
|
15
|
+
});
|
|
16
|
+
return LAZY_LOAD_OBSERVERS[threshold];
|
|
17
|
+
};
|
|
18
|
+
const IntersectCardStyled = styled("div")(
|
|
19
|
+
({ minHeight }) => ({
|
|
20
|
+
minHeight: `${minHeight}px`,
|
|
21
|
+
width: "100%"
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
function IntersectCard(props) {
|
|
25
|
+
const { setIsVisible, threshold, minHeight = 120 } = props;
|
|
26
|
+
const [observer] = useState(
|
|
27
|
+
getObserver(threshold)
|
|
28
|
+
);
|
|
29
|
+
const intersectCardRef = useRef(null);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const element = intersectCardRef.current;
|
|
32
|
+
if (observer && element) {
|
|
33
|
+
element.setIsVisible = setIsVisible;
|
|
34
|
+
observer.observe(element);
|
|
35
|
+
}
|
|
36
|
+
return () => {
|
|
37
|
+
if (observer && element) {
|
|
38
|
+
observer.unobserve(element);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}, [observer, setIsVisible]);
|
|
42
|
+
return /* @__PURE__ */ jsx(IntersectCardStyled, { ref: intersectCardRef, minHeight });
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
IntersectCard as I
|
|
46
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { LazyLoadCardProps } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Componente wrapper que implementa lazy loading para cards del DataGrid.
|
|
4
|
+
*
|
|
5
|
+
* Controla cuándo renderizar el contenido real de una card basándose en
|
|
6
|
+
* su visibilidad en el viewport.
|
|
7
|
+
* @returns Contenido de la card o placeholder según su visibilidad
|
|
8
|
+
*
|
|
9
|
+
* **Cuando IntersectionObserver NO está disponible:**
|
|
10
|
+
* - Se renderiza inmediatamente el contenido real
|
|
11
|
+
*
|
|
12
|
+
* **Cuando IntersectionObserver SÍ está disponible:**
|
|
13
|
+
* - Fase 1: Renderiza IntersectCard
|
|
14
|
+
* - Fase 2: Cuando entra en viewport → isVisible = true
|
|
15
|
+
* - Fase 3: Renderiza el contenido real (children)
|
|
16
|
+
*/
|
|
17
|
+
export declare function LazyLoadCard(props: LazyLoadCardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { I as IntersectCard } from "../IntersectCard/index.js";
|
|
4
|
+
const isIntersectionObserverAvailable = () => {
|
|
5
|
+
return typeof window !== "undefined" && "IntersectionObserver" in window && "IntersectionObserverEntry" in window && "intersectionRatio" in window.IntersectionObserverEntry.prototype;
|
|
6
|
+
};
|
|
7
|
+
function LazyLoadCard(props) {
|
|
8
|
+
const {
|
|
9
|
+
children,
|
|
10
|
+
enableIntersectionObserver = true,
|
|
11
|
+
threshold = 100,
|
|
12
|
+
minHeight = 120
|
|
13
|
+
} = props;
|
|
14
|
+
const [isVisible, setIsVisible] = useState(
|
|
15
|
+
!(enableIntersectionObserver && isIntersectionObserverAvailable())
|
|
16
|
+
);
|
|
17
|
+
return /* @__PURE__ */ jsx(Fragment, { children: isVisible ? (
|
|
18
|
+
// Contenido real: se renderiza cuando es visible o cuando no se usa observer
|
|
19
|
+
children
|
|
20
|
+
) : (
|
|
21
|
+
// Placeholder: elemento centinela que detecta cuándo debe cargar el contenido
|
|
22
|
+
/* @__PURE__ */ jsx(
|
|
23
|
+
IntersectCard,
|
|
24
|
+
{
|
|
25
|
+
setIsVisible,
|
|
26
|
+
threshold,
|
|
27
|
+
minHeight
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
) });
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
LazyLoadCard as L
|
|
34
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Column, RowsChangeData } from 'react-data-grid';
|
|
2
|
+
import { CardsViewConfig, RowKey } from '../../types';
|
|
3
|
+
import { Maybe } from '@m4l/core';
|
|
4
|
+
import { IViewConfig } from '../../contexts/DataGridContext/types';
|
|
5
|
+
import { Sizes } from '@m4l/styles';
|
|
6
|
+
/**
|
|
7
|
+
* Props para el componente IntersectCard
|
|
8
|
+
*/
|
|
9
|
+
export interface IntersectCardProps {
|
|
10
|
+
/**
|
|
11
|
+
* Función callback que se ejecuta cuando el elemento entra en el viewport.
|
|
12
|
+
* Recibe true cuando el elemento es visible.
|
|
13
|
+
* @param visible - Estado de visibilidad del elemento
|
|
14
|
+
*/
|
|
15
|
+
setIsVisible: (visible: boolean) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Distancia en píxeles desde el borde del viewport donde se activa la detección.
|
|
18
|
+
* Un valor de 100 significa que el elemento se considerará visible cuando esté
|
|
19
|
+
* a 100px o menos del área visible de la pantalla.
|
|
20
|
+
* @default 100
|
|
21
|
+
*/
|
|
22
|
+
threshold: number;
|
|
23
|
+
/**
|
|
24
|
+
* Altura mínima del placeholder en píxeles
|
|
25
|
+
* @default '120px'
|
|
26
|
+
*/
|
|
27
|
+
minHeight?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Tipo extendido para el elemento div que incluye el método setIsVisible.
|
|
31
|
+
* Este método se adjunta dinámicamente al elemento DOM para que el Observer
|
|
32
|
+
* pueda comunicarse con el componente React.
|
|
33
|
+
*/
|
|
34
|
+
export type IntersectCardRef = HTMLDivElement & {
|
|
35
|
+
setIsVisible?: (visible: boolean) => void;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Props para el componente LazyLoadCard
|
|
39
|
+
*/
|
|
40
|
+
export interface LazyLoadCardProps {
|
|
41
|
+
/**
|
|
42
|
+
* Contenido de la card que se renderizará una vez que sea visible.
|
|
43
|
+
* Típicamente será un componente Card con los datos de la fila.
|
|
44
|
+
*/
|
|
45
|
+
children: React.ReactNode;
|
|
46
|
+
/**
|
|
47
|
+
* Habilita o deshabilita el lazy loading con IntersectionObserver.
|
|
48
|
+
* Si se deshabilita, la card se renderiza inmediatamente.
|
|
49
|
+
* @default true
|
|
50
|
+
*/
|
|
51
|
+
enableIntersectionObserver?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Distancia en píxeles desde el borde del viewport donde se activa la carga.
|
|
54
|
+
* Un valor más alto carga las cards antes de que sean visibles,
|
|
55
|
+
* mejorando la experiencia del usuario.
|
|
56
|
+
* @default 100
|
|
57
|
+
*/
|
|
58
|
+
threshold?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Altura mínima del placeholder en píxeles
|
|
61
|
+
* @default 120
|
|
62
|
+
*/
|
|
63
|
+
minHeight?: number;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Props para el componente CardRow
|
|
67
|
+
*/
|
|
68
|
+
export interface CardRowProps<TRow, TKey extends RowKey = RowKey> {
|
|
69
|
+
/**
|
|
70
|
+
* Fila que se mostrará en la tarjeta
|
|
71
|
+
*/
|
|
72
|
+
row: TRow;
|
|
73
|
+
/**
|
|
74
|
+
* Columnas que se mostrarán en la tarjeta (procesadas, filtradas por visibilidad)
|
|
75
|
+
*/
|
|
76
|
+
columns: readonly Column<TRow, any>[];
|
|
77
|
+
/**
|
|
78
|
+
* Columnas originales sin filtrar (para el modal de detalle)
|
|
79
|
+
*/
|
|
80
|
+
originalColumns: readonly Column<TRow, any>[];
|
|
81
|
+
/**
|
|
82
|
+
* Función que devuelve la clave de la fila
|
|
83
|
+
*/
|
|
84
|
+
rowKeyGetter: (row: TRow) => TKey;
|
|
85
|
+
/**
|
|
86
|
+
* Filas seleccionadas actualmente
|
|
87
|
+
*/
|
|
88
|
+
selectedRows?: ReadonlySet<TKey>;
|
|
89
|
+
/**
|
|
90
|
+
* Función para manejar el cambio de filas seleccionadas
|
|
91
|
+
*/
|
|
92
|
+
onSelectedRowsChange?: (mapRowsSelected: ReadonlySet<TKey>) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Función para manejar cambios en las filas (para editores)
|
|
95
|
+
*/
|
|
96
|
+
onRowsChange?: Maybe<(rows: TRow[], data: RowsChangeData<TRow, any>) => void>;
|
|
97
|
+
/**
|
|
98
|
+
* Indica si se debe renderizar el contenido personalizado de la tarjeta
|
|
99
|
+
*/
|
|
100
|
+
customRender?: CardsViewConfig<TRow>['customRender'];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Props para el componente CardDetails
|
|
104
|
+
*/
|
|
105
|
+
export interface CardDetailsProps<TRow> {
|
|
106
|
+
row: TRow;
|
|
107
|
+
columns: readonly Column<TRow, any>[];
|
|
108
|
+
viewColumnsConfig: IViewConfig<any, any>[];
|
|
109
|
+
onRowsChange?: Maybe<(rows: TRow[], data: RowsChangeData<TRow, any>) => void>;
|
|
110
|
+
size?: Extract<Sizes, 'small' | 'medium'>;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Props para el componente CardHeader
|
|
114
|
+
*/
|
|
115
|
+
export interface CardHeaderProps<TRow> {
|
|
116
|
+
row: TRow;
|
|
117
|
+
onOpenDetail: () => void;
|
|
118
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CheckboxCellAdapterProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador que renderiza el checkbox apropidado según el viewMode
|
|
4
|
+
* - En viewMode 'cards': usa CheckboxFormatter (MUI)
|
|
5
|
+
* - En viewMode 'table': usa SelectCellFormatter (react-data-grid)
|
|
6
|
+
*/
|
|
7
|
+
export declare const CheckboxCellAdapter: import('react').ForwardRefExoticComponent<CheckboxCellAdapterProps & import('react').RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useContext } from "react";
|
|
3
|
+
import { SelectCellFormatter } from "react-data-grid";
|
|
4
|
+
import { C as CheckboxFormatter } from "../Table/subcomponents/CheckboxFormatter.js";
|
|
5
|
+
import { a as DataGridContext } from "../../contexts/DataGridContext/index.js";
|
|
6
|
+
import { k as CheckboxCellWrapperStyled } from "../../slots/DataGridSlot.js";
|
|
7
|
+
const CheckboxCellAdapter = forwardRef(function CheckboxCellAdapter2(props, ref) {
|
|
8
|
+
const {
|
|
9
|
+
value,
|
|
10
|
+
disabled,
|
|
11
|
+
tabIndex,
|
|
12
|
+
onChange,
|
|
13
|
+
"aria-label": ariaLabel
|
|
14
|
+
} = props;
|
|
15
|
+
const context = useContext(DataGridContext);
|
|
16
|
+
const viewMode = context?.viewMode ?? "cards";
|
|
17
|
+
if (viewMode !== "table") {
|
|
18
|
+
return /* @__PURE__ */ jsx(CheckboxCellWrapperStyled, { children: /* @__PURE__ */ jsx(
|
|
19
|
+
CheckboxFormatter,
|
|
20
|
+
{
|
|
21
|
+
ref,
|
|
22
|
+
checked: value,
|
|
23
|
+
disabled,
|
|
24
|
+
tabIndex,
|
|
25
|
+
onChange,
|
|
26
|
+
"aria-label": ariaLabel
|
|
27
|
+
}
|
|
28
|
+
) });
|
|
29
|
+
}
|
|
30
|
+
return /* @__PURE__ */ jsx(
|
|
31
|
+
SelectCellFormatter,
|
|
32
|
+
{
|
|
33
|
+
value,
|
|
34
|
+
disabled,
|
|
35
|
+
tabIndex,
|
|
36
|
+
onChange,
|
|
37
|
+
"aria-label": ariaLabel || "Select"
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
export {
|
|
42
|
+
CheckboxCellAdapter as C
|
|
43
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useIsMobile } from "@m4l/graphics";
|
|
3
|
-
import {
|
|
3
|
+
import { l as ControlNavigateStyled } from "../../slots/DataGridSlot.js";
|
|
4
4
|
import { R as RowsCount } from "../HeaderActions/subcomponents/RowsCount/index.js";
|
|
5
5
|
import { u as useComponentSize } from "../../../../hooks/useComponentSize/useComponentSize.js";
|
|
6
6
|
import { P as Pager } from "../../../Pager/Pager.js";
|
|
@@ -2,10 +2,11 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
|
2
2
|
import { F as Filter } from "./subcomponents/Filter/index.js";
|
|
3
3
|
import { S as Settings } from "./subcomponents/Settings/index.js";
|
|
4
4
|
import { D as Density } from "./subcomponents/Density/index.js";
|
|
5
|
+
import { V as ViewMode } from "./subcomponents/ViewMode/index.js";
|
|
5
6
|
import { u as useDataGrid } from "../../hooks/useDataGrid.js";
|
|
6
7
|
import { useIsMobile } from "@m4l/graphics";
|
|
7
8
|
import { M as MobileMenuActions } from "./subcomponents/MobileMenuActions/index.js";
|
|
8
|
-
import { A as ActionsRootStyled,
|
|
9
|
+
import { A as ActionsRootStyled, m as ActionsConfigContainerStyled, n as ContainerLeftActionsStyled, o as ContainerRightActionsStyled } from "../../slots/DataGridSlot.js";
|
|
9
10
|
import { u as useComponentSize } from "../../../../hooks/useComponentSize/useComponentSize.js";
|
|
10
11
|
function HeaderActions(props) {
|
|
11
12
|
const {
|
|
@@ -19,7 +20,7 @@ function HeaderActions(props) {
|
|
|
19
20
|
columns
|
|
20
21
|
} = props;
|
|
21
22
|
const isMobile = useIsMobile();
|
|
22
|
-
const { rowHeights } = useDataGrid();
|
|
23
|
+
const { rowHeights, viewMode, cardsViewConfig } = useDataGrid();
|
|
23
24
|
const { currentSize } = useComponentSize(size);
|
|
24
25
|
return /* @__PURE__ */ jsx(ActionsRootStyled, { ownerState: { size: currentSize }, children: isMobile ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
25
26
|
leftActions,
|
|
@@ -30,7 +31,8 @@ function HeaderActions(props) {
|
|
|
30
31
|
leftActions,
|
|
31
32
|
typeof rowHeights !== "number" && /* @__PURE__ */ jsx(Density, {}),
|
|
32
33
|
withLocalFilters && /* @__PURE__ */ jsx(Filter, {}),
|
|
33
|
-
withSettings && /* @__PURE__ */ jsx(Settings, { ...settingsProps, columns })
|
|
34
|
+
withSettings && !(viewMode === "cards" && cardsViewConfig?.customRender) && /* @__PURE__ */ jsx(Settings, { ...settingsProps, columns }),
|
|
35
|
+
cardsViewConfig !== void 0 && /* @__PURE__ */ jsx(ViewMode, {})
|
|
34
36
|
] }),
|
|
35
37
|
rightActions && /* @__PURE__ */ jsx(ContainerRightActionsStyled, { children: rightActions })
|
|
36
38
|
] }) });
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
|
2
2
|
import { useModuleDictionary, useModuleSkeleton } from "@m4l/core";
|
|
3
3
|
import { Skeleton } from "@mui/material";
|
|
4
4
|
import { u as useDataGrid } from "../../../../hooks/useDataGrid.js";
|
|
5
|
-
import { R as RowsCountRootStyled,
|
|
5
|
+
import { R as RowsCountRootStyled, p as RowsCountLabelStyled, q as RowsCountValueStyled } from "../../../../slots/DataGridSlot.js";
|
|
6
6
|
function RowsCount() {
|
|
7
7
|
const { rowsCount, size } = useDataGrid();
|
|
8
8
|
const { getLabel } = useModuleDictionary();
|
|
@@ -4,17 +4,26 @@ import { useEnvironment, useModuleDictionary } from "@m4l/core";
|
|
|
4
4
|
import { u as useModalSettings } from "../hooks/useModalSettings/index.js";
|
|
5
5
|
import { p as pathIcons } from "../../../../icons.js";
|
|
6
6
|
import { u as useDataGrid } from "../../../../hooks/useDataGrid.js";
|
|
7
|
+
import { u as useModalSettingsCards } from "../hooks/useModalSettingsCards/index.js";
|
|
7
8
|
function Settings(props) {
|
|
8
9
|
const { columns } = props;
|
|
9
10
|
const { host_static_assets, environment_assets } = useEnvironment();
|
|
10
|
-
const { size } = useDataGrid();
|
|
11
|
+
const { size, viewMode } = useDataGrid();
|
|
11
12
|
const modalSettings = useModalSettings(size, columns);
|
|
13
|
+
const modalSettingsCards = useModalSettingsCards(size, columns);
|
|
12
14
|
const { getLabel } = useModuleDictionary();
|
|
15
|
+
const handleClick = () => {
|
|
16
|
+
if (viewMode === "table") {
|
|
17
|
+
modalSettings();
|
|
18
|
+
} else {
|
|
19
|
+
modalSettingsCards();
|
|
20
|
+
}
|
|
21
|
+
};
|
|
13
22
|
return /* @__PURE__ */ jsx(
|
|
14
23
|
IconButton,
|
|
15
24
|
{
|
|
16
25
|
tooltip: getLabel("data_grid.tooltip_settings"),
|
|
17
|
-
onClick:
|
|
26
|
+
onClick: handleClick,
|
|
18
27
|
"aria-label": "settings",
|
|
19
28
|
icon: `${host_static_assets}/${environment_assets}/${pathIcons.configuration}`,
|
|
20
29
|
"data-testid": "settings-button"
|
|
@@ -4,7 +4,7 @@ import { useModuleDictionary, useEnvironment } from "@m4l/core";
|
|
|
4
4
|
import DataGrid from "react-data-grid";
|
|
5
5
|
import { I as IconButton } from "../../../../../../../mui_extended/IconButton/IconButton.js";
|
|
6
6
|
import { p as pathIcons } from "../../../../../../icons.js";
|
|
7
|
-
import {
|
|
7
|
+
import { r as ColumnsConfigWrapperStyled, s as ColumnsConfigDataGridStyled, t as ColumnsConfigSelColumnsStyled, T as TableWrapperDataGridStyled, u as ColumnsConfigActiosStyled } from "../../../../../../slots/DataGridSlot.js";
|
|
8
8
|
import { D as DICTIONARY } from "../../../../../../dictionary.js";
|
|
9
9
|
import { C as ColumnInteractiveCheckFormatter } from "../../../../../../formatters/ColumnInteractiveCheckFormatter/formatter.js";
|
|
10
10
|
function getRowsFromColumnsConfig(columnsConfig, columns) {
|