Skip to content

feat: performance optimizations#60

Merged
kaesetoast merged 5 commits into
mainfrom
feat_performance_optim
Jun 11, 2026
Merged

feat: performance optimizations#60
kaesetoast merged 5 commits into
mainfrom
feat_performance_optim

Conversation

@kaesetoast

@kaesetoast kaesetoast commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

Release Notes

New Features

  • Added keyboard shortcut (M key) to quickly assign/unassign tasks to yourself
  • Lazy-loaded rich text editor and task development panel for faster initial page loads

Performance

  • Implemented virtual scrolling for task lists and boards—significantly faster performance when working with large numbers of tasks

Improvements

  • Optimized data caching to reduce unnecessary network requests
  • Enhanced real-time data synchronization for more reliable updates
  • Task board data now includes full label information

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kaesetoast, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 16 minutes and 28 seconds. Learn how PR review limits work.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8fd6422e-4358-4f04-958a-e9917fce7098

📥 Commits

Reviewing files that changed from the base of the PR and between fd44ace and 846512d.

📒 Files selected for processing (14)
  • src/components/views/BoardView.tsx
  • src/components/views/ListView.tsx
  • src/components/views/TaskViewsContainer.tsx
  • src/components/views/VirtualizedTaskCards.tsx
  • src/db/mutations/sync.ts
  • src/db/mutations/tasks.ts
  • src/hooks/live-sync-provider.tsx
  • src/lib/query-cache-defaults.ts
  • src/lib/query-cache-fresh.ts
  • src/lib/sync-envelope.test.ts
  • src/lib/sync-envelope.ts
  • src/router.tsx
  • src/routes/_signed-in.tsx
  • src/routes/_signed-in/dashboard.tsx
📝 Walkthrough

Walkthrough

The PR introduces task virtualization for performant large-list rendering, refactors task cards to accept assignment context via props, establishes a centralized event-driven cache invalidation system via LiveSyncProvider, and eliminates router-based cache invalidation across all mutation and query hooks in favor of React Query-only management.

Changes

Task Virtualization and View Enhancement

Layer / File(s) Summary
Build setup and dependencies
package.json, vite.config.ts
Adds @tanstack/react-virtual, rollup-plugin-visualizer, and build:analyze npm script for bundle analysis.
Task view props contract
src/components/views/task-view-types.ts
Extends TaskViewProps with users array and assigningTaskId to pass assignment context to all task views.
Task card memoization and prop-driven rendering
src/components/TaskCard.tsx
TaskCard, TaskCardShell, and TaskCardComponent are converted to memo-ized components; accept users/assigningTaskId props instead of relying on internal state/queries; avatar lookup switched to use passed users array.
Virtualized list components
src/components/views/VirtualizedTaskCards.tsx, src/components/views/VirtualizedTaskListRows.tsx
Two new generic virtualized list components using @tanstack/react-virtual; render only visible items with absolute positioning, dynamic measurement, and configurable overscan.
Task view container assignment handling
src/components/views/TaskViewsContainer.tsx
TaskViewsContainer tracks assigningTaskId state, fetches users, wires keyboard 'm' shortcut for task assignment/unassignment, and passes users/assigningTaskId into active TaskViewComponent.
BoardView and ListView virtualization integration
src/components/views/BoardView.tsx, src/components/views/ListView.tsx
BoardView and ListView replace direct iteration with VirtualizedTaskCards and VirtualizedTaskListRows; stabilize git summaries query key; pass users/assigningTaskId to rendered cards.
Lazy-loaded components and Suspense boundaries
src/components/OpenTask.tsx
RichtextEditor and TaskDevelopmentSection are lazy-loaded and wrapped in Suspense boundaries with TabLoadingFallback spinner.

Cache Management and Sync System Migration

Layer / File(s) Summary
Cache freshness utility and router defaults
src/lib/query-cache-fresh.ts, src/router.tsx
Adds isQueryCacheFresh helper to check query staleness; router configuration now includes defaultStaleTime, defaultGcTime, and background stale reload mode.
Bundle types extended with labels
src/db/queries/bundles.ts
ProjectBoardBundle, SprintBoardBundle, and AllTasksBoardBundle now include labels; fetch handlers query and include label data in responses.
Cache hydration helpers updated for labels
src/db/queries/hydrate-query-cache.ts
hydrateProjectBoardCache, hydrateAllTasksBoardCache, and hydrateSprintBoardCache now hydrate labels query cache alongside existing data.
Route loaders with conditional cache fetching
src/routes/_signed-in.tsx, src/routes/_signed-in/dashboard.tsx, src/routes/_signed-in/projects.$projectId.tasks.tsx, src/routes/_signed-in/sprints.$sprintId.tasks.tsx, src/routes/_signed-in/tasks.tsx
Route loaders check cache freshness before fetching bundles; only fetch/hydrate when data is stale, reducing unnecessary network calls.
Query hooks simplified: Remove useEventSource subscriptions
src/db/queries/attachments.ts, src/db/queries/comments.ts, src/db/queries/dashboard.ts, src/db/queries/labels.ts, src/db/queries/notifications.ts, src/db/queries/projects.ts, src/db/queries/sprints.ts, src/db/queries/statuses.ts, src/db/queries/tasks.ts
All query hooks now return useSuspenseQuery results directly; per-hook event-source topic subscriptions and refetch callbacks removed; server handler console logging removed.
Centralized LiveSyncProvider for cache invalidation
src/hooks/live-sync-provider.tsx, src/hooks/use-git-task-live-sync.ts
New LiveSyncProvider opens single SSE connection, parses topic/entityId from event payloads, and invalidates React Query caches; use-git-task-live-sync stubbed as live sync is now centrally handled.
Sync topic publishing refactoring
src/db/mutations/sync.ts
sync function refactored to route through publishSyncTopic helper; publishes both original topic and derived "coarse" topics with structured { topic, payload } request body.
Mutation hooks remove router invalidation
src/db/mutations/attachments.ts, src/db/mutations/comments.ts, src/db/mutations/labels.ts, src/db/mutations/projects.ts, src/db/mutations/sprints.ts, src/db/mutations/statuses.ts, src/db/mutations/sub-tasks.ts, src/db/mutations/tasks.ts
All mutation hooks remove useRouter imports and router.invalidate() calls; useCallback dependency arrays exclude router; cache updates rely on React Query invalidation or optimistic patching.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • pnodev/project-y#9: Introduces the board/sidebar React Query cache hydration helpers that this PR extends to include labels.
  • pnodev/project-y#37: Prior git live-sync implementation in use-git-task-live-sync that this PR consolidates into LiveSyncProvider.
  • pnodev/project-y#21: Adds useEventSource-driven refetching that this PR replaces with centralized LiveSyncProvider cache invalidation.

Poem

🐰 Hop along now, let's virtualize the view,
No more useEventSource, the LiveSync is new!
Props flow like carrots through cards that are memoized,
Cache stays fresh, routes optimized—
The assignment "m" key hops true! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: performance optimizations' accurately describes the main focus of the changeset, which includes virtualization implementations, lazy loading, query caching improvements, and removal of redundant router invalidations.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat_performance_optim

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (4)
src/components/views/BoardView.tsx (1)

175-186: 💤 Low value

Missing assigningTaskId prop on drag overlay.

The DragOverlay receives users but not assigningTaskId. If a user starts dragging a task while an assignment mutation is in flight for that same task, the drag preview won't show the loading spinner. This is a minor UX inconsistency.

Suggested fix
         <TaskCardComponent
           task={activeTask}
           users={users}
