@arquimedes.co/eureka-forms 3.0.57-test → 3.0.58-claude-evlog-migration
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/dist/App/App.stories.js +3 -2
- package/dist/App/AppHooks.js +2 -3
- package/dist/Form/Form.js +2 -1
- package/dist/Form/FormFunctions.js +3 -2
- package/dist/Form/FormTypes/ColumnForm/ColumnForm.js +2 -1
- package/dist/Form/FormTypes/StepperForm/StepperForm.js +2 -1
- package/dist/FormSteps/FileUploadStep/MaterialFileUploadStep/FileComponent/FileComponent.js +2 -1
- package/dist/FormSteps/FileUploadStep/MaterialFileUploadStep/MaterialFileUploadStep.js +3 -2
- package/dist/FormSteps/MapperStep/MaterialMapperStep/Element/PagedMapperElement/PagedMapperElement.js +2 -1
- package/dist/FormSteps/SmartSelectStep/MaterialSmartSelectStep/MaterialSmartSelectStep.js +2 -1
- package/dist/FormSteps/Step.js +2 -1
- package/dist/FormSteps/StepFunctions.js +2 -1
- package/dist/Login/LoginPage.js +2 -1
- package/dist/Shared/ErkDatePicker/ErkDatePicker.js +3 -3
- package/dist/Shared/ErkDateRangePicker/ErkDateRangePicker.js +2 -2
- package/dist/Shared/ErkTimePicker/ErkTimePicker.js +1 -0
- package/dist/Shared/ErkTimePicker/ErkTimePicker.module.css +0 -1
- package/dist/Shared/Navbar/Navbar.js +2 -1
- package/dist/Shared/SmartDraftRenderer/LinkDecorator.js +2 -2
- package/dist/Utils/Logger.d.ts +24 -0
- package/dist/Utils/Logger.js +38 -0
- package/dist/Utils/PhoneFunctions.js +3 -2
- package/dist/Widget.js +2 -0
- package/dist/main.js +5 -2
- package/package.json +2 -1
package/dist/App/App.stories.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import App from './App';
|
|
3
|
+
import { log } from '../Utils/Logger';
|
|
3
4
|
/**
|
|
4
5
|
* Stories to test full forms from a `{ form, values }` payload:
|
|
5
6
|
*
|
|
@@ -149,8 +150,8 @@ const meta = {
|
|
|
149
150
|
idOrganization: 'storybook',
|
|
150
151
|
valuesData: {},
|
|
151
152
|
customSubmit: (values) => {
|
|
152
|
-
//
|
|
153
|
-
|
|
153
|
+
// Storybook fixtures only — real submissions must never log field values.
|
|
154
|
+
log.info({ form: { id: 'storybook' }, action: { name: 'submit' }, fields: Object.keys(values) });
|
|
154
155
|
return Promise.resolve();
|
|
155
156
|
},
|
|
156
157
|
},
|
package/dist/App/AppHooks.js
CHANGED
|
@@ -11,6 +11,7 @@ import { calcDependencies } from '../Form/FormFunctions';
|
|
|
11
11
|
import { iterateNestedSteps } from '../FormSteps/StepFunctions';
|
|
12
12
|
import { createNextState } from '@reduxjs/toolkit';
|
|
13
13
|
import { BaseConfirmationMessage } from '../Contexts/FormContext';
|
|
14
|
+
import { errorFields, log } from '../Utils/Logger';
|
|
14
15
|
export const useSetupApp = (isEmbedded, props) => {
|
|
15
16
|
const { preview, internal, postview, partial, editable, handleConfirmed, customSteps, valuesData, apiKey, formData, classifiers, idCurrentAgent, formStyle: formStyleOverride, ...others } = props;
|
|
16
17
|
const [form, setForm] = useState(undefined);
|
|
@@ -136,8 +137,6 @@ export const useSetupApp = (isEmbedded, props) => {
|
|
|
136
137
|
};
|
|
137
138
|
useEffect(() => {
|
|
138
139
|
void loadData();
|
|
139
|
-
// eslint-disable-next-line no-console
|
|
140
|
-
console.log('Form props Changed!');
|
|
141
140
|
return () => {
|
|
142
141
|
dispatch({ type: 'CLEAR' });
|
|
143
142
|
};
|
|
@@ -189,7 +188,7 @@ export const useLogRocket = (organization, form, { apiKey, internal, postview, p
|
|
|
189
188
|
});
|
|
190
189
|
}
|
|
191
190
|
catch (error) {
|
|
192
|
-
|
|
191
|
+
log.warn({ session: { provider: 'logrocket' }, error: errorFields(error) });
|
|
193
192
|
}
|
|
194
193
|
}
|
|
195
194
|
};
|
package/dist/Form/Form.js
CHANGED
|
@@ -19,6 +19,7 @@ import FormContext, { IdFormContext } from '../Contexts/FormContext';
|
|
|
19
19
|
import { getAppState } from '../Utils/store';
|
|
20
20
|
import LoginPage from '../Login/LoginPage';
|
|
21
21
|
import { focusStep } from '../States/SiteSlice';
|
|
22
|
+
import { errorFields, log } from '../Utils/Logger';
|
|
22
23
|
function FormComponent({ form, apiKey, reload, isWidget, branding, setSubmit, scrollToTop, customSteps, containerRef, customSubmit, customSubmitBtns, customConfirmation, }) {
|
|
23
24
|
const { idOrganization, internal, postview, user } = useAppSelector((state) => state.global);
|
|
24
25
|
const formMethods = useForm({
|
|
@@ -76,7 +77,7 @@ function FormComponent({ form, apiKey, reload, isWidget, branding, setSubmit, sc
|
|
|
76
77
|
setShowConfirmation(resp?.data);
|
|
77
78
|
}
|
|
78
79
|
catch (error) {
|
|
79
|
-
|
|
80
|
+
log.error({ form: { step: 'submit' }, error: errorFields(error) });
|
|
80
81
|
}
|
|
81
82
|
},
|
|
82
83
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -3,6 +3,7 @@ import FormStepTypes, { EntityValueDataTypes } from '../constants/FormStepTypes'
|
|
|
3
3
|
import { calcStepDeps } from '../FormSteps/StepHooks';
|
|
4
4
|
import { calcRecursiveData } from '../Utils/FormStepFunctions';
|
|
5
5
|
import { isValidPhoneNumber } from '../Utils/PhoneFunctions';
|
|
6
|
+
import { log } from '../Utils/Logger';
|
|
6
7
|
/**
|
|
7
8
|
* Function that cals the value of a step to output on submit
|
|
8
9
|
*/
|
|
@@ -166,7 +167,7 @@ function calcStepDependency(idStep, steps, values, customSteps) {
|
|
|
166
167
|
if (!depStep) {
|
|
167
168
|
const originalValue = values.global[idStep];
|
|
168
169
|
if (!originalValue)
|
|
169
|
-
|
|
170
|
+
log.warn({ form: { step: idStep }, dependency: { resolved: false } });
|
|
170
171
|
return {
|
|
171
172
|
idOriginal: idStep,
|
|
172
173
|
type: originalValue ? 'ORIGINAL' : 'MISSING',
|
|
@@ -176,7 +177,7 @@ function calcStepDependency(idStep, steps, values, customSteps) {
|
|
|
176
177
|
}
|
|
177
178
|
const originalValue = values.sections[depStep.idSection]?.[depStep.id] ?? values.global[depStep.id];
|
|
178
179
|
if (!depStep.stepPath)
|
|
179
|
-
|
|
180
|
+
log.warn({ form: { step: depStep.id, type: depStep.type }, dependency: { stepPath: false } });
|
|
180
181
|
return {
|
|
181
182
|
type: depStep.type,
|
|
182
183
|
idOriginal: depStep.stepPath?.[0] ?? [idStep],
|
|
@@ -11,6 +11,7 @@ import CustomBtn from '../../../Shared/CustomBtn/CustomBtn';
|
|
|
11
11
|
import FormContext, { IdFormContext } from '../../../Contexts/FormContext';
|
|
12
12
|
import { addPagedValues } from '../../../States/SiteSlice';
|
|
13
13
|
import { getAppState } from '../../../Utils/store';
|
|
14
|
+
import { log } from '../../../Utils/Logger';
|
|
14
15
|
function ColumnForm({ onSubmit, customSubmitBtns, ...props }) {
|
|
15
16
|
const [loading, setLoading] = useState(false);
|
|
16
17
|
const { postview, editable, formStyle } = useAppSelector((state) => state.global);
|
|
@@ -29,7 +30,7 @@ function ColumnForm({ onSubmit, customSubmitBtns, ...props }) {
|
|
|
29
30
|
}, [props.setSubmit]);
|
|
30
31
|
/** Esto se usa para no tener que escuchar todo el tiempo los errores del formulario */
|
|
31
32
|
const handleErrors = handleSubmit(() => { }, (errors) => {
|
|
32
|
-
|
|
33
|
+
log.warn({ form: { type: 'column' }, validation: { fields: Object.keys(errors) } });
|
|
33
34
|
});
|
|
34
35
|
const submit = useCallback(async () => {
|
|
35
36
|
setLoading(true);
|
|
@@ -11,6 +11,7 @@ import { getAppState } from '../../../Utils/store';
|
|
|
11
11
|
import CustomBtn from '../../../Shared/CustomBtn/CustomBtn';
|
|
12
12
|
import FormContext, { IdFormContext } from '../../../Contexts/FormContext';
|
|
13
13
|
import { addPagedValues } from '../../../States/SiteSlice';
|
|
14
|
+
import { log } from '../../../Utils/Logger';
|
|
14
15
|
function StepperForm({ onSubmit, scrollToTop }) {
|
|
15
16
|
const [loading, setLoading] = useState(undefined);
|
|
16
17
|
const { postview, editable, formStyle } = useAppSelector((state) => state.global);
|
|
@@ -24,7 +25,7 @@ function StepperForm({ onSubmit, scrollToTop }) {
|
|
|
24
25
|
const next = useAppSelector((state) => state.site.nextSections);
|
|
25
26
|
/** Esto se usa para no tener que escuchar todo el tiempo los errores del formulario */
|
|
26
27
|
const handleErrors = handleSubmit(() => { }, (errors) => {
|
|
27
|
-
|
|
28
|
+
log.warn({ form: { type: 'stepper' }, validation: { fields: Object.keys(errors) } });
|
|
28
29
|
});
|
|
29
30
|
const handlePrevious = useCallback(() => {
|
|
30
31
|
dispatch(SiteReducer.handlePrevious({ values: getValues(), form }));
|
|
@@ -6,6 +6,7 @@ import FileIcon from '../../../../Icons/FileIcon';
|
|
|
6
6
|
import ErrorIcon from '../../../../Icons/ErrorIcon';
|
|
7
7
|
import CloseIcon from '../../../../Icons/CloseIcon';
|
|
8
8
|
import { isUploadedFileObject } from '../FileFunctions';
|
|
9
|
+
import { errorFields, log } from '../../../../Utils/Logger';
|
|
9
10
|
function FileUploadComponent({ file, formStyle, error, editable, handleRemove, fetchDownloadUrl, }) {
|
|
10
11
|
const [downloading, setDownloading] = useState(false);
|
|
11
12
|
if (!file) {
|
|
@@ -23,7 +24,7 @@ function FileUploadComponent({ file, formStyle, error, editable, handleRemove, f
|
|
|
23
24
|
setDownloading(false);
|
|
24
25
|
}
|
|
25
26
|
catch (error) {
|
|
26
|
-
|
|
27
|
+
log.error({ upload: { operation: 'download' }, error: errorFields(error) });
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
};
|
|
@@ -10,6 +10,7 @@ import maxSize from '../../../constants/Files/FileMaxSize';
|
|
|
10
10
|
import { useAppSelector } from '../../../hooks';
|
|
11
11
|
import CustomContext from '../../../Contexts/CustomContext';
|
|
12
12
|
import { useFormStep } from '../../StepHooks';
|
|
13
|
+
import { errorFields, log } from '../../../Utils/Logger';
|
|
13
14
|
function FileUploadStep({ step, editable }) {
|
|
14
15
|
const { ref, value, onChange, error: fieldError, } = useFormStep(step, {
|
|
15
16
|
defaultValue: [],
|
|
@@ -65,7 +66,7 @@ function FileUploadStep({ step, editable }) {
|
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
catch (error) {
|
|
68
|
-
|
|
69
|
+
log.error({ upload: { operation: 'validate' }, error: errorFields(error) });
|
|
69
70
|
}
|
|
70
71
|
}, [idOrganization]);
|
|
71
72
|
const uploadFile = useCallback(async (pFile) => {
|
|
@@ -77,7 +78,7 @@ function FileUploadStep({ step, editable }) {
|
|
|
77
78
|
setFileChange((prev) => prev.map((f) => (f.file === pFile.file ? { ...f, state: 'DONE', ...resp[0] } : f)));
|
|
78
79
|
}
|
|
79
80
|
catch (error) {
|
|
80
|
-
|
|
81
|
+
log.error({ upload: { operation: 'upload' }, error: errorFields(error) });
|
|
81
82
|
}
|
|
82
83
|
}, []);
|
|
83
84
|
useEffect(() => {
|
|
@@ -10,6 +10,7 @@ import DeleteIcon from '../../../../../Icons/DeleteIcon';
|
|
|
10
10
|
import { MobileStepper, styled } from '@mui/material';
|
|
11
11
|
import ArrowRightIcon from '../../../../../Icons/ArrowRightIcon';
|
|
12
12
|
import ArrowLeftIcon from '../../../../../Icons/ArrowLeftIcon';
|
|
13
|
+
import { log } from '../../../../../Utils/Logger';
|
|
13
14
|
function PagedMapperElement({ step, num, loading, element, children, editable, onChange, value, handleDelete, customElementModifiers, customElementRender, }) {
|
|
14
15
|
const deletable = step.deletable ?? true;
|
|
15
16
|
const { size } = useContext(FormContext);
|
|
@@ -43,7 +44,7 @@ function PagedMapperElement({ step, num, loading, element, children, editable, o
|
|
|
43
44
|
}, [value]);
|
|
44
45
|
/** Esto se usa para no tener que escuchar todo el tiempo los errores del formulario */
|
|
45
46
|
const handleErrors = handleSubmit(() => { }, (errors) => {
|
|
46
|
-
|
|
47
|
+
log.warn({ form: { type: 'mapper' }, validation: { fields: Object.keys(errors) } });
|
|
47
48
|
});
|
|
48
49
|
const handleChangePage = useCallback(async (index) => {
|
|
49
50
|
const valid = await trigger(undefined, { shouldFocus: true });
|
|
@@ -10,6 +10,7 @@ import { selectDependencies, selectStepDependencies, useFormStep } from '../../S
|
|
|
10
10
|
import { shallowEqual } from 'react-redux';
|
|
11
11
|
import MaterialInputContainer from '../../Utils/MaterialInputContainer/MaterialInputContainer';
|
|
12
12
|
import { FormTypes } from '../../../constants/FormStepTypes';
|
|
13
|
+
import { errorFields, log } from '../../../Utils/Logger';
|
|
13
14
|
function SmartSelectStep({ step, editable, getOptions, calcDepError, defaultValue, filterOptions, IconComponent, valueOverwrite, getValueString, changeListener, getValueWarning, getOptionSelected, getOptionalDependencies = () => [], getOptionsConditionsIdSteps = () => [], renderNestedSteps, }) {
|
|
14
15
|
const { ref, value, error, field, onChange: handleChange, } = useFormStep(step, {
|
|
15
16
|
sizeChange: true,
|
|
@@ -82,7 +83,7 @@ function SmartSelectStep({ step, editable, getOptions, calcDepError, defaultValu
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
catch (error) {
|
|
85
|
-
|
|
86
|
+
log.error({ api: { endpoint: 'smartSelect' }, error: errorFields(error) });
|
|
86
87
|
setOptions(null);
|
|
87
88
|
}
|
|
88
89
|
setLoading(false);
|
package/dist/FormSteps/Step.js
CHANGED
|
@@ -24,6 +24,7 @@ import CustomContext from '../Contexts/CustomContext';
|
|
|
24
24
|
import { selectOriginalValue, useCondition } from './StepHooks';
|
|
25
25
|
import TimePickerStep from './TimePickerStep/TimePickerStep';
|
|
26
26
|
import PhoneInputStep from './PhoneInputStep/PhoneInputStep';
|
|
27
|
+
import { log } from '../Utils/Logger';
|
|
27
28
|
function StepComponent({ step, ...props }) {
|
|
28
29
|
const { postview, partial } = useAppSelector((state) => state.global);
|
|
29
30
|
const { customSteps, customClientInfoStep } = useContext(CustomContext);
|
|
@@ -31,7 +32,7 @@ function StepComponent({ step, ...props }) {
|
|
|
31
32
|
const showStep = useCondition(step?.condition);
|
|
32
33
|
/** A rootSteps entry with no matching step definition must not take the whole form down with it. */
|
|
33
34
|
if (!step) {
|
|
34
|
-
|
|
35
|
+
log.error({ form: { step }, render: { component: 'Step', reason: 'step_not_found' } });
|
|
35
36
|
return _jsx(_Fragment, {});
|
|
36
37
|
}
|
|
37
38
|
if (!showStep)
|
|
@@ -4,6 +4,7 @@ import AYFFormStepTypes from '../constants/AYFFormStepTypes';
|
|
|
4
4
|
import { getRawText } from '../Utils/DraftFunctions';
|
|
5
5
|
import ConditionTypes, { ExpressionTypes, OperatorTypes } from '../constants/ConditionTypes';
|
|
6
6
|
import EntityPropertyTypes from '../constants/EntityPropertyTypes';
|
|
7
|
+
import { log } from '../Utils/Logger';
|
|
7
8
|
export function calcFillerSize(step, steps, values, size) {
|
|
8
9
|
const maxSize = step.maxSize ?? size.blockNum;
|
|
9
10
|
if (maxSize < size.blockNum) {
|
|
@@ -196,7 +197,7 @@ export const calcDefaultValue = (step) => {
|
|
|
196
197
|
export const iterateNestedSteps = (idStep, steps, iteration, path = []) => {
|
|
197
198
|
const step = steps[idStep];
|
|
198
199
|
if (!step) {
|
|
199
|
-
|
|
200
|
+
log.warn({ form: { step: idStep }, reason: 'missing_step' });
|
|
200
201
|
return;
|
|
201
202
|
}
|
|
202
203
|
iteration(step, path);
|
package/dist/Login/LoginPage.js
CHANGED
|
@@ -11,6 +11,7 @@ import { setUser } from '../States/GlobalSlice';
|
|
|
11
11
|
import { jwtDecode } from 'jwt-decode';
|
|
12
12
|
import LoginTextField from './LoginTextField';
|
|
13
13
|
import MaterialProviders from '../Utils/MaterialProviders';
|
|
14
|
+
import { errorFields, log } from '../Utils/Logger';
|
|
14
15
|
const EMAIL_REGEX =
|
|
15
16
|
// eslint-disable-next-line no-control-regex
|
|
16
17
|
/^(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i;
|
|
@@ -51,7 +52,7 @@ function LoginPage({ form }) {
|
|
|
51
52
|
catch (err) {
|
|
52
53
|
setLoading(false);
|
|
53
54
|
if (err?.response?.status !== 400) {
|
|
54
|
-
|
|
55
|
+
log.error({ action: { name: 'login' }, error: errorFields(err) });
|
|
55
56
|
}
|
|
56
57
|
if (err?.response?.data === 'Invalid Organization') {
|
|
57
58
|
setError('password', {
|
|
@@ -132,7 +132,7 @@ const StyledDay = styled(MuiPickerDay)(({ theme }) => ({
|
|
|
132
132
|
backgroundColor: theme.palette.primary.main + '33',
|
|
133
133
|
},
|
|
134
134
|
'&.Erk-MuiPickerDay-dayOutsideMonth': {
|
|
135
|
-
color:
|
|
135
|
+
color: theme.palette.text.disabled,
|
|
136
136
|
'&.Mui-selected': {
|
|
137
137
|
color: theme.palette.primary.contrastText,
|
|
138
138
|
},
|
|
@@ -178,7 +178,7 @@ orientation: _orientation, ...others }) {
|
|
|
178
178
|
layout: {
|
|
179
179
|
sx: {
|
|
180
180
|
//Pasar esto al componente de layout?
|
|
181
|
-
backgroundColor: '
|
|
181
|
+
backgroundColor: 'background.paper',
|
|
182
182
|
textTransform: 'capitalize',
|
|
183
183
|
'& .Erk-MuiDayCalendar-weekDayLabel': {
|
|
184
184
|
gridColumn: 1,
|
|
@@ -237,7 +237,7 @@ orientation: _orientation, ...others }) {
|
|
|
237
237
|
},
|
|
238
238
|
layout: {
|
|
239
239
|
sx: {
|
|
240
|
-
backgroundColor: '
|
|
240
|
+
backgroundColor: 'background.paper',
|
|
241
241
|
textTransform: 'capitalize',
|
|
242
242
|
'& .Erk-MuiDayCalendar-weekDayLabel': {
|
|
243
243
|
cursor: 'default',
|
|
@@ -75,7 +75,7 @@ const StyledDay = styled(MuiDateRangePickerDay)(({ theme }) => ({
|
|
|
75
75
|
backgroundColor: theme.palette.primary.main + '33',
|
|
76
76
|
},
|
|
77
77
|
'&.Erk-MuiDateRangePickerDay-dayOutsideMonth': {
|
|
78
|
-
color:
|
|
78
|
+
color: theme.palette.text.disabled,
|
|
79
79
|
'&.Mui-selected': {
|
|
80
80
|
color: theme.palette.primary.contrastText,
|
|
81
81
|
},
|
|
@@ -152,7 +152,7 @@ function CustomDatePickerRange({ error, disabled, readOnly, helperText, size = '
|
|
|
152
152
|
shortcuts: shortcuts ? { items: shortcuts } : undefined,
|
|
153
153
|
layout: {
|
|
154
154
|
sx: {
|
|
155
|
-
backgroundColor: '
|
|
155
|
+
backgroundColor: 'background.paper',
|
|
156
156
|
textTransform: 'capitalize',
|
|
157
157
|
'& .Erk-MuiDayCalendar-weekDayLabel': {
|
|
158
158
|
cursor: 'default',
|
|
@@ -46,6 +46,7 @@ function CustomSelect({ value, onChange, label, error, required, pickDays, helpe
|
|
|
46
46
|
},
|
|
47
47
|
], style: { zIndex: 1301 }, children: _jsxs("div", { className: styles.container, style: {
|
|
48
48
|
paddingTop: error && helperText ? '0px' : '30px',
|
|
49
|
+
backgroundColor: palette.background.paper,
|
|
49
50
|
}, children: [error && helperText && (_jsx("div", { className: styles.errorMessage, style: {
|
|
50
51
|
color: palette.error.main,
|
|
51
52
|
}, children: helperText })), pickDays && (_jsx("div", { className: styles.numberPickerContainer, children: _jsx(StyledTextField, { label: "D\u00EDas", type: "number", labelMargin: 0, value: (value?.days ?? minDays) + '', onChange: (event) => handleChange({ ...value, days: parseInt(event.target.value) }), slotProps: { htmlInput: { min: minDays, max: maxDays } } }) })), pickHours && (_jsx("div", { className: styles.numberPickerContainer, children: _jsx(StyledTextField, { label: "Horas", type: "number", labelMargin: 0, value: (value?.hours ?? minHours) + '', onChange: (event) => handleChange({ ...value, hours: parseInt(event.target.value) }), slotProps: { htmlInput: { min: minHours, max: maxHours } } }) })), pickMinutes && (_jsx("div", { className: styles.numberPickerContainer, children: _jsx(StyledTextField, { type: "number", label: "Minutos", labelMargin: 0, slotProps: { htmlInput: { min: minMinutes, max: maxMinutes } }, value: (value?.minutes ?? minMinutes) + '', onChange: (event) => handleChange({ ...value, minutes: parseInt(event.target.value) }) }) })), working === undefined && (_jsxs("div", { className: styles.workingContainer, children: ["H\u00E1biles:", _jsx(ErkToggle, { checked: !!value?.working, disabled: working !== undefined, onChange: (working) => {
|
|
@@ -4,6 +4,7 @@ import styles from './Navbar.module.css';
|
|
|
4
4
|
import { IconButton, Avatar, Menu, MenuItem } from '@mui/material';
|
|
5
5
|
import { logout } from '../../Services/UserService';
|
|
6
6
|
import { useAppSelector } from '../../hooks';
|
|
7
|
+
import { errorFields, log } from '../../Utils/Logger';
|
|
7
8
|
function Navbar({ logo, color, apiKey }) {
|
|
8
9
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
9
10
|
const user = useAppSelector((state) => state.global.user);
|
|
@@ -14,7 +15,7 @@ function Navbar({ logo, color, apiKey }) {
|
|
|
14
15
|
await logout(apiKey);
|
|
15
16
|
}
|
|
16
17
|
catch (err) {
|
|
17
|
-
|
|
18
|
+
log.error({ action: { name: 'logout' }, error: errorFields(err) });
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
localStorage.removeItem('token');
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { errorFields, log } from '../../Utils/Logger';
|
|
2
3
|
export function LinkComponent({ children, decoratedText }) {
|
|
3
4
|
// Add protocol if missing
|
|
4
5
|
const getHref = (url) => {
|
|
@@ -38,8 +39,7 @@ export function findLinkEntities(contentBlock, callback) {
|
|
|
38
39
|
}
|
|
39
40
|
catch (error) {
|
|
40
41
|
// Fail silently to avoid breaking the editor
|
|
41
|
-
|
|
42
|
-
console.warn('LinkDecorator: Error finding link entities:', error);
|
|
42
|
+
log.warn({ render: { component: 'LinkDecorator' }, error: errorFields(error) });
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
export const linkDecorator = {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { log, parseError } from 'evlog';
|
|
2
|
+
/**
|
|
3
|
+
* Configure evlog for the form renderer. Called by the entry points this package owns — `main.tsx` and
|
|
4
|
+
* `Widget.tsx` — never at module scope.
|
|
5
|
+
*
|
|
6
|
+
* `initLogger` overwrites every global evlog holds, including the host's drain, and this package is also
|
|
7
|
+
* consumed as a library: `admin/Frontend` deep-imports `dist/App/App` and `dist/FormSteps/StepFunctions`,
|
|
8
|
+
* which reach this module. Initialising on import would run *after* the admin SPA's own `initLogger` and
|
|
9
|
+
* silently relabel its events `eureka-forms`. A consumer that wants forms' configuration calls this itself.
|
|
10
|
+
*
|
|
11
|
+
* `redact` stays on everywhere. These forms collect third parties' personal data on third parties' sites,
|
|
12
|
+
* so the redaction pass is the last line of defence behind the rule that field values are never logged at
|
|
13
|
+
* all — see `docs/CONVENCIONES_LOGS.md` §3 in the Eureka-All workspace.
|
|
14
|
+
*/
|
|
15
|
+
export declare function initFormsLogger(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Loggable fields for a caught value. The global `log` API takes plain objects, not `Error`s, and a stack
|
|
18
|
+
* trace adds nothing in a published form — the message and the class are what identify the failure.
|
|
19
|
+
*/
|
|
20
|
+
export declare function errorFields(error: unknown): {
|
|
21
|
+
message: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
};
|
|
24
|
+
export { log, parseError };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { initLogger, log, parseError } from 'evlog';
|
|
2
|
+
/**
|
|
3
|
+
* Local runs are detected from the hostname rather than a build-time flag: this package ships through both
|
|
4
|
+
* the Vite app build and the webpack `Embeddables` build, and only one of them defines `import.meta.env`.
|
|
5
|
+
*/
|
|
6
|
+
const isLocal = typeof window !== 'undefined' && /^(localhost|127\.0\.0\.1|\[::1\])$/.test(window.location.hostname);
|
|
7
|
+
/**
|
|
8
|
+
* Configure evlog for the form renderer. Called by the entry points this package owns — `main.tsx` and
|
|
9
|
+
* `Widget.tsx` — never at module scope.
|
|
10
|
+
*
|
|
11
|
+
* `initLogger` overwrites every global evlog holds, including the host's drain, and this package is also
|
|
12
|
+
* consumed as a library: `admin/Frontend` deep-imports `dist/App/App` and `dist/FormSteps/StepFunctions`,
|
|
13
|
+
* which reach this module. Initialising on import would run *after* the admin SPA's own `initLogger` and
|
|
14
|
+
* silently relabel its events `eureka-forms`. A consumer that wants forms' configuration calls this itself.
|
|
15
|
+
*
|
|
16
|
+
* `redact` stays on everywhere. These forms collect third parties' personal data on third parties' sites,
|
|
17
|
+
* so the redaction pass is the last line of defence behind the rule that field values are never logged at
|
|
18
|
+
* all — see `docs/CONVENCIONES_LOGS.md` §3 in the Eureka-All workspace.
|
|
19
|
+
*/
|
|
20
|
+
export function initFormsLogger() {
|
|
21
|
+
initLogger({
|
|
22
|
+
env: { service: 'eureka-forms' },
|
|
23
|
+
pretty: isLocal,
|
|
24
|
+
redact: true,
|
|
25
|
+
// `debug` is available locally and never reaches a published form.
|
|
26
|
+
minLevel: isLocal ? 'debug' : 'info',
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Loggable fields for a caught value. The global `log` API takes plain objects, not `Error`s, and a stack
|
|
31
|
+
* trace adds nothing in a published form — the message and the class are what identify the failure.
|
|
32
|
+
*/
|
|
33
|
+
export function errorFields(error) {
|
|
34
|
+
if (error instanceof Error)
|
|
35
|
+
return { message: error.message, name: error.name };
|
|
36
|
+
return { message: String(error) };
|
|
37
|
+
}
|
|
38
|
+
export { log, parseError };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as libphonenumber from 'libphonenumber-js/max';
|
|
2
|
-
import { guessCountryByPartialPhoneNumber, removeDialCode
|
|
2
|
+
import { guessCountryByPartialPhoneNumber, removeDialCode } from 'react-international-phone';
|
|
3
|
+
import { log } from './Logger';
|
|
3
4
|
export function isValidPhoneNumber(phone) {
|
|
4
5
|
if (!phone.startsWith('+'))
|
|
5
6
|
phone = '+' + phone;
|
|
@@ -19,7 +20,7 @@ export function isEmptyPhoneNumber(phone) {
|
|
|
19
20
|
return true;
|
|
20
21
|
}
|
|
21
22
|
if (!country) {
|
|
22
|
-
|
|
23
|
+
log.warn({ validation: { field: 'phone', reason: 'country_not_found' } });
|
|
23
24
|
return true;
|
|
24
25
|
}
|
|
25
26
|
return false;
|
package/dist/Widget.js
CHANGED
|
@@ -2,6 +2,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { createRoot } from 'react-dom/client';
|
|
3
3
|
import App from './App/App';
|
|
4
4
|
import './Utils/MuiClassnameSetup';
|
|
5
|
+
import { initFormsLogger } from './Utils/Logger';
|
|
6
|
+
initFormsLogger();
|
|
5
7
|
const WIDGET_ID = document.currentScript?.getAttribute('data-id') ?? 'widget:eureka';
|
|
6
8
|
const element = document.getElementById(WIDGET_ID);
|
|
7
9
|
const props = {};
|
package/dist/main.js
CHANGED
|
@@ -5,6 +5,8 @@ import styles from './index.module.css';
|
|
|
5
5
|
import App from './App/App';
|
|
6
6
|
import './index.css';
|
|
7
7
|
import './Utils/MuiClassnameSetup';
|
|
8
|
+
import { initFormsLogger, log } from './Utils/Logger';
|
|
9
|
+
initFormsLogger();
|
|
8
10
|
const urlParams = new URLSearchParams(window.location.search);
|
|
9
11
|
const values = urlParams.get('data-values');
|
|
10
12
|
let dataValues = undefined;
|
|
@@ -12,8 +14,9 @@ if (values) {
|
|
|
12
14
|
try {
|
|
13
15
|
dataValues = JSON.parse(decodeURIComponent(values));
|
|
14
16
|
}
|
|
15
|
-
catch
|
|
16
|
-
|
|
17
|
+
catch {
|
|
18
|
+
// The parser message quotes the offending input, which here is prefilled form values.
|
|
19
|
+
log.error({ form: { source: 'data-values' }, outcome: { status: 'error', reason: 'invalid_json' } });
|
|
17
20
|
}
|
|
18
21
|
}
|
|
19
22
|
const idOrganization = urlParams.get('idOrganization') ?? undefined;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arquimedes.co/eureka-forms",
|
|
3
3
|
"repository": "git://github.com/Arquimede5/Eureka-Forms.git",
|
|
4
|
-
"version":"3.0.
|
|
4
|
+
"version":"3.0.58-claude-evlog-migration",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"watch": "tsgo --noEmit --watch --project tsconfig.app.json",
|
|
7
7
|
"start": "vite",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"axios": "1.16.0",
|
|
21
21
|
"date-fns": "4.1.0",
|
|
22
22
|
"draft-js": "0.11.7",
|
|
23
|
+
"evlog": "^2.22.4",
|
|
23
24
|
"i18n-iso-countries": "7.14.0",
|
|
24
25
|
"jwt-decode": "4.0.0",
|
|
25
26
|
"libphonenumber-js": "1.12.42",
|