@m4l/components 9.3.23 → 9.3.24-JT04112025.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/CommonActions/components/ActionFormCancel/ActionFormCancel.js +17 -8
- package/components/CommonActions/components/ActionFormCancel/types.d.ts +9 -0
- package/components/DataGrid/formatters/ColumnIconFormatter/index.d.ts +1 -0
- package/components/DataGrid/index.d.ts +1 -1
- package/components/DataGrid/types.d.ts +2 -0
- package/components/DynamicFilter/helpers/formatToInitialFilters.js +3 -3
- package/components/DynamicFilter/subcomponents/FieldTypes/BooleanFilter/helpers.js +11 -3
- package/components/DynamicFilter/subcomponents/FieldTypes/DateTimeFilter/helpers.js +16 -4
- package/components/DynamicFilter/subcomponents/FieldTypes/NumberFilter/helpers.js +11 -8
- package/components/DynamicFilter/subcomponents/FieldTypes/SelectAsyncFilter/helpers.js +21 -8
- package/components/DynamicFilter/subcomponents/FieldTypes/SelectFilter/helpers.js +18 -8
- package/components/DynamicFilter/subcomponents/FieldTypes/StringFilter/helpers.js +5 -3
- package/components/Label/Label.js +1 -1
- package/components/PaperForm/PaperForm.js +1 -1
- package/components/PaperForm/components/Header.js +9 -7
- package/components/PaperForm/styles.js +9 -4
- package/components/PaperForm/types.d.ts +3 -2
- package/components/Stepper/Stepper.styles.js +2 -0
- package/components/Stepper/dictionary.js +0 -1
- package/components/Stepper/subcomponents/StepArea/hooks/useStepArea.d.ts +13 -0
- package/components/Stepper/subcomponents/StepArea/hooks/useStepArea.js +111 -0
- package/components/Stepper/subcomponents/StepArea/hooks/useVisibileSteps.d.ts +8 -0
- package/components/Stepper/subcomponents/StepArea/hooks/useVisibileSteps.js +79 -0
- package/components/Stepper/subcomponents/StepArea/index.js +7 -115
- package/components/Stepper/subcomponents/StepperButtons/StepperCancelButton/index.d.ts +2 -2
- package/components/Stepper/subcomponents/StepperButtons/StepperCancelButton/index.js +3 -53
- package/components/Stepper/subcomponents/StepperButtons/StepperNextButton/index.js +3 -2
- package/components/Stepper/subcomponents/StepperButtons/StepperPrevButton/index.js +3 -2
- package/components/Stepper/subcomponents/StepperButtons/StepperSubmitButton/index.js +24 -5
- package/components/Stepper/subcomponents/StepperContent/subcomponents/Step/hooks/useIsStepVisible.d.ts +8 -0
- package/components/Stepper/subcomponents/StepperContent/subcomponents/Step/hooks/useIsStepVisible.js +93 -0
- package/components/Stepper/subcomponents/StepperContent/subcomponents/Step/index.js +2 -51
- package/components/Stepper/types.d.ts +4 -0
- package/components/ToastContainer/ToastContainer.js +1 -0
- package/components/ToastContainer/constants.d.ts +1 -1
- package/components/ToastContainer/constants.js +1 -1
- package/components/WindowBase/contexts/WindowToolsMFContext/WindowToolsMFContext.js +47 -3
- package/components/WindowBase/contexts/WindowToolsMFContext/types.d.ts +1 -1
- package/components/WindowBase/subcomponents/Component/index.d.ts +12 -1
- package/components/WindowBase/subcomponents/Component/index.js +56 -2
- package/components/WindowBase/subcomponents/Component/types.d.ts +1 -0
- package/components/WindowBase/types.d.ts +1 -1
- package/components/areas/components/AreasViewer/subcomponents/Area/subcomponents/Window/Window.js +1 -0
- package/components/areas/components/AreasViewer/subcomponents/Area/subcomponents/Window/hooks/useWindow.js +1 -1
- package/components/areas/contexts/AreasContext/store.js +5 -1
- package/components/areas/contexts/AreasContext/types.d.ts +1 -1
- package/components/hook-form/RHFormContext/styles.js +2 -1
- package/components/mui_extended/CircularProgress/types.d.ts +1 -1
- package/components/popups/components/PopupsProvider/contexts/PopupsContext/store.js +5 -1
- package/components/popups/components/PopupsProvider/contexts/PopupsContext/types.d.ts +1 -1
- package/components/popups/components/PopupsProvider/hooks/usePopups.d.ts +2 -4
- package/components/popups/components/PopupsProvider/hooks/usePopups.js +19 -7
- package/components/popups/components/PopupsViewer/PopupsViewer.js +1 -1
- package/components/popups/components/PopupsViewer/PopupsViewer.styles.js +1 -1
- package/components/popups/components/PopupsViewer/subcomponents/Popup/Popup.js +32 -21
- package/index.js +60 -58
- package/package.json +1 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { useRef, useCallback, useSyncExternalStore, useMemo } from "react";
|
|
2
|
+
import { useFormContext } from "react-hook-form";
|
|
3
|
+
import { u as useStepper } from "../../../hooks/useStepper/index.js";
|
|
4
|
+
import { e as evaluateVisibilityStepCondition } from "../../../helpers/evaluateVisibilityStepCondition/index.js";
|
|
5
|
+
import { d as deepShallow } from "../../../../../utils/deepShallow.js";
|
|
6
|
+
function calculateVisibleSteps(steps, formValues, visibilityData) {
|
|
7
|
+
return steps.filter(
|
|
8
|
+
(step) => evaluateVisibilityStepCondition(step, formValues || {}, visibilityData || {})
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
function generateStepsKey(steps) {
|
|
12
|
+
return steps.map((step) => step.key).join(",");
|
|
13
|
+
}
|
|
14
|
+
function useVisibileSteps() {
|
|
15
|
+
const formContext = useFormContext();
|
|
16
|
+
const {
|
|
17
|
+
steps,
|
|
18
|
+
visibilityData
|
|
19
|
+
} = useStepper(
|
|
20
|
+
(state) => ({
|
|
21
|
+
steps: state.steps,
|
|
22
|
+
visibilityData: state.visibilityData
|
|
23
|
+
}),
|
|
24
|
+
deepShallow
|
|
25
|
+
);
|
|
26
|
+
const previousStepsKeyRef = useRef(null);
|
|
27
|
+
const cachedVisibleStepsRef = useRef([]);
|
|
28
|
+
const listenersRef = useRef(/* @__PURE__ */ new Set());
|
|
29
|
+
const subscribe = useCallback((callback) => {
|
|
30
|
+
listenersRef.current.add(callback);
|
|
31
|
+
const { unsubscribe } = formContext.watch((formValues) => {
|
|
32
|
+
const newVisibleSteps = calculateVisibleSteps(
|
|
33
|
+
steps,
|
|
34
|
+
formValues,
|
|
35
|
+
visibilityData
|
|
36
|
+
);
|
|
37
|
+
const newStepsKey = generateStepsKey(newVisibleSteps);
|
|
38
|
+
if (newStepsKey !== previousStepsKeyRef.current) {
|
|
39
|
+
previousStepsKeyRef.current = newStepsKey;
|
|
40
|
+
cachedVisibleStepsRef.current = newVisibleSteps;
|
|
41
|
+
listenersRef.current.forEach((listener) => listener());
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return () => {
|
|
45
|
+
listenersRef.current.delete(callback);
|
|
46
|
+
unsubscribe();
|
|
47
|
+
};
|
|
48
|
+
}, [formContext, steps, visibilityData]);
|
|
49
|
+
const getSnapshot = useCallback(() => {
|
|
50
|
+
const formValues = formContext.getValues();
|
|
51
|
+
const currentVisibleSteps = calculateVisibleSteps(
|
|
52
|
+
steps,
|
|
53
|
+
formValues,
|
|
54
|
+
visibilityData
|
|
55
|
+
);
|
|
56
|
+
const stepsKey = generateStepsKey(currentVisibleSteps);
|
|
57
|
+
if (previousStepsKeyRef.current === null) {
|
|
58
|
+
previousStepsKeyRef.current = stepsKey;
|
|
59
|
+
cachedVisibleStepsRef.current = currentVisibleSteps;
|
|
60
|
+
}
|
|
61
|
+
if (stepsKey === previousStepsKeyRef.current) {
|
|
62
|
+
return cachedVisibleStepsRef.current;
|
|
63
|
+
}
|
|
64
|
+
previousStepsKeyRef.current = stepsKey;
|
|
65
|
+
cachedVisibleStepsRef.current = currentVisibleSteps;
|
|
66
|
+
return currentVisibleSteps;
|
|
67
|
+
}, [formContext, steps, visibilityData]);
|
|
68
|
+
const visibleSteps = useSyncExternalStore(
|
|
69
|
+
subscribe,
|
|
70
|
+
getSnapshot,
|
|
71
|
+
getSnapshot
|
|
72
|
+
);
|
|
73
|
+
return useMemo(() => ({
|
|
74
|
+
visibleSteps
|
|
75
|
+
}), [visibleSteps]);
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
useVisibileSteps as u
|
|
79
|
+
};
|
|
@@ -1,127 +1,19 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from "react";
|
|
3
|
-
import { useFormContext, useWatch } from "react-hook-form";
|
|
4
|
-
import { u as useStepper } from "../../hooks/useStepper/index.js";
|
|
5
2
|
import { e as StepAreaStyled, f as StepStyled, g as StepNameStyled } from "../../slots/StepperSlot.js";
|
|
6
3
|
import { I as Indicator } from "./subcomponents/Inidicator/index.js";
|
|
7
|
-
import {
|
|
8
|
-
import { u as
|
|
9
|
-
import { e as evaluateVisibilityStepCondition } from "../../helpers/evaluateVisibilityStepCondition/index.js";
|
|
4
|
+
import { u as useStepArea } from "./hooks/useStepArea.js";
|
|
5
|
+
import { u as useVisibileSteps } from "./hooks/useVisibileSteps.js";
|
|
10
6
|
function StepArea() {
|
|
11
|
-
const {
|
|
12
|
-
const
|
|
13
|
-
const {
|
|
14
|
-
activateFieldsValidation,
|
|
15
|
-
startExternalValidation,
|
|
16
|
-
endExternalValidation
|
|
17
|
-
} = useDynamicValidation();
|
|
18
|
-
const {
|
|
19
|
-
currentStep,
|
|
20
|
-
steps,
|
|
21
|
-
visibleTitle,
|
|
22
|
-
setCurrentStep,
|
|
23
|
-
orientation,
|
|
24
|
-
setStepValidationStatus,
|
|
25
|
-
stepValidationStatus,
|
|
26
|
-
visibilityData
|
|
27
|
-
} = useStepper(
|
|
28
|
-
(state) => ({
|
|
29
|
-
currentStep: state.currentStep,
|
|
30
|
-
steps: state.steps,
|
|
31
|
-
visibleTitle: state.visibleTitle,
|
|
32
|
-
setCurrentStep: state.actions.setCurrentStep,
|
|
33
|
-
indicatorType: state.indicatorType,
|
|
34
|
-
orientation: state.orientation,
|
|
35
|
-
setStepValidationStatus: state.actions.setStepValidationStatus,
|
|
36
|
-
stepValidationStatus: state.stepValidationStatus,
|
|
37
|
-
visibilityData: state.visibilityData
|
|
38
|
-
}),
|
|
39
|
-
shallow
|
|
40
|
-
);
|
|
41
|
-
const allSteps = steps;
|
|
42
|
-
const visibleSteps = useMemo(() => {
|
|
43
|
-
return steps.filter(
|
|
44
|
-
(step) => evaluateVisibilityStepCondition(step, formValues || {}, visibilityData)
|
|
45
|
-
);
|
|
46
|
-
}, [steps, formValues, visibilityData]);
|
|
7
|
+
const { visibleSteps } = useVisibileSteps();
|
|
8
|
+
const { handleStepClick, visibleTitle, orientation, steps, currentStep } = useStepArea({ visibleSteps });
|
|
47
9
|
const ownerState = {
|
|
48
10
|
visibleTitle,
|
|
49
11
|
orientation,
|
|
50
12
|
totalSteps: visibleSteps.length
|
|
51
13
|
};
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
);
|
|
56
|
-
if (targetIndex === currentIndex) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const isNavigatingForward = targetIndex > currentIndex;
|
|
60
|
-
const targetOriginalIndex = steps.findIndex(
|
|
61
|
-
(s) => s.key === visibleSteps[targetIndex].key
|
|
62
|
-
);
|
|
63
|
-
if (!isNavigatingForward) {
|
|
64
|
-
setCurrentStep(targetOriginalIndex);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const isSkippingSteps = targetIndex > currentIndex + 1;
|
|
68
|
-
if (isSkippingSteps) {
|
|
69
|
-
for (let i = currentIndex; i < targetIndex; i++) {
|
|
70
|
-
const step = visibleSteps[i];
|
|
71
|
-
const stepOriginalIndex = steps.findIndex((s) => s.key === step.key);
|
|
72
|
-
startExternalValidation();
|
|
73
|
-
const isValid = await trigger(step.validationFields);
|
|
74
|
-
endExternalValidation();
|
|
75
|
-
if (!isValid) {
|
|
76
|
-
setCurrentStep(stepOriginalIndex);
|
|
77
|
-
setStepValidationStatus(stepOriginalIndex, false);
|
|
78
|
-
activateFieldsValidation(step.validationFields || []);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
setStepValidationStatus(stepOriginalIndex, true);
|
|
82
|
-
}
|
|
83
|
-
} else {
|
|
84
|
-
const currentStepData = visibleSteps[currentIndex];
|
|
85
|
-
const currentStepOriginalIndex = steps.findIndex(
|
|
86
|
-
(s) => s.key === currentStepData.key
|
|
87
|
-
);
|
|
88
|
-
startExternalValidation();
|
|
89
|
-
const isCurrentValid = await trigger(currentStepData.validationFields);
|
|
90
|
-
endExternalValidation();
|
|
91
|
-
if (!isCurrentValid) {
|
|
92
|
-
setStepValidationStatus(currentStepOriginalIndex, false);
|
|
93
|
-
activateFieldsValidation(currentStepData.validationFields || []);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
setStepValidationStatus(currentStepOriginalIndex, true);
|
|
97
|
-
}
|
|
98
|
-
setCurrentStep(targetOriginalIndex);
|
|
99
|
-
if (isNavigatingForward) {
|
|
100
|
-
const currentStepData = visibleSteps[currentIndex];
|
|
101
|
-
const currentStepOriginalIndex = steps.findIndex(
|
|
102
|
-
(s) => s.key === currentStepData.key
|
|
103
|
-
);
|
|
104
|
-
const isCurrentStepValid = stepValidationStatus[currentStepOriginalIndex] !== false;
|
|
105
|
-
if (isCurrentStepValid) {
|
|
106
|
-
const targetStep = visibleSteps[targetIndex];
|
|
107
|
-
const targetStepFields = targetStep.validationFields || [];
|
|
108
|
-
if (targetStepFields.length > 0) {
|
|
109
|
-
clearErrors(targetStepFields);
|
|
110
|
-
setTimeout(() => {
|
|
111
|
-
clearErrors(targetStepFields);
|
|
112
|
-
setStepValidationStatus(targetOriginalIndex, true);
|
|
113
|
-
}, 100);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
return /* @__PURE__ */ jsx(StepAreaStyled, { ownerState, children: allSteps.map((step, originalIndex) => {
|
|
119
|
-
const isStepVisible = evaluateVisibilityStepCondition(
|
|
120
|
-
step,
|
|
121
|
-
formValues || {},
|
|
122
|
-
visibilityData
|
|
123
|
-
);
|
|
124
|
-
const visibleStepIndex = isStepVisible ? visibleSteps.findIndex((visStep) => visStep.key === step.key) : -1;
|
|
14
|
+
return /* @__PURE__ */ jsx(StepAreaStyled, { ownerState, children: steps.map((step, originalIndex) => {
|
|
15
|
+
const visibleStepIndex = visibleSteps.findIndex((visibleStep) => visibleStep.key === step.key);
|
|
16
|
+
const isStepVisible = visibleStepIndex !== -1;
|
|
125
17
|
return /* @__PURE__ */ jsxs(
|
|
126
18
|
StepStyled,
|
|
127
19
|
{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ActionFormCancelProps } from '../../../../CommonActions/components/ActionFormCancel/types';
|
|
2
2
|
/**
|
|
3
3
|
* Botón modular para cancelar el proceso del Stepper
|
|
4
4
|
*/
|
|
5
|
-
export declare function StepperCancelButton(props:
|
|
5
|
+
export declare function StepperCancelButton(props: ActionFormCancelProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,58 +1,8 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { useFormContext, useFormState } from "react-hook-form";
|
|
4
|
-
import { u as useStepperActions } from "../../../hooks/useStepperActions/index.js";
|
|
5
|
-
import { D as DICTIONARY$1 } from "../../../dictionary.js";
|
|
6
|
-
import { D as DICTIONARY } from "../../../../CommonActions/dictionary.js";
|
|
7
|
-
import { useModuleDictionary } from "@m4l/core";
|
|
8
|
-
import { u as useModal } from "../../../../../hooks/useModal/index.js";
|
|
9
|
-
import { u as useWindowToolsMF } from "../../../../WindowBase/hooks/useWindowToolsMF/index.js";
|
|
10
|
-
import { W as WindowConfirm } from "../../../../WindowConfirm/WindowConfirm.js";
|
|
11
|
-
import { B as Button } from "../../../../mui_extended/Button/Button.js";
|
|
2
|
+
import { A as ActionFormCancel } from "../../../../CommonActions/components/ActionFormCancel/ActionFormCancel.js";
|
|
12
3
|
function StepperCancelButton(props) {
|
|
13
|
-
const {
|
|
14
|
-
|
|
15
|
-
const { cancelAction } = useStepperActions();
|
|
16
|
-
const { openModal } = useModal();
|
|
17
|
-
const { close: closeWindow } = useWindowToolsMF();
|
|
18
|
-
const { control } = useFormContext();
|
|
19
|
-
const { isDirty } = useFormState({
|
|
20
|
-
control
|
|
21
|
-
});
|
|
22
|
-
const onConfirmQuit = useCallback(() => {
|
|
23
|
-
cancelAction();
|
|
24
|
-
closeWindow();
|
|
25
|
-
}, [cancelAction, closeWindow]);
|
|
26
|
-
const handleCancel = useCallback(() => {
|
|
27
|
-
if (isDirty) {
|
|
28
|
-
openModal({
|
|
29
|
-
window: /* @__PURE__ */ jsx(
|
|
30
|
-
WindowConfirm,
|
|
31
|
-
{
|
|
32
|
-
variant: "warning",
|
|
33
|
-
title: getLabel(DICTIONARY.CONFIRM_QUIT_TITLE),
|
|
34
|
-
msg: getLabel(DICTIONARY.CONFIRM_QUIT_MSG),
|
|
35
|
-
onClickIntro: onConfirmQuit
|
|
36
|
-
}
|
|
37
|
-
),
|
|
38
|
-
variant: "warning"
|
|
39
|
-
});
|
|
40
|
-
} else {
|
|
41
|
-
onConfirmQuit();
|
|
42
|
-
}
|
|
43
|
-
}, [getLabel, isDirty, openModal, onConfirmQuit]);
|
|
44
|
-
return /* @__PURE__ */ jsx(
|
|
45
|
-
Button,
|
|
46
|
-
{
|
|
47
|
-
type: "button",
|
|
48
|
-
label: label || getLabel(DICTIONARY$1.LABEL_CANCEL_BUTTON),
|
|
49
|
-
variant: "outlined",
|
|
50
|
-
color: "default",
|
|
51
|
-
onClick: handleCancel,
|
|
52
|
-
...rest,
|
|
53
|
-
"data-testid": "stepper-cancel-button"
|
|
54
|
-
}
|
|
55
|
-
);
|
|
4
|
+
const { ...rest } = props;
|
|
5
|
+
return /* @__PURE__ */ jsx(ActionFormCancel, { "data-testid": "stepper-cancel-button", ...rest });
|
|
56
6
|
}
|
|
57
7
|
export {
|
|
58
8
|
StepperCancelButton as S
|
|
@@ -7,15 +7,16 @@ import { useModuleDictionary, useEnvironment } from "@m4l/core";
|
|
|
7
7
|
import { I as IconButton } from "../../../../mui_extended/IconButton/IconButton.js";
|
|
8
8
|
import { B as Button } from "../../../../mui_extended/Button/Button.js";
|
|
9
9
|
function StepperNextButton(props) {
|
|
10
|
-
const { label, ...rest } = props;
|
|
10
|
+
const { label, forceIsMobile, ...rest } = props;
|
|
11
11
|
const { nextStepAction } = useStepperActions();
|
|
12
12
|
const isMobile = useIsMobile();
|
|
13
|
+
const isMobileForce = forceIsMobile !== void 0 ? forceIsMobile : isMobile;
|
|
13
14
|
const { getLabel } = useModuleDictionary();
|
|
14
15
|
const { host_static_assets, environment_assets } = useEnvironment();
|
|
15
16
|
const handleNext = async () => {
|
|
16
17
|
await nextStepAction();
|
|
17
18
|
};
|
|
18
|
-
return
|
|
19
|
+
return isMobileForce ? /* @__PURE__ */ jsx(
|
|
19
20
|
IconButton,
|
|
20
21
|
{
|
|
21
22
|
type: "button",
|
|
@@ -8,12 +8,13 @@ import { D as DICTIONARY } from "../../../dictionary.js";
|
|
|
8
8
|
import { I as IconButton } from "../../../../mui_extended/IconButton/IconButton.js";
|
|
9
9
|
import { B as Button } from "../../../../mui_extended/Button/Button.js";
|
|
10
10
|
function StepperPrevButton(props) {
|
|
11
|
-
const { label, ...rest } = props;
|
|
11
|
+
const { label, forceIsMobile, ...rest } = props;
|
|
12
12
|
const { currentStep } = useStepper((state) => ({
|
|
13
13
|
currentStep: state.currentStep
|
|
14
14
|
}));
|
|
15
15
|
const { host_static_assets, environment_assets } = useEnvironment();
|
|
16
16
|
const isMobile = useIsMobile();
|
|
17
|
+
const isMobileForce = forceIsMobile !== void 0 ? forceIsMobile : isMobile;
|
|
17
18
|
const { getLabel } = useModuleDictionary();
|
|
18
19
|
const { prevStepAction } = useStepperActions();
|
|
19
20
|
const handlePrev = () => {
|
|
@@ -22,7 +23,7 @@ function StepperPrevButton(props) {
|
|
|
22
23
|
if (currentStep === 0) {
|
|
23
24
|
return null;
|
|
24
25
|
}
|
|
25
|
-
return
|
|
26
|
+
return isMobileForce ? /* @__PURE__ */ jsx(
|
|
26
27
|
IconButton,
|
|
27
28
|
{
|
|
28
29
|
type: "button",
|
|
@@ -1,18 +1,37 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { D as DICTIONARY } from "../../../dictionary.js";
|
|
3
|
-
import { useModuleDictionary } from "@m4l/core";
|
|
4
|
-
import {
|
|
3
|
+
import { useModuleDictionary, useEnvironment } from "@m4l/core";
|
|
4
|
+
import { useIsMobile } from "@m4l/graphics";
|
|
5
|
+
import { p as pathIcons } from "../../../icons.js";
|
|
6
|
+
import { useFormContext } from "react-hook-form";
|
|
7
|
+
import { L as LoadingButton } from "../../../../mui_extended/LoadingButton/LoadingButton.js";
|
|
8
|
+
import { I as IconButton } from "../../../../mui_extended/IconButton/IconButton.js";
|
|
9
|
+
import { C as CircularProgress } from "../../../../mui_extended/CircularProgress/CircularProgress.js";
|
|
5
10
|
function StepperSubmitButton(props) {
|
|
6
|
-
const { label, ...rest } = props;
|
|
11
|
+
const { label, forceIsMobile, ...rest } = props;
|
|
7
12
|
const { getLabel } = useModuleDictionary();
|
|
8
|
-
|
|
9
|
-
|
|
13
|
+
const { host_static_assets, environment_assets } = useEnvironment();
|
|
14
|
+
const isMobile = useIsMobile();
|
|
15
|
+
const isMobileForce = forceIsMobile !== void 0 ? forceIsMobile : isMobile;
|
|
16
|
+
const { formState: { isSubmitting } } = useFormContext();
|
|
17
|
+
return isMobileForce ? /* @__PURE__ */ jsx(
|
|
18
|
+
IconButton,
|
|
19
|
+
{
|
|
20
|
+
type: "submit",
|
|
21
|
+
icon: isSubmitting ? /* @__PURE__ */ jsx(CircularProgress, { color: "default" }) : `${host_static_assets}/${environment_assets}/${pathIcons.circleCheck}`,
|
|
22
|
+
"data-testid": "stepper-prev-button",
|
|
23
|
+
variant: "contained",
|
|
24
|
+
color: "primary"
|
|
25
|
+
}
|
|
26
|
+
) : /* @__PURE__ */ jsx(
|
|
27
|
+
LoadingButton,
|
|
10
28
|
{
|
|
11
29
|
type: "submit",
|
|
12
30
|
label: label || getLabel(DICTIONARY.LABEL_SUBMIT_BUTTON),
|
|
13
31
|
variant: "contained",
|
|
14
32
|
color: "primary",
|
|
15
33
|
"data-testid": "stepper-submit-button",
|
|
34
|
+
loading: isSubmitting,
|
|
16
35
|
...rest
|
|
17
36
|
}
|
|
18
37
|
);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { StepProps } from '../../../../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook que determina si un step debe ser visible
|
|
4
|
+
* Usa useSyncExternalStore para optimizar re-renders:
|
|
5
|
+
* - Solo re-renderiza el componente si el valor booleano cambia realmente
|
|
6
|
+
* - Aunque el formulario cambie, si la visibilidad sigue siendo la misma, no re-renderiza
|
|
7
|
+
*/
|
|
8
|
+
export declare function useIsStepVisible(props: Pick<StepProps, 'stepKey'>): boolean;
|
package/components/Stepper/subcomponents/StepperContent/subcomponents/Step/hooks/useIsStepVisible.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { useRef, useCallback, useSyncExternalStore } from "react";
|
|
2
|
+
import { u as useStepper } from "../../../../../hooks/useStepper/index.js";
|
|
3
|
+
import { useFormContext } from "react-hook-form";
|
|
4
|
+
import { d as deepShallow } from "../../../../../../../utils/deepShallow.js";
|
|
5
|
+
import { e as evaluateVisibilityStepCondition } from "../../../../../helpers/evaluateVisibilityStepCondition/index.js";
|
|
6
|
+
function calculateStepVisibility(stepKey, steps, currentStep, formValues, visibilityData) {
|
|
7
|
+
const stepConfig = steps.find((step) => step.key === stepKey);
|
|
8
|
+
if (!stepConfig) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const meetsVisibilityCondition = evaluateVisibilityStepCondition(
|
|
12
|
+
stepConfig,
|
|
13
|
+
formValues || {},
|
|
14
|
+
visibilityData || {}
|
|
15
|
+
);
|
|
16
|
+
if (!meetsVisibilityCondition) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const currentStepConfig = steps[currentStep];
|
|
20
|
+
if (!currentStepConfig) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
if (evaluateVisibilityStepCondition(currentStepConfig, formValues || {}, visibilityData || {})) {
|
|
24
|
+
return stepKey === currentStepConfig.key;
|
|
25
|
+
}
|
|
26
|
+
const visibleStepsUpToCurrent = [];
|
|
27
|
+
for (let i = 0; i <= currentStep; i++) {
|
|
28
|
+
const step = steps[i];
|
|
29
|
+
if (evaluateVisibilityStepCondition(step, formValues || {}, visibilityData || {})) {
|
|
30
|
+
visibleStepsUpToCurrent.push(step);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (visibleStepsUpToCurrent.length === 0) {
|
|
34
|
+
for (let i = currentStep + 1; i < steps.length; i++) {
|
|
35
|
+
const step = steps[i];
|
|
36
|
+
if (evaluateVisibilityStepCondition(step, formValues || {}, visibilityData || {})) {
|
|
37
|
+
return stepKey === step.key;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const activeVisibleStep = visibleStepsUpToCurrent[visibleStepsUpToCurrent.length - 1];
|
|
43
|
+
return stepKey === activeVisibleStep.key;
|
|
44
|
+
}
|
|
45
|
+
function useIsStepVisible(props) {
|
|
46
|
+
const { stepKey } = props;
|
|
47
|
+
const formContext = useFormContext();
|
|
48
|
+
const { currentStep, steps, visibilityData } = useStepper((state) => ({
|
|
49
|
+
currentStep: state.currentStep,
|
|
50
|
+
steps: state.steps,
|
|
51
|
+
visibilityData: state.visibilityData
|
|
52
|
+
}), deepShallow);
|
|
53
|
+
const previousValueRef = useRef(null);
|
|
54
|
+
const listenersRef = useRef(/* @__PURE__ */ new Set());
|
|
55
|
+
const subscribe = useCallback((callback) => {
|
|
56
|
+
listenersRef.current.add(callback);
|
|
57
|
+
const { unsubscribe } = formContext.watch((formValues) => {
|
|
58
|
+
const newValue = calculateStepVisibility(
|
|
59
|
+
stepKey,
|
|
60
|
+
steps,
|
|
61
|
+
currentStep,
|
|
62
|
+
formValues,
|
|
63
|
+
visibilityData
|
|
64
|
+
);
|
|
65
|
+
if (newValue !== previousValueRef.current) {
|
|
66
|
+
previousValueRef.current = newValue;
|
|
67
|
+
listenersRef.current.forEach((listener) => listener());
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
return () => {
|
|
71
|
+
listenersRef.current.delete(callback);
|
|
72
|
+
unsubscribe();
|
|
73
|
+
};
|
|
74
|
+
}, [formContext, stepKey, steps, currentStep, visibilityData]);
|
|
75
|
+
const getSnapshot = useCallback(() => {
|
|
76
|
+
const formValues = formContext.getValues();
|
|
77
|
+
const value = calculateStepVisibility(
|
|
78
|
+
stepKey,
|
|
79
|
+
steps,
|
|
80
|
+
currentStep,
|
|
81
|
+
formValues,
|
|
82
|
+
visibilityData
|
|
83
|
+
);
|
|
84
|
+
if (previousValueRef.current === null) {
|
|
85
|
+
previousValueRef.current = value;
|
|
86
|
+
}
|
|
87
|
+
return value;
|
|
88
|
+
}, [formContext, stepKey, steps, currentStep, visibilityData]);
|
|
89
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
90
|
+
}
|
|
91
|
+
export {
|
|
92
|
+
useIsStepVisible as u
|
|
93
|
+
};
|
|
@@ -1,58 +1,9 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from "react";
|
|
3
|
-
import { u as useStepper } from "../../../../hooks/useStepper/index.js";
|
|
4
|
-
import { useWatch } from "react-hook-form";
|
|
5
2
|
import { j as StepContentStyled } from "../../../../slots/StepperSlot.js";
|
|
6
|
-
import {
|
|
3
|
+
import { u as useIsStepVisible } from "./hooks/useIsStepVisible.js";
|
|
7
4
|
function Step(props) {
|
|
8
5
|
const { stepKey, children } = props;
|
|
9
|
-
const
|
|
10
|
-
const { currentStep, steps, visibilityData } = useStepper((state) => ({
|
|
11
|
-
currentStep: state.currentStep,
|
|
12
|
-
steps: state.steps,
|
|
13
|
-
visibilityData: state.visibilityData
|
|
14
|
-
}));
|
|
15
|
-
const stepConfig = useMemo(() => {
|
|
16
|
-
return steps.find((step) => step.key === stepKey);
|
|
17
|
-
}, [steps, stepKey]);
|
|
18
|
-
const isStepVisible = useMemo(() => {
|
|
19
|
-
if (!stepConfig) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
const meetsVisibilityCondition = evaluateVisibilityStepCondition(
|
|
23
|
-
stepConfig,
|
|
24
|
-
formValues || {},
|
|
25
|
-
visibilityData
|
|
26
|
-
);
|
|
27
|
-
if (!meetsVisibilityCondition) {
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
const currentStepConfig = steps[currentStep];
|
|
31
|
-
if (!currentStepConfig) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
if (evaluateVisibilityStepCondition(currentStepConfig, formValues || {}, visibilityData)) {
|
|
35
|
-
return stepKey === currentStepConfig.key;
|
|
36
|
-
}
|
|
37
|
-
const visibleStepsUpToCurrent = [];
|
|
38
|
-
for (let i = 0; i <= currentStep; i++) {
|
|
39
|
-
const step = steps[i];
|
|
40
|
-
if (evaluateVisibilityStepCondition(step, formValues || {}, visibilityData)) {
|
|
41
|
-
visibleStepsUpToCurrent.push(step);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (visibleStepsUpToCurrent.length === 0) {
|
|
45
|
-
for (let i = currentStep + 1; i < steps.length; i++) {
|
|
46
|
-
const step = steps[i];
|
|
47
|
-
if (evaluateVisibilityStepCondition(step, formValues || {}, visibilityData)) {
|
|
48
|
-
return stepKey === step.key;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
const activeVisibleStep = visibleStepsUpToCurrent[visibleStepsUpToCurrent.length - 1];
|
|
54
|
-
return stepKey === activeVisibleStep.key;
|
|
55
|
-
}, [currentStep, stepKey, stepConfig, steps, formValues, visibilityData]);
|
|
6
|
+
const isStepVisible = useIsStepVisible({ stepKey });
|
|
56
7
|
return /* @__PURE__ */ jsx(StepContentStyled, { ownerState: { isStepVisible }, children });
|
|
57
8
|
}
|
|
58
9
|
export {
|
|
@@ -150,6 +150,10 @@ export interface StepperFooterLeftActionsProps {
|
|
|
150
150
|
* Props para los botones del Stepper que extienden las props de Button de mui_extended
|
|
151
151
|
*/
|
|
152
152
|
export interface StepperButtonProps extends Omit<ButtonProps, 'label'> {
|
|
153
|
+
/**
|
|
154
|
+
* Forzar a un una versión especifica no importando el dispositivo
|
|
155
|
+
*/
|
|
156
|
+
forceIsMobile?: boolean;
|
|
153
157
|
label?: string;
|
|
154
158
|
}
|
|
155
159
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const TOAST_KEY_COMPONENT = "M4LToastContainer";
|
|
2
|
-
export declare const DEFAULT_CLOSE_TIME =
|
|
2
|
+
export declare const DEFAULT_CLOSE_TIME = 10000;
|
|
3
3
|
export declare const ICONS_PATH = "frontend/components/toast/assets/icons";
|
|
4
4
|
export declare const TOAST_NATIVE_STYLES: {
|
|
5
5
|
'&': {
|
|
@@ -1,9 +1,53 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import React, { createContext } from "react";
|
|
2
|
+
import React, { createContext, useMemo } from "react";
|
|
3
3
|
const WindowToolsMFContext = createContext(null);
|
|
4
4
|
function WindowToolsMFProvider(props) {
|
|
5
|
-
const {
|
|
6
|
-
|
|
5
|
+
const {
|
|
6
|
+
children,
|
|
7
|
+
getCookie,
|
|
8
|
+
getWindowId,
|
|
9
|
+
getCookies,
|
|
10
|
+
setActions,
|
|
11
|
+
setCookie,
|
|
12
|
+
startProgress,
|
|
13
|
+
stopProgress,
|
|
14
|
+
toast,
|
|
15
|
+
close,
|
|
16
|
+
setFnQueryClose,
|
|
17
|
+
setWindowTitle,
|
|
18
|
+
setWindowSubTitle,
|
|
19
|
+
setWindowEditionInfo
|
|
20
|
+
} = props;
|
|
21
|
+
const value = useMemo(() => ({
|
|
22
|
+
getCookie,
|
|
23
|
+
getWindowId,
|
|
24
|
+
getCookies,
|
|
25
|
+
setActions,
|
|
26
|
+
setCookie,
|
|
27
|
+
startProgress,
|
|
28
|
+
stopProgress,
|
|
29
|
+
toast,
|
|
30
|
+
close,
|
|
31
|
+
setFnQueryClose,
|
|
32
|
+
setWindowTitle,
|
|
33
|
+
setWindowSubTitle,
|
|
34
|
+
setWindowEditionInfo
|
|
35
|
+
}), [
|
|
36
|
+
getCookie,
|
|
37
|
+
getWindowId,
|
|
38
|
+
getCookies,
|
|
39
|
+
setActions,
|
|
40
|
+
setCookie,
|
|
41
|
+
startProgress,
|
|
42
|
+
stopProgress,
|
|
43
|
+
toast,
|
|
44
|
+
close,
|
|
45
|
+
setFnQueryClose,
|
|
46
|
+
setWindowTitle,
|
|
47
|
+
setWindowSubTitle,
|
|
48
|
+
setWindowEditionInfo
|
|
49
|
+
]);
|
|
50
|
+
return /* @__PURE__ */ jsx(WindowToolsMFContext.Provider, { value, children });
|
|
7
51
|
}
|
|
8
52
|
const MemonizedWindowToolsMFContext = React.memo(WindowToolsMFProvider);
|
|
9
53
|
export {
|
|
@@ -53,7 +53,7 @@ export interface WindowToolsMF {
|
|
|
53
53
|
/**
|
|
54
54
|
* Método para cerrar la ventana actual.
|
|
55
55
|
*/
|
|
56
|
-
close: () => void;
|
|
56
|
+
close: (useFnQueryClose?: boolean) => void;
|
|
57
57
|
/**
|
|
58
58
|
* Método para establecer la función de consulta de cierre de la ventana.
|
|
59
59
|
* @param fnQueryClose La función de consulta de cierre de la ventana que se desea establecer.
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { ComponentProps } from './types';
|
|
3
3
|
/**
|
|
4
|
-
* Componente encargado de renderizar el componente de la ventana.
|
|
4
|
+
* Componente encargado de renderizar el componente de la ventana con transición y loader.
|
|
5
|
+
* Usa useTransition para priorizar el loader y mantener la UI responsive durante el renderizado pesado.
|
|
6
|
+
*
|
|
7
|
+
* ## Flujo de renderizado:
|
|
8
|
+
* 1. Monta con shouldRender=false, isPending=false → muestra nada (o loader inicial)
|
|
9
|
+
* 2. useEffect ejecuta: startTransition(() => setShouldRender(true))
|
|
10
|
+
* 3. React marca la actualización como "no urgente" e inmediatamente isPending=true → muestra loader
|
|
11
|
+
* 4. React procesa el cambio de shouldRender: useMemo se re-ejecuta y crea el componente pesado
|
|
12
|
+
* 5. Cuando termina TODO el trabajo de render: isPending=false → muestra componente con fade in
|
|
13
|
+
*
|
|
14
|
+
* La clave es que React mantiene isPending=true durante TODO el tiempo que tarde en procesar
|
|
15
|
+
* la actualización de estado y el render que causa (incluyendo el useMemo pesado).
|
|
5
16
|
*/
|
|
6
17
|
export declare const WindowBaseComponent: (props: ComponentProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
18
|
export declare const MemonizedComponent: React.MemoExoticComponent<(props: ComponentProps) => import("react/jsx-runtime").JSX.Element>;
|