mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
fix(web): isolate home template cards beneath sticky header (#42906)
This commit is contained in:
3 files changed
+33
-30
No files matched your search
@@ -35,7 +35,7 @@ async function pngResponse(width: number, height: number) {
|
||||
// object URL is unusable. These are the additional browser regression contracts.
|
||||
it('decodes binary assets and retires object URLs on source replacement and unmount', async () => {
|
||||
request.mockReset()
|
||||
request.mockImplementation(() => pngResponse(2, 3))
|
||||
request.mockResolvedValue(await pngResponse(2, 3))
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: { queries: { retry: false, staleTime: 300_000 } },
|
||||
})
|
||||
@@ -49,24 +49,22 @@ it('decodes binary assets and retires object URLs on source replacement and unmo
|
||||
const screen = await render(view('_assets/first.png'))
|
||||
try {
|
||||
await expect
|
||||
.poll(() => screen.getByTestId('gallery-image').element().getAttribute('src'))
|
||||
.toMatch(/^blob:/)
|
||||
.element(screen.getByTestId('gallery-image'), { timeout: 5_000 })
|
||||
.toHaveAttribute('src', expect.stringMatching(/^blob:/))
|
||||
const firstImage = screen.getByTestId('gallery-image').element()
|
||||
if (!(firstImage instanceof HTMLImageElement)) throw new TypeError('Expected an image')
|
||||
await firstImage.decode()
|
||||
expect([firstImage.naturalWidth, firstImage.naturalHeight]).toEqual([2, 3])
|
||||
const firstUrl = firstImage.src
|
||||
expect(revoke).not.toHaveBeenCalled()
|
||||
request.mockImplementation(() => pngResponse(4, 5))
|
||||
request.mockResolvedValue(await pngResponse(4, 5))
|
||||
await screen.rerender(view('_assets/second.png'))
|
||||
await expect
|
||||
.poll(() => screen.getByTestId('gallery-image').element().getAttribute('src'))
|
||||
.not.toBe(firstUrl)
|
||||
await expect
|
||||
.poll(() => screen.getByTestId('gallery-image').element().getAttribute('src'))
|
||||
.toMatch(/^blob:/)
|
||||
.element(screen.getByTestId('gallery-image'), { timeout: 5_000 })
|
||||
.toHaveAttribute('src', expect.stringMatching(/^blob:/))
|
||||
const secondImage = screen.getByTestId('gallery-image').element()
|
||||
if (!(secondImage instanceof HTMLImageElement)) throw new TypeError('Expected an image')
|
||||
expect(secondImage.src).not.toBe(firstUrl)
|
||||
await secondImage.decode()
|
||||
expect([secondImage.naturalWidth, secondImage.naturalHeight]).toEqual([4, 5])
|
||||
expect(revoke).toHaveBeenCalledWith(firstUrl)
|
||||
@@ -115,14 +113,14 @@ it('recovers after a malformed asset causes the real gallery to remove its image
|
||||
.element(screen.getByRole('button', { name: /^common\.imageGallery\.previewImage/ }))
|
||||
.not.toBeInTheDocument()
|
||||
|
||||
request.mockImplementation(() => pngResponse(6, 7))
|
||||
request.mockResolvedValue(await pngResponse(6, 7))
|
||||
await screen.rerender(view('_assets/valid.png'))
|
||||
await expect
|
||||
.element(screen.getByRole('button', { name: /^common\.imageGallery\.previewImage/ }))
|
||||
.toBeVisible()
|
||||
await expect
|
||||
.poll(() => screen.getByTestId('gallery-image').element().getAttribute('src'))
|
||||
.toMatch(/^blob:/)
|
||||
.element(screen.getByTestId('gallery-image'), { timeout: 5_000 })
|
||||
.toHaveAttribute('src', expect.stringMatching(/^blob:/))
|
||||
const recoveredImage = screen.getByTestId('gallery-image').element()
|
||||
if (!(recoveredImage instanceof HTMLImageElement)) throw new TypeError('Expected an image')
|
||||
await recoveredImage.decode()
|
||||
|
||||
@@ -440,21 +440,26 @@ export function HomeContent() {
|
||||
/>
|
||||
|
||||
<div className={cn('relative flex flex-1 shrink-0 grow flex-col pb-6')}>
|
||||
<section
|
||||
aria-labelledby="home-templates-title"
|
||||
className={cn('shrink-0 content-start gap-2.5 px-8', MAIN_NAV_APP_CARD_GRID_CLASS_NAME)}
|
||||
>
|
||||
{searchFilteredList.map((app) => (
|
||||
<TemplateCard
|
||||
key={app.app_id}
|
||||
app={app}
|
||||
canCreate={canCreateApp}
|
||||
onCreate={() => handleCreateFromTemplate(app)}
|
||||
onTry={handleTryApp}
|
||||
/>
|
||||
))}
|
||||
{searchFilteredList.length === 0 && (
|
||||
<div role="status" className="col-span-full rounded-lg bg-workflow-process-bg p-4">
|
||||
<section aria-labelledby="home-templates-title" className="shrink-0 px-8">
|
||||
{searchFilteredList.length > 0 ? (
|
||||
<ul
|
||||
// Safari drops list semantics from grid lists after preflight removes markers.
|
||||
// oxlint-disable-next-line jsx-a11y/no-redundant-roles -- Restore Safari list semantics.
|
||||
role="list"
|
||||
className={cn('content-start gap-2.5', MAIN_NAV_APP_CARD_GRID_CLASS_NAME)}
|
||||
>
|
||||
{searchFilteredList.map((app) => (
|
||||
<TemplateCard
|
||||
key={app.app_id}
|
||||
app={app}
|
||||
canCreate={canCreateApp}
|
||||
onCreate={() => handleCreateFromTemplate(app)}
|
||||
onTry={handleTryApp}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
) : (
|
||||
<div role="status" className="rounded-lg bg-workflow-process-bg p-4">
|
||||
<p className="title-md-semi-bold text-text-primary">
|
||||
{t(($) => $['newApp.noTemplateFound'], { ns: 'app' })}
|
||||
</p>
|
||||
|
||||
@@ -56,9 +56,9 @@ export function TemplateCard({ app, canCreate, onCreate, onTry }: TemplateCardPr
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
<li
|
||||
className={cn(
|
||||
'group relative col-span-1 flex h-35.5 flex-col overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg pb-3 text-left shadow-xs shadow-shadow-shadow-3',
|
||||
'group relative isolate col-span-1 flex h-35.5 flex-col overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg pb-3 text-left shadow-xs shadow-shadow-shadow-3',
|
||||
isClickable && 'cursor-pointer',
|
||||
)}
|
||||
>
|
||||
@@ -129,6 +129,6 @@ export function TemplateCard({ app, canCreate, onCreate, onTry }: TemplateCardPr
|
||||
{app.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user