Improve task planner reset settings
All checks were successful
Deploy Sokko G / deploy (push) Successful in 6s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 6s
This commit is contained in:
parent
d54a93e1f4
commit
ee1c8afa9a
7 changed files with 180 additions and 63 deletions
|
|
@ -55,7 +55,7 @@ function applyDueResets(data, now = Date.now()) {
|
|||
const tasks = data.tasks.map((task) => {
|
||||
if (task.type === "unique") return task;
|
||||
const resetAt = task.type === "daily"
|
||||
? getLatestDailyReset(now, data.resetTime)
|
||||
? getLatestDailyReset(now, task.dailyResetTime || data.resetTime)
|
||||
: getLatestWeeklyReset(now, data.resetTime, task.weeklyResetDay ?? data.weeklyResetDay);
|
||||
latestResetAt = Math.max(latestResetAt, resetAt);
|
||||
if (!task.checked || resetAt <= (task.checkedAt || data.lastResetAt)) return task;
|
||||
|
|
@ -845,6 +845,7 @@ function TaskPlannerItem({
|
|||
const nextType = event.target.value;
|
||||
const nextTask = { ...current, type: nextType };
|
||||
if (nextType !== "weekly") delete nextTask.weeklyResetDay;
|
||||
if (nextType !== "daily") delete nextTask.dailyResetTime;
|
||||
return nextTask;
|
||||
})}
|
||||
aria-label={textContent.typeLabel || "Type"}
|
||||
|
|
@ -909,41 +910,22 @@ function TaskPlannerItem({
|
|||
)}
|
||||
{settingsOpen && (
|
||||
<div className="task-planner-task-settings">
|
||||
{task.type === "weekly" && (
|
||||
<label className="task-planner-weekly-override">
|
||||
<span>{textContent.taskWeeklyResetDayLabel || "Jour hebdo"}</span>
|
||||
<select
|
||||
value={task.weeklyResetDay ?? ""}
|
||||
onChange={(event) => onUpdateTask(task.id, (current) => {
|
||||
const nextTask = { ...current };
|
||||
if (event.target.value === "") {
|
||||
delete nextTask.weeklyResetDay;
|
||||
} else {
|
||||
nextTask.weeklyResetDay = Number(event.target.value);
|
||||
}
|
||||
return nextTask;
|
||||
})}
|
||||
>
|
||||
<option value="">{textContent.inheritWeeklyResetDay || "Global"}</option>
|
||||
{WEEK_DAYS.map((day) => <option key={day.value} value={day.value}>{day.label}</option>)}
|
||||
</select>
|
||||
</label>
|
||||
)}
|
||||
<LinksEditor
|
||||
label={textContent.linksLabel || "Parent"}
|
||||
relations={relations}
|
||||
task={task}
|
||||
tasks={tasks}
|
||||
parentMap={parentMap}
|
||||
relationTargets={relationTargets}
|
||||
emptyLabel={textContent.emptyLinks || "Aucun parent"}
|
||||
addLabel={textContent.addLinkLabel || "Définir un parent"}
|
||||
removeLabel={textContent.removeRelationTitle || "Retirer"}
|
||||
prerequisiteLabel={textContent.prerequisiteCheckboxLabel || "Pré requis"}
|
||||
onAddLinkTarget={onAddLinkTarget}
|
||||
onRemoveLinkTarget={onRemoveLinkTarget}
|
||||
onSetPrerequisite={onSetPrerequisite}
|
||||
/>
|
||||
<TaskResetSettings task={task} data={data} textContent={textContent} onUpdateTask={onUpdateTask} />
|
||||
<LinksEditor
|
||||
label={textContent.linksLabel || "Parent"}
|
||||
relations={relations}
|
||||
task={task}
|
||||
tasks={tasks}
|
||||
parentMap={parentMap}
|
||||
relationTargets={relationTargets}
|
||||
emptyLabel={textContent.emptyLinks || "Aucun parent"}
|
||||
addLabel={textContent.addLinkLabel || "Définir un parent"}
|
||||
removeLabel={textContent.removeRelationTitle || "Retirer"}
|
||||
prerequisiteLabel={textContent.prerequisiteCheckboxLabel || "Pré requis"}
|
||||
onAddLinkTarget={onAddLinkTarget}
|
||||
onRemoveLinkTarget={onRemoveLinkTarget}
|
||||
onSetPrerequisite={onSetPrerequisite}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{children && <ul className="task-planner-list task-planner-child-list">{children}</ul>}
|
||||
|
|
@ -951,6 +933,73 @@ function TaskPlannerItem({
|
|||
);
|
||||
}
|
||||
|
||||
function TaskResetSettings({ task, data, textContent, onUpdateTask }) {
|
||||
if (task.type === "daily") {
|
||||
const hasOverride = Boolean(task.dailyResetTime);
|
||||
return (
|
||||
<div className="task-planner-reset-override">
|
||||
<span>{textContent.taskDailyResetTimeLabel || "Heure quotidienne"}</span>
|
||||
<div className="task-planner-reset-control">
|
||||
<input
|
||||
type="time"
|
||||
value={task.dailyResetTime || data.resetTime}
|
||||
onChange={(event) => onUpdateTask(task.id, (current) => {
|
||||
const nextTask = { ...current };
|
||||
if (event.target.value && event.target.value !== data.resetTime) nextTask.dailyResetTime = event.target.value;
|
||||
else delete nextTask.dailyResetTime;
|
||||
return nextTask;
|
||||
})}
|
||||
aria-label={`${textContent.taskDailyResetTimeLabel || "Heure quotidienne"} ${task.title}`}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onUpdateTask(task.id, (current) => {
|
||||
const nextTask = { ...current };
|
||||
delete nextTask.dailyResetTime;
|
||||
return nextTask;
|
||||
})}
|
||||
disabled={!hasOverride}
|
||||
title={textContent.inheritResetTime || "Utiliser l'heure globale"}
|
||||
aria-label={`${textContent.inheritResetTime || "Utiliser l'heure globale"} ${task.title}`}
|
||||
>
|
||||
<Icon name="rubber" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (task.type === "weekly") {
|
||||
return (
|
||||
<label className="task-planner-reset-override">
|
||||
<span>{textContent.taskWeeklyResetDayLabel || "Jour hebdo"}</span>
|
||||
<select
|
||||
value={task.weeklyResetDay ?? ""}
|
||||
onChange={(event) => onUpdateTask(task.id, (current) => {
|
||||
const nextTask = { ...current };
|
||||
if (event.target.value === "") {
|
||||
delete nextTask.weeklyResetDay;
|
||||
} else {
|
||||
nextTask.weeklyResetDay = Number(event.target.value);
|
||||
}
|
||||
return nextTask;
|
||||
})}
|
||||
>
|
||||
<option value="">{textContent.inheritWeeklyResetDay || "Global"}</option>
|
||||
{WEEK_DAYS.map((day) => <option key={day.value} value={day.value}>{day.label}</option>)}
|
||||
</select>
|
||||
</label>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="task-planner-reset-override is-empty">
|
||||
<span>{textContent.taskResetLabel || "Réinitialisation"}</span>
|
||||
<p>{textContent.noTaskResetLabel || "Aucun reset"}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function LinksEditor({ label, relations, task, tasks, parentMap, relationTargets, emptyLabel, addLabel, removeLabel, prerequisiteLabel, onAddLinkTarget, onRemoveLinkTarget, onSetPrerequisite }) {
|
||||
const descendantIds = new Set();
|
||||
function collectDescendants(taskId) {
|
||||
|
|
@ -965,6 +1014,17 @@ function LinksEditor({ label, relations, task, tasks, parentMap, relationTargets
|
|||
return (
|
||||
<div className="task-planner-relations">
|
||||
<span>{label}</span>
|
||||
<select
|
||||
value=""
|
||||
onChange={(event) => {
|
||||
onAddLinkTarget(task.id, event.target.value);
|
||||
event.target.value = "";
|
||||
}}
|
||||
aria-label={addLabel}
|
||||
>
|
||||
<option value="">{addLabel}</option>
|
||||
{availableTargets.map((target) => <option key={target.id} value={target.id}>{target.title}</option>)}
|
||||
</select>
|
||||
<div>
|
||||
{relations.length ? relations.map((relation) => (
|
||||
<div className="task-planner-relation-chip" key={relation.id}>
|
||||
|
|
@ -984,17 +1044,6 @@ function LinksEditor({ label, relations, task, tasks, parentMap, relationTargets
|
|||
</div>
|
||||
)) : <em>{emptyLabel}</em>}
|
||||
</div>
|
||||
<select
|
||||
value=""
|
||||
onChange={(event) => {
|
||||
onAddLinkTarget(task.id, event.target.value);
|
||||
event.target.value = "";
|
||||
}}
|
||||
aria-label={addLabel}
|
||||
>
|
||||
<option value="">{addLabel}</option>
|
||||
{availableTargets.map((target) => <option key={target.id} value={target.id}>{target.title}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue