mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-07 06:19:43 -10:00
fix(web-shell): center the managed host empty conversation as one group
The host mount entry has no .appChatEmpty ancestor, so the managed empty conversation kept its full-height content box and pinned the composer to the bottom. Give host-mounted empty conversations the same shrink-to-content centering, mount the entry through the managedHome fill wrapper, and drop the empty trailing status row below the composer. Co-authored-by: Qwen-Coder <[email protected]>
This commit is contained in:
1 parent
e8e72184ec
commit
1a6d59469d
4 files changed
+73
-15
No files matched your search
@@ -720,6 +720,20 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Host-mounted managed home has no .appChatEmpty ancestor, so give its
|
||||
empty conversation the same shrink-to-content behavior here. The
|
||||
centered group must exclude the session header, which stays pinned at
|
||||
the top. */
|
||||
.chatPane[data-managed-home][data-managed-empty] .content {
|
||||
flex: 0 0 auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.chatPane[data-managed-home][data-managed-empty] {
|
||||
justify-content: center;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* The chat view (message list + composer) stays mounted while a panel is shown,
|
||||
just hidden — so the composer keeps its unsent draft and attachments instead
|
||||
of losing them on unmount. */
|
||||
|
||||
@@ -195,7 +195,7 @@ export function ManagedAgentWebShell(props: ManagedAgentWebShellProps) {
|
||||
<CompactModeContext.Provider value={false}>
|
||||
<div
|
||||
ref={setPortalRoot}
|
||||
className={`${shellStyles.app} ${theme === WebShellThemeId.Dark ? `${shellStyles.themeDark} dark` : shellStyles.themeLight} ${className ?? ''}`}
|
||||
className={`${shellStyles.app} ${shellStyles.managedHome} ${theme === WebShellThemeId.Dark ? `${shellStyles.themeDark} dark` : shellStyles.themeLight} ${className ?? ''}`}
|
||||
style={style}
|
||||
data-web-shell-root
|
||||
data-web-shell-shadcn
|
||||
|
||||
@@ -4025,6 +4025,38 @@ describe('ManagedSessionsPage', () => {
|
||||
},
|
||||
);
|
||||
|
||||
it('marks the managed home conversation as empty only without messages or failure', async () => {
|
||||
mocks.client.getTranscript.mockResolvedValue({
|
||||
events: [],
|
||||
lastEventId: 0,
|
||||
});
|
||||
await render('s1', 'en', provider, undefined, true, {
|
||||
hostSessionOnly: true,
|
||||
});
|
||||
expect(
|
||||
container
|
||||
.querySelector('[data-managed-home]')
|
||||
?.getAttribute('data-managed-empty'),
|
||||
).toBe('true');
|
||||
|
||||
await act(async () => root.unmount());
|
||||
container.remove();
|
||||
container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
root = createRoot(container);
|
||||
mocks.client.getSession.mockImplementation(async (id: string) =>
|
||||
id === 's1' ? { ...summary(id), failure: 'runtime lost' } : summary(id),
|
||||
);
|
||||
await render('s1', 'en', provider, undefined, true, {
|
||||
hostSessionOnly: true,
|
||||
});
|
||||
expect(
|
||||
container
|
||||
.querySelector('[data-managed-home]')
|
||||
?.getAttribute('data-managed-empty'),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it('renders Chinese Managed labels and states without English fallback overriding them', async () => {
|
||||
await render('s1', 'zh-CN');
|
||||
expect(container.querySelector('nav')?.getAttribute('aria-label')).toBe(
|
||||
|
||||
@@ -1697,6 +1697,11 @@ function ManagedSessionsContent({
|
||||
<section
|
||||
className={`${shellStyles.chatPane} ${home ? '' : 'gap-3'}`}
|
||||
data-managed-home={home || undefined}
|
||||
data-managed-empty={
|
||||
home && messages.length === 0 && !summary?.failure
|
||||
? true
|
||||
: undefined
|
||||
}
|
||||
aria-label={t('managed.conversation')}
|
||||
>
|
||||
{summary && home && (
|
||||
@@ -1984,7 +1989,7 @@ function ManagedSessionsContent({
|
||||
{summary?.failure && (
|
||||
<div
|
||||
role="alert"
|
||||
className="mx-auto mb-2 flex w-full max-w-[var(--chat-shell-width)] items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-[10px] text-xs leading-relaxed text-destructive"
|
||||
className="mx-auto mt-auto mb-2 flex w-full max-w-[var(--chat-shell-width)] items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-[10px] text-xs leading-relaxed text-destructive"
|
||||
>
|
||||
<span aria-hidden="true" className="mt-0.5 shrink-0">
|
||||
⚠
|
||||
@@ -1995,7 +2000,7 @@ function ManagedSessionsContent({
|
||||
{pendingElsewhere && !busy && (
|
||||
<div
|
||||
role="status"
|
||||
className="mb-2 flex items-center gap-3 text-sm text-muted-foreground"
|
||||
className="mx-auto mt-auto mb-2 flex w-full max-w-[var(--chat-shell-width)] items-center gap-3 text-sm text-muted-foreground"
|
||||
>
|
||||
<p>{t('managed.pendingElsewhere')}</p>
|
||||
<Button
|
||||
@@ -2010,7 +2015,7 @@ function ManagedSessionsContent({
|
||||
{pendingHere && !busy && (
|
||||
<div
|
||||
role="status"
|
||||
className="mx-auto mb-2 flex w-full max-w-[var(--chat-shell-width)] items-start justify-between gap-3 rounded-lg border bg-muted/40 px-3 py-[10px] text-xs leading-relaxed text-muted-foreground"
|
||||
className="mx-auto mt-auto mb-2 flex w-full max-w-[var(--chat-shell-width)] items-start justify-between gap-3 rounded-lg border bg-muted/40 px-3 py-[10px] text-xs leading-relaxed text-muted-foreground"
|
||||
>
|
||||
<p className="min-w-0 flex-1">{t('managed.uncertain')}</p>
|
||||
<Button
|
||||
@@ -2648,17 +2653,24 @@ function ManagedSessionsContent({
|
||||
{t('managed.approvalFixed')}
|
||||
</p>
|
||||
)}
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
{sessionId &&
|
||||
!active &&
|
||||
summary &&
|
||||
!summary.capabilities.canSend && (
|
||||
<span className="mr-auto text-sm text-muted-foreground">
|
||||
{t('managed.newRequired')}
|
||||
</span>
|
||||
)}
|
||||
{(!home || Boolean(text.trim())) && cancelButton}
|
||||
</div>
|
||||
{((sessionId &&
|
||||
!active &&
|
||||
summary &&
|
||||
!summary.capabilities.canSend) ||
|
||||
(!home && cancelButton) ||
|
||||
Boolean(text.trim())) && (
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
{sessionId &&
|
||||
!active &&
|
||||
summary &&
|
||||
!summary.capabilities.canSend && (
|
||||
<span className="mr-auto text-sm text-muted-foreground">
|
||||
{t('managed.newRequired')}
|
||||
</span>
|
||||
)}
|
||||
{(!home || Boolean(text.trim())) && cancelButton}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
cancelButton && (
|
||||
|
||||
Reference in new issue
Block a user