+          assigningTaskId={assigningTaskId}
           showSprint={showSprint}
           showProject={showProject}
           taskLinkTo={taskLinkTo}
           gitSummary={gitSummaries?.[activeTask.id]}
           closingStatusId={closingStatusId}
         />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/views/BoardView.tsx` around lines 175 - 186, The DragOverlay
rendering of TaskCardComponent is missing the assigningTaskId prop, so when a
task is being dragged while an assignment mutation is in flight the preview
won't show the loading spinner; update the DragOverlay block where
TaskCardComponent is rendered (the conditional using activeTask) to pass
assigningTaskId={assigningTaskId} along with users, showSprint, showProject,
taskLinkTo, gitSummary (gitSummaries?.[activeTask.id]), and closingStatusId so
the preview can reflect the in-flight assignment state.
src/router.tsx (1)

23-25: ⚡ Quick win

Unify cache timing constants across router and freshness helpers.

These values are duplicated across cache-related modules; if one side changes later, loaders can overfetch or skip hydration inconsistently.

♻️ Suggested refactor
diff --git a/src/lib/query-cache-fresh.ts b/src/lib/query-cache-fresh.ts
@@
-const DEFAULT_STALE_TIME_MS = 60_000;
+export const DEFAULT_STALE_TIME_MS = 60_000;
+export const DEFAULT_GC_TIME_MS = 5 * 60_000;

diff --git a/src/router.tsx b/src/router.tsx
@@
+import { DEFAULT_GC_TIME_MS, DEFAULT_STALE_TIME_MS } from "./lib/query-cache-fresh";
@@
-        staleTime: 60_000,
-        gcTime: 5 * 60_000,
+        staleTime: DEFAULT_STALE_TIME_MS,
+        gcTime: DEFAULT_GC_TIME_MS,
@@
-    defaultStaleTime: 60_000,
-    defaultGcTime: 5 * 60_000,
+    defaultStaleTime: DEFAULT_STALE_TIME_MS,
+    defaultGcTime: DEFAULT_GC_TIME_MS,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/router.tsx` around lines 23 - 25, The cache timing values
(defaultStaleTime, defaultGcTime, defaultStaleReloadMode) are duplicated and
must be centralized: extract these constants into a single shared export (e.g.,
CACHE_DEFAULTS or named exports defaultStaleTime, defaultGcTime,
defaultStaleReloadMode) in a common module and replace the literal values in the
router (where defaultStaleTime/defaultGcTime/defaultStaleReloadMode are used)
and in the freshness helpers to import and consume those shared constants so
both modules always use the same source of truth; ensure the new module exports
stable names and update imports accordingly.
src/hooks/live-sync-provider.tsx (2)

175-184: ⚡ Quick win

Use URLSearchParams for safer query string construction.

Manual query string building doesn't handle URL encoding and is more error-prone than the standard URLSearchParams API.

🔧 Refactor to URLSearchParams
     const topics = [
       ...COARSE_TOPICS,
       ...(ownerTopic ? [ownerTopic] : []),
       ...(notificationsTopic ? [notificationsTopic] : []),
     ];
-    let topicsString = "?";
-    for (const topic of topics) {
-      if (topicsString !== "?") topicsString += "&";
-      topicsString += `topic[]=${topic}`;
-    }
+    const params = new URLSearchParams();
+    for (const topic of topics) {
+      params.append("topic[]", topic);
+    }

     const sse = new EventSource(
-      `${SYNC_STREAM_BASE}/stream/${SYNC_APP_ID}${topicsString}`
+      `${SYNC_STREAM_BASE}/stream/${SYNC_APP_ID}?${params.toString()}`
     );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks/live-sync-provider.tsx` around lines 175 - 184, The manual
construction of topicsString from topics (built from COARSE_TOPICS, ownerTopic,
notificationsTopic) should be replaced with URLSearchParams to ensure proper URL
encoding and simpler code; create a new URLSearchParams instance, append each
topic with key "topic[]" (iterating the topics array used in the existing block)
and then use params.toString() to get the encoded query string instead of the
current topicsString concatenation logic.

69-77: ⚡ Quick win

Remove unreachable notification and owner topic checks.

The onUpdate handler (lines 154-162) already checks for notificationsTopic and ownerTopic and returns early before calling handleCoarseSyncEvent (line 164). These duplicate checks in handleCoarseSyncEvent are dead code—they can never be true because those topics are filtered out upstream.

♻️ Simplify by removing unreachable checks
 function handleCoarseSyncEvent(
   queryClient: QueryClient,
   topic: string,
   data: unknown,
   entityId: string | undefined,
   ownerTopic: string | null,
   notificationsTopic: string | null
 ) {
-  if (notificationsTopic && topic === notificationsTopic) {
-    void queryClient.invalidateQueries({ queryKey: ["in-app-notifications"] });
-    return;
-  }
-
-  if (ownerTopic && topic === ownerTopic) {
-    void queryClient.invalidateQueries({ queryKey: ["dashboard-stats"] });
-    return;
-  }
-
   switch (topic) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks/live-sync-provider.tsx` around lines 69 - 77, The duplicate checks
for notificationsTopic and ownerTopic inside handleCoarseSyncEvent are
unreachable because onUpdate already filters those topics and returns early;
remove the conditional blocks that compare topic === notificationsTopic and
topic === ownerTopic and the associated void queryClient.invalidateQueries calls
(the ones invalidating ["in-app-notifications"] and ["dashboard-stats"]),
leaving handleCoarseSyncEvent to only handle remaining topic cases; keep the
existing logic in onUpdate and ensure no other callers rely on those removed
branches.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/views/ListView.tsx`:
- Around line 266-282: The virtualization branch currently triggers whenever
sortedTasks.length > 25, bypassing manual sort; update the condition so
manualSortEnabled takes precedence—i.e., only render VirtualizedTaskListRows
when !manualSortEnabled && sortedTasks.length > 25, otherwise follow the
manual-sort branch that renders TaskListRow(s) using orderedTaskIds, location,
columnFlags, updateTask, closingStatusId and manualSortEnabled; locate the check
around VirtualizedTaskListRows and adjust the conditional accordingly.

In `@src/components/views/TaskViewsContainer.tsx`:
- Around line 90-113: The global "m" handler can trigger while the user is
typing or re-fire during an in-flight toggle; update handleKeyPress to
early-return if event.repeat is true or if the event target is an input/textarea
or an element with contentEditable (e.g., check event.target for instanceof
HTMLInputElement/HTMLTextAreaElement or
element.closest('[contenteditable="true"]')), and also guard against concurrent
mutations by returning when assigningTaskId is non-null; ensure you reference
and use the existing symbols handleKeyPress, assignTask, unassignTask,
setAssigningTaskId, assigningTaskId, hoveredTaskId, currentUserId and add
assigningTaskId and setAssigningTaskId to the useEffect dependency array so the
hook reacts correctly.

In `@src/components/views/VirtualizedTaskCards.tsx`:
- Around line 18-20: The effect that sets scrollElementRef.current is running
too late (it's keyed to items.length) so the virtualizer may see a null scroll
element on initial mount; replace this useEffect with a synchronous capture by
using useLayoutEffect with no items.length dependency (i.e., run once on mount)
or convert listRef to a callback ref that sets scrollElementRef.current from
listRef.current?.parentElement immediately; update the code references: replace
the useEffect that touches scrollElementRef and listRef with a useLayoutEffect
(or implement a callback ref assigned where listRef is used) so the
virtualizer's getScrollElement sees a non-null value on initial render.

In `@src/db/mutations/sync.ts`:
- Around line 67-76: The publish behavior is inconsistent: coarse topics
(COARSE_TOPIC_PREFIXES branch) send an envelope { topic, entityId, payload }
while fine-grained topics publish payload directly, causing consumers to have to
unwrap differently; pick one consistent contract and implement it across both
paths. Update the publishing call sites (the publishSyncTopic invocations for
fine-grained topics and in the COARSE_TOPIC_PREFIXES loop) to always use the
same envelope shape (e.g., { topic, entityId?: string, payload }) and adjust
callers/consumers accordingly, referencing publishSyncTopic,
COARSE_TOPIC_PREFIXES, coarseTopic, entityId and the code path that handles
fine-grained topic publishing so all subscribers receive the same structure.
Ensure tests or docs are updated to reflect the unified envelope contract.

In `@src/db/mutations/tasks.ts`:
- Around line 1346-1356: The detail cache update inside the
queryClient.setQueryData callback for ["tasks", input.taskId] only patches
statusId and updatedAt, causing sortOrder to become stale; update this patch to
also set the new sortOrder (compute it using input.targetIndex and the target
bucket ordering logic the same way patchMovedTask computes the reordered list)
or, if computing client-side is undesirable, call
queryClient.invalidateQueries(["tasks", input.taskId]) after the mutation
succeeds so the detail cache is refetched; refer to patchMovedTask,
input.targetIndex, input.taskId, and TaskWithRelations to locate and mirror the
server-side sortOrder calculation.
- Line 653: The map that resolves labelIds into label objects uses
labels.find(... )! which can yield undefined; change the mapping inside the
functions that build the labels array (the code using labels.find((label) =>
label.id === id)!) to produce only existing labels by replacing the non-null
assertion with a safe lookup and then filtering out missing values (e.g., map to
possibly-undefined and then .filter(Boolean) or use a type guard) so only actual
Label objects are pushed; apply this same fix to the other occurrence that maps
labelIds to labels in this file (the earlier mapping around the same
labels/labelIds logic).
- Around line 645-661: The list cache patching must be moved to run
optimistically before the server mutation so detail and list views stay
consistent; call getTaskListQueryKeys(queryClient, task), compute patchList
(using task.id, labelIds, labels) and apply it with queryClient.setQueryData for
each queryKey prior to sending the mutation (the same place where the detail
cache is updated), and ensure any rollback logic still restores original list
data on mutation error.

In `@src/hooks/live-sync-provider.tsx`:
- Around line 186-196: The EventSource connection (created as sse via new
EventSource(`${SYNC_STREAM_BASE}/stream/${SYNC_APP_ID}${topicsString}`)) lacks
error and open handlers; add sse.addEventListener("error", ...) to surface
connection failures (log the event/error and call a provided onError callback if
available) and sse.addEventListener("open", ...) to log/handle successful
reconnects (or call an onOpen callback), ensure the existing
onUpdate(event.data) remains, and keep the return cleanup sse.close() — this
surfaces network/server errors and connection state for live-sync debugging.

In `@src/routes/_signed-in.tsx`:
- Around line 29-40: The sidebar bundle gating currently sets needsSidebar using
only projects/sprints freshness; update the logic so needsSidebar also becomes
true when user preferences are stale. Specifically, modify the computation of
needsSidebar (which references isQueryCacheFresh,
projectsQueryOptions().queryKey and sprintsQueryOptions().queryKey) to include
userPreferencesQueryOptions().queryKey (or reuse needsPreferences) so that
fetchSidebarBundle() runs whenever preferences are stale; keep
fetchUserPreferences() logic as-is to still fetch preferences in parallel.

---

Nitpick comments:
In `@src/components/views/BoardView.tsx`:
- Around line 175-186: The DragOverlay rendering of TaskCardComponent is missing
the assigningTaskId prop, so when a task is being dragged while an assignment
mutation is in flight the preview won't show the loading spinner; update the
DragOverlay block where TaskCardComponent is rendered (the conditional using
activeTask) to pass assigningTaskId={assigningTaskId} along with users,
showSprint, showProject, taskLinkTo, gitSummary (gitSummaries?.[activeTask.id]),
and closingStatusId so the preview can reflect the in-flight assignment state.

In `@src/hooks/live-sync-provider.tsx`:
- Around line 175-184: The manual construction of topicsString from topics
(built from COARSE_TOPICS, ownerTopic, notificationsTopic) should be replaced
with URLSearchParams to ensure proper URL encoding and simpler code; create a
new URLSearchParams instance, append each topic with key "topic[]" (iterating
the topics array used in the existing block) and then use params.toString() to
get the encoded query string instead of the current topicsString concatenation
logic.
- Around line 69-77: The duplicate checks for notificationsTopic and ownerTopic
inside handleCoarseSyncEvent are unreachable because onUpdate already filters
those topics and returns early; remove the conditional blocks that compare topic
=== notificationsTopic and topic === ownerTopic and the associated void
queryClient.invalidateQueries calls (the ones invalidating
["in-app-notifications"] and ["dashboard-stats"]), leaving handleCoarseSyncEvent
to only handle remaining topic cases; keep the existing logic in onUpdate and
ensure no other callers rely on those removed branches.

In `@src/router.tsx`:
- Around line 23-25: The cache timing values (defaultStaleTime, defaultGcTime,
defaultStaleReloadMode) are duplicated and must be centralized: extract these
constants into a single shared export (e.g., CACHE_DEFAULTS or named exports
defaultStaleTime, defaultGcTime, defaultStaleReloadMode) in a common module and
replace the literal values in the router (where
defaultStaleTime/defaultGcTime/defaultStaleReloadMode are used) and in the
freshness helpers to import and consume those shared constants so both modules
always use the same source of truth; ensure the new module exports stable names
and update imports accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 152846e4-3885-4c2b-99ff-9893975c259d

📥 Commits

Reviewing files that changed from the base of the PR and between d878b44 and fd44ace.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (40)
  • package.json
  • src/components/OpenTask.tsx
  • src/components/TaskCard.tsx
  • src/components/views/BoardView.tsx
  • src/components/views/ListView.tsx
  • src/components/views/TaskViewsContainer.tsx
  • src/components/views/VirtualizedTaskCards.tsx
  • src/components/views/VirtualizedTaskListRows.tsx
  • src/components/views/task-view-types.ts
  • src/db/mutations/attachments.ts
  • src/db/mutations/comments.ts
  • src/db/mutations/labels.ts
  • src/db/mutations/projects.ts
  • src/db/mutations/sprints.ts
  • src/db/mutations/statuses.ts
  • src/db/mutations/sub-tasks.ts
  • src/db/mutations/sync.ts
  • src/db/mutations/tasks.ts
  • src/db/queries/attachments.ts
  • src/db/queries/bundles.ts
  • src/db/queries/comments.ts
  • src/db/queries/dashboard.ts
  • src/db/queries/hydrate-query-cache.ts
  • src/db/queries/labels.ts
  • src/db/queries/notifications.ts
  • src/db/queries/projects.ts
  • src/db/queries/sprints.ts
  • src/db/queries/statuses.ts
  • src/db/queries/tasks.ts
  • src/hooks/live-sync-provider.tsx
  • src/hooks/use-event-source.ts
  • src/hooks/use-git-task-live-sync.ts
  • src/lib/query-cache-fresh.ts
  • src/router.tsx
  • src/routes/_signed-in.tsx
  • src/routes/_signed-in/dashboard.tsx
  • src/routes/_signed-in/projects.$projectId.tasks.tsx
  • src/routes/_signed-in/sprints.$sprintId.tasks.tsx
  • src/routes/_signed-in/tasks.tsx
  • vite.config.ts
💤 Files with no reviewable changes (1)
  • src/hooks/use-event-source.ts

Comment thread src/components/views/ListView.tsx Outdated
Comment thread src/components/views/TaskViewsContainer.tsx Outdated
Comment thread src/components/views/VirtualizedTaskCards.tsx Outdated
Comment thread src/db/mutations/sync.ts
Comment thread src/db/mutations/tasks.ts
Comment thread src/db/mutations/tasks.ts Outdated
Comment thread src/db/mutations/tasks.ts
Comment thread src/hooks/live-sync-provider.tsx
Comment thread src/routes/_signed-in.tsx Outdated
@netlify

netlify Bot commented Jun 10, 2026

Copy link
Copy Markdown

Deploy Preview for pno-project-y ready!

Name Link
🔨 Latest commit 846512d
🔍 Latest deploy log https://app.netlify.com/projects/pno-project-y/deploys/6a2a62dea26aa200080d3853
😎 Deploy Preview https://deploy-preview-60--pno-project-y.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@kaesetoast kaesetoast merged commit b892945 into main Jun 11, 2026
5 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.12.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant