Skip to content

Improve Study Planner task visibility and delayed goal rescheduling#16

Merged
geokoko merged 23 commits intomasterfrom
feature/study-planner-task-display
Mar 14, 2026
Merged

Improve Study Planner task visibility and delayed goal rescheduling#16
geokoko merged 23 commits intomasterfrom
feature/study-planner-task-display

Conversation

@geokoko
Copy link
Copy Markdown
Owner

@geokoko geokoko commented Mar 5, 2026

Study Planner — Task Visibility, Delayed Goal Rescheduling & UI Improvements

New features:

Users can now manually reschedule a delayed, unachieved study goal to appear on today's date as a one-shot operation via a new "Re-plan" section (backed by a replanned_for_date column on study_goals). Achieved goals no longer disappear; they show in a collapsible "Completed (N)" section with strikethrough styling and can be un-checked to reactivate. A sort/group toolbar above Today's Tasks lets users sort by Status, Priority, Deadline, or Title, and group by Status or Category.

Bug fixes:

Calendar View Day Details tabs are now wrapped in a ScrollPane so content is scrollable when it overflows (#20). The re-plan ComboBox now renders items correctly by using explicit cell factories instead of a StringConverter-only approach (#19). Unlinked goals are now always visible even on days with no scheduled tasks.

Behaviour changes:

POSTPONED tasks are excluded from the daily planner alongside CANCELLED ones. Expanded task goal panels survive UI rebuilds. IN_PROGRESS and DELAYED tasks with a study goal planned for a date surface in the planner even if their deadline wouldn't otherwise bring them up. Overdue non-recurring tasks are marked DELAYED on startup, and creating a study goal for an OPEN task automatically moves it to IN_PROGRESS.

@geokoko geokoko self-assigned this Mar 5, 2026
Copilot AI review requested due to automatic review settings March 5, 2026 21:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the Study Planner with two main features: improved task visibility on calendar dates (showing tasks with linked goals even when they wouldn't otherwise surface based on deadline logic), and a new "Re-plan" feature that lets users manually reschedule delayed study goals to appear on today's date as a one-shot operation. Additionally, it simplifies the missed recurring occurrence detection to only look back one day (yesterday), marks overdue non-recurring tasks as DELAYED on startup, and auto-transitions tasks from OPEN to IN_PROGRESS when a goal is created for them.

Changes:

  • Added replanned_for_date column to study_goals table to support one-shot manual rescheduling of delayed goals, with corresponding entity, query, and service layer changes.
  • Enhanced getTasksForDate to include IN_PROGRESS/DELAYED tasks that have a goal planned for the queried date (even if their deadline doesn't match), and simplified missed recurring occurrence detection to check only yesterday.
  • Added startup DELAYED-marking for overdue tasks and OPEN→IN_PROGRESS auto-transition when a study goal is created for a task.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/main/resources/schema.sql Adds replanned_for_date migration via ALTER TABLE for existing databases
src/main/java/.../StudyPlannerPanel.java Adds "Re-plan a Delayed Goal" UI section with ComboBox and button
src/main/java/.../StudySyncUI.java Calls markDelayedTasks() on app startup
src/main/java/.../TaskService.java Adds once-per-day guard to markDelayedTasks, goal-based task inclusion in getTasksForDate, and simplifies missed occurrence detection to yesterday-only
src/main/java/.../StudyService.java Adds OPEN→IN_PROGRESS auto-transition, getDelayedGoalsForReplanning(), replanGoalForToday(), and skips replanned goals in delay processing
src/main/java/.../StudyGoal.java Adds replannedForDate field, updated constructors, row mapper, save SQL, and all queries to handle replanned goals; adds findDelayedAndNotReplanned()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

geokoko and others added 11 commits March 6, 2026 01:26
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Each tab in the calendar Day Details dialog returned a plain VBox,
so content was clipped when it exceeded the tab height. Wrap every
tab's content in a ScrollPane with fitToWidth so users can scroll
through long lists of goals, sessions, and tasks.
The re-plan ComboBox used only a StringConverter, which can leave
popup list cells blank in JavaFX. Replace with explicit setCellFactory
and setButtonCell so each delayed goal renders its task title,
description, and delay duration correctly.
Previously achieved goals simply vanished from the UI. Now they
appear in a collapsible 'Completed (N)' section below the active
goals, with strikethrough text and a green-tinted background. Users
can un-check a completed goal to move it back to active. Applies to
both task-linked and unlinked goal panels.
Track expanded task IDs in a Set so that when updateTasksDisplay()
rebuilds the task list (e.g. after checking/unchecking a goal), cards
that were previously expanded remain open with their goals panel
visible.
POSTPONED non-recurring tasks were included alongside DELAYED tasks
in the daily planner. Remove POSTPONED from the isPending filter in
getTasksForDate() so only OPEN, IN_PROGRESS, and DELAYED tasks
appear. CANCELLED was already excluded. Goal-linking (getActiveTasks)
already returns only OPEN/IN_PROGRESS, so no change needed there.
Add a toolbar with Sort (Status, Priority, Deadline, Title) and
Group (None, Status, Category) dropdowns above the task list.
Sorting and grouping are applied on each display refresh, with
group headers rendered as labeled separators when grouping is active.
The early return when tasks were empty prevented the unlinked goals
section (and re-plan section) from rendering. Convert the early
return into an if/else so the 'No tasks' message still shows but
the rest of the display continues to render regardless.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 16 comments.

Comments suppressed due to low confidence (1)

src/main/java/com/studysync/domain/service/TaskService.java:197

  • markDelayedTasks() filters overdue tasks but doesn’t exclude recurring tasks. Since applyBusinessRules() intentionally won’t mark recurring tasks as DELAYED, recurring tasks can still be included, unnecessarily saved, and counted as “updated”. Add a !task.isRecurring() filter (or only persist tasks whose status actually changed).
        List<Task> delayedTasks = Task.findAll().stream()
                .filter(task -> task.getStatus() != TaskStatus.COMPLETED &&
                                 task.getStatus() != TaskStatus.CANCELLED &&
                                 task.getDeadline() != null &&
                                 task.getDeadline().isBefore(today) &&

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

geokoko and others added 10 commits March 14, 2026 18:06
Avoid repeated Task.findById calls during ComboBox cell rendering by
preloading task titles once in buildReplanSection and formatting from
cached data.
All four replanned_for_date query clauses (findByDate,
findByDateIncludingDelayed, findByTaskIdForDate, findUnlinkedForDate)
filtered with achieved = FALSE, causing completed replanned goals to
vanish from their replanned date. Remove the achieved constraint so
replanned goals remain visible in the Completed section after being
checked off.
It now correctly excludes POSTPONED tasks, explaining the new approach correctly.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Task.findAll() was already called at the top of the method, so the
per-goal Task.findById lookups in the goal-linking pass were redundant
DB round-trips. Build a Map<String, Task> from the initial findAll
result and use it for O(1) lookups instead.
Inject DateTimeService and replace all 9 occurrences of
LocalDate.now() so that StudyService uses the same date source as
the UI. Prevents mismatches around midnight or in tests where
DateTimeService may provide a different date.
The missed-occurrence block was inside the else branch of the
tasks.isEmpty() check, so it never ran on task-free days. Move it
outside the conditional so carry-forward items render regardless.
Also fix indentation of the else body.
Wrap the check-then-set of lastDelayedTasksProcessedDate in
TaskService.markDelayedTasks() and lastDelayProcessingDate in
StudyService.ensureDelayedGoalsProcessedToday() with synchronized
blocks so concurrent callers cannot both pass the guard.
Remove Optional, Arrays, and StringConverter imports that are no
longer referenced.
The Goals tab refresh path in createGoalsTab called
parentTab.setContent() without scrollWrap, losing scrollability
after adding a goal.
In StudyService.addStudyGoal, check the boolean returned by
Task.updateStatus and log a warning on failure instead of
unconditionally logging success.

Remove unused linkedTask and parentPanel parameters from
buildCompletedGoalsSection and update both call sites.
@geokoko geokoko merged commit 6835297 into master Mar 14, 2026
1 check passed
@geokoko geokoko deleted the feature/study-planner-task-display branch March 14, 2026 16:43
geokoko added a commit that referenced this pull request Mar 14, 2026
)

Study Planner: task visibility, delayed goal rescheduling & UI improvements
Closes #18, #19, #20

Features:
- Add one-shot delayed goal rescheduling to Study Planner (re-plan a delayed goal for today)
- Show completed goals in a collapsible section instead of hiding them
- Preserve task card expand state across goal edits
- Add sort (Status/Priority/Deadline/Title) and group (None/Status/Category) controls to Today's Tasks

Bug fixes:
- Make Day Details dialog tabs scrollable (wrap each tab in ScrollPane)
- Fix re-plan ComboBox rendering blank items (use explicit cell factories)
- Exclude POSTPONED tasks from daily Study Planner view
- Always show unlinked goals and missed occurrences even when no tasks are scheduled
- Include achieved replanned goals on their replanned date
- Wrap Goals tab content in ScrollPane on refresh path
- Use DateTimeService instead of LocalDate.now() in StudyService for date consistency
- Make once-per-day delay-processing guards thread-safe
- Check Task.updateStatus return value and log on failure
- Align study planner task visibility with goal scheduling rules
- Add replanned_for_date to CREATE TABLE and fix guard assignment ordering

Performance:
- Cache task titles for delayed-goal ComboBox rendering (avoid DB calls in cell render)
- Eliminate N+1 Task.findById calls in getTasksForDate (reuse existing findAll result)

Cleanup:
- Remove unused imports (Optional, Arrays, StringConverter)
- Use short names for ArrayList and Set in TaskService
- Remove unnecessary fully-qualified TaskStatus references
- Remove unused parameters from buildCompletedGoalsSection

---
Co-authored-by: geokoko <geokoko@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants