mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix(web): align compact dialog titles (#1253)
This commit is contained in:
@@ -1431,6 +1431,7 @@ export function NewSession(props: {
|
||||
confirmingLabel={t('codexSync.duplicates.confirm.confirming')}
|
||||
onConfirm={handleMergeDuplicateSessions}
|
||||
isPending={isMergingDuplicateSessions}
|
||||
centerTitle
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -59,8 +59,10 @@ export function RenameSessionDialog(props: RenameSessionDialogProps) {
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
|
||||
<DialogContent className="max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('dialog.rename.title')}</DialogTitle>
|
||||
<DialogHeader className="pr-0">
|
||||
<DialogTitle className="min-h-6 px-10 text-center leading-6">
|
||||
{t('dialog.rename.title')}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<form onSubmit={handleSubmit} className="mt-4 flex flex-col gap-4">
|
||||
<input
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import { render, screen, within } from '@testing-library/react'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { I18nProvider } from '@/lib/i18n-context'
|
||||
import { ToastProvider } from '@/lib/toast-context'
|
||||
import { RenameSessionDialog } from './RenameSessionDialog'
|
||||
import { SessionExportDialog } from './SessionExportDialog'
|
||||
import { UriConfirmDialog } from './UriConfirmDialog'
|
||||
|
||||
function renderWithProviders(content: React.ReactNode) {
|
||||
return render(
|
||||
<I18nProvider>
|
||||
<ToastProvider>{content}</ToastProvider>
|
||||
</I18nProvider>
|
||||
)
|
||||
}
|
||||
|
||||
function expectCenteredTitle(name: string) {
|
||||
const dialog = screen.getByRole('dialog')
|
||||
const title = within(dialog).getByRole('heading', { name })
|
||||
|
||||
expect(title.parentElement).toHaveClass('pr-0')
|
||||
expect(title).toHaveClass('min-h-6', 'px-10', 'text-center', 'leading-6')
|
||||
expect(within(dialog).getByRole('button', { name: 'Close' })).toHaveClass('top-3', 'h-8')
|
||||
}
|
||||
|
||||
describe('session dialog title alignment', () => {
|
||||
it('centers the rename dialog title on the close button centerline', () => {
|
||||
renderWithProviders(
|
||||
<RenameSessionDialog
|
||||
isOpen={true}
|
||||
onClose={vi.fn()}
|
||||
currentName="Session"
|
||||
onRename={vi.fn(async () => {})}
|
||||
isPending={false}
|
||||
/>
|
||||
)
|
||||
|
||||
expectCenteredTitle('Rename Session')
|
||||
})
|
||||
|
||||
it('centers the export dialog title on the close button centerline', () => {
|
||||
renderWithProviders(
|
||||
<SessionExportDialog
|
||||
isOpen={true}
|
||||
onClose={vi.fn()}
|
||||
sessionId="session-1"
|
||||
api={null}
|
||||
/>
|
||||
)
|
||||
|
||||
expectCenteredTitle('Export conversation')
|
||||
})
|
||||
|
||||
it('centers the external-link dialog title on the close button centerline', () => {
|
||||
renderWithProviders(
|
||||
<UriConfirmDialog
|
||||
open={true}
|
||||
url="obsidian://open"
|
||||
scheme="obsidian"
|
||||
onCancel={vi.fn()}
|
||||
onOpen={vi.fn()}
|
||||
onAlwaysAllow={vi.fn()}
|
||||
/>
|
||||
)
|
||||
|
||||
expectCenteredTitle('Open this link?')
|
||||
})
|
||||
})
|
||||
@@ -101,8 +101,10 @@ export function SessionExportDialog(props: SessionExportDialogProps) {
|
||||
return (
|
||||
<Dialog open={props.isOpen} onOpenChange={(open) => !open && handleClose()}>
|
||||
<DialogContent className="max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('session.export.title')}</DialogTitle>
|
||||
<DialogHeader className="pr-0">
|
||||
<DialogTitle className="min-h-6 px-10 text-center leading-6">
|
||||
{t('session.export.title')}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="mt-2">
|
||||
{t('session.export.description')}
|
||||
</DialogDescription>
|
||||
|
||||
@@ -391,6 +391,7 @@ export function SessionHeader(props: {
|
||||
confirmingLabel={t('dialog.reopen.dismiss')}
|
||||
onConfirm={async () => setReopenError(null)}
|
||||
isPending={false}
|
||||
centerTitle
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -419,6 +420,7 @@ export function SessionHeader(props: {
|
||||
onConfirm={archiveSession}
|
||||
isPending={isPending}
|
||||
destructive
|
||||
centerTitle
|
||||
/>
|
||||
|
||||
<ConfirmDialog
|
||||
@@ -440,6 +442,7 @@ export function SessionHeader(props: {
|
||||
onConfirm={handleDelete}
|
||||
isPending={isPending}
|
||||
destructive
|
||||
centerTitle
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -886,6 +886,7 @@ function SessionItem(props: {
|
||||
confirmingLabel={t('dialog.reopen.dismiss')}
|
||||
onConfirm={async () => setReopenError(null)}
|
||||
isPending={false}
|
||||
centerTitle
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -919,6 +920,7 @@ function SessionItem(props: {
|
||||
onConfirm={archiveSession}
|
||||
isPending={isPending}
|
||||
destructive
|
||||
centerTitle
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -933,6 +935,7 @@ function SessionItem(props: {
|
||||
onConfirm={deleteSession}
|
||||
isPending={isPending}
|
||||
destructive
|
||||
centerTitle
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
|
||||
@@ -38,8 +38,10 @@ export function UriConfirmDialog(props: UriConfirmDialogProps) {
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={(isOpen) => !isOpen && onCancel()}>
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('dialog.uri.title')}</DialogTitle>
|
||||
<DialogHeader className="pr-0">
|
||||
<DialogTitle className="min-h-6 px-10 text-center leading-6">
|
||||
{t('dialog.uri.title')}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<DialogDescription className="mt-2">
|
||||
{t('dialog.uri.description')}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { render, screen, within } from '@testing-library/react'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { I18nProvider } from '@/lib/i18n-context'
|
||||
import { ConfirmDialog } from './ConfirmDialog'
|
||||
|
||||
function renderDialog(centerTitle = false) {
|
||||
render(
|
||||
<I18nProvider>
|
||||
<ConfirmDialog
|
||||
isOpen={true}
|
||||
onClose={vi.fn()}
|
||||
title="Archive Session"
|
||||
description="Archive this session?"
|
||||
confirmLabel="Archive"
|
||||
confirmingLabel="Archiving..."
|
||||
onConfirm={vi.fn(async () => {})}
|
||||
isPending={false}
|
||||
centerTitle={centerTitle}
|
||||
/>
|
||||
</I18nProvider>
|
||||
)
|
||||
}
|
||||
|
||||
describe('ConfirmDialog', () => {
|
||||
it('centers an opted-in title on the close button centerline', () => {
|
||||
renderDialog(true)
|
||||
|
||||
const dialog = screen.getByRole('dialog')
|
||||
const title = within(dialog).getByRole('heading', { name: 'Archive Session' })
|
||||
|
||||
expect(title.parentElement).toHaveClass('pr-0')
|
||||
expect(title).toHaveClass('min-h-6', 'px-10', 'text-center', 'leading-6')
|
||||
expect(within(dialog).getByRole('button', { name: 'Close' })).toHaveClass('top-3', 'h-8')
|
||||
})
|
||||
|
||||
it('keeps the default dialog title layout when centering is not requested', () => {
|
||||
renderDialog()
|
||||
|
||||
const title = screen.getByRole('heading', { name: 'Archive Session' })
|
||||
|
||||
expect(title.parentElement).toHaveClass('pr-12')
|
||||
expect(title).not.toHaveClass('min-h-6', 'px-10', 'leading-6')
|
||||
})
|
||||
})
|
||||
@@ -19,6 +19,7 @@ type ConfirmDialogProps = {
|
||||
onConfirm: () => Promise<void>
|
||||
isPending: boolean
|
||||
destructive?: boolean
|
||||
centerTitle?: boolean
|
||||
}
|
||||
|
||||
export function ConfirmDialog(props: ConfirmDialogProps) {
|
||||
@@ -32,7 +33,8 @@ export function ConfirmDialog(props: ConfirmDialogProps) {
|
||||
confirmingLabel,
|
||||
onConfirm,
|
||||
isPending,
|
||||
destructive = false
|
||||
destructive = false,
|
||||
centerTitle = false
|
||||
} = props
|
||||
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
@@ -61,8 +63,14 @@ export function ConfirmDialog(props: ConfirmDialogProps) {
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
|
||||
<DialogContent className="max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{title}</DialogTitle>
|
||||
<DialogHeader className={centerTitle ? 'pr-0' : undefined}>
|
||||
<DialogTitle
|
||||
className={centerTitle
|
||||
? 'min-h-6 px-10 text-center leading-6'
|
||||
: undefined}
|
||||
>
|
||||
{title}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="mt-2 whitespace-pre-line">
|
||||
{description}
|
||||
</DialogDescription>
|
||||
|
||||
Reference in New Issue
Block a user