remove unused exports, components and hooks (#819)
This commit is contained in:
committed by
GitHub
parent
2dba0713c8
commit
0cbb8cd057
@@ -9,7 +9,6 @@ import {
|
||||
} from 'shared/types.ts';
|
||||
import type { ProcessStartPayload } from '@/types/logs';
|
||||
import FileChangeRenderer from './FileChangeRenderer';
|
||||
import { renderJson } from './ToolDetails';
|
||||
import { useExpandable } from '@/stores/useExpandableStore';
|
||||
import {
|
||||
AlertCircle,
|
||||
@@ -41,6 +40,11 @@ type Props = {
|
||||
};
|
||||
|
||||
type FileEditAction = Extract<ActionType, { action: 'file_edit' }>;
|
||||
type JsonValue = any;
|
||||
|
||||
const renderJson = (v: JsonValue) => (
|
||||
<pre className="whitespace-pre-wrap">{JSON.stringify(v, null, 2)}</pre>
|
||||
);
|
||||
|
||||
const getEntryIcon = (entryType: NormalizedEntryType) => {
|
||||
const iconSize = 'h-3 w-3';
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
import MarkdownRenderer from '@/components/ui/markdown-renderer.tsx';
|
||||
import RawLogText from '@/components/common/RawLogText';
|
||||
import { Braces, FileText } from 'lucide-react';
|
||||
|
||||
type JsonValue = any;
|
||||
|
||||
type ToolResult = {
|
||||
type: 'markdown' | 'json';
|
||||
value: JsonValue;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
arguments?: JsonValue | null;
|
||||
result?: ToolResult | null;
|
||||
commandOutput?: string | null; // presence => command mode
|
||||
commandExit?:
|
||||
| { type: 'success'; success: boolean }
|
||||
| { type: 'exit_code'; code: number }
|
||||
| null;
|
||||
};
|
||||
|
||||
export const renderJson = (v: JsonValue) => (
|
||||
<pre className="whitespace-pre-wrap">{JSON.stringify(v, null, 2)}</pre>
|
||||
);
|
||||
|
||||
export default function ToolDetails({
|
||||
arguments: args,
|
||||
result,
|
||||
commandOutput,
|
||||
}: Props) {
|
||||
const isCommandMode = commandOutput !== undefined;
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
{args && (
|
||||
<section>
|
||||
{!isCommandMode ? (
|
||||
<>
|
||||
<div className="flex items-center gap-2 text-xs text-zinc-500">
|
||||
<Braces className="h-3 w-3" />
|
||||
<span>Arguments</span>
|
||||
</div>
|
||||
{renderJson(args)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<RawLogText
|
||||
content={
|
||||
typeof args === 'string'
|
||||
? args
|
||||
: JSON.stringify(args, null, 2)
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
)}
|
||||
|
||||
{result && !isCommandMode && (
|
||||
<section>
|
||||
<div className="flex items-center gap-2 text-xs text-zinc-500">
|
||||
{result.type === 'json' ? (
|
||||
<Braces className="h-3 w-3" />
|
||||
) : (
|
||||
<FileText className="h-3 w-3" />
|
||||
)}
|
||||
<span>Result</span>
|
||||
</div>
|
||||
<div className="mt-1">
|
||||
{result.type === 'markdown' ? (
|
||||
<MarkdownRenderer content={String(result.value ?? '')} />
|
||||
) : (
|
||||
renderJson(result.value)
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{isCommandMode && (
|
||||
<section>
|
||||
<div className="mt-1">
|
||||
<RawLogText content={commandOutput ?? ''} />
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -26,5 +26,3 @@ export function ProfileVariantBadge({
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProfileVariantBadge;
|
||||
|
||||
@@ -115,4 +115,3 @@ const PrivacyOptInDialog = NiceModal.create(() => {
|
||||
});
|
||||
|
||||
export { PrivacyOptInDialog };
|
||||
export default PrivacyOptInDialog;
|
||||
|
||||
@@ -196,4 +196,3 @@ const CreatePrDialog = NiceModal.create(() => {
|
||||
});
|
||||
|
||||
export { CreatePrDialog as CreatePRDialog };
|
||||
export default CreatePrDialog;
|
||||
|
||||
@@ -94,4 +94,3 @@ const DeleteTaskConfirmationDialog =
|
||||
});
|
||||
|
||||
export { DeleteTaskConfirmationDialog };
|
||||
export default DeleteTaskConfirmationDialog;
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
import { Label } from '@/components/ui/label';
|
||||
import BranchSelector from '@/components/tasks/BranchSelector';
|
||||
import ExecutorProfileSelector from './ExecutorProfileSelector';
|
||||
import type {
|
||||
GitBranch,
|
||||
ExecutorConfig,
|
||||
ExecutorProfileId,
|
||||
} from 'shared/types';
|
||||
|
||||
type Props = {
|
||||
// Branch selector props
|
||||
branches?: GitBranch[];
|
||||
selectedBranch?: string | null;
|
||||
onBranchSelect?: (branch: string) => void;
|
||||
showBranchSelector?: boolean;
|
||||
branchSelectorProps?: {
|
||||
placeholder?: string;
|
||||
className?: string;
|
||||
excludeCurrentBranch?: boolean;
|
||||
};
|
||||
|
||||
// Executor profile selector props
|
||||
profiles?: Record<string, ExecutorConfig> | null;
|
||||
selectedProfile?: ExecutorProfileId | null;
|
||||
onProfileSelect?: (profile: ExecutorProfileId) => void;
|
||||
showExecutorSelector?: boolean;
|
||||
executorSelectorProps?: {
|
||||
showLabel?: boolean;
|
||||
showVariantSelector?: boolean;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
// Common props
|
||||
disabled?: boolean;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
function TaskSettings({
|
||||
// Branch selector props
|
||||
branches = [],
|
||||
selectedBranch,
|
||||
onBranchSelect,
|
||||
showBranchSelector = true,
|
||||
branchSelectorProps = {},
|
||||
|
||||
// Executor profile selector props
|
||||
profiles,
|
||||
selectedProfile,
|
||||
onProfileSelect,
|
||||
showExecutorSelector = true,
|
||||
executorSelectorProps = {},
|
||||
|
||||
// Common props
|
||||
disabled = false,
|
||||
className = '',
|
||||
}: Props) {
|
||||
return (
|
||||
<div className={`space-y-3 ${className}`}>
|
||||
{/* Executor Profile Selector */}
|
||||
{showExecutorSelector &&
|
||||
profiles &&
|
||||
selectedProfile &&
|
||||
onProfileSelect && (
|
||||
<ExecutorProfileSelector
|
||||
profiles={profiles}
|
||||
selectedProfile={selectedProfile}
|
||||
onProfileSelect={onProfileSelect}
|
||||
disabled={disabled}
|
||||
{...executorSelectorProps}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Branch Selector */}
|
||||
{showBranchSelector &&
|
||||
branches.length > 0 &&
|
||||
selectedBranch !== undefined &&
|
||||
onBranchSelect && (
|
||||
<div>
|
||||
<Label htmlFor="base-branch" className="text-sm font-medium">
|
||||
Branch
|
||||
</Label>
|
||||
<BranchSelector
|
||||
branches={branches}
|
||||
selectedBranch={selectedBranch}
|
||||
onBranchSelect={onBranchSelect}
|
||||
placeholder="Select branch"
|
||||
className="mt-1.5"
|
||||
{...branchSelectorProps}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TaskSettings;
|
||||
@@ -1,2 +1 @@
|
||||
export { default as ExecutorProfileSelector } from './ExecutorProfileSelector';
|
||||
export { default as TaskSettings } from './TaskSettings';
|
||||
|
||||
@@ -12,7 +12,7 @@ function getStatusIcon(status?: string) {
|
||||
return <Circle aria-hidden className="h-4 w-4 text-muted-foreground" />;
|
||||
}
|
||||
|
||||
export function TodoPanel() {
|
||||
function TodoPanel() {
|
||||
const { entries } = useEntries();
|
||||
const { todos } = usePinnedTodos(entries);
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import type {
|
||||
ExecutionProcessRunReason,
|
||||
ExecutionProcessStatus,
|
||||
ExecutionProcess,
|
||||
} from 'shared/types';
|
||||
import type { ExecutionProcessRunReason } from 'shared/types';
|
||||
|
||||
// Process run reasons
|
||||
export const PROCESS_RUN_REASONS = {
|
||||
@@ -12,51 +8,14 @@ export const PROCESS_RUN_REASONS = {
|
||||
DEV_SERVER: 'devserver' as ExecutionProcessRunReason,
|
||||
} as const;
|
||||
|
||||
// Process statuses
|
||||
export const PROCESS_STATUSES = {
|
||||
RUNNING: 'running' as ExecutionProcessStatus,
|
||||
COMPLETED: 'completed' as ExecutionProcessStatus,
|
||||
FAILED: 'failed' as ExecutionProcessStatus,
|
||||
KILLED: 'killed' as ExecutionProcessStatus,
|
||||
} as const;
|
||||
|
||||
// Helper functions
|
||||
export const isAutoCollapsibleProcess = (
|
||||
runReason: ExecutionProcessRunReason
|
||||
): boolean => {
|
||||
return (
|
||||
runReason === PROCESS_RUN_REASONS.SETUP_SCRIPT ||
|
||||
runReason === PROCESS_RUN_REASONS.CLEANUP_SCRIPT
|
||||
);
|
||||
};
|
||||
|
||||
export const isCodingAgent = (
|
||||
runReason: ExecutionProcessRunReason
|
||||
): boolean => {
|
||||
return runReason === PROCESS_RUN_REASONS.CODING_AGENT;
|
||||
};
|
||||
|
||||
export const isProcessCompleted = (status: ExecutionProcessStatus): boolean => {
|
||||
return (
|
||||
status === PROCESS_STATUSES.COMPLETED || status === PROCESS_STATUSES.FAILED
|
||||
);
|
||||
};
|
||||
|
||||
export const shouldShowInLogs = (
|
||||
runReason: ExecutionProcessRunReason
|
||||
): boolean => {
|
||||
return runReason !== PROCESS_RUN_REASONS.DEV_SERVER;
|
||||
};
|
||||
|
||||
export const getLatestCodingAgent = (
|
||||
processes: ExecutionProcess[]
|
||||
): string | null => {
|
||||
const codingAgents = processes.filter((p) => isCodingAgent(p.run_reason));
|
||||
if (codingAgents.length === 0) return null;
|
||||
|
||||
return codingAgents.sort((a, b) =>
|
||||
a.started_at === b.started_at
|
||||
? a.id.localeCompare(b.id) // tie-break for same timestamp
|
||||
: new Date(b.started_at).getTime() - new Date(a.started_at).getTime()
|
||||
)[0].id;
|
||||
};
|
||||
|
||||
@@ -3,8 +3,6 @@ export { useAttemptExecution } from './useAttemptExecution';
|
||||
export { useOpenInEditor } from './useOpenInEditor';
|
||||
export { useDevServer } from './useDevServer';
|
||||
export { useRebase } from './useRebase';
|
||||
export { useCreatePR } from './useCreatePR';
|
||||
export { useMerge } from './useMerge';
|
||||
export { usePush } from './usePush';
|
||||
export { useProjectBranches } from './useProjectBranches';
|
||||
export { useKeyboardShortcut } from './useKeyboardShortcut';
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { attemptsApi, type Result } from '@/lib/api';
|
||||
import type { CreateGitHubPrRequest, GitHubServiceError } from 'shared/types';
|
||||
|
||||
export function useCreatePR(
|
||||
attemptId: string | undefined,
|
||||
onSuccess?: (prUrl?: string) => void,
|
||||
onError?: (err: unknown) => void
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<
|
||||
Result<string, GitHubServiceError>,
|
||||
Error,
|
||||
CreateGitHubPrRequest
|
||||
>({
|
||||
mutationFn: async (prData: CreateGitHubPrRequest) => {
|
||||
if (!attemptId)
|
||||
return { success: false, error: undefined, message: 'No attempt ID' };
|
||||
return attemptsApi.createPR(attemptId, prData);
|
||||
},
|
||||
onSuccess: (result) => {
|
||||
if (result.success) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['branchStatus', attemptId],
|
||||
});
|
||||
onSuccess?.(result.data);
|
||||
} else {
|
||||
throw (
|
||||
result.error || new Error(result.message || 'Failed to create PR')
|
||||
);
|
||||
}
|
||||
},
|
||||
onError: (err) => {
|
||||
console.error('Failed to create PR:', err);
|
||||
onError?.(err);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { applyPatch } from 'rfc6902';
|
||||
import type { ExecutionProcess } from 'shared/types';
|
||||
import type { ProcessStartPayload } from '@/types/logs';
|
||||
|
||||
interface ProcessData {
|
||||
[processId: string]: any;
|
||||
}
|
||||
|
||||
interface UseEventSourceManagerParams {
|
||||
processes: ExecutionProcess[];
|
||||
enabled: boolean;
|
||||
getEndpoint: (process: ExecutionProcess) => string;
|
||||
initialData?: any;
|
||||
}
|
||||
|
||||
interface UseEventSourceManagerResult {
|
||||
processData: ProcessData;
|
||||
isConnected: boolean;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
export const useEventSourceManager = ({
|
||||
processes,
|
||||
enabled,
|
||||
getEndpoint,
|
||||
initialData = null,
|
||||
}: UseEventSourceManagerParams): UseEventSourceManagerResult => {
|
||||
const [processData, setProcessData] = useState<ProcessData>({});
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const eventSourcesRef = useRef<Map<string, EventSource>>(new Map());
|
||||
const processDataRef = useRef<ProcessData>({});
|
||||
const processedEntriesRef = useRef<Map<string, Set<number>>>(new Map());
|
||||
const processesRef = useRef<ExecutionProcess[]>([]);
|
||||
const enabledRef = useRef<boolean>(enabled);
|
||||
const getEndpointRef = useRef(getEndpoint);
|
||||
const retryCountsRef = useRef<Map<string, number>>(new Map());
|
||||
const retryTimersRef = useRef<Map<string, ReturnType<typeof setTimeout>>>(
|
||||
new Map()
|
||||
);
|
||||
|
||||
// Keep latest values in refs for retry handlers
|
||||
useEffect(() => {
|
||||
processesRef.current = processes;
|
||||
}, [processes]);
|
||||
useEffect(() => {
|
||||
enabledRef.current = enabled;
|
||||
}, [enabled]);
|
||||
useEffect(() => {
|
||||
getEndpointRef.current = getEndpoint;
|
||||
}, [getEndpoint]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled || !processes.length) {
|
||||
// Close all connections and reset state
|
||||
eventSourcesRef.current.forEach((es) => es.close());
|
||||
eventSourcesRef.current.clear();
|
||||
setProcessData({});
|
||||
setIsConnected(false);
|
||||
setError(null);
|
||||
processDataRef.current = {};
|
||||
processedEntriesRef.current.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const currentIds = new Set(processes.map((p) => p.id));
|
||||
|
||||
// Remove old connections
|
||||
eventSourcesRef.current.forEach((es, id) => {
|
||||
if (!currentIds.has(id)) {
|
||||
es.close();
|
||||
eventSourcesRef.current.delete(id);
|
||||
delete processDataRef.current[id];
|
||||
processedEntriesRef.current.delete(id);
|
||||
}
|
||||
});
|
||||
|
||||
// Helper to open an EventSource with auto-retry on transient failures (e.g., race before store is ready)
|
||||
const openEventSource = (process: ExecutionProcess) => {
|
||||
// If disabled or process no longer present, don't connect
|
||||
if (!enabledRef.current) return;
|
||||
if (!processesRef.current.find((p) => p.id === process.id)) return;
|
||||
|
||||
const endpoint = getEndpointRef.current(process);
|
||||
|
||||
// Reinitialize process data on each (re)connect to avoid duplicating history
|
||||
processDataRef.current[process.id] = initialData
|
||||
? structuredClone(initialData)
|
||||
: { entries: [] };
|
||||
processedEntriesRef.current.delete(process.id);
|
||||
|
||||
// Inject process start marker as the first entry (client-side only)
|
||||
const processStartPayload: ProcessStartPayload = {
|
||||
processId: process.id,
|
||||
runReason: process.run_reason,
|
||||
startedAt: process.started_at,
|
||||
status: process.status,
|
||||
};
|
||||
const processStartEntry = {
|
||||
type: 'PROCESS_START' as const,
|
||||
content: processStartPayload,
|
||||
};
|
||||
processDataRef.current[process.id].entries.push(processStartEntry);
|
||||
|
||||
const eventSource = new EventSource(endpoint);
|
||||
|
||||
eventSource.onopen = () => {
|
||||
setError(null);
|
||||
setIsConnected(true);
|
||||
retryCountsRef.current.set(process.id, 0);
|
||||
};
|
||||
|
||||
eventSource.addEventListener('json_patch', (event) => {
|
||||
try {
|
||||
const patches = JSON.parse(event.data);
|
||||
|
||||
if (!processedEntriesRef.current.has(process.id)) {
|
||||
processedEntriesRef.current.set(process.id, new Set());
|
||||
}
|
||||
applyPatch(processDataRef.current[process.id], patches);
|
||||
setProcessData({ ...processDataRef.current });
|
||||
} catch (err) {
|
||||
console.error('Failed to apply JSON patch:', err);
|
||||
setError('Failed to process log update');
|
||||
}
|
||||
});
|
||||
|
||||
eventSource.addEventListener('finished', () => {
|
||||
eventSource.close();
|
||||
eventSourcesRef.current.delete(process.id);
|
||||
retryCountsRef.current.delete(process.id);
|
||||
const t = retryTimersRef.current.get(process.id);
|
||||
if (t) {
|
||||
clearTimeout(t);
|
||||
retryTimersRef.current.delete(process.id);
|
||||
}
|
||||
setIsConnected(eventSourcesRef.current.size > 0);
|
||||
});
|
||||
|
||||
eventSource.onerror = () => {
|
||||
setError('Connection failed');
|
||||
eventSource.close();
|
||||
eventSourcesRef.current.delete(process.id);
|
||||
|
||||
const nextAttempt = (retryCountsRef.current.get(process.id) || 0) + 1;
|
||||
retryCountsRef.current.set(process.id, nextAttempt);
|
||||
|
||||
const maxAttempts = 6;
|
||||
if (
|
||||
nextAttempt <= maxAttempts &&
|
||||
enabledRef.current &&
|
||||
processesRef.current.find((p) => p.id === process.id)
|
||||
) {
|
||||
const delay = Math.min(1500, 250 * 2 ** (nextAttempt - 1));
|
||||
const timer = setTimeout(() => openEventSource(process), delay);
|
||||
const prevTimer = retryTimersRef.current.get(process.id);
|
||||
if (prevTimer) clearTimeout(prevTimer);
|
||||
retryTimersRef.current.set(process.id, timer);
|
||||
} else {
|
||||
setIsConnected(eventSourcesRef.current.size > 0);
|
||||
}
|
||||
};
|
||||
|
||||
eventSourcesRef.current.set(process.id, eventSource);
|
||||
};
|
||||
|
||||
// Add new connections
|
||||
processes.forEach((process) => {
|
||||
if (eventSourcesRef.current.has(process.id)) return;
|
||||
openEventSource(process);
|
||||
});
|
||||
|
||||
setIsConnected(eventSourcesRef.current.size > 0);
|
||||
|
||||
return () => {
|
||||
// Cleanup all event sources and any pending retry timers
|
||||
eventSourcesRef.current.forEach((es) => es.close());
|
||||
eventSourcesRef.current.clear();
|
||||
retryTimersRef.current.forEach((t) => clearTimeout(t));
|
||||
retryTimersRef.current.clear();
|
||||
};
|
||||
}, [processes, enabled, getEndpoint, initialData]);
|
||||
|
||||
return { processData, isConnected, error };
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { projectsApi } from '@/lib/api';
|
||||
|
||||
export function useProjectBranches(projectId?: string) {
|
||||
return useQuery({
|
||||
queryKey: ['projectBranches', projectId],
|
||||
queryFn: () => projectsApi.getBranches(projectId!),
|
||||
enabled: !!projectId,
|
||||
staleTime: 30_000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export const UI_TO_I18N = {
|
||||
ES: 'es',
|
||||
} as const;
|
||||
|
||||
export const SUPPORTED_UI_LANGUAGES = ['BROWSER', 'EN', 'JA', 'ES'] as const;
|
||||
const SUPPORTED_UI_LANGUAGES = ['BROWSER', 'EN', 'JA', 'ES'] as const;
|
||||
export const SUPPORTED_I18N_CODES = Object.values(UI_TO_I18N);
|
||||
|
||||
const FALLBACK_ENDONYMS = {
|
||||
|
||||
@@ -52,7 +52,7 @@ export type {
|
||||
UpdateFollowUpDraftRequest,
|
||||
} from 'shared/types';
|
||||
|
||||
export class ApiError<E = unknown> extends Error {
|
||||
class ApiError<E = unknown> extends Error {
|
||||
public status?: number;
|
||||
public error_data?: E;
|
||||
|
||||
@@ -69,7 +69,7 @@ export class ApiError<E = unknown> extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
export const makeRequest = async (url: string, options: RequestInit = {}) => {
|
||||
const makeRequest = async (url: string, options: RequestInit = {}) => {
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
...(options.headers || {}),
|
||||
@@ -641,17 +641,6 @@ export const githubApi = {
|
||||
const response = await makeRequest(`/api/github/repositories?page=${page}`);
|
||||
return handleApiResponse<RepositoryInfo[]>(response);
|
||||
},
|
||||
// createProjectFromRepository: async (
|
||||
// data: CreateProjectFromGitHub
|
||||
// ): Promise<Project> => {
|
||||
// const response = await makeRequest('/api/projects/from-github', {
|
||||
// method: 'POST',
|
||||
// body: JSON.stringify(data, (_key, value) =>
|
||||
// typeof value === 'bigint' ? Number(value) : value
|
||||
// ),
|
||||
// });
|
||||
// return handleApiResponse<Project>(response);
|
||||
// },
|
||||
};
|
||||
|
||||
// Task Templates APIs
|
||||
|
||||
@@ -14,7 +14,7 @@ export function displayConflictOpLabel(op?: ConflictOp | null): string {
|
||||
}
|
||||
}
|
||||
|
||||
export function formatConflictHeader(
|
||||
function formatConflictHeader(
|
||||
op: ConflictOp | null | undefined,
|
||||
sourceBranch: string,
|
||||
baseBranch?: string
|
||||
|
||||
@@ -16,4 +16,3 @@ export const useDiffViewStore = create<State>((set) => ({
|
||||
}));
|
||||
|
||||
export const useDiffViewMode = () => useDiffViewStore((s) => s.mode);
|
||||
export const useToggleDiffViewMode = () => useDiffViewStore((s) => s.toggle);
|
||||
|
||||
@@ -7,7 +7,7 @@ type State = {
|
||||
clear: () => void;
|
||||
};
|
||||
|
||||
export const useExpandableStore = create<State>((set) => ({
|
||||
const useExpandableStore = create<State>((set) => ({
|
||||
expanded: {},
|
||||
setKey: (key, value) =>
|
||||
set((s) =>
|
||||
|
||||
@@ -26,7 +26,7 @@ const defaultUiState: TaskUiState = {
|
||||
fileToDelete: null,
|
||||
};
|
||||
|
||||
export const useTaskDetailsUiStore = create<TaskDetailsUiStore>((set, get) => ({
|
||||
const useTaskDetailsUiStore = create<TaskDetailsUiStore>((set, get) => ({
|
||||
ui: {},
|
||||
|
||||
getUiState: (taskId: string) => {
|
||||
@@ -59,17 +59,6 @@ export const useTaskDetailsUiStore = create<TaskDetailsUiStore>((set, get) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
// Convenience hooks for specific UI state
|
||||
export const useTaskLoading = (taskId: string) => {
|
||||
const { getUiState, setUiState } = useTaskDetailsUiStore();
|
||||
const { loading } = getUiState(taskId);
|
||||
|
||||
return {
|
||||
loading,
|
||||
setLoading: (value: boolean) => setUiState(taskId, { loading: value }),
|
||||
};
|
||||
};
|
||||
|
||||
export const useTaskStopping = (taskId: string) => {
|
||||
const { getUiState, setUiState } = useTaskDetailsUiStore();
|
||||
const { isStopping } = getUiState(taskId);
|
||||
@@ -80,17 +69,3 @@ export const useTaskStopping = (taskId: string) => {
|
||||
setUiState(taskId, { isStopping: value }),
|
||||
};
|
||||
};
|
||||
|
||||
export const useTaskDeletingFiles = (taskId: string) => {
|
||||
const { getUiState, setUiState } = useTaskDetailsUiStore();
|
||||
const { deletingFiles, fileToDelete } = getUiState(taskId);
|
||||
|
||||
return {
|
||||
deletingFiles,
|
||||
fileToDelete,
|
||||
setFileToDelete: (value: string | null) =>
|
||||
setUiState(taskId, { fileToDelete: value }),
|
||||
setDeletingFiles: (value: Set<string>) =>
|
||||
setUiState(taskId, { deletingFiles: value }),
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user