@m4l/components 9.2.60 → 9.2.61

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 (62) hide show
  1. package/components/DataGrid/DataGrid.js +17 -3
  2. package/components/DataGrid/Datagrid.styles.js +72 -20
  3. package/components/DataGrid/constants.d.ts +2 -0
  4. package/components/DataGrid/constants.js +7 -3
  5. package/components/DataGrid/contexts/DataGridContext/index.js +77 -30
  6. package/components/DataGrid/contexts/DataGridContext/types.d.ts +5 -2
  7. package/components/DataGrid/dictionary.d.ts +8 -0
  8. package/components/DataGrid/dictionary.js +26 -17
  9. package/components/DataGrid/icons.d.ts +7 -0
  10. package/components/DataGrid/icons.js +8 -1
  11. package/components/DataGrid/slots/DataGridEnum.d.ts +7 -1
  12. package/components/DataGrid/slots/DataGridEnum.js +6 -0
  13. package/components/DataGrid/slots/DataGridSlot.d.ts +6 -0
  14. package/components/DataGrid/slots/DataGridSlot.js +35 -5
  15. package/components/DataGrid/subcomponents/HeaderActions/subcomponents/Filter/index.js +9 -1
  16. package/components/DataGrid/subcomponents/Table/hooks/getDragHeaderRenderer.d.ts +3 -1
  17. package/components/DataGrid/subcomponents/Table/hooks/getDragHeaderRenderer.js +9 -2
  18. package/components/DataGrid/subcomponents/Table/hooks/useHeaderMenuActions.d.ts +6 -0
  19. package/components/DataGrid/subcomponents/Table/hooks/useHeaderMenuActions.js +262 -0
  20. package/components/DataGrid/subcomponents/Table/hooks/useSortColumnsRows.d.ts +6 -4
  21. package/components/DataGrid/subcomponents/Table/hooks/useSortColumnsRows.js +35 -20
  22. package/components/DataGrid/subcomponents/Table/index.js +97 -34
  23. package/components/DataGrid/subcomponents/Table/subcomponents/ActionsColumn.js +1 -1
  24. package/components/DataGrid/subcomponents/Table/subcomponents/DraggableHeaderRenderer.d.ts +1 -0
  25. package/components/DataGrid/subcomponents/Table/subcomponents/DraggableHeaderRenderer.js +79 -4
  26. package/components/DataGrid/subcomponents/Table/subcomponents/HeaderRenderClick/HeaderRenderClick.d.ts +5 -0
  27. package/components/DataGrid/subcomponents/Table/subcomponents/HeaderRenderClick/HeaderRenderClick.js +146 -0
  28. package/components/DataGrid/subcomponents/Table/subcomponents/HeaderRenderClick/index.d.ts +1 -0
  29. package/components/DataGrid/subcomponents/Table/subcomponents/HeaderRenderClick/index.js +1 -0
  30. package/components/DataGrid/subcomponents/Table/subcomponents/HeaderRenderClick/types.d.ts +131 -0
  31. package/components/DataGrid/subcomponents/Table/subcomponents/SelectColumn.js +1 -1
  32. package/components/DataGrid/subcomponents/editors/TextEditor/index.js +1 -1
  33. package/components/DataGrid/tests/HeaderRenderClick.test.d.ts +1 -0
  34. package/components/DataGrid/tests/useHeaderMenuActions.test.d.ts +1 -0
  35. package/components/DataGrid/types.d.ts +53 -0
  36. package/components/DynamicFilter/store/DynamicFilterContext.js +63 -23
  37. package/components/DynamicFilter/subcomponents/PopoverFilter/usePopoverFilter.d.ts +3 -3
  38. package/components/DynamicFilter/types.d.ts +3 -0
  39. package/components/DynamicSort/DynamicSort.js +10 -6
  40. package/components/DynamicSort/store/DynamicSortContext.js +96 -67
  41. package/components/DynamicSort/store/DynamicSortStore.js +53 -4
  42. package/components/DynamicSort/store/types.d.ts +11 -0
  43. package/components/DynamicSort/subcomponents/PopoverSort/usePopoverSort.d.ts +3 -3
  44. package/components/DynamicSort/types.d.ts +4 -0
  45. package/components/NumberInput/hooks/useNumberInput/useNumberInput.js +0 -2
  46. package/components/hook-form/RHFAutocompleteAsync/reducer/RHFAutocompleteReducer.js +0 -5
  47. package/components/hook-form/RHFormContext/index.d.ts +1 -1
  48. package/components/mui_extended/CheckBox/CheckBox.styles.js +2 -1
  49. package/hooks/useDynamicFilterAndSort/useDynamicFilterAndSort.d.ts +3 -0
  50. package/hooks/useDynamicFilterAndSort/useDynamicFilterAndSort.js +334 -88
  51. package/index.js +7 -7
  52. package/package.json +1 -1
  53. package/storybook/components/DataGrid/DataGrid.stories.d.ts +22 -0
  54. package/storybook/components/DataGrid/MswHandles.d.ts +1 -0
  55. package/storybook/components/DataGrid/helpers/filterFieldsSeedData.d.ts +5 -0
  56. package/storybook/components/DataGrid/helpers/getRows.d.ts +4 -0
  57. package/storybook/components/DataGrid/helpers/getRowsWithBackendSimulation.d.ts +9 -0
  58. package/storybook/components/DataGrid/helpers/sortsSeedData.d.ts +5 -0
  59. package/storybook/components/DataGrid/helpers/types.d.ts +1 -0
  60. package/storybook/components/DataGrid/helpers/useSeed.d.ts +3 -0
  61. package/storybook/components/DataGrid/subcomponents/DataGridRender.d.ts +2 -0
  62. package/storybook/components/ObjectLogs/ObjectLogs.stories.d.ts +2 -2
