@m4l/components 9.2.60-J18062025.beta.1 → 9.2.60-J25062025.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.
@@ -625,11 +625,28 @@ const dataGridStyles = {
625
625
  /**
626
626
  * Estilos para el contenedor del nombre de la columna y el icono de sort
627
627
  */
628
- nameColumnIcon: () => ({
628
+ nameColumnIcon: ({ theme }) => ({
629
629
  display: "flex",
630
630
  alignItems: "center",
631
- justifyContent: "space-between",
632
- gap: "5px"
631
+ gap: theme.vars.size.baseSpacings.sp1,
632
+ position: "relative",
633
+ overflow: "visible"
634
+ }),
635
+ /**
636
+ * Estilos para el contenedor del nombre de la columna
637
+ */
638
+ nameColumn: () => ({
639
+ textOverflow: "ellipsis",
640
+ overflow: "hidden",
641
+ whiteSpace: "nowrap"
642
+ }),
643
+ /**
644
+ * Estilos para el contenedor del icono de la columna
645
+ */
646
+ iconColumn: ({ theme }) => ({
647
+ display: "flex",
648
+ alignItems: "center",
649
+ gap: theme.vars.size.baseSpacings.sp1
633
650
  }),
634
651
  /**
635
652
  * Estilos para el popover del header actions
@@ -15,6 +15,7 @@ export declare const pathIcons: {
15
15
  search: string;
16
16
  sortAsc: string;
17
17
  sortDesc: string;
18
+ filter2: string;
18
19
  removeSort: string;
19
20
  freezeColumn: string;
20
21
  unfreezeColumn: string;
@@ -15,6 +15,7 @@ const pathIcons = {
15
15
  search: "frontend/components/data_grid/assets/icons/search.svg",
16
16
  sortAsc: "frontend/components/data_grid/assets/icons/sort_asc.svg",
17
17
  sortDesc: "frontend/components/data_grid/assets/icons/sort_desc.svg",
18
+ filter2: "frontend/components/data_grid/assets/icons/filter.svg",
18
19
  removeSort: "frontend/components/data_grid/assets/icons/eraser.svg",
19
20
  freezeColumn: "frontend/components/data_grid/assets/icons/pin.svg",
20
21
  unfreezeColumn: "frontend/components/data_grid/assets/icons/pin-off.svg",
@@ -25,7 +25,9 @@ export declare enum TableSlots {
25
25
  headerRenderClick = "headerRenderClick",
26
26
  menuList = "menuList",
27
27
  buttonHeaderActions = "buttonHeaderActions",
28
- nameColumnIcon = "nameColumnIcon"
28
+ nameColumnIcon = "nameColumnIcon",
29
+ iconColumn = "iconColumn",
30
+ nameColumn = "nameColumn"
29
31
  }
30
32
  export declare enum TextEditorSlots {
31
33
  inputTexEditor = "inputTexEditor"
@@ -29,6 +29,8 @@ var TableSlots = /* @__PURE__ */ ((TableSlots2) => {
29
29
  TableSlots2["menuList"] = "menuList";
30
30
  TableSlots2["buttonHeaderActions"] = "buttonHeaderActions";
31
31
  TableSlots2["nameColumnIcon"] = "nameColumnIcon";
32
+ TableSlots2["iconColumn"] = "iconColumn";
33
+ TableSlots2["nameColumn"] = "nameColumn";
32
34
  return TableSlots2;
33
35
  })(TableSlots || {});
34
36
  var TextEditorSlots = /* @__PURE__ */ ((TextEditorSlots2) => {
@@ -48,6 +48,8 @@ export declare const HeaderRenderClickStyled: import('@emotion/styled').StyledCo
48
48
  export declare const MenuListStyled: import('@emotion/styled').StyledComponent<any, {}, {}>;
49
49
  export declare const ButtonHeaderActionsStyled: import('@emotion/styled').StyledComponent<any, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
50
50
  export declare const NameColumnIconStyled: import('@emotion/styled').StyledComponent<any, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
51
+ export declare const IconColumnStyled: import('@emotion/styled').StyledComponent<any, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
52
+ export declare const NameColumnStyled: import('@emotion/styled').StyledComponent<any, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
51
53
  /**
52
54
  * ****************
53
55
  * Slots TextEditor
@@ -104,6 +104,14 @@ const NameColumnIconStyled = styled("div", {
104
104
  name: DATAGRID_PREFIX_NAME,
105
105
  slot: TableSlots.nameColumnIcon
106
106
  })(dataGridStyles.nameColumnIcon);
107
+ const IconColumnStyled = styled("div", {
108
+ name: DATAGRID_PREFIX_NAME,
109
+ slot: TableSlots.iconColumn
110
+ })(dataGridStyles.iconColumn);
111
+ const NameColumnStyled = styled("div", {
112
+ name: DATAGRID_PREFIX_NAME,
113
+ slot: TableSlots.nameColumn
114
+ })(dataGridStyles.nameColumn);
107
115
  const InputTextEditorStyled = styled("input", {
108
116
  name: DATAGRID_PREFIX_NAME,
109
117
  slot: TextEditorSlots.inputTexEditor
@@ -118,7 +126,7 @@ export {
118
126
  CustomHeaderStyled as C,
119
127
  DataGridRootStyled as D,
120
128
  HeaderInputBaseStyled as H,
121
- IconSearchStyled as I,
129
+ IconColumnStyled as I,
122
130
  MenuListStyled as M,
123
131
  NameColumnIconStyled as N,
124
132
  RowsCountRootStyled as R,
@@ -136,8 +144,10 @@ export {
136
144
  ColumnsConfigActiosStyled as j,
137
145
  ContentModalSettingStyled as k,
138
146
  TableContainerStyled as l,
139
- DraggableHeaderRootStyled as m,
140
- DraggableWrapperInputBaseStyled as n,
141
- HeaderRenderClickStyled as o,
142
- InputTextEditorStyled as p
147
+ NameColumnStyled as m,
148
+ DraggableHeaderRootStyled as n,
149
+ DraggableWrapperInputBaseStyled as o,
150
+ IconSearchStyled as p,
151
+ HeaderRenderClickStyled as q,
152
+ InputTextEditorStyled as r
143
153
  };
@@ -21,7 +21,10 @@ function useHeaderMenuActions(columnKey, finalColumns, defaultSortable) {
21
21
  if (!columnKey) {
22
22
  return false;
23
23
  }
24
- return column?.sortable !== false ? defaultSortable : false;
24
+ if (typeof column?.sortable === "boolean") {
25
+ return column.sortable;
26
+ }
27
+ return defaultSortable;
25
28
  }, [columnKey, column, defaultSortable]);
26
29
  const canSortExternally = useMemo(() => {
27
30
  if (!columnKey || !externalSortSettings) {
@@ -208,7 +211,7 @@ function useHeaderMenuActions(columnKey, finalColumns, defaultSortable) {
208
211
  const filterAction = externalFilterSettings ? [
209
212
  {
210
213
  type: "menuItem",
211
- startIcon: `${host_static_assets}/${environment_assets}/${pathIcons.filter}`,
214
+ startIcon: `${host_static_assets}/${environment_assets}/${pathIcons.filter2}`,
212
215
  label: getLabel(DICTIONARY.ADD_FILTER_COLUMN),
213
216
  dataTestId: "filter-add",
214
217
  onClick: () => {
@@ -5,7 +5,7 @@ import { useDrag, useDrop } from "react-dnd";
5
5
  import { HeaderRenderer } from "react-data-grid";
6
6
  import { u as useFocusRef } from "../hooks/useFocusRef.js";
7
7
  import { u as useFilters } from "../../../hooks/useFilters.js";
8
- import { N as NameColumnIconStyled, m as DraggableHeaderRootStyled, B as ButtonHeaderActionsStyled, n as DraggableWrapperInputBaseStyled, I as IconSearchStyled, H as HeaderInputBaseStyled } from "../../../slots/DataGridSlot.js";
8
+ import { N as NameColumnIconStyled, m as NameColumnStyled, I as IconColumnStyled, n as DraggableHeaderRootStyled, B as ButtonHeaderActionsStyled, o as DraggableWrapperInputBaseStyled, p as IconSearchStyled, H as HeaderInputBaseStyled } from "../../../slots/DataGridSlot.js";
9
9
  import { p as pathIcons } from "../../../icons.js";
10
10
  import { u as useDataGrid } from "../../../hooks/useDataGrid.js";
11
11
  import { I as Icon } from "../../../../Icon/Icon.js";
@@ -20,14 +20,16 @@ function DraggableHeaderRenderer(props) {
20
20
  } = props;
21
21
  const { ref, tabIndex } = useFocusRef(isCellSelected);
22
22
  const { getLabel } = useModuleDictionary();
23
- const { size, classes } = useDataGrid();
23
+ const { size, classes, externalSortSettings, externalFilterSettings } = useDataGrid();
24
24
  const { host_static_assets, environment_assets } = useEnvironment();
25
25
  const { activeFilters, filters, onChangeFilter } = useFilters();
26
- const { externalSortSettings } = useDataGrid();
27
26
  const [filter, setFilter] = useState(filters?.get(column.key) || "");
28
27
  const currentExternalSort = externalSortSettings?.sortsApplied?.find(
29
28
  (s) => s.columnKey === column.key
30
29
  );
30
+ const currentExternalFilter = externalFilterSettings?.filtersApplied?.find(
31
+ (f) => f.columnKey === column.key
32
+ );
31
33
  const [{ isDragging }, drag] = useDrag({
32
34
  type: "COLUMN_DRAG",
33
35
  item: { key: column.key },
@@ -57,6 +59,38 @@ function DraggableHeaderRenderer(props) {
57
59
  setFilter(e.target.value);
58
60
  };
59
61
  const getSortIcon = (direction) => direction === "asc" ? `${host_static_assets}/${environment_assets}/${pathIcons.sortAsc}` : `${host_static_assets}/${environment_assets}/${pathIcons.sortDesc}`;
62
+ const getColumnIcons = () => {
63
+ const icons = [];
64
+ if (currentExternalSort) {
65
+ const sortIconPath = getSortIcon(currentExternalSort.direction);
66
+ icons.push(
67
+ /* @__PURE__ */ jsx(
68
+ Icon,
69
+ {
70
+ src: sortIconPath,
71
+ size: "small",
72
+ color: "text.secondary"
73
+ },
74
+ "sort-icon"
75
+ )
76
+ );
77
+ }
78
+ if (currentExternalFilter?.isValid) {
79
+ const filterIconPath = `${host_static_assets}/${environment_assets}/${pathIcons.filter2}`;
80
+ icons.push(
81
+ /* @__PURE__ */ jsx(
82
+ Icon,
83
+ {
84
+ src: filterIconPath,
85
+ size: "small",
86
+ color: "text.secondary"
87
+ },
88
+ "filter-icon"
89
+ )
90
+ );
91
+ }
92
+ return icons.length > 0 ? icons : null;
93
+ };
60
94
  useEffect(() => {
61
95
  if (!activeFilters) {
62
96
  setFilter("");
@@ -66,12 +100,14 @@ function DraggableHeaderRenderer(props) {
66
100
  if (newColumn.withinHeaderRenderer) {
67
101
  newColumn.name = newColumn.withinHeaderRenderer(props);
68
102
  }
69
- if (currentExternalSort && !newColumn.withinHeaderRenderer) {
70
- const sortIconPath = getSortIcon(currentExternalSort.direction);
71
- newColumn.name = /* @__PURE__ */ jsxs(NameColumnIconStyled, { children: [
72
- newColumn.name,
73
- /* @__PURE__ */ jsx(Icon, { src: sortIconPath, size })
74
- ] });
103
+ if (!newColumn.withinHeaderRenderer) {
104
+ const columnIcons = getColumnIcons();
105
+ if (columnIcons) {
106
+ newColumn.name = /* @__PURE__ */ jsxs(NameColumnIconStyled, { children: [
107
+ /* @__PURE__ */ jsx(NameColumnStyled, { children: newColumn.name }),
108
+ /* @__PURE__ */ jsx(IconColumnStyled, { children: columnIcons })
109
+ ] });
110
+ }
75
111
  }
76
112
  return /* @__PURE__ */ jsxs(
77
113
  DraggableHeaderRootStyled,
@@ -2,11 +2,12 @@ import { jsx } from "react/jsx-runtime";
2
2
  import { useState, useMemo, useEffect, useCallback } from "react";
3
3
  import { useModuleDictionary } from "@m4l/core";
4
4
  import { M as MenuItem } from "../../../../../mui_extended/MenuItem/MenuItem.js";
5
- import { M as MenuListStyled, o as HeaderRenderClickStyled } from "../../../../slots/DataGridSlot.js";
5
+ import { M as MenuListStyled, q as HeaderRenderClickStyled } from "../../../../slots/DataGridSlot.js";
6
6
  import { M as MenuDivider } from "../../../../../mui_extended/MenuDivider/MenuDivider.js";
7
7
  import { P as Popover } from "../../../../../mui_extended/Popover/Popover.js";
8
8
  import { D as DICTIONARY } from "../../../../dictionary.js";
9
9
  import { g as DATAGRID_HEADER_RENDER_CLICK_KEY } from "../../../../constants.js";
10
+ import { u as useFilters } from "../../../../hooks/useFilters.js";
10
11
  function HeaderRenderClick(props) {
11
12
  const {
12
13
  menuActions,
@@ -22,6 +23,7 @@ function HeaderRenderClick(props) {
22
23
  ...other
23
24
  } = props;
24
25
  const { getLabel } = useModuleDictionary();
26
+ const { activeFilters } = useFilters();
25
27
  const [anchorEl, setAnchorEl] = useState(null);
26
28
  const resolvedAnchorEl = externalOpen ?? anchorEl;
27
29
  const open = typeof externalOpen !== "undefined" ? Boolean(externalOpen) : Boolean(anchorEl);
@@ -122,7 +124,15 @@ function HeaderRenderClick(props) {
122
124
  arrowType,
123
125
  ...other,
124
126
  slots: { ...slots },
125
- slotProps: { paper: { ...paperProps } },
127
+ slotProps: {
128
+ paper: {
129
+ ...paperProps,
130
+ sx: {
131
+ mt: !activeFilters ? 0.3 : 6.5,
132
+ ...paperProps?.sx
133
+ }
134
+ }
135
+ },
126
136
  disableAutoFocus: true,
127
137
  disableEnforceFocus: true,
128
138
  anchorOrigin: { vertical: "bottom", horizontal: "left" },
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { p as InputTextEditorStyled } from "../../../slots/DataGridSlot.js";
2
+ import { r as InputTextEditorStyled } from "../../../slots/DataGridSlot.js";
3
3
  function autoFocusAndSelect(input) {
4
4
  input?.focus();
5
5
  input?.select();
@@ -13,7 +13,8 @@ const checkBoxStyles = {
13
13
  paddingRight: theme.vars.size.baseSpacings.sp1,
14
14
  overflow: "visible",
15
15
  boxSizing: "border-box",
16
- gap: theme.vars.size.baseSpacings.sp1
16
+ gap: theme.vars.size.baseSpacings.sp1,
17
+ width: "fit-content"
17
18
  };
18
19
  },
19
20
  /**
@@ -1,7 +1,5 @@
1
- import { FilterFieldApplied } from '../../components/DynamicFilter/types';
2
- import { SortFieldApplied } from '../../components/DynamicSort/types';
3
1
  import { UseDynamicFilterAndSortProps } from './types';
4
- import { SortChangeEvent, FilterChangeEvent } from '../../components/DataGrid/types';
2
+ import { SortSettings, FilterSettings } from '../../components/DataGrid/types';
5
3
  /**
6
4
  * Hook para manejar los filtros y ordenamientos dinamicos
7
5
  */
@@ -10,8 +8,6 @@ export declare const useDynamicFilterAndSort: (props: UseDynamicFilterAndSortPro
10
8
  rightActions: import("react/jsx-runtime").JSX.Element;
11
9
  visibleCustomHeader: boolean;
12
10
  customHeaderComponent: import("react/jsx-runtime").JSX.Element;
13
- getCurrentSorts: () => SortFieldApplied[];
14
- handleChangeSortExternal: (sortApplied: SortChangeEvent) => void;
15
- handleChangeFilterExternal: (event: FilterChangeEvent) => void;
16
- getCurrentFilters: () => FilterFieldApplied[];
11
+ externalSortSettings: SortSettings | undefined;
12
+ externalFilterSettings: FilterSettings | undefined;
17
13
  };
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { useEnvironment, useModuleDictionary } from "@m4l/core";
3
- import { useState, useRef, useMemo, useCallback } from "react";
3
+ import { useState, useRef, useMemo, useCallback, useReducer } from "react";
4
4
  import { D as DynamicFilter } from "../../components/DynamicFilter/DynamicFilter.js";
5
5
  import { D as DynamicSort } from "../../components/DynamicSort/DynamicSort.js";
6
6
  import { I as IconButton } from "../../components/mui_extended/IconButton/IconButton.js";
@@ -78,6 +78,10 @@ const useDynamicFilterAndSort = (props) => {
78
78
  }
79
79
  return true;
80
80
  }, [eventRefs, fields]);
81
+ const [changeFlags, dispatchChangeFlag] = useReducer(
82
+ (state, action) => ({ ...state, [action]: !state[action] }),
83
+ { filters: false, sorts: false }
84
+ );
81
85
  const handleChangeFilters = useCallback(
82
86
  (filters, rawFilters) => {
83
87
  setInvisibleBadge((prev) => ({ ...prev, filter: filters.length === 0 }));
@@ -96,6 +100,7 @@ const useDynamicFilterAndSort = (props) => {
96
100
  onChangeFilterSort(eventRefs.current);
97
101
  }
98
102
  refOnChangeFilterSort.current++;
103
+ dispatchChangeFlag("filters");
99
104
  },
100
105
  [onChangeFilterSort, prefixCookie, setCookie, setInvisibleBadge, sorts]
101
106
  );
@@ -118,6 +123,7 @@ const useDynamicFilterAndSort = (props) => {
118
123
  } else {
119
124
  refOnChangeFilterSort.current++;
120
125
  }
126
+ dispatchChangeFlag("sorts");
121
127
  },
122
128
  [
123
129
  onChangeFilterSort,
@@ -360,15 +366,43 @@ const useDynamicFilterAndSort = (props) => {
360
366
  ),
361
367
  [togglesLeftActions, dataTestId, dynamicsFiltersSorts]
362
368
  );
369
+ const externalSortSettings = useMemo(() => {
370
+ if (!sorts || sorts.length === 0) {
371
+ return void 0;
372
+ }
373
+ return {
374
+ sortsColumns: sorts.map((sort) => sort.name),
375
+ sortsApplied: getCurrentSorts().map((sort) => ({
376
+ columnKey: sort.field.name,
377
+ removable: !sort.fixed,
378
+ direction: sort.operator
379
+ })),
380
+ onChange: handleChangeSortExternal
381
+ };
382
+ }, [sorts, changeFlags.sorts, getCurrentSorts, handleChangeSortExternal]);
383
+ const externalFilterSettings = useMemo(() => {
384
+ if (!fields || fields.length === 0) {
385
+ return void 0;
386
+ }
387
+ return {
388
+ filterColumns: fields.map((filter) => ({
389
+ name: filter.name,
390
+ multiple: filter.multiple || false
391
+ })),
392
+ filtersApplied: getCurrentFilters().map((filter) => ({
393
+ columnKey: filter.field.name,
394
+ isValid: filter.isSet
395
+ })),
396
+ onChange: handleChangeFilterExternal
397
+ };
398
+ }, [fields, changeFlags.filters, getCurrentFilters, handleChangeFilterExternal]);
363
399
  return {
364
400
  leftActions,
365
401
  rightActions: finalRightActions,
366
402
  visibleCustomHeader,
367
403
  customHeaderComponent,
368
- getCurrentSorts,
369
- handleChangeSortExternal,
370
- handleChangeFilterExternal,
371
- getCurrentFilters
404
+ externalSortSettings,
405
+ externalFilterSettings
372
406
  };
373
407
  };
374
408
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m4l/components",
3
- "version": "9.2.60-J18062025.beta.1",
3
+ "version": "9.2.60-J25062025.beta.1",
4
4
  "license": "UNLICENSED",
5
5
  "description": "M4L Components",
6
6
  "lint-staged": {
@@ -8,6 +8,8 @@ interface DataGridRenderProps<TRow, TSummaryRow, TKey extends RowKey = RowKey> {
8
8
  dynamicColumns?: boolean;
9
9
  filterSortAutomatic?: boolean;
10
10
  visibleRefreshFilterSort?: boolean;
11
+ withExternalSortSettings?: boolean;
12
+ withExternalFilterSettings?: boolean;
11
13
  }
12
14
  /**
13
15
  * Componente que renderiza el DataGrid para el storybook
@@ -1,16 +0,0 @@
1
- import { DataGridProps, RowKey } from '../../../../src/components/DataGrid/types';
2
- import { RowType, SeedProps } from '../helpers/types';
3
- interface DataGridRenderProps<TRow, TSummaryRow, TKey extends RowKey = RowKey> {
4
- dataGridProps: DataGridProps<TRow, TSummaryRow, TKey>;
5
- seedProps: SeedProps;
6
- rowsSelecteds?: boolean;
7
- withCustomHeader?: boolean;
8
- dynamicColumns?: boolean;
9
- filterSortAutomatic?: boolean;
10
- visibleRefreshFilterSort?: boolean;
11
- }
12
- /**
13
- * Componente que renderiza el DataGrid para el storybook
14
- */
15
- declare function DataGridRenderWithActions<TKey extends RowKey = RowKey>(props: DataGridRenderProps<RowType, unknown, TKey>): import("react/jsx-runtime").JSX.Element;
16
- export default DataGridRenderWithActions;