@arquimedes.co/eureka-forms 3.0.69 → 3.0.70
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/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.js +5 -1
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.d.ts +3 -1
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.js +4 -2
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.test.js +14 -0
- package/package.json +1 -1
|
@@ -124,6 +124,10 @@ function MaterialBookingStep({ step, editable, fetchSlots: customFetchSlots }) {
|
|
|
124
124
|
const personSelectionMode = usesEdge
|
|
125
125
|
? (offer?.personSelection ?? PersonSelectionMode.NONE)
|
|
126
126
|
: step.personSelectionMode;
|
|
127
|
-
return (_jsx("div", { ref: ref, style: cssVars, children: _jsx(ErkBookingPicker, { value: value, onChange: handleChange, label: step.label, description: step.description, durationMinutes: offer?.durationMinutes ?? step.durationMinutes, bufferMinutes: step.bufferMinutes, bookingMode: step.bookingMode, temporaryLockMinutes: step.temporaryLockMinutes, personSelectionMode: personSelectionMode, persons: usesEdge ? persons : step.persons,
|
|
127
|
+
return (_jsx("div", { ref: ref, style: cssVars, children: _jsx(ErkBookingPicker, { value: value, onChange: handleChange, label: step.label, description: step.description, durationMinutes: offer?.durationMinutes ?? step.durationMinutes, bufferMinutes: step.bufferMinutes, bookingMode: step.bookingMode, temporaryLockMinutes: step.temporaryLockMinutes, personSelectionMode: personSelectionMode, persons: usesEdge ? persons : step.persons,
|
|
128
|
+
// Whoever holds a slot must be named unless the step lets strangers book; asking for the name
|
|
129
|
+
// whenever it is required keeps the hold from being refused for a step that never turned the
|
|
130
|
+
// contact fields on.
|
|
131
|
+
collectContact: !step.allowAnonymous || step.collectContact === true, requireContact: !step.allowAnonymous, fetchSlots: usesEdge ? fetchSlots : customFetchSlots, fetchDays: usesEdge ? fetchDays : undefined, holdSlot: usesEdge ? holdSlot : undefined, disabled: usesEdge && !offer, readOnly: isReadOnly, error: error?.message ?? offerError }) }));
|
|
128
132
|
}
|
|
129
133
|
export default MaterialBookingStep;
|
|
@@ -12,6 +12,8 @@ export interface ErkBookingPickerProps {
|
|
|
12
12
|
persons?: BookablePerson[];
|
|
13
13
|
/** Recopila nombre/correo del que agenda. */
|
|
14
14
|
collectContact?: boolean;
|
|
15
|
+
/** El nombre es obligatorio para confirmar: el paso no admite reservas anónimas. */
|
|
16
|
+
requireContact?: boolean;
|
|
15
17
|
/** Provee los slots disponibles para una persona + día. */
|
|
16
18
|
fetchSlots?: (args: {
|
|
17
19
|
personId?: string;
|
|
@@ -48,5 +50,5 @@ export interface ErkBookingPickerProps {
|
|
|
48
50
|
* En el paso final el panel derecho desaparece y el resumen se expande en una columna
|
|
49
51
|
* centrada (cross-fade corto). Confirmar cierra el modal y deja el resumen compacto.
|
|
50
52
|
*/
|
|
51
|
-
declare function ErkBookingPicker({ value, onChange, label, description, durationMinutes, bufferMinutes, bookingMode, temporaryLockMinutes, personSelectionMode, persons, collectContact, fetchSlots, fetchDays, holdSlot, disabled, readOnly, error, }: ErkBookingPickerProps): JSX.Element;
|
|
53
|
+
declare function ErkBookingPicker({ value, onChange, label, description, durationMinutes, bufferMinutes, bookingMode, temporaryLockMinutes, personSelectionMode, persons, collectContact, requireContact, fetchSlots, fetchDays, holdSlot, disabled, readOnly, error, }: ErkBookingPickerProps): JSX.Element;
|
|
52
54
|
export default ErkBookingPicker;
|
|
@@ -59,7 +59,7 @@ function capitalize(text) {
|
|
|
59
59
|
* En el paso final el panel derecho desaparece y el resumen se expande en una columna
|
|
60
60
|
* centrada (cross-fade corto). Confirmar cierra el modal y deja el resumen compacto.
|
|
61
61
|
*/
|
|
62
|
-
function ErkBookingPicker({ value, onChange, label, description, durationMinutes, bufferMinutes, bookingMode, temporaryLockMinutes, personSelectionMode, persons, collectContact = false, fetchSlots, fetchDays, holdSlot, disabled = false, readOnly = false, error, }) {
|
|
62
|
+
function ErkBookingPicker({ value, onChange, label, description, durationMinutes, bufferMinutes, bookingMode, temporaryLockMinutes, personSelectionMode, persons, collectContact = false, requireContact = false, fetchSlots, fetchDays, holdSlot, disabled = false, readOnly = false, error, }) {
|
|
63
63
|
const needsPerson = !!personSelectionMode && personSelectionMode !== PersonSelectionMode.NONE;
|
|
64
64
|
const personsOptional = personSelectionMode === PersonSelectionMode.OPTIONAL;
|
|
65
65
|
const today = startOfDay(new Date());
|
|
@@ -160,6 +160,8 @@ function ErkBookingPicker({ value, onChange, label, description, durationMinutes
|
|
|
160
160
|
return !!date;
|
|
161
161
|
case 'hour':
|
|
162
162
|
return !!slot;
|
|
163
|
+
case 'confirm':
|
|
164
|
+
return !requireContact || contactName.trim().length > 0;
|
|
163
165
|
default:
|
|
164
166
|
return true;
|
|
165
167
|
}
|
|
@@ -287,6 +289,6 @@ function ErkBookingPicker({ value, onChange, label, description, durationMinutes
|
|
|
287
289
|
? 'Si todo está bien, completa tus datos y confirma.'
|
|
288
290
|
: 'Si todo está bien, confirma tu cita.' })] }, "confirm"))] })] }), _jsxs("div", { className: styles.navbar, children: [_jsx("div", { className: styles.navSummary, children: isFinal || !canAdvance || navParts.length === 0
|
|
289
291
|
? STEP_HINT[currentKey]
|
|
290
|
-
: navParts.reduce((acc, part, i) => i === 0 ? [part] : [...acc, _jsx("span", { children: " \u00B7 " }, `s${i}`), part], []) }), wizStep > 0 && (_jsx(ErkButton, { text: "Atr\u00E1s", variant: "outlined", onClick: () => goToStep(wizStep - 1) })), isFinal ? (_jsx(ErkButton, { text: holding ? 'Reservando…' : 'Confirmar cita', sx: ACCENT_SX, disabled: !slot || holding, onClick: () => void confirm() })) : (_jsx(ErkButton, { text: "Siguiente", disabled: !canAdvance, onClick: () => goToStep(wizStep + 1) }))] })] }) }), error && _jsx("div", { className: styles.err, children: error })] }));
|
|
292
|
+
: navParts.reduce((acc, part, i) => i === 0 ? [part] : [...acc, _jsx("span", { children: " \u00B7 " }, `s${i}`), part], []) }), wizStep > 0 && (_jsx(ErkButton, { text: "Atr\u00E1s", variant: "outlined", onClick: () => goToStep(wizStep - 1) })), isFinal ? (_jsx(ErkButton, { text: holding ? 'Reservando…' : 'Confirmar cita', sx: ACCENT_SX, disabled: !slot || holding || !canAdvance, onClick: () => void confirm() })) : (_jsx(ErkButton, { text: "Siguiente", disabled: !canAdvance, onClick: () => goToStep(wizStep + 1) }))] })] }) }), error && _jsx("div", { className: styles.err, children: error })] }));
|
|
291
293
|
}
|
|
292
294
|
export default ErkBookingPicker;
|
|
@@ -141,6 +141,20 @@ describe('ErkBookingPicker (wizard)', () => {
|
|
|
141
141
|
expect(fetchSlots).toHaveBeenCalledTimes(2);
|
|
142
142
|
expect(onChange).not.toHaveBeenCalled();
|
|
143
143
|
});
|
|
144
|
+
it('does not confirm without a name when the step requires one', async () => {
|
|
145
|
+
const user = userEvent.setup();
|
|
146
|
+
const onChange = vi.fn();
|
|
147
|
+
render(_jsx(MaterialProviders, { formStyle: InternalFormStyle, children: _jsx(ErkBookingPicker, { value: null, onChange: onChange, label: "Agendar cita", durationMinutes: 30, personSelectionMode: PersonSelectionMode.NONE, collectContact: true, requireContact: true, fetchSlots: () => Promise.resolve(SLOTS) }) }));
|
|
148
|
+
await user.click(screen.getByRole('button', { name: 'Agendar cita' }));
|
|
149
|
+
await user.click(clickableToday());
|
|
150
|
+
await user.click(screen.getByRole('button', { name: 'Siguiente' }));
|
|
151
|
+
await user.click(await screen.findByRole('button', { name: '09:00' }));
|
|
152
|
+
await user.click(screen.getByRole('button', { name: 'Siguiente' }));
|
|
153
|
+
const confirm = await screen.findByRole('button', { name: 'Confirmar cita' });
|
|
154
|
+
expect(confirm).toBeDisabled();
|
|
155
|
+
await user.type(screen.getByLabelText('Nombre'), 'Juan');
|
|
156
|
+
expect(confirm).toBeEnabled();
|
|
157
|
+
});
|
|
144
158
|
it('renders the compact summary when a value exists', () => {
|
|
145
159
|
render(_jsx(MaterialProviders, { formStyle: InternalFormStyle, children: _jsx(ErkBookingPicker, { value: {
|
|
146
160
|
type: 'BOOKING_VALUE',
|
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.70",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"watch": "node node_modules/@typescript/native/bin/tsc --noEmit --watch --project tsconfig.app.json",
|
|
7
7
|
"start": "vite",
|