@@ -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";
@@ -15,14 +15,40 @@ import { g as getPurgedCookie } from "./helpers.js";
15
15
  import { u as useWindowToolsMF } from "../../components/WindowBase/hooks/useWindowToolsMF/index.js";
16
16
  import { a as DICCTIONARY } from "../../components/DynamicFilter/dictionary.js";
17
17
  const useDynamicFilterAndSort = (props) => {
18
- const { fields, sorts, onChangeFilterSort, dataTestId, withAllField, rightActions, initialFilterToggleed = true, initialSortToggleed = true, prefixCookie, setCookie, getCookie, filterSortAutomatic = true, visibleRefresh = false, withExternalRefresh } = props;
18
+ const {
19
+ fields,
20
+ sorts,
21
+ onChangeFilterSort,
22
+ dataTestId,
23
+ withAllField,
24
+ rightActions,
25
+ initialFilterToggleed = true,
26
+ initialSortToggleed = true,
27
+ prefixCookie,
28
+ setCookie,
29
+ getCookie,
30
+ filterSortAutomatic = true,
31
+ visibleRefresh = false,
32
+ withExternalRefresh
33
+ } = props;
19
34
  const { host_static_assets, environment_assets } = useEnvironment();
20
- const [togglesLeftActions, setTogglesLeftActions] = useState(() => ({ filter: initialFilterToggleed, sort: initialSortToggleed }));
35
+ const [togglesLeftActions, setTogglesLeftActions] = useState(() => ({
36
+ filter: initialFilterToggleed,
37
+ sort: initialSortToggleed
38
+ }));
21
39
  const [initialAppliedFilters] = useState(() => {
22
- return getPurgedCookie(getCookie?.(prefixCookie ? `${prefixCookie}_${COOKIE_APPLIED_FILTERS}` : COOKIE_APPLIED_FILTERS));
40
+ return getPurgedCookie(
41
+ getCookie?.(
42
+ prefixCookie ? `${prefixCookie}_${COOKIE_APPLIED_FILTERS}` : COOKIE_APPLIED_FILTERS
43
+ )
44
+ );
23
45
  });
24
46
  const [initialAppliedSorts] = useState(() => {
25
- return getPurgedCookie(getCookie?.(prefixCookie ? `${prefixCookie}_${COOKIE_APPLIED_SORTS}` : COOKIE_APPLIED_SORTS));
47
+ return getPurgedCookie(
48
+ getCookie?.(
49
+ prefixCookie ? `${prefixCookie}_${COOKIE_APPLIED_SORTS}` : COOKIE_APPLIED_SORTS
50
+ )
51
+ );
26
52
  });
27
53
  const refOnChangeFilterSort = useRef(0);
28
54
  const fireOnChangeFilterRef = useRef(null);
@@ -33,7 +59,10 @@ const useDynamicFilterAndSort = (props) => {
33
59
  filter: initialAppliedFilters?.length === 0,
34
60
  sort: initialAppliedSorts?.length === 0
35
61
  }));
36
- const visibleCustomHeader = useMemo(() => togglesLeftActions.filter || togglesLeftActions.sort, [togglesLeftActions]);
62
+ const visibleCustomHeader = useMemo(
63
+ () => togglesLeftActions.filter || togglesLeftActions.sort,
64
+ [togglesLeftActions]
65
+ );
37
66
  const refreshIconUrl = `${host_static_assets}/${environment_assets}/${ASSETS.refresh}`;
38
67
  const eventRefs = useRef({
39
68
  eventFilters: { filters: initialAppliedFilters, rawFilters: [] },
@@ -49,35 +78,61 @@ const useDynamicFilterAndSort = (props) => {
49
78
  }
50
79
  return true;
51
80
  }, [eventRefs, fields]);
52
- const handleChangeFilters = useCallback((filters, rawFilters) => {
53
- setInvisibleBadge((prev) => ({ ...prev, filter: filters.length === 0 }));
54
- if (eventRefs.current?.eventFilters?.filters && !deepEqual(eventRefs.current?.eventFilters?.filters, filters)) {
55
- setCookie?.(prefixCookie ? `${prefixCookie}_${COOKIE_APPLIED_FILTERS}` : COOKIE_APPLIED_FILTERS, "window", filters);
56
- }
57
- eventRefs.current = {
58
- ...eventRefs.current,
59
- eventFilters: { filters, rawFilters }
60
- };
61
- if (refOnChangeFilterSort.current > 0 || refOnChangeFilterSort.current === 0 && !sorts) {
62
- onChangeFilterSort(eventRefs.current);
63
- }
64
- refOnChangeFilterSort.current++;
65
- }, [onChangeFilterSort, prefixCookie, setCookie, setInvisibleBadge, sorts]);
66
- const handleChangeSorts = useCallback((newSorts, rawSorts) => {
67
- setInvisibleBadge((prev) => ({ ...prev, sort: newSorts.length === 0 }));
68
- if (eventRefs.current?.eventSorts?.sorts && !deepEqual(eventRefs.current?.eventSorts?.sorts, newSorts)) {
69
- setCookie?.(prefixCookie ? `${prefixCookie}_${COOKIE_APPLIED_SORTS}` : COOKIE_APPLIED_SORTS, "window", newSorts);
70
- }
71
- eventRefs.current = {
72
- ...eventRefs.current,
73
- eventSorts: { sorts: newSorts, rawSorts }
74
- };
75
- if (isValidFilters()) {
76
- onChangeFilterSort(eventRefs.current);
77
- } else {
81
+ const [changeFlags, dispatchChangeFlag] = useReducer(
82
+ (state, action) => ({ ...state, [action]: !state[action] }),
83
+ { filters: false, sorts: false }
84
+ );
85
+ const handleChangeFilters = useCallback(
86
+ (filters, rawFilters) => {
87
+ setInvisibleBadge((prev) => ({ ...prev, filter: filters.length === 0 }));
88
+ if (eventRefs.current?.eventFilters?.filters && !deepEqual(eventRefs.current?.eventFilters?.filters, filters)) {
89
+ setCookie?.(
90
+ prefixCookie ? `${prefixCookie}_${COOKIE_APPLIED_FILTERS}` : COOKIE_APPLIED_FILTERS,
91
+ "window",
92
+ filters
93
+ );
94
+ }
95
+ eventRefs.current = {
96
+ ...eventRefs.current,
97
+ eventFilters: { filters, rawFilters }
98
+ };
99
+ if (refOnChangeFilterSort.current > 0 || refOnChangeFilterSort.current === 0 && !sorts) {
100
+ onChangeFilterSort(eventRefs.current);
101
+ }
78
102
  refOnChangeFilterSort.current++;
79
- }
80
- }, [onChangeFilterSort, prefixCookie, setCookie, setInvisibleBadge, isValidFilters]);
103
+ dispatchChangeFlag("filters");
104
+ },
105
+ [onChangeFilterSort, prefixCookie, setCookie, setInvisibleBadge, sorts]
106
+ );
107
+ const handleChangeSorts = useCallback(
108
+ (newSorts, rawSorts) => {
109
+ setInvisibleBadge((prev) => ({ ...prev, sort: newSorts.length === 0 }));
110
+ if (eventRefs.current?.eventSorts?.sorts && !deepEqual(eventRefs.current?.eventSorts?.sorts, newSorts)) {
111
+ setCookie?.(
112
+ prefixCookie ? `${prefixCookie}_${COOKIE_APPLIED_SORTS}` : COOKIE_APPLIED_SORTS,
113
+ "window",
114
+ newSorts
115
+ );
116
+ }
117
+ eventRefs.current = {
118
+ ...eventRefs.current,
119
+ eventSorts: { sorts: newSorts, rawSorts }
120
+ };
121
+ if (isValidFilters()) {
122
+ onChangeFilterSort(eventRefs.current);
123
+ } else {
124
+ refOnChangeFilterSort.current++;
125
+ }
126
+ dispatchChangeFlag("sorts");
127
+ },
128
+ [
129
+ onChangeFilterSort,
130
+ prefixCookie,
131
+ setCookie,
132
+ setInvisibleBadge,
133
+ isValidFilters
134
+ ]
135
+ );
81
136
  const onRefresh = useCallback(() => {
82
137
  if (!filterSortAutomatic) {
83
138
  if (fireOnChangeFilterRef.current) {
@@ -90,73 +145,264 @@ const useDynamicFilterAndSort = (props) => {
90
145
  if (isValidFilters()) {
91
146
  onChangeFilterSort(eventRefs.current);
92
147
  } else {
93
- toast({ title: getLabel(DICCTIONARY.error_invalid_filters_before) }, { type: "error" });
148
+ toast(
149
+ { title: getLabel(DICCTIONARY.error_invalid_filters_before) },
150
+ { type: "error" }
151
+ );
94
152
  }
95
153
  }
96
- }, [filterSortAutomatic, getLabel, isValidFilters, onChangeFilterSort, toast]);
97
- const leftActions = useMemo(() => /* @__PURE__ */ jsxs(StackLeftActionsStyled, { direction: "row", ...getPropDataTestId(M4LDYNAMIC_KEY_FILTER_AND_SORT, DynamicFilterAndSortSlots.stackLeftActions, dataTestId), children: [
98
- /* @__PURE__ */ jsx(ToggleIconButton, { badgeProps: { variant: "dot", invisible: invisibleBadge.filter, color: "primary" }, icon: `${host_static_assets}/${environment_assets}/${ICON_PATH_FILTER}`, isToggled: togglesLeftActions.filter, onToggle: () => handleToggles("filter") }),
99
- /* @__PURE__ */ jsx(ToggleIconButton, { badgeProps: { variant: "dot", invisible: invisibleBadge.sort, color: "primary" }, icon: `${host_static_assets}/${environment_assets}/${ICON_PATH_SORT}`, isToggled: togglesLeftActions.sort, onToggle: () => handleToggles("sort") })
100
- ] }), [togglesLeftActions, invisibleBadge, host_static_assets, environment_assets]);
101
- const finalRightActions = useMemo(() => /* @__PURE__ */ jsxs(
102
- StackRightActionsStyled,
103
- {
104
- direction: "row",
105
- ...getPropDataTestId(M4LDYNAMIC_KEY_FILTER_AND_SORT, DynamicFilterAndSortSlots.stackRightActions, dataTestId),
106
- children: [
107
- /* @__PURE__ */ jsx(
108
- IconButton,
109
- {
110
- icon: refreshIconUrl,
111
- "aria-label": "refresh",
112
- onClick: onRefresh,
113
- variant: "outline"
114
- }
154
+ }, [
155
+ filterSortAutomatic,
156
+ getLabel,
157
+ isValidFilters,
158
+ onChangeFilterSort,
159
+ toast
160
+ ]);
161
+ const leftActions = useMemo(
162
+ () => /* @__PURE__ */ jsxs(
163
+ StackLeftActionsStyled,
164
+ {
165
+ direction: "row",
166
+ ...getPropDataTestId(
167
+ M4LDYNAMIC_KEY_FILTER_AND_SORT,
168
+ DynamicFilterAndSortSlots.stackLeftActions,
169
+ dataTestId
115
170
  ),
116
- rightActions
117
- ]
118
- }
119
- ), [dataTestId, rightActions, refreshIconUrl, onRefresh]);
120
- const dynamicsFiltersSorts = useMemo(() => /* @__PURE__ */ jsxs(Fragment, { children: [
121
- /* @__PURE__ */ jsx(
122
- DynamicFilter,
171
+ children: [
172
+ /* @__PURE__ */ jsx(
173
+ ToggleIconButton,
174
+ {
175
+ badgeProps: {
176
+ variant: "dot",
177
+ invisible: invisibleBadge.filter,
178
+ color: "primary"
179
+ },
180
+ icon: `${host_static_assets}/${environment_assets}/${ICON_PATH_FILTER}`,
181
+ isToggled: togglesLeftActions.filter,
182
+ onToggle: () => handleToggles("filter")
183
+ }
184
+ ),
185
+ /* @__PURE__ */ jsx(
186
+ ToggleIconButton,
187
+ {
188
+ badgeProps: {
189
+ variant: "dot",
190
+ invisible: invisibleBadge.sort,
191
+ color: "primary"
192
+ },
193
+ icon: `${host_static_assets}/${environment_assets}/${ICON_PATH_SORT}`,
194
+ isToggled: togglesLeftActions.sort,
195
+ onToggle: () => handleToggles("sort")
196
+ }
197
+ )
198
+ ]
199
+ }
200
+ ),
201
+ [
202
+ togglesLeftActions,
203
+ invisibleBadge,
204
+ host_static_assets,
205
+ environment_assets,
206
+ dataTestId
207
+ ]
208
+ );
209
+ const finalRightActions = useMemo(
210
+ () => /* @__PURE__ */ jsxs(
211
+ StackRightActionsStyled,
123
212
  {
124
- ref: fireOnChangeFilterRef,
125
- visibleRefresh,
126
- automatic: filterSortAutomatic,
127
- fields,
128
- initialAppliedFilters,
129
- onChangeFilters: handleChangeFilters,
130
- withAllField
213
+ direction: "row",
214
+ ...getPropDataTestId(
215
+ M4LDYNAMIC_KEY_FILTER_AND_SORT,
216
+ DynamicFilterAndSortSlots.stackRightActions,
217
+ dataTestId
218
+ ),
219
+ children: [
220
+ /* @__PURE__ */ jsx(
221
+ IconButton,
222
+ {
223
+ icon: refreshIconUrl,
224
+ "aria-label": "refresh",
225
+ onClick: onRefresh,
226
+ variant: "outline"
227
+ }
228
+ ),
229
+ rightActions
230
+ ]
131
231
  }
132
232
  ),
133
- sorts ? /* @__PURE__ */ jsx(
134
- DynamicSort,
233
+ [dataTestId, rightActions, refreshIconUrl, onRefresh]
234
+ );
235
+ const getCurrentSorts = useCallback(() => {
236
+ if (fireOnChangeSortRef.current) {
237
+ return fireOnChangeSortRef.current.getCurrentSorts();
238
+ }
239
+ return [];
240
+ }, [fireOnChangeSortRef]);
241
+ const handleChangeSortExternal = useCallback(
242
+ (sortApplied) => {
243
+ if (fireOnChangeSortRef.current) {
244
+ const sort = sorts?.find((sort2) => sort2.name === sortApplied.columnKey);
245
+ const isFixed = sort?.presence === "fixed";
246
+ switch (sortApplied.action) {
247
+ case "add":
248
+ const newSort = {
249
+ id: fireOnChangeSortRef.current.getNewId(),
250
+ field: {
251
+ name: sortApplied.columnKey,
252
+ type: sort?.type || "string",
253
+ urlIcon: sort?.urlIcon || "",
254
+ label: sort?.label || sortApplied.columnKey
255
+ },
256
+ isSet: true,
257
+ fixed: isFixed,
258
+ fieldType: sort?.type || "string",
259
+ operator: sortApplied.direction
260
+ };
261
+ setTogglesLeftActions((prev) => ({ ...prev, sort: true }));
262
+ fireOnChangeSortRef.current.addExternalSort(newSort);
263
+ break;
264
+ case "remove":
265
+ if (!isFixed) {
266
+ fireOnChangeSortRef.current.removeExternalSort(
267
+ sortApplied.columnKey
268
+ );
269
+ }
270
+ break;
271
+ }
272
+ }
273
+ },
274
+ [fireOnChangeSortRef, sorts]
275
+ );
276
+ const handleChangeFilterExternal = useCallback(
277
+ (event) => {
278
+ if (fireOnChangeFilterRef.current) {
279
+ switch (event.action) {
280
+ case "add":
281
+ setTogglesLeftActions((prev) => ({ ...prev, filter: true }));
282
+ fireOnChangeFilterRef.current.addExternalFilter(event.columnKey);
283
+ break;
284
+ case "openPopoverMenuFields":
285
+ setTogglesLeftActions((prev) => ({ ...prev, filter: true }));
286
+ fireOnChangeFilterRef.current.openPopoverMenuFields();
287
+ break;
288
+ default:
289
+ return;
290
+ }
291
+ }
292
+ },
293
+ [fireOnChangeFilterRef]
294
+ );
295
+ const getCurrentFilters = useCallback(() => {
296
+ if (fireOnChangeFilterRef.current) {
297
+ return fireOnChangeFilterRef.current.getCurrentFilters();
298
+ }
299
+ return [];
300
+ }, [fireOnChangeFilterRef]);
301
+ const dynamicsFiltersSorts = useMemo(
302
+ () => /* @__PURE__ */ jsxs(Fragment, { children: [
303
+ /* @__PURE__ */ jsx(
304
+ DynamicFilter,
305
+ {
306
+ ref: fireOnChangeFilterRef,
307
+ visibleRefresh,
308
+ automatic: filterSortAutomatic,
309
+ fields,
310
+ initialAppliedFilters,
311
+ onChangeFilters: handleChangeFilters,
312
+ withAllField
313
+ }
314
+ ),
315
+ sorts ? /* @__PURE__ */ jsx(
316
+ DynamicSort,
317
+ {
318
+ ref: fireOnChangeSortRef,
319
+ visibleRefresh,
320
+ automatic: filterSortAutomatic,
321
+ fields: sorts,
322
+ initialAppliedSorts,
323
+ onChangeSorts: handleChangeSorts
324
+ }
325
+ ) : null,
326
+ withExternalRefresh && /* @__PURE__ */ jsx(
327
+ IconButton,
328
+ {
329
+ icon: refreshIconUrl,
330
+ "aria-label": "refresh",
331
+ onClick: onRefresh
332
+ }
333
+ )
334
+ ] }),
335
+ [
336
+ visibleRefresh,
337
+ filterSortAutomatic,
338
+ fields,
339
+ initialAppliedFilters,
340
+ handleChangeFilters,
341
+ withAllField,
342
+ sorts,
343
+ initialAppliedSorts,
344
+ handleChangeSorts,
345
+ withExternalRefresh,
346
+ refreshIconUrl,
347
+ onRefresh
348
+ ]
349
+ );
350
+ const customHeaderComponent = useMemo(
351
+ () => /* @__PURE__ */ jsx(
352
+ StackCustomHeaderStyled,
135
353
  {
136
- ref: fireOnChangeSortRef,
137
- visibleRefresh,
138
- automatic: filterSortAutomatic,
139
- fields: sorts,
140
- initialAppliedSorts,
141
- onChangeSorts: handleChangeSorts
354
+ direction: "row",
355
+ ownerState: {
356
+ showDynamicFilter: togglesLeftActions.filter,
357
+ showDynamicSort: togglesLeftActions.sort
358
+ },
359
+ ...getPropDataTestId(
360
+ M4LDYNAMIC_KEY_FILTER_AND_SORT,
361
+ DynamicFilterAndSortSlots.stackCustomHeader,
362
+ dataTestId
363
+ ),
364
+ children: dynamicsFiltersSorts
142
365
  }
143
- ) : null,
144
- withExternalRefresh && /* @__PURE__ */ jsx(IconButton, { icon: refreshIconUrl, "aria-label": "refresh", onClick: onRefresh })
145
- ] }), [visibleRefresh, filterSortAutomatic, fields, initialAppliedFilters, handleChangeFilters, withAllField, sorts, initialAppliedSorts, handleChangeSorts, withExternalRefresh, refreshIconUrl, onRefresh]);
146
- const customHeaderComponent = useMemo(() => /* @__PURE__ */ jsx(
147
- StackCustomHeaderStyled,
148
- {
149
- direction: "row",
150
- ownerState: { showDynamicFilter: togglesLeftActions.filter, showDynamicSort: togglesLeftActions.sort },
151
- ...getPropDataTestId(M4LDYNAMIC_KEY_FILTER_AND_SORT, DynamicFilterAndSortSlots.stackCustomHeader, dataTestId),
152
- children: dynamicsFiltersSorts
366
+ ),
367
+ [togglesLeftActions, dataTestId, dynamicsFiltersSorts]
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;
153
386
  }
154
- ), [togglesLeftActions]);
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]);
155
399
  return {
156
400
  leftActions,
157
401
  rightActions: finalRightActions,
158
402
  visibleCustomHeader,
159
- customHeaderComponent
403
+ customHeaderComponent,
404
+ externalSortSettings,
405
+ externalFilterSettings
160
406
  };
161
407
  };
162
408
  export {
package/index.js CHANGED
@@ -33,7 +33,7 @@ import { D as D2 } from "./components/DataGrid/DataGrid.js";
33
33
  import { g as g5 } from "./components/DataGrid/dictionary.js";
34
34
  import { N, T as T2 } from "./components/DataGrid/subcomponents/editors/TextEditor/index.js";
35
35
  import { g as g6 } from "./components/DataGrid/utils/getDataGridRowsFromSet.js";
36
- import { b as b3, a as a4, d as d2 } from "./components/DataGrid/constants.js";
36
+ import { b as b3, a as a4, e } from "./components/DataGrid/constants.js";
37
37
  import { C as C2 } from "./components/DataGrid/formatters/ColumnBooleanFormatter/formatter.js";
38
38
  import { u as u2 } from "./components/DataGrid/formatters/ColumnBooleanFormatter/useColumnBoolean.js";
39
39
  import { C as C3 } from "./components/DataGrid/formatters/ColumnConcatenatedValuesFormatter/formatter.js";
@@ -56,7 +56,7 @@ import { u as u10 } from "./components/DataGrid/formatters/ColumnUncertaintyForm
56
56
  import { C as C12 } from "./components/DataGrid/formatters/ColumnChipStatusFormatter/formatter.js";
57
57
  import { u as u11 } from "./components/DataGrid/formatters/ColumnChipStatusFormatter/useColumnChipStatus.js";
58
58
  import { D as D3 } from "./components/DragResizeWindowRND/DragResizeWindowRND.js";
59
- import { d as d3 } from "./components/DragResizeWindowRND/classes/index.js";
59
+ import { d as d2 } from "./components/DragResizeWindowRND/classes/index.js";
60
60
  import { g as g7 } from "./components/DynamicFilter/dictionary.js";
61
61
  import { a as a5, g as g8 } from "./components/DynamicFilter/helpers/frontEndHelpers.js";
62
62
  import { g as g9 } from "./components/DynamicFilter/helpers/getRawFiltersForNetwork.js";
@@ -119,7 +119,7 @@ import { D as D8 } from "./components/formatters/DistanceToNowFormatter/Distance
119
119
  import { g as g18 } from "./components/formatters/dictionary.js";
120
120
  import { G } from "./components/GridLayout/GridLayout.js";
121
121
  import { R as R3 } from "./components/GridLayout/subcomponents/Responsive/index.js";
122
- import { c as c2, e, d as d4 } from "./components/GridLayout/subcomponents/Responsive/responsiveUtils.js";
122
+ import { c as c2, e as e2, d as d3 } from "./components/GridLayout/subcomponents/Responsive/responsiveUtils.js";
123
123
  import { i, k } from "./components/GridLayout/utils.js";
124
124
  import { w } from "./components/GridLayout/subcomponents/withSizeProvider/index.js";
125
125
  import { H as H2 } from "./components/HelmetPage/index.js";
@@ -258,7 +258,7 @@ export {
258
258
  C15 as ConcatenatedFormatter,
259
259
  b3 as DATAGRID_ROW_HEADER_HEIGHTS,
260
260
  a4 as DATAGRID_ROW_HEIGHTS,
261
- d2 as DATAGRID_SEMANTIC_WIDTHS,
261
+ e as DATAGRID_SEMANTIC_WIDTHS,
262
262
  D as DICTIONARY,
263
263
  D2 as DataGrid,
264
264
  D7 as DateFormatter,
@@ -379,13 +379,13 @@ export {
379
379
  W2 as WindowToolsMFContext,
380
380
  a12 as WindowToolsMFProvider,
381
381
  c2 as addLayoutItemToBreakPointIfNoExists,
382
- e as addLayoutItemToBreakPoints,
382
+ e2 as addLayoutItemToBreakPoints,
383
383
  c4 as capitalizeFirstLetter,
384
- d4 as cloneLayouts,
384
+ d3 as cloneLayouts,
385
385
  c3 as createDynamicMFStore,
386
386
  c as createToaster,
387
387
  d as defaultCommonActionsDictionary,
388
- d3 as dragResizeWindowRNDClasses,
388
+ d2 as dragResizeWindowRNDClasses,
389
389
  f as formatDistanceToNow,
390
390
  g as getAccountPopoverDictionary,
391
391
  g2 as getAppBarDictionary,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m4l/components",
3
- "version": "9.2.60",
3
+ "version": "9.2.61",
4
4
  "license": "UNLICENSED",
5
5
  "description": "M4L Components",
6
6
  "lint-staged": {
@@ -49,5 +49,27 @@ export declare const RowMenuActions: Story;
49
49
  * Filter y Sort en busqueda manual
50
50
  */
51
51
  export declare const CustomHeaderFilterSortManual: Story;
52
+ /**
53
+ * DataGrid con leftActions, rightActions y
54
+ * Filter y Sort en busqueda automatica
55
+ */
56
+ export declare const CustomHeaderAutomaticWithExternalFiltersAndSorts: Story;
57
+ /**
58
+ * DataGrid con leftActions, rightActions y
59
+ * Filter y Sort en busqueda manual
60
+ */
61
+ export declare const CustomHeaderManualWithExternalFiltersAndSorts: Story;
52
62
  export declare const DynamicColumns: Story;
63
+ /**
64
+ * Menú de columna con botón de remover sort deshabilitado
65
+ */
66
+ export declare const HeaderRenderClickRemoveExternalSortDisabled: Story;
67
+ /**
68
+ * Menú de columna con botón de agregar filtro deshabilitado
69
+ */
70
+ export declare const HeaderRenderClickAddFilterDisabled: Story;
71
+ /**
72
+ * Demostración completa: aplica sort DESC en 'phone', agrega filtro 'email contains 5' y cambia sort DESC en 'name'
73
+ */
74
+ export declare const HeaderRenderClickFullActions: Story;
53
75
  export default meta;
@@ -0,0 +1 @@
1
+ export declare const mswHandles: import('msw').HttpHandler[];
@@ -0,0 +1,5 @@
1
+ import { FilterField } from '../../../../src/components/DynamicFilter/types';
2
+ /**
3
+ * Helper que retorna los fields configurados para el DataGrid de Storybook
4
+ */
5
+ export declare const filterFieldsSeedData: FilterField[];
@@ -3,3 +3,7 @@ import { RowType, SeedProps } from './types';
3
3
  * Función para generar las filas para el DataGrid de Storybook
4
4
  */
5
5
  export declare const getRows: (props: SeedProps) => RowType[];
6
+ /**
7
+ * Función para generar filas con nombres duplicados para probar ordenamiento múltiple
8
+ */
9
+ export declare const getRowsForMultiSort: (props: SeedProps) => RowType[];
@@ -0,0 +1,9 @@
1
+ import { RowType } from './types';
2
+ import { RawFilterFieldApply } from '../../../../src/components/DynamicFilter/types';
3
+ import { RawSortFieldApply } from '../../../../src/components/DynamicSort/types';
4
+ /**
5
+ * Función que simula el comportamiento del backend
6
+ * Recibe exactamente los mismos parámetros que se enviarían al backend real
7
+ */
8
+ export declare function getRowsWithBackendSimulation(originalRows: RowType[], f: Omit<RawFilterFieldApply, 'ft'>[] | undefined, // filtros en formato snake_case (sin ft)
9
+ s: RawSortFieldApply[] | undefined): RowType[];
@@ -0,0 +1,5 @@
1
+ import { SortField } from '../../../../src/components/DynamicSort/types';
2
+ /**
3
+ * Helper que retorna los sorts configurados para el DataGrid de Storybook
4
+ */
5
+ export declare const sortsSeedData: SortField[];
@@ -21,6 +21,7 @@ export type ColumnType = 'string' | 'number' | 'boolean' | 'date' | 'custom';
21
21
  export interface RowType {
22
22
  id: string;
23
23
  name: string;
24
+ filterableOnlyOne: string;
24
25
  email: string;
25
26
  phone: string;
26
27
  ip: string;
@@ -4,5 +4,8 @@ import { SeedProps } from './types';
4
4
  */
5
5
  export declare const useSeed: (props: SeedProps) => {
6
6
  columns: readonly import('./types').Column<import('./types').RowType, unknown>[];
7
+ filters: import('../../../../src').FilterField[];
8
+ sorts: import('../../../../src').SortField[];
7
9
  rows: import('./types').RowType[];
10
+ rowsMultiSort: import('./types').RowType[];
8
11
  };
@@ -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
@@ -3,5 +3,5 @@ import { ObjectLogs } from '../../../src/components/ObjectLogs/ObjectLogs';
3
3
  import { ObjectLogsM4LProps, ObjectLogsOtherProps } from '../../../src/components/ObjectLogs/types';
4
4
  declare const meta: Meta<typeof ObjectLogs>;
5
5
  export default meta;
6
- export declare const DefaultM4L: import('@storybook/csf').AnnotatedStoryFn<import('@storybook/react').ReactRenderer, ObjectLogsM4LProps>;
7
- export declare const DefaultOthers: import('@storybook/csf').AnnotatedStoryFn<import('@storybook/react').ReactRenderer, ObjectLogsOtherProps>;
6
+ export declare const DefaultM4L: import('@storybook/core/csf').AnnotatedStoryFn<import('@storybook/react').ReactRenderer, ObjectLogsM4LProps>;
7
+ export declare const DefaultOthers: import('@storybook/core/csf').AnnotatedStoryFn<import('@storybook/react').ReactRenderer, ObjectLogsOtherProps>;