fix(dayplan): restore time-based auto-sort for places and free reorder for untimed
Timed places now auto-sort chronologically when a time is set. Untimed places can be freely dragged between timed items. Transports are inserted by time with per-day position override. Fixes regression from multi-day spanning PR that removed timed/untimed split.
This commit is contained in:
@@ -341,14 +341,13 @@ const DayPlanSidebar = React.memo(function DayPlanSidebar({
|
||||
initTransportPositions(dayId)
|
||||
}
|
||||
|
||||
// Build base list: ALL places (timed and untimed) + notes sorted by order_index/sort_order
|
||||
// Places keep their order_index ordering — only transports are inserted based on time.
|
||||
// All places keep their order_index — untimed can be freely moved, timed auto-sort when time is set
|
||||
const baseItems = [
|
||||
...da.map(a => ({ type: 'place' as const, sortKey: a.order_index, data: a })),
|
||||
...dn.map(n => ({ type: 'note' as const, sortKey: n.sort_order, data: n })),
|
||||
].sort((a, b) => a.sortKey - b.sortKey)
|
||||
|
||||
// Only transports are inserted among base items based on time/position
|
||||
// Transports are inserted among places based on time
|
||||
const timedTransports = transport.map(r => ({
|
||||
type: 'transport' as const,
|
||||
data: r,
|
||||
@@ -360,22 +359,20 @@ const DayPlanSidebar = React.memo(function DayPlanSidebar({
|
||||
return timedTransports.map((item, i) => ({ ...item, sortKey: i }))
|
||||
}
|
||||
|
||||
// Insert transports among base items using persisted position or time-to-position mapping.
|
||||
// Insert transports among places based on per-day position or time
|
||||
const result = [...baseItems]
|
||||
for (let ti = 0; ti < timedTransports.length; ti++) {
|
||||
const timed = timedTransports[ti]
|
||||
const minutes = timed.minutes
|
||||
|
||||
// Use per-day position if available, fallback to global position
|
||||
const dayObj = days.find(d => d.id === dayId)
|
||||
// Use per-day position if explicitly set by user reorder
|
||||
const perDayPos = timed.data.day_positions?.[dayId] ?? timed.data.day_positions?.[String(dayId)]
|
||||
const effectivePos = perDayPos ?? timed.data.day_plan_position
|
||||
if (effectivePos != null) {
|
||||
result.push({ type: timed.type, sortKey: effectivePos, data: timed.data })
|
||||
if (perDayPos != null) {
|
||||
result.push({ type: timed.type, sortKey: perDayPos, data: timed.data })
|
||||
continue
|
||||
}
|
||||
|
||||
// Find insertion position: after the last base item with time <= this transport's time
|
||||
// Find insertion position: after the last place with time <= this transport's time
|
||||
let insertAfterKey = -Infinity
|
||||
for (const item of result) {
|
||||
if (item.type === 'place') {
|
||||
|
||||
@@ -168,6 +168,34 @@ export function getParticipants(assignmentId: string | number) {
|
||||
export function updateTime(id: string | number, placeTime: string | null, endTime: string | null) {
|
||||
db.prepare('UPDATE day_assignments SET assignment_time = ?, assignment_end_time = ? WHERE id = ?')
|
||||
.run(placeTime ?? null, endTime ?? null, id);
|
||||
|
||||
// Auto-sort: reorder timed assignments chronologically within the day
|
||||
if (placeTime) {
|
||||
const assignment = db.prepare('SELECT day_id FROM day_assignments WHERE id = ?').get(id) as { day_id: number } | undefined;
|
||||
if (assignment) {
|
||||
const dayAssignments = db.prepare(`
|
||||
SELECT da.id, COALESCE(da.assignment_time, p.place_time) as effective_time
|
||||
FROM day_assignments da
|
||||
JOIN places p ON da.place_id = p.id
|
||||
WHERE da.day_id = ?
|
||||
ORDER BY da.order_index ASC
|
||||
`).all(assignment.day_id) as { id: number; effective_time: string | null }[];
|
||||
|
||||
// Separate timed and untimed, sort timed by time
|
||||
const timed = dayAssignments.filter(a => a.effective_time).sort((a, b) => {
|
||||
const ta = a.effective_time!.includes(':') ? a.effective_time! : '99:99';
|
||||
const tb = b.effective_time!.includes(':') ? b.effective_time! : '99:99';
|
||||
return ta.localeCompare(tb);
|
||||
});
|
||||
const untimed = dayAssignments.filter(a => !a.effective_time);
|
||||
|
||||
// Interleave: timed in chronological order, untimed keep relative position
|
||||
const reordered = [...timed, ...untimed];
|
||||
const update = db.prepare('UPDATE day_assignments SET order_index = ? WHERE id = ?');
|
||||
reordered.forEach((a, i) => update.run(i, a.id));
|
||||
}
|
||||
}
|
||||
|
||||
return getAssignmentWithPlace(Number(id));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user