refactor: move shared hooks from ui/hooks to shared/hooks (#729)

Reorganize hook structure to follow vertical slice architecture:
- Move useSmartPolling, useThemeAware, useToast to features/shared/hooks
- Update 38+ import statements across codebase
- Update test file mocks to reference new locations
- Remove old ui/hooks directory

This change aligns shared utilities with the architectural pattern
where truly shared code resides in the shared directory.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Wirasm 2025-09-22 12:54:55 +03:00 committed by GitHub
parent 3ff3f7f2dc
commit d3a5c3311a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 40 additions and 40 deletions

View File

@ -5,7 +5,7 @@ import { Button } from "../ui/Button";
import { Input } from "../ui/Input";
import { Card } from "../ui/Card";
import { Select } from "../ui/Select";
import { useToast } from "../../features/ui/hooks/useToast";
import { useToast } from "../../features/shared/hooks/useToast";
import {
bugReportService,
BugContext,

View File

@ -2,7 +2,7 @@ import { AlertCircle, WifiOff } from "lucide-react";
import type React from "react";
import { useEffect } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { useToast } from "../../features/ui/hooks/useToast";
import { useToast } from "../../features/shared/hooks/useToast";
import { cn } from "../../lib/utils";
import { credentialsService } from "../../services/credentialsService";
import { isLmConfigured } from "../../utils/onboarding";

View File

@ -3,7 +3,7 @@ import { Key, ExternalLink, Save, Loader } from "lucide-react";
import { Input } from "../ui/Input";
import { Button } from "../ui/Button";
import { Select } from "../ui/Select";
import { useToast } from "../../features/ui/hooks/useToast";
import { useToast } from "../../features/shared/hooks/useToast";
import { credentialsService } from "../../services/credentialsService";
interface ProviderStepProps {

View File

@ -4,7 +4,7 @@ import { Input } from '../ui/Input';
import { Button } from '../ui/Button';
import { Card } from '../ui/Card';
import { credentialsService, Credential } from '../../services/credentialsService';
import { useToast } from '../../features/ui/hooks/useToast';
import { useToast } from '../../features/shared/hooks/useToast';
interface CustomCredential {
key: string;

View File

@ -3,7 +3,7 @@ import { Code, Check, Save, Loader } from 'lucide-react';
import { Card } from '../ui/Card';
import { Input } from '../ui/Input';
import { Button } from '../ui/Button';
import { useToast } from '../../features/ui/hooks/useToast';
import { useToast } from '../../features/shared/hooks/useToast';
import { credentialsService } from '../../services/credentialsService';
interface CodeExtractionSettingsProps {

View File

@ -4,7 +4,7 @@ import { Toggle } from '../ui/Toggle';
import { Card } from '../ui/Card';
import { useTheme } from '../../contexts/ThemeContext';
import { credentialsService } from '../../services/credentialsService';
import { useToast } from '../../features/ui/hooks/useToast';
import { useToast } from '../../features/shared/hooks/useToast';
import { serverHealthService } from '../../services/serverHealthService';
export const FeaturesSection = () => {

View File

@ -2,7 +2,7 @@ import { useState } from 'react';
import { FileCode, Copy, Check } from 'lucide-react';
import { Card } from '../ui/Card';
import { Button } from '../ui/Button';
import { useToast } from '../../features/ui/hooks/useToast';
import { useToast } from '../../features/shared/hooks/useToast';
import { copyToClipboard } from '../../features/shared/utils/clipboard';
type RuleType = 'claude' | 'universal';

View File

@ -3,7 +3,7 @@ import { Card } from '../ui/Card';
import { Button } from '../ui/Button';
import { Input } from '../ui/Input';
import { Badge } from '../ui/Badge';
import { useToast } from '../../features/ui/hooks/useToast';
import { useToast } from '../../features/shared/hooks/useToast';
import { cn } from '../../lib/utils';
import { credentialsService, OllamaInstance } from '../../services/credentialsService';
import { OllamaModelDiscoveryModal } from './OllamaModelDiscoveryModal';

View File

@ -3,7 +3,7 @@ import { Badge } from '../ui/Badge';
import { Button } from '../ui/Button';
import { Card } from '../ui/Card';
import { cn } from '../../lib/utils';
import { useToast } from '../../features/ui/hooks/useToast';
import { useToast } from '../../features/shared/hooks/useToast';
import { ollamaService } from '../../services/ollamaService';
import type { HealthIndicatorProps } from './types/OllamaTypes';

View File

@ -13,7 +13,7 @@ import { Button } from '../ui/Button';
import { Input } from '../ui/Input';
import { Badge } from '../ui/Badge';
import { Card } from '../ui/Card';
import { useToast } from '../../features/ui/hooks/useToast';
import { useToast } from '../../features/shared/hooks/useToast';
import { ollamaService, type OllamaModel, type ModelDiscoveryResponse } from '../../services/ollamaService';
import type { OllamaInstance, ModelSelectionState } from './types/OllamaTypes';

View File

@ -3,7 +3,7 @@ import ReactDOM from 'react-dom';
import { X, Search, RotateCcw, Zap, Server, Eye, Settings, Download, Box } from 'lucide-react';
import { Button } from '../ui/Button';
import { Input } from '../ui/Input';
import { useToast } from '../../features/ui/hooks/useToast';
import { useToast } from '../../features/shared/hooks/useToast';
interface ContextInfo {
current?: number;

View File

@ -4,7 +4,7 @@ import { Card } from '../ui/Card';
import { Input } from '../ui/Input';
import { Select } from '../ui/Select';
import { Button } from '../ui/Button';
import { useToast } from '../../features/ui/hooks/useToast';
import { useToast } from '../../features/shared/hooks/useToast';
import { credentialsService } from '../../services/credentialsService';
import OllamaModelDiscoveryModal from './OllamaModelDiscoveryModal';
import OllamaModelSelectionModal from './OllamaModelSelectionModal';

View File

@ -5,7 +5,7 @@
import { Globe, Loader2, Upload } from "lucide-react";
import { useId, useState } from "react";
import { useToast } from "../../ui/hooks/useToast";
import { useToast } from "@/features/shared/hooks/useToast";
import { Button, Input, Label } from "../../ui/primitives";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "../../ui/primitives/dialog";
import { cn } from "../../ui/primitives/styles";

View File

@ -6,7 +6,7 @@
import { formatDistanceToNowStrict } from "date-fns";
import { Code, ExternalLink, Eye, FileText, MoreHorizontal, Trash2 } from "lucide-react";
import { useState } from "react";
import { useToast } from "../../ui/hooks/useToast";
import { useToast } from "@/features/shared/hooks/useToast";
import { Button } from "../../ui/primitives";
import {
DropdownMenu,

View File

@ -23,14 +23,14 @@ vi.mock("../../services", () => ({
}));
// Mock the toast hook
vi.mock("../../../ui/hooks/useToast", () => ({
vi.mock("@/features/shared/hooks/useToast", () => ({
useToast: () => ({
showToast: vi.fn(),
}),
}));
// Mock smart polling
vi.mock("../../../ui/hooks", () => ({
vi.mock("@/features/shared/hooks", () => ({
useSmartPolling: () => ({
refetchInterval: 30000,
isPaused: false,

View File

@ -10,8 +10,8 @@ import { useActiveOperations } from "../../progress/hooks";
import { progressKeys } from "../../progress/hooks/useProgressQueries";
import type { ActiveOperation, ActiveOperationsResponse } from "../../progress/types";
import { DISABLED_QUERY_KEY, STALE_TIMES } from "../../shared/queryPatterns";
import { useSmartPolling } from "../../ui/hooks";
import { useToast } from "../../ui/hooks/useToast";
import { useSmartPolling } from "@/features/shared/hooks";
import { useToast } from "@/features/shared/hooks/useToast";
import { knowledgeService } from "../services";
import type {
CrawlRequest,

View File

@ -6,7 +6,7 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { CrawlingProgress } from "../../progress/components/CrawlingProgress";
import type { ActiveOperation } from "../../progress/types";
import { useToast } from "../../ui/hooks/useToast";
import { useToast } from "@/features/shared/hooks/useToast";
import { AddKnowledgeDialog } from "../components/AddKnowledgeDialog";
import { KnowledgeHeader } from "../components/KnowledgeHeader";
import { KnowledgeList } from "../components/KnowledgeList";

View File

@ -1,7 +1,7 @@
import { Copy, ExternalLink } from "lucide-react";
import type React from "react";
import { useState } from "react";
import { useToast } from "../../ui/hooks";
import { useToast } from "@/features/shared/hooks";
import { Button, cn, glassmorphism, Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/primitives";
import type { McpServerConfig, McpServerStatus, SupportedIDE } from "../types";
import { copyToClipboard } from "../../shared/utils/clipboard";

View File

@ -1,6 +1,6 @@
import { useQuery } from "@tanstack/react-query";
import { STALE_TIMES } from "../../shared/queryPatterns";
import { useSmartPolling } from "../../ui/hooks";
import { useSmartPolling } from "@/features/shared/hooks";
import { mcpApi } from "../services";
// Query keys factory

View File

@ -7,7 +7,7 @@ import { type UseQueryResult, useQueries, useQuery, useQueryClient } from "@tans
import { useEffect, useMemo, useRef } from "react";
import { APIServiceError } from "../../shared/errors";
import { DISABLED_QUERY_KEY, STALE_TIMES } from "../../shared/queryPatterns";
import { useSmartPolling } from "../../ui/hooks";
import { useSmartPolling } from "../../shared/hooks";
import { progressService } from "../services";
import type { ActiveOperationsResponse, ProgressResponse, ProgressStatus } from "../types";

View File

@ -1,6 +1,6 @@
import { Clipboard, Pin, Trash2 } from "lucide-react";
import type React from "react";
import { useToast } from "../../ui/hooks/useToast";
import { useToast } from "@/features/shared/hooks/useToast";
import { cn, glassmorphism } from "../../ui/primitives/styles";
import { SimpleTooltip } from "../../ui/primitives/tooltip";

View File

@ -20,14 +20,14 @@ vi.mock("../../services", () => ({
}));
// Mock the toast hook
vi.mock("../../../ui/hooks/useToast", () => ({
vi.mock("@/features/shared/hooks/useToast", () => ({
useToast: () => ({
showToast: vi.fn(),
}),
}));
// Mock smart polling
vi.mock("../../../ui/hooks", () => ({
vi.mock("@/features/shared/hooks", () => ({
useSmartPolling: () => ({
refetchInterval: 5000,
isPaused: false,

View File

@ -6,8 +6,8 @@ import {
replaceOptimisticEntity,
} from "@/features/shared/optimistic";
import { DISABLED_QUERY_KEY, STALE_TIMES } from "../../shared/queryPatterns";
import { useSmartPolling } from "../../ui/hooks";
import { useToast } from "../../ui/hooks/useToast";
import { useSmartPolling } from "@/features/shared/hooks";
import { useToast } from "@/features/shared/hooks/useToast";
import { projectService } from "../services";
import type { CreateProjectRequest, Project, UpdateProjectRequest } from "../types";

View File

@ -1,6 +1,6 @@
import { Clipboard, Edit, Trash2 } from "lucide-react";
import type React from "react";
import { useToast } from "../../../ui/hooks/useToast";
import { useToast } from "@/features/shared/hooks/useToast";
import { cn, glassmorphism } from "../../../ui/primitives/styles";
import { SimpleTooltip } from "../../../ui/primitives/tooltip";

View File

@ -20,14 +20,14 @@ vi.mock("../../services", () => ({
const showToastMock = vi.fn();
// Mock the toast hook
vi.mock("../../../../ui/hooks/useToast", () => ({
vi.mock("../../../../shared/hooks/useToast", () => ({
useToast: () => ({
showToast: showToastMock,
}),
}));
// Mock smart polling
vi.mock("../../../../ui/hooks", () => ({
vi.mock("../../../../shared/hooks", () => ({
useSmartPolling: () => ({
refetchInterval: 5000,
isPaused: false,

View File

@ -1,5 +1,5 @@
import { useCallback } from "react";
import { useToast } from "../../../ui/hooks/useToast";
import { useToast } from "@/features/shared/hooks/useToast";
import { useProjectFeatures } from "../../hooks/useProjectQueries";
import type { Assignee, CreateTaskRequest, Task, UpdateTaskRequest, UseTaskEditorReturn } from "../types";
import { useCreateTask, useUpdateTask } from "./useTaskQueries";

View File

@ -6,8 +6,8 @@ import {
type OptimisticEntity,
} from "@/features/shared/optimistic";
import { DISABLED_QUERY_KEY, STALE_TIMES } from "../../../shared/queryPatterns";
import { useSmartPolling } from "../../../ui/hooks";
import { useToast } from "../../../ui/hooks/useToast";
import { useSmartPolling } from "../../../shared/hooks";
import { useToast } from "../../../shared/hooks/useToast";
import { taskService } from "../services";
import type { CreateTaskRequest, Task, UpdateTaskRequest } from "../types";

View File

@ -6,7 +6,7 @@ import { AnimatePresence, motion } from "framer-motion";
import { CheckCircle, Copy, Database, ExternalLink, X } from "lucide-react";
import React from "react";
import { copyToClipboard } from "@/features/shared/utils/clipboard";
import { useToast } from "@/features/ui/hooks/useToast";
import { useToast } from "@/features/shared/hooks/useToast";
import type { PendingMigration } from "../types";
interface PendingMigrationsModalProps {

View File

@ -4,7 +4,7 @@
import { useQuery } from "@tanstack/react-query";
import { STALE_TIMES } from "@/features/shared/queryPatterns";
import { useSmartPolling } from "@/features/ui/hooks/useSmartPolling";
import { useSmartPolling } from "@/features/shared/hooks/useSmartPolling";
import { migrationService } from "../services/migrationService";
import type { MigrationHistoryResponse, MigrationStatusResponse, PendingMigration } from "../types";

View File

@ -4,7 +4,7 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { STALE_TIMES } from "@/features/shared/queryPatterns";
import { useSmartPolling } from "@/features/ui/hooks/useSmartPolling";
import { useSmartPolling } from "@/features/shared/hooks/useSmartPolling";
import { versionService } from "../services/versionService";
import type { VersionCheckResponse } from "../types";

View File

@ -1,3 +1,3 @@
export * from "./useSmartPolling";
export * from "./useThemeAware";
export * from "./useToast";
export * from "./useToast";

View File

@ -1,6 +1,6 @@
import { AlertCircle, CheckCircle, Info, XCircle } from "lucide-react";
import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
import { createOptimisticId } from "../../shared/optimistic";
import { createOptimisticId } from "../optimistic";
// Toast types
interface Toast {

View File

@ -1,5 +1,5 @@
import type React from "react";
import { createToastContext, getToastIcon, ToastContext } from "../hooks/useToast";
import { createToastContext, getToastIcon, ToastContext } from "../../shared/hooks/useToast";
import {
ToastProvider as RadixToastProvider,
Toast,

View File

@ -14,7 +14,7 @@ import {
Database,
} from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
import { useToast } from "../features/ui/hooks/useToast";
import { useToast } from "../features/shared/hooks/useToast";
import { useSettings } from "../contexts/SettingsContext";
import { useStaggeredEntrance } from "../hooks/useStaggeredEntrance";
import { FeaturesSection } from "../components/settings/FeaturesSection";