feat(core): migrate workspace + runtimes to TanStack Query (Phase 3+4)
- Create core/workspace/ with queries (members, agents, skills, list) and mutations - Create core/runtimes/ with queries - Migrate 11 consumer files from useWorkspaceStore.members/agents/skills to useQuery - Replace all WS refreshMap entries with qc.invalidateQueries - Simplify workspace store: delete members/agents/skills fields + refresh methods, hydrateWorkspace becomes synchronous (TQ auto-fetches on component mount) - Delete useRuntimeStore (no consumers left), runtimes-page uses local useState + TQ - Remove workspace→runtime cross-store dependency - Clean up dead test helper mocks Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1d812bd446
commit
e40341ab73
24 changed files with 251 additions and 289 deletions
|
|
@ -68,6 +68,7 @@ import { useAuthStore } from "@/features/auth";
|
|||
import { useWorkspaceStore, useActorName } from "@/features/workspace";
|
||||
import { useWorkspaceId } from "@core/hooks";
|
||||
import { issueListOptions, issueDetailOptions } from "@core/issues/queries";
|
||||
import { memberListOptions, agentListOptions } from "@core/workspace/queries";
|
||||
import { useUpdateIssue, useDeleteIssue } from "@core/issues/mutations";
|
||||
import { useIssueTimeline } from "@/features/issues/hooks/use-issue-timeline";
|
||||
import { useIssueReactions } from "@/features/issues/hooks/use-issue-reactions";
|
||||
|
|
@ -177,12 +178,12 @@ export function IssueDetail({ issueId, onDelete, defaultSidebarOpen = true, layo
|
|||
const router = useRouter();
|
||||
const user = useAuthStore((s) => s.user);
|
||||
const workspace = useWorkspaceStore((s) => s.workspace);
|
||||
const members = useWorkspaceStore((s) => s.members);
|
||||
const agents = useWorkspaceStore((s) => s.agents);
|
||||
const currentMemberRole = members.find((m) => m.user_id === user?.id)?.role;
|
||||
|
||||
// Issue navigation — read from TQ list cache
|
||||
const wsId = useWorkspaceId();
|
||||
const { data: members = [] } = useQuery(memberListOptions(wsId));
|
||||
const { data: agents = [] } = useQuery(agentListOptions(wsId));
|
||||
const currentMemberRole = members.find((m) => m.user_id === user?.id)?.role;
|
||||
const { data: allIssues = [] } = useQuery(issueListOptions(wsId));
|
||||
const currentIndex = allIssues.findIndex((i) => i.id === id);
|
||||
const prevIssue = currentIndex > 0 ? allIssues[currentIndex - 1] : null;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ import {
|
|||
PRIORITY_CONFIG,
|
||||
} from "@/features/issues/config";
|
||||
import { StatusIcon, PriorityIcon } from "@/features/issues/components";
|
||||
import { useWorkspaceStore } from "@/features/workspace";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useWorkspaceId } from "@core/hooks";
|
||||
import { memberListOptions, agentListOptions } from "@core/workspace/queries";
|
||||
import { ActorAvatar } from "@/components/common/actor-avatar";
|
||||
import {
|
||||
useIssueViewStore,
|
||||
|
|
@ -155,8 +157,9 @@ function ActorSubContent({
|
|||
noAssigneeCount?: number;
|
||||
}) {
|
||||
const [search, setSearch] = useState("");
|
||||
const members = useWorkspaceStore((s) => s.members);
|
||||
const agents = useWorkspaceStore((s) => s.agents);
|
||||
const wsId = useWorkspaceId();
|
||||
const { data: members = [] } = useQuery(memberListOptions(wsId));
|
||||
const { data: agents = [] } = useQuery(agentListOptions(wsId));
|
||||
const query = search.toLowerCase();
|
||||
const filteredMembers = members.filter((m) =>
|
||||
m.name.toLowerCase().includes(query),
|
||||
|
|
|
|||
|
|
@ -3,8 +3,11 @@
|
|||
import { useState } from "react";
|
||||
import { Lock, UserMinus } from "lucide-react";
|
||||
import type { Agent, IssueAssigneeType, UpdateIssueRequest } from "@/shared/types";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useAuthStore } from "@/features/auth";
|
||||
import { useWorkspaceStore, useActorName } from "@/features/workspace";
|
||||
import { useActorName } from "@/features/workspace";
|
||||
import { useWorkspaceId } from "@core/hooks";
|
||||
import { memberListOptions, agentListOptions } from "@core/workspace/queries";
|
||||
import { ActorAvatar } from "@/components/common/actor-avatar";
|
||||
import {
|
||||
PropertyPicker,
|
||||
|
|
@ -44,8 +47,9 @@ export function AssigneePicker({
|
|||
const setOpen = controlledOnOpenChange ?? setInternalOpen;
|
||||
const [filter, setFilter] = useState("");
|
||||
const user = useAuthStore((s) => s.user);
|
||||
const members = useWorkspaceStore((s) => s.members);
|
||||
const agents = useWorkspaceStore((s) => s.agents);
|
||||
const wsId = useWorkspaceId();
|
||||
const { data: members = [] } = useQuery(memberListOptions(wsId));
|
||||
const { data: agents = [] } = useQuery(agentListOptions(wsId));
|
||||
const { getActorName } = useActorName();
|
||||
|
||||
const currentMember = members.find((m) => m.user_id === user?.id);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue