Add inline timer form validation
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
This commit is contained in:
parent
3e16ea278d
commit
d54a93e1f4
6 changed files with 80 additions and 4 deletions
|
|
@ -94,6 +94,27 @@ function hasTimePartValue(parts) {
|
|||
return Boolean(String(parts?.hours || "").trim() || String(parts?.minutes || "").trim() || String(parts?.seconds || "").trim());
|
||||
}
|
||||
|
||||
function getCountdownValidationError(type, draft, textContent) {
|
||||
const requiredError = textContent.requiredError || "Valeur requise.";
|
||||
const invalidError = textContent.invalidError || "Valeur invalide.";
|
||||
if (type === "duration" && timePartsToDurationMs(draft.duration) <= 0) {
|
||||
return requiredError;
|
||||
}
|
||||
if (type === "daily_time" && !timePartsToString(draft.time)) {
|
||||
return invalidError;
|
||||
}
|
||||
if (type === "time_pattern") {
|
||||
if (!hasTimePartValue(draft.pattern)) return requiredError;
|
||||
if (!timePartsToString(draft.pattern, { allowWildcard: true })) return invalidError;
|
||||
}
|
||||
if (type === "interval") {
|
||||
const startTimeHasValue = hasTimePartValue(draft.intervalStartTime);
|
||||
if (timePartsToDurationMs(draft.interval) <= 0) return requiredError;
|
||||
if (startTimeHasValue && !timePartsToString(draft.intervalStartTime)) return invalidError;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
export function TimerModule({ toolboxId, moduleId, context }) {
|
||||
const data = context.normalizeTimerData(context.getModuleData(toolboxId, moduleId, { activeTab: "stopwatch" }));
|
||||
const textContent = context.moduleText?.timer || {};
|
||||
|
|
@ -194,6 +215,8 @@ export function TimerModule({ toolboxId, moduleId, context }) {
|
|||
function createCountdown(event) {
|
||||
countdownDraft.handleSubmit(event, (draft, { updateValues }) => {
|
||||
const type = COUNTDOWN_TYPES.includes(draft.type) ? draft.type : "duration";
|
||||
const validationError = getCountdownValidationError(type, draft, textContent);
|
||||
if (validationError) return validationError;
|
||||
const label = draft.label.trim() || textContent.defaultCountdownLabel || "Timer";
|
||||
const now = getNowMs();
|
||||
let countdown = null;
|
||||
|
|
@ -335,6 +358,7 @@ export function TimerModule({ toolboxId, moduleId, context }) {
|
|||
<CountdownControls
|
||||
textContent={textContent}
|
||||
form={countdownDraft.values}
|
||||
error={countdownDraft.error}
|
||||
onChange={countdownDraft.updateValues}
|
||||
onSubmit={createCountdown}
|
||||
/>
|
||||
|
|
@ -441,9 +465,9 @@ function StopwatchControls({ textContent, elapsedMs, running, onStart, onPause,
|
|||
);
|
||||
}
|
||||
|
||||
function CountdownControls({ textContent, form, onChange, onSubmit }) {
|
||||
function CountdownControls({ textContent, form, error, onChange, onSubmit }) {
|
||||
return (
|
||||
<form className="timer-control-panel timer-countdown-form" role="tabpanel" onSubmit={onSubmit}>
|
||||
<form className="timer-control-panel timer-countdown-form" role="tabpanel" onSubmit={onSubmit} aria-describedby={error ? "timer-countdown-error" : undefined}>
|
||||
<label>
|
||||
<span>{textContent.countdownLabel || "Libellé"}</span>
|
||||
<input value={form.label} onChange={(event) => onChange({ label: event.target.value })} placeholder={textContent.countdownLabelPlaceholder || "Boss, event, craft..."} />
|
||||
|
|
@ -490,6 +514,12 @@ function CountdownControls({ textContent, form, onChange, onSubmit }) {
|
|||
</label>
|
||||
</div>
|
||||
)}
|
||||
{error && (
|
||||
<p id="timer-countdown-error" className="timer-form-error" role="alert">
|
||||
<Icon name="close" />
|
||||
<span>{error}</span>
|
||||
</p>
|
||||
)}
|
||||
<button className="primary" type="submit">{textContent.addCountdownButton || "Ajouter"}</button>
|
||||
</form>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue