Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): support query code when creating new pages #3940

Merged
merged 13 commits into from
Mar 12, 2025
62 changes: 54 additions & 8 deletions ee/tabby-ui/app/pages/components/new-page-form.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useContext, useMemo, useRef, useState } from 'react'
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import * as z from 'zod'

import { makeFormErrorHandler } from '@/lib/tabby/gql'
import { ExtendedCombinedError } from '@/lib/types'
import { isCodeSourceContext } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import {
Form,
Expand All @@ -14,22 +16,49 @@ import {
} from '@/components/ui/form'
import { IconArrowRight } from '@/components/ui/icons'
import { Input } from '@/components/ui/input'
import { RepoSelect } from '@/components/textarea-search/repo-select'

import { PageContext } from './page-context'

export function NewPageForm({
onSubmit
}: {
onSubmit: (title: string) => Promise<ExtendedCombinedError | void>
onSubmit: (v: {
titlePrompt: string
codeSourceId: string | undefined
}) => Promise<ExtendedCombinedError | void>
}) {
const { fetchingContextInfo, contextInfo } = useContext(PageContext)
const inputRef = useRef<HTMLInputElement | null>(null)
const formSchema = z.object({
title: z.string().trim()
titlePrompt: z.string().trim()
})
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema)
})
const title = form.watch('title')
const titlePrompt = form.watch('titlePrompt')

const [selectedRepoId, setSelectedRepoId] = useState<string | undefined>()
const repos = useMemo(() => {
return contextInfo?.sources.filter(x => isCodeSourceContext(x.sourceKind))
}, [contextInfo?.sources])

const focusInput = () => {
inputRef.current?.focus()
}

const handleSelectRepo = (id: string | undefined) => {
setSelectedRepoId(id)
setTimeout(() => {
focusInput()
}, 10)
}

const handleSubmit = async (values: z.infer<typeof formSchema>) => {
const error = await onSubmit(values.title.trim())
const error = await onSubmit({
titlePrompt: values.titlePrompt.trim(),
codeSourceId: selectedRepoId
})

if (error) {
makeFormErrorHandler(form)(error)
Expand All @@ -42,15 +71,22 @@ export function NewPageForm({
<div className="flex w-full items-center gap-2">
<FormField
control={form.control}
name="title"
render={({ field }) => (
name="titlePrompt"
render={({ field: { ref, ...rest } }) => (
<FormItem className="flex-1">
<FormControl>
<Input
autoFocus
className="h-auto w-full border-none text-3xl font-semibold shadow-none outline-none focus-visible:ring-0"
placeholder="What is your page about?"
{...field}
autoCapitalize="none"
autoComplete="off"
autoCorrect="off"
ref={e => {
ref(e)
inputRef.current = e
}}
{...rest}
/>
</FormControl>
<FormMessage />
Expand All @@ -60,11 +96,21 @@ export function NewPageForm({
<Button
className="h-auto w-auto px-2"
type="submit"
disabled={!title}
disabled={!titlePrompt}
>
<IconArrowRight />
</Button>
</div>
<div className="mt-4 pl-3" onClick={e => focusInput()}>
<RepoSelect
repos={repos}
isInitializing={fetchingContextInfo}
value={selectedRepoId}
onChange={handleSelectRepo}
placeholder="Select repository"
showChevron
/>
</div>
<div className="my-2">
<FormMessage />
</div>
Expand Down
2 changes: 1 addition & 1 deletion ee/tabby-ui/app/pages/components/page-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function PageContent({ page, onUpdate }: Props) {
<Button
size="sm"
variant="ghost"
className="h-auto gap-0.5 px-2 py-1 font-normal"
className="h-auto gap-0.5 px-2 py-1 font-medium text-foreground/60"
disabled={isLoading}
onClick={() => {
setShowForm(true)
Expand Down
4 changes: 3 additions & 1 deletion ee/tabby-ui/app/pages/components/page-context.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createContext, Dispatch, SetStateAction } from 'react'

import { MoveSectionDirection } from '@/lib/gql/generates/graphql'
import { ContextInfo, MoveSectionDirection } from '@/lib/gql/generates/graphql'

type PageContextValue = {
mode: 'edit' | 'view'
Expand All @@ -18,6 +18,8 @@ type PageContextValue = {
) => Promise<void>
pageIdFromURL: string | undefined
isNew: boolean
fetchingContextInfo: boolean
contextInfo: ContextInfo | undefined
}

export const PageContext = createContext<PageContextValue>(
Expand Down
Loading