add categories to task planner
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
e306bfc5d6
commit
3cd350c7b8
10 changed files with 459 additions and 120 deletions
|
|
@ -154,8 +154,8 @@ export function normalizeChecklistData(data) {
|
|||
const sections = Array.isArray(data?.sections)
|
||||
? data.sections.map((section) => normalizeChecklistSection(section)).filter((section) => section.items.length || section.title)
|
||||
: [];
|
||||
const legacyItems = (data?.items || []).map(normalizeChecklistItem).filter((item) => item.label);
|
||||
if (!sections.length && legacyItems.length) return { hideCompletedSections, hideCompletedSectionsFully, sections: [{ id: uid("section"), title: "", items: legacyItems }], items: legacyItems };
|
||||
const simpleItems = (data?.items || []).map(normalizeChecklistItem).filter((item) => item.label);
|
||||
if (!sections.length && simpleItems.length) return { hideCompletedSections, hideCompletedSectionsFully, sections: [{ id: uid("section"), title: "", items: simpleItems }], items: simpleItems };
|
||||
const items = sections.flatMap((section) => section.items);
|
||||
return { hideCompletedSections, hideCompletedSectionsFully, sections, items };
|
||||
}
|
||||
|
|
@ -267,7 +267,6 @@ export function normalizeCalculatorData(data) {
|
|||
|
||||
export function normalizeTimerData(data) {
|
||||
const stopwatch = data?.stopwatch || {};
|
||||
const legacyAlertMode = TIMER_ALERT_MODES.has(data?.alertMode) ? data.alertMode : "off";
|
||||
const laps = (Array.isArray(stopwatch.laps) ? stopwatch.laps : [])
|
||||
.map((lap) => ({
|
||||
id: lap?.id || uid("timer"),
|
||||
|
|
@ -282,7 +281,7 @@ export function normalizeTimerData(data) {
|
|||
id: countdown?.id || uid("timer"),
|
||||
label: String(countdown?.label || "Timer").trim() || "Timer",
|
||||
type,
|
||||
alertMode: TIMER_ALERT_MODES.has(countdown?.alertMode) ? countdown.alertMode : legacyAlertMode
|
||||
alertMode: TIMER_ALERT_MODES.has(countdown?.alertMode) ? countdown.alertMode : "off"
|
||||
};
|
||||
if (type === "duration") {
|
||||
const durationMs = Math.max(0, Number(countdown?.durationMs) || 0);
|
||||
|
|
@ -299,8 +298,7 @@ export function normalizeTimerData(data) {
|
|||
return isTimeString(pattern, true) ? { ...normalized, pattern } : null;
|
||||
}
|
||||
if (type === "interval") {
|
||||
const legacyIntervalMs = (Number.parseInt(countdown?.intervalMinutes, 10) || 0) * 60000;
|
||||
const intervalMs = Math.max(0, Number(countdown?.intervalMs) || legacyIntervalMs);
|
||||
const intervalMs = Math.max(0, Number(countdown?.intervalMs) || 0);
|
||||
const anchorAt = Math.max(0, Number(countdown?.anchorAt) || 0);
|
||||
return intervalMs > 0 ? { ...normalized, intervalMs, anchorAt } : null;
|
||||
}
|
||||
|
|
@ -324,6 +322,7 @@ export function normalizeTimerData(data) {
|
|||
function normalizeTaskPlannerTask(task) {
|
||||
const title = String(task?.title || "").trim() || "Tâche";
|
||||
const type = TASK_TYPES.has(task?.type) ? task.type : "unique";
|
||||
const category = String(task?.category || "").trim();
|
||||
const normalized = {
|
||||
id: task?.id || uid("task"),
|
||||
title,
|
||||
|
|
@ -332,23 +331,29 @@ function normalizeTaskPlannerTask(task) {
|
|||
checked: task?.checked === true,
|
||||
checkedAt: normalizeTimestamp(task?.checkedAt)
|
||||
};
|
||||
if (category) normalized.category = category;
|
||||
if (type === "weekly" && task?.weeklyResetDay !== undefined) normalized.weeklyResetDay = normalizeWeekDay(task.weeklyResetDay);
|
||||
if (!normalized.checked) normalized.checkedAt = 0;
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function normalizeTaskPlannerCategoryOrder(value, tasks) {
|
||||
const categories = new Set(tasks.map((task) => task.category).filter(Boolean));
|
||||
const ordered = [];
|
||||
(Array.isArray(value) ? value : []).forEach((category) => {
|
||||
const normalized = String(category || "").trim();
|
||||
if (normalized && categories.has(normalized) && !ordered.includes(normalized)) ordered.push(normalized);
|
||||
});
|
||||
tasks.forEach((task) => {
|
||||
if (task.category && !ordered.includes(task.category)) ordered.push(task.category);
|
||||
});
|
||||
return ordered;
|
||||
}
|
||||
|
||||
function normalizeTaskPlannerRelations(data, taskIds) {
|
||||
const seen = new Set();
|
||||
const seenChildren = new Set();
|
||||
const legacyDependencies = new Set((Array.isArray(data?.dependencies) ? data.dependencies : [])
|
||||
.map((relation) => `${relation?.fromTaskId || ""}:${relation?.toTaskId || ""}`));
|
||||
const sourceRelations = Array.isArray(data?.relations)
|
||||
? data.relations
|
||||
: [
|
||||
...(Array.isArray(data?.links) ? data.links : []),
|
||||
...(Array.isArray(data?.dependencies) ? data.dependencies : []).map((relation) => ({ ...relation, dependency: true }))
|
||||
];
|
||||
return sourceRelations
|
||||
return (Array.isArray(data?.relations) ? data.relations : [])
|
||||
.map((relation) => {
|
||||
const fromTaskId = String(relation?.fromTaskId || "");
|
||||
const toTaskId = String(relation?.toTaskId || "");
|
||||
|
|
@ -361,22 +366,32 @@ function normalizeTaskPlannerRelations(data, taskIds) {
|
|||
id: relation?.id || uid("relation"),
|
||||
fromTaskId,
|
||||
toTaskId,
|
||||
dependency: relation?.dependency === true || legacyDependencies.has(key)
|
||||
prerequisite: relation?.prerequisite === true
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
export function normalizeTaskPlannerData(data) {
|
||||
const tasks = (Array.isArray(data?.tasks) ? data.tasks : []).map(normalizeTaskPlannerTask).filter(Boolean);
|
||||
const rawTasks = (Array.isArray(data?.tasks) ? data.tasks : []).map(normalizeTaskPlannerTask).filter(Boolean);
|
||||
const rawTaskIds = new Set(rawTasks.map((task) => task.id));
|
||||
const relations = normalizeTaskPlannerRelations(data, rawTaskIds);
|
||||
const childTaskIds = new Set(relations.map((relation) => relation.fromTaskId));
|
||||
const tasks = rawTasks.map((task) => {
|
||||
if (!childTaskIds.has(task.id) || !task.category) return task;
|
||||
const normalized = { ...task };
|
||||
delete normalized.category;
|
||||
return normalized;
|
||||
});
|
||||
const taskIds = new Set(tasks.map((task) => task.id));
|
||||
return {
|
||||
sortMode: TASK_SORT_MODES.has(data?.sortMode) ? data.sortMode : "manual",
|
||||
weeklyResetDay: normalizeWeekDay(data?.weeklyResetDay),
|
||||
resetTime: isClockTimeString(data?.resetTime) ? data.resetTime : DEFAULT_TASK_PLANNER_RESET_TIME,
|
||||
lastResetAt: normalizeTimestamp(data?.lastResetAt),
|
||||
categoryOrder: normalizeTaskPlannerCategoryOrder(data?.categoryOrder, tasks),
|
||||
tasks,
|
||||
relations: normalizeTaskPlannerRelations(data, taskIds)
|
||||
relations: relations.filter((relation) => taskIds.has(relation.fromTaskId) && taskIds.has(relation.toTaskId))
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -387,7 +402,7 @@ function clampPercent(value) {
|
|||
}
|
||||
|
||||
export function normalizeImageAnnotationData(data) {
|
||||
const image = String(data?.image || data?.dataUrl || "");
|
||||
const image = String(data?.image || "");
|
||||
const markers = (data?.markers || [])
|
||||
.map((marker) => ({
|
||||
id: marker?.id || uid("marker"),
|
||||
|
|
@ -528,12 +543,14 @@ export function compactModuleDataForStorage(type, value) {
|
|||
type: task.type
|
||||
};
|
||||
if (task.description) compactTask.description = task.description;
|
||||
if (task.category) compactTask.category = task.category;
|
||||
if (task.checked) compactTask.checked = true;
|
||||
if (task.checked && task.checkedAt) compactTask.checkedAt = task.checkedAt;
|
||||
if (task.type === "weekly" && task.weeklyResetDay !== undefined) compactTask.weeklyResetDay = task.weeklyResetDay;
|
||||
return compactTask;
|
||||
});
|
||||
}
|
||||
if (normalized.categoryOrder.length) compact.categoryOrder = normalized.categoryOrder;
|
||||
if (normalized.relations.length) {
|
||||
compact.relations = normalized.relations.map((relation) => {
|
||||
const compactRelation = {
|
||||
|
|
@ -541,7 +558,7 @@ export function compactModuleDataForStorage(type, value) {
|
|||
fromTaskId: relation.fromTaskId,
|
||||
toTaskId: relation.toTaskId
|
||||
};
|
||||
if (relation.dependency) compactRelation.dependency = true;
|
||||
if (relation.prerequisite) compactRelation.prerequisite = true;
|
||||
return compactRelation;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue