webui: Architecture and UI improvements (#19596)

This commit is contained in:
Aleksander Grygier 2026-02-14 09:06:41 +01:00 committed by GitHub
parent 2d8015e8a4
commit baa12f3831
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
76 changed files with 1061 additions and 2818 deletions

View file

@ -1,14 +1,14 @@
<script module lang="ts">
import { defineMeta } from '@storybook/addon-svelte-csf';
import ChatForm from '$lib/components/app/chat/ChatForm/ChatForm.svelte';
import ChatScreenForm from '$lib/components/app/chat/ChatScreen/ChatScreenForm.svelte';
import { expect } from 'storybook/test';
import jpgAsset from './fixtures/assets/1.jpg?url';
import svgAsset from './fixtures/assets/hf-logo.svg?url';
import pdfAsset from './fixtures/assets/example.pdf?raw';
const { Story } = defineMeta({
title: 'Components/ChatScreen/ChatForm',
component: ChatForm,
title: 'Components/ChatScreen/ChatScreenForm',
component: ChatScreenForm,
parameters: {
layout: 'centered'
}
@ -44,7 +44,8 @@
<Story
name="Default"
args={{ class: 'max-w-[56rem] w-[calc(100vw-2rem)]' }}
play={async ({ canvas, userEvent }) => {
play={async (context) => {
const { canvas, userEvent } = context;
const textarea = await canvas.findByRole('textbox');
const submitButton = await canvas.findByRole('button', { name: 'Send' });
@ -74,7 +75,8 @@
class: 'max-w-[56rem] w-[calc(100vw-2rem)]',
uploadedFiles: fileAttachments
}}
play={async ({ canvas }) => {
play={async (context) => {
const { canvas } = context;
const jpgAttachment = canvas.getByAltText('1.jpg');
const svgAttachment = canvas.getByAltText('hf-logo.svg');
const pdfFileExtension = canvas.getByText('PDF');

View file

@ -68,18 +68,22 @@ You can also test inline links like https://example.com or https://docs.python.o
All links should have \`target="_blank"\` and \`rel="noopener noreferrer"\` attributes for security.`,
class: 'max-w-[56rem] w-[calc(100vw-2rem)]'
}}
play={async ({ canvasElement }) => {
play={async (context) => {
const { canvasElement } = context;
// Wait for component to render
await new Promise((resolve) => setTimeout(resolve, 100));
// Find all links in the rendered content
const links = canvasElement.querySelectorAll('a[href]');
const links = (canvasElement as HTMLElement).querySelectorAll(
'a[href]'
) as NodeListOf<HTMLAnchorElement>;
const linkList = Array.from(links) as HTMLAnchorElement[];
// Test that we have the expected number of links
expect(links.length).toBeGreaterThan(0);
// Test each link for proper attributes
links.forEach((link) => {
links.forEach((link: HTMLAnchorElement) => {
const href = link.getAttribute('href');
// Test that external links have proper security attributes
@ -90,37 +94,35 @@ All links should have \`target="_blank"\` and \`rel="noopener noreferrer"\` attr
});
// Test specific links exist
const hugginFaceLink = Array.from(links).find(
const hugginFaceLink = linkList.find(
(link) => link.getAttribute('href') === 'https://huggingface.co'
);
expect(hugginFaceLink).toBeTruthy();
expect(hugginFaceLink?.textContent).toBe('Hugging Face Homepage');
const githubLink = Array.from(links).find(
const githubLink = linkList.find(
(link) => link.getAttribute('href') === 'https://github.com/ggml-org/llama.cpp'
);
expect(githubLink).toBeTruthy();
expect(githubLink?.textContent).toBe('GitHub Repository');
const openaiLink = Array.from(links).find(
(link) => link.getAttribute('href') === 'https://openai.com'
);
const openaiLink = linkList.find((link) => link.getAttribute('href') === 'https://openai.com');
expect(openaiLink).toBeTruthy();
expect(openaiLink?.textContent).toBe('OpenAI Website');
const googleLink = Array.from(links).find(
const googleLink = linkList.find(
(link) => link.getAttribute('href') === 'https://www.google.com'
);
expect(googleLink).toBeTruthy();
expect(googleLink?.textContent).toBe('Google Search');
// Test inline links (auto-linked URLs)
const exampleLink = Array.from(links).find(
const exampleLink = linkList.find(
(link) => link.getAttribute('href') === 'https://example.com'
);
expect(exampleLink).toBeTruthy();
const pythonDocsLink = Array.from(links).find(
const pythonDocsLink = linkList.find(
(link) => link.getAttribute('href') === 'https://docs.python.org'
);
expect(pythonDocsLink).toBeTruthy();