generated from kevisual/vite-react-template
add useShallow
This commit is contained in:
@@ -16,6 +16,7 @@ import {
|
|||||||
import { Star, GitFork, FileText, Edit, FolderGit2, MoreVertical, FileText as IssueIcon, Settings, Play, Trash2, RefreshCw, BookOpen, Copy, Clock, Info, Eye, Square } from 'lucide-react'
|
import { Star, GitFork, FileText, Edit, FolderGit2, MoreVertical, FileText as IssueIcon, Settings, Play, Trash2, RefreshCw, BookOpen, Copy, Clock, Info, Eye, Square } from 'lucide-react'
|
||||||
import { useRepoStore } from '../store'
|
import { useRepoStore } from '../store'
|
||||||
import { useMemo, useState } from 'react'
|
import { useMemo, useState } from 'react'
|
||||||
|
import { useShallow } from 'zustand/shallow'
|
||||||
import { myOrgs } from '../store/build'
|
import { myOrgs } from '../store/build'
|
||||||
import { app, cnb } from '@/agents/app'
|
import { app, cnb } from '@/agents/app'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
@@ -32,7 +33,13 @@ interface RepoCardProps {
|
|||||||
|
|
||||||
export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings, onDelete, onSync }: RepoCardProps) {
|
export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings, onDelete, onSync }: RepoCardProps) {
|
||||||
const [deletePopoverOpen, setDeletePopoverOpen] = useState(false)
|
const [deletePopoverOpen, setDeletePopoverOpen] = useState(false)
|
||||||
const { workspaceList, getWorkspaceDetail, getList, buildUpdate, stopWorkspace } = useRepoStore();
|
const { workspaceList, getWorkspaceDetail, getList, buildUpdate, stopWorkspace } = useRepoStore(useShallow((state) => ({
|
||||||
|
workspaceList: state.workspaceList,
|
||||||
|
getWorkspaceDetail: state.getWorkspaceDetail,
|
||||||
|
getList: state.getList,
|
||||||
|
buildUpdate: state.buildUpdate,
|
||||||
|
stopWorkspace: state.stopWorkspace,
|
||||||
|
})));
|
||||||
const workspace = useMemo(() => {
|
const workspace = useMemo(() => {
|
||||||
return workspaceList.find(ws => ws.slug === repo.path)
|
return workspaceList.find(ws => ws.slug === repo.path)
|
||||||
}, [workspaceList, repo.path])
|
}, [workspaceList, repo.path])
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { Input } from '@/components/ui/input'
|
|||||||
import { Label } from '@/components/ui/label'
|
import { Label } from '@/components/ui/label'
|
||||||
import { Textarea } from '@/components/ui/textarea'
|
import { Textarea } from '@/components/ui/textarea'
|
||||||
import { useRepoStore } from '../store'
|
import { useRepoStore } from '../store'
|
||||||
|
import { useShallow } from 'zustand/shallow'
|
||||||
|
|
||||||
interface CreateRepoDialogProps {
|
interface CreateRepoDialogProps {
|
||||||
open: boolean
|
open: boolean
|
||||||
@@ -27,7 +28,10 @@ interface FormData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function CreateRepoDialog({ open, onOpenChange }: CreateRepoDialogProps) {
|
export function CreateRepoDialog({ open, onOpenChange }: CreateRepoDialogProps) {
|
||||||
const { createRepo, refresh } = useRepoStore()
|
const { createRepo, refresh } = useRepoStore(useShallow((state) => ({
|
||||||
|
createRepo: state.createRepo,
|
||||||
|
refresh: state.refresh,
|
||||||
|
})))
|
||||||
const { register, handleSubmit, reset } = useForm<FormData>()
|
const { register, handleSubmit, reset } = useForm<FormData>()
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { Label } from '@/components/ui/label'
|
|||||||
import { Textarea } from '@/components/ui/textarea'
|
import { Textarea } from '@/components/ui/textarea'
|
||||||
import { TagsInput } from '@/components/tags-input'
|
import { TagsInput } from '@/components/tags-input'
|
||||||
import { useRepoStore } from '../store'
|
import { useRepoStore } from '../store'
|
||||||
|
import { useShallow } from 'zustand/shallow'
|
||||||
|
|
||||||
interface EditRepoDialogProps {
|
interface EditRepoDialogProps {
|
||||||
open: boolean
|
open: boolean
|
||||||
@@ -36,7 +37,10 @@ interface FormData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function EditRepoDialog({ open, onOpenChange, repo }: EditRepoDialogProps) {
|
export function EditRepoDialog({ open, onOpenChange, repo }: EditRepoDialogProps) {
|
||||||
const { updateRepoInfo, getList } = useRepoStore()
|
const { updateRepoInfo, getList } = useRepoStore(useShallow((state) => ({
|
||||||
|
updateRepoInfo: state.updateRepoInfo,
|
||||||
|
getList: state.getList,
|
||||||
|
})))
|
||||||
const { register, handleSubmit, reset, setValue } = useForm<FormData>()
|
const { register, handleSubmit, reset, setValue } = useForm<FormData>()
|
||||||
const [tags, setTags] = useState<string[]>([])
|
const [tags, setTags] = useState<string[]>([])
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Input } from '@/components/ui/input'
|
|||||||
import { Label } from '@/components/ui/label'
|
import { Label } from '@/components/ui/label'
|
||||||
import { useRepoStore } from '../store'
|
import { useRepoStore } from '../store'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
|
import { useShallow } from 'zustand/shallow'
|
||||||
import { get, set } from 'idb-keyval'
|
import { get, set } from 'idb-keyval'
|
||||||
import { gitea } from '@/agents/app';
|
import { gitea } from '@/agents/app';
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
@@ -11,7 +12,12 @@ import { toast } from 'sonner'
|
|||||||
const SYNC_REPO_STORAGE_KEY = 'sync-repo-mapping'
|
const SYNC_REPO_STORAGE_KEY = 'sync-repo-mapping'
|
||||||
|
|
||||||
export function SyncRepoDialog() {
|
export function SyncRepoDialog() {
|
||||||
const { syncDialogOpen, setSyncDialogOpen, selectedSyncRepo, buildSync } = useRepoStore()
|
const { syncDialogOpen, setSyncDialogOpen, selectedSyncRepo, buildSync } = useRepoStore(useShallow((state) => ({
|
||||||
|
syncDialogOpen: state.syncDialogOpen,
|
||||||
|
setSyncDialogOpen: state.setSyncDialogOpen,
|
||||||
|
selectedSyncRepo: state.selectedSyncRepo,
|
||||||
|
buildSync: state.buildSync,
|
||||||
|
})))
|
||||||
const [toRepo, setToRepo] = useState('')
|
const [toRepo, setToRepo] = useState('')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -153,7 +153,6 @@ const WorkTabContent = () => {
|
|||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center py-2 text-neutral-400">
|
<div className="flex flex-col items-center justify-center py-2 text-neutral-400">
|
||||||
<div className='mb-2'>小代理</div>
|
|
||||||
<div className="grid grid-cols-1 gap-3 w-full max-w-sm">
|
<div className="grid grid-cols-1 gap-3 w-full max-w-sm">
|
||||||
{links.map(link => (
|
{links.map(link => (
|
||||||
<LinkItem key={link.label} label={link.label} icon={link.icon} url={link.url} />
|
<LinkItem key={link.label} label={link.label} icon={link.icon} url={link.url} />
|
||||||
@@ -164,8 +163,15 @@ const WorkTabContent = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function WorkspaceDetailDialog() {
|
export function WorkspaceDetailDialog() {
|
||||||
const { showWorkspaceDialog, setShowWorkspaceDialog, workspaceLink, stopWorkspace, workspaceTab, setWorkspaceTab } = useRepoStore()
|
const { showWorkspaceDialog, setShowWorkspaceDialog, workspaceLink, stopWorkspace, workspaceTab, setWorkspaceTab, selectWorkspace } = useRepoStore(useShallow((state) => ({
|
||||||
|
showWorkspaceDialog: state.showWorkspaceDialog,
|
||||||
|
setShowWorkspaceDialog: state.setShowWorkspaceDialog,
|
||||||
|
workspaceLink: state.workspaceLink,
|
||||||
|
stopWorkspace: state.stopWorkspace,
|
||||||
|
workspaceTab: state.workspaceTab,
|
||||||
|
setWorkspaceTab: state.setWorkspaceTab,
|
||||||
|
selectWorkspace: state.selectWorkspace,
|
||||||
|
})))
|
||||||
const linkItems: LinkItem[] = [
|
const linkItems: LinkItem[] = [
|
||||||
{
|
{
|
||||||
key: 'webide' as LinkItemKey,
|
key: 'webide' as LinkItemKey,
|
||||||
@@ -231,13 +237,12 @@ export function WorkspaceDetailDialog() {
|
|||||||
getUrl: (data) => data.codebuddycn
|
getUrl: (data) => data.codebuddycn
|
||||||
},
|
},
|
||||||
].sort((a, b) => (a.order || 0) - (b.order || 0))
|
].sort((a, b) => (a.order || 0) - (b.order || 0))
|
||||||
|
console.log('workspaceLink', selectWorkspace)
|
||||||
return (
|
return (
|
||||||
<Dialog open={showWorkspaceDialog} onOpenChange={setShowWorkspaceDialog}>
|
<Dialog open={showWorkspaceDialog} onOpenChange={setShowWorkspaceDialog}>
|
||||||
<DialogContent className="max-w-md! bg-white">
|
<DialogContent className="max-w-md! bg-white">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="text-neutral-900">打开工作区</DialogTitle>
|
<DialogTitle className="text-neutral-900">工作区</DialogTitle>
|
||||||
<DialogDescription className="text-neutral-500">选择一个编辑器或方式来打开工作区</DialogDescription>
|
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
{/* Tab 导航 */}
|
{/* Tab 导航 */}
|
||||||
<div className="flex border-b border-neutral-200">
|
<div className="flex border-b border-neutral-200">
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { useRepoStore } from './store/index'
|
import { useRepoStore } from './store/index'
|
||||||
|
import { useShallow } from 'zustand/shallow'
|
||||||
import { RepoCard } from './components/RepoCard'
|
import { RepoCard } from './components/RepoCard'
|
||||||
import { EditRepoDialog } from './modules/EditRepoDialog'
|
import { EditRepoDialog } from './modules/EditRepoDialog'
|
||||||
import { CreateRepoDialog } from './modules/CreateRepoDialog'
|
import { CreateRepoDialog } from './modules/CreateRepoDialog'
|
||||||
@@ -12,7 +13,22 @@ import Fuse from 'fuse.js'
|
|||||||
import { useNavigate } from '@tanstack/react-router'
|
import { useNavigate } from '@tanstack/react-router'
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
const { list, refresh, loading, editRepo, setEditRepo, workspaceList, showEditDialog, setShowEditDialog, showCreateDialog, setShowCreateDialog, startWorkspace, deleteItem, setSelectedSyncRepo, setSyncDialogOpen } = useRepoStore()
|
const { list, refresh, loading, editRepo, setEditRepo, workspaceList, showEditDialog, setShowEditDialog, showCreateDialog, setShowCreateDialog, startWorkspace, deleteItem, setSelectedSyncRepo, setSyncDialogOpen } = useRepoStore(useShallow((state) => ({
|
||||||
|
list: state.list,
|
||||||
|
refresh: state.refresh,
|
||||||
|
loading: state.loading,
|
||||||
|
editRepo: state.editRepo,
|
||||||
|
setEditRepo: state.setEditRepo,
|
||||||
|
workspaceList: state.workspaceList,
|
||||||
|
showEditDialog: state.showEditDialog,
|
||||||
|
setShowEditDialog: state.setShowEditDialog,
|
||||||
|
showCreateDialog: state.showCreateDialog,
|
||||||
|
setShowCreateDialog: state.setShowCreateDialog,
|
||||||
|
startWorkspace: state.startWorkspace,
|
||||||
|
deleteItem: state.deleteItem,
|
||||||
|
setSelectedSyncRepo: state.setSelectedSyncRepo,
|
||||||
|
setSyncDialogOpen: state.setSyncDialogOpen,
|
||||||
|
})))
|
||||||
const [searchQuery, setSearchQuery] = useState('')
|
const [searchQuery, setSearchQuery] = useState('')
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user