From 5124086501985a220494c264417855ad215de0a3 Mon Sep 17 00:00:00 2001 From: aliang <1098486429@qq.com> Date: Sat, 27 Apr 2024 00:21:24 +0800 Subject: [PATCH] feat(ui): integrate repository list (#1975) * feat(ui): integrate repository list * format * gql --- .../files/components/file-directory-view.tsx | 9 +- .../app/files/components/file-tree-header.tsx | 41 +++++--- .../app/files/components/file-tree-panel.tsx | 6 +- .../app/files/components/file-tree.tsx | 20 ++-- .../files/components/source-code-browser.tsx | 99 +++++++++++++------ ee/tabby-ui/app/files/components/utils.ts | 56 ++++++++++- ee/tabby-ui/lib/tabby/gql.ts | 3 +- 7 files changed, 166 insertions(+), 68 deletions(-) diff --git a/ee/tabby-ui/app/files/components/file-directory-view.tsx b/ee/tabby-ui/app/files/components/file-directory-view.tsx index 41afcbdc34f6..110c543c9efe 100644 --- a/ee/tabby-ui/app/files/components/file-directory-view.tsx +++ b/ee/tabby-ui/app/files/components/file-directory-view.tsx @@ -10,7 +10,6 @@ import { Table, TableBody, TableCell, TableRow } from '@/components/ui/table' import { BlobHeader } from './blob-header' import { TFileTreeNode } from './file-tree' import { SourceCodeBrowserContext, TFileMapItem } from './source-code-browser' -import { resolveFileNameFromPath } from './utils' interface DirectoryViewProps extends React.HTMLAttributes { loading: boolean @@ -87,7 +86,7 @@ const DirectoryView: React.FC = ({ onClick={e => onClickFile(file)} className="cursor-pointer px-1 py-2 hover:text-primary hover:underline" > - {resolveFileNameFromPath(file.fullPath)} + {file.name} @@ -129,9 +128,9 @@ function getCurrentDirFromTree( } else { let pathSegments = path.split('/') let currentNodes: TFileTreeNode[] = treeData - while (pathSegments.length) { - let name = pathSegments.shift() - let node = find(currentNodes, t => t.name === name) + for (let i = 1; i < pathSegments.length; i++) { + const path = pathSegments.slice(0, i + 1).join('/') + let node = find(currentNodes, t => t.fullPath === path) if (node?.children) { currentNodes = node?.children } else { diff --git a/ee/tabby-ui/app/files/components/file-tree-header.tsx b/ee/tabby-ui/app/files/components/file-tree-header.tsx index 0aefc0a15334..e7ac1a24fea3 100644 --- a/ee/tabby-ui/app/files/components/file-tree-header.tsx +++ b/ee/tabby-ui/app/files/components/file-tree-header.tsx @@ -1,6 +1,7 @@ 'use client' import React, { useContext } from 'react' +import { isEmpty } from 'lodash-es' import { useQuery } from 'urql' import { graphql } from '@/lib/gql/generates' @@ -32,9 +33,12 @@ import { useTopbarProgress } from '@/components/topbar-progress-indicator' import { SourceCodeBrowserContext, TFileMap } from './source-code-browser' import { fetchEntriesFromPath, + generatePathPrefixFromPath, getDirectoriesFromBasename, + key2RepositoryKind, resolveFileNameFromPath, - resolveRepoNameFromPath + resolveRepoIdFromPath, + resolveRepoKindFromPath } from './utils' interface FileTreeHeaderProps extends React.HTMLAttributes {} @@ -47,8 +51,8 @@ type SearchOption = { } const repositorySearch = graphql(/* GraphQL */ ` - query RepositorySearch($repositoryName: String!, $pattern: String!) { - repositorySearch(repositoryName: $repositoryName, pattern: $pattern) { + query RepositorySearch($kind: RepositoryKind!, $id: ID!, $pattern: String!) { + repositorySearch(kind: $kind, id: $id, pattern: $pattern) { type path indices @@ -66,10 +70,18 @@ const FileTreeHeader: React.FC = ({ setActivePath, initialized, updateFileMap, - setExpandedKeys + setExpandedKeys, + fileMap } = useContext(SourceCodeBrowserContext) const { setProgress } = useTopbarProgress() - const curerntRepoName = resolveRepoNameFromPath(activePath) + + const prefix = generatePathPrefixFromPath(activePath) + const repoKind = resolveRepoKindFromPath(activePath) + const repoId = resolveRepoIdFromPath(activePath) + const curerntRepoName = React.useMemo(() => { + if (!prefix || isEmpty(fileMap)) return undefined + return fileMap?.[prefix]?.name + }, [prefix, fileMap]) const inputRef = React.useRef(null) const [input, setInput] = React.useState() @@ -83,10 +95,11 @@ const FileTreeHeader: React.FC = ({ const [{ data: repositorySearchData }] = useQuery({ query: repositorySearch, variables: { - repositoryName: curerntRepoName, + kind: key2RepositoryKind(repoKind), + id: repoId, pattern: repositorySearchPattern ?? '' }, - pause: !curerntRepoName || !repositorySearchPattern + pause: !prefix || !repositorySearchPattern }) React.useEffect(() => { @@ -122,7 +135,7 @@ const FileTreeHeader: React.FC = ({ const path = value.path if (!path) return - const fullPath = `${curerntRepoName}/${path}` + const fullPath = `${prefix}/${path}` try { setProgress(true) const entries = await fetchEntriesFromPath(fullPath) @@ -131,7 +144,7 @@ const FileTreeHeader: React.FC = ({ const patchMap: TFileMap = {} // fetch dirs for (const entry of entries) { - const path = `${curerntRepoName}/${entry.basename}` + const path = `${prefix}/${entry.basename}` patchMap[path] = { file: entry, name: resolveFileNameFromPath(path), @@ -140,7 +153,7 @@ const FileTreeHeader: React.FC = ({ } } const expandedKeys = initialExpandedDirs.map(dir => - [curerntRepoName, dir].filter(Boolean).join('/') + [prefix, dir].filter(Boolean).join('/') ) if (patchMap) { updateFileMap(patchMap) @@ -194,7 +207,7 @@ const FileTreeHeader: React.FC = ({