Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 60 additions & 2 deletions apps/code/src/renderer/components/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,26 @@ import { useTasks } from "@features/tasks/hooks/useTasks";
import { TourOverlay } from "@features/tour/components/TourOverlay";
import { useTourStore } from "@features/tour/stores/tourStore";
import { createFirstTaskTour } from "@features/tour/tours/createFirstTaskTour";
import {
useWorkspaces,
workspaceApi,
} from "@features/workspace/hooks/useWorkspace";
import { useFeatureFlag } from "@hooks/useFeatureFlag";
import { useIntegrations } from "@hooks/useIntegrations";
import { Box, Flex } from "@radix-ui/themes";
import { BILLING_FLAG } from "@shared/constants";
import { useTRPC } from "@renderer/trpc/client";
import { BILLING_FLAG, SYNC_CLOUD_TASKS_FLAG } from "@shared/constants";
import { useCommandMenuStore } from "@stores/commandMenuStore";
import { useNavigationStore } from "@stores/navigationStore";
import { useShortcutsSheetStore } from "@stores/shortcutsSheetStore";
import { useCallback, useEffect } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { logger } from "@utils/logger";
import { useCallback, useEffect, useRef } from "react";
import { useTaskDeepLink } from "../hooks/useTaskDeepLink";
import { GlobalEventHandlers } from "./GlobalEventHandlers";

const log = logger.scope("main-layout");

export function MainLayout() {
const {
view,
Expand All @@ -56,7 +65,12 @@ export function MainLayout() {
close: closeShortcutsSheet,
} = useShortcutsSheetStore();
const { data: tasks } = useTasks();
const { data: workspaces, isFetched: workspacesFetched } = useWorkspaces();
const trpcReact = useTRPC();
const queryClient = useQueryClient();
const reconcilingTaskIds = useRef<Set<string>>(new Set());
const billingEnabled = useFeatureFlag(BILLING_FLAG);
const syncCloudTasksEnabled = useFeatureFlag(SYNC_CLOUD_TASKS_FLAG);

// Space switcher data
const sidebarData = useSidebarData({ activeView: view });
Expand All @@ -80,6 +94,50 @@ export function MainLayout() {
}
}, [tasks, hydrateTask]);

useEffect(() => {
if (!syncCloudTasksEnabled) return;
if (!tasks || !workspaces || !workspacesFetched) return;
const missing = tasks.filter(
(t) => !workspaces[t.id] && !reconcilingTaskIds.current.has(t.id),
);
if (missing.length === 0) return;
for (const t of missing) reconcilingTaskIds.current.add(t.id);
void Promise.allSettled(
missing.map((t) =>
workspaceApi.create({
taskId: t.id,
mainRepoPath: "",
folderId: "",
folderPath: "",
mode: "cloud",
}),
),
).then((results) => {
Comment thread
greptile-apps[bot] marked this conversation as resolved.
let anySucceeded = false;
for (const [i, r] of results.entries()) {
const id = missing[i].id;
reconcilingTaskIds.current.delete(id);
if (r.status === "rejected") {
log.warn(`Failed to reconcile workspace for task ${id}`, r.reason);
} else {
anySucceeded = true;
}
}
if (anySucceeded) {
void queryClient.invalidateQueries(
trpcReact.workspace.getAll.pathFilter(),
);
}
});
Comment thread
greptile-apps[bot] marked this conversation as resolved.
}, [
syncCloudTasksEnabled,
tasks,
workspaces,
workspacesFetched,
queryClient,
trpcReact,
]);

useEffect(() => {
if (view.type === "task-detail" && !view.data && !view.taskId) {
navigateToTaskInput();
Expand Down
1 change: 1 addition & 0 deletions apps/code/src/shared/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const BILLING_FLAG = "posthog-code-billing";
export const INBOX_GATED_DUE_TO_SCALE_FLAG = "inbox-gated-due-to-scale";
export const SYNC_CLOUD_TASKS_FLAG = "posthog-code-sync-cloud-tasks";
export const BRANCH_PREFIX = "posthog-code/";
export const DATA_DIR = ".posthog-code";
export const WORKTREES_DIR = ".posthog-code/worktrees";
Expand Down
Loading