mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-10-24 19:27:23 +00:00
fix(client): compose shared buttons for two disclosures and seed re-enabled ask drafts
Compose the shared Button for the memory-artifacts and web-search disclosure rows, keeping only their geometry local. The web-search row keeps its instant hover by suppressing the recipe's color transition, since the chevron beside it reveals without a fade and the existing test pins that. Seed the ask-specific draft when Save drafts is re-enabled. An answer captured while saving was off has no persisted ask draft for autosave to restore, so expanding opened an empty composer and the next collapse read that empty value back over the in-memory answer.
This commit is contained in:
parent
bf7ae2549b
commit
3565f77171
3 changed files with 22 additions and 12 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import { useId, useMemo, useState } from 'react';
|
||||
import { ChevronDown } from 'lucide-react';
|
||||
import { Tools } from 'librechat-data-provider';
|
||||
import { disclosureChevronVariants } from '@librechat/client';
|
||||
import { Button, disclosureChevronVariants } from '@librechat/client';
|
||||
import type { MemoryArtifact, TAttachment } from 'librechat-data-provider';
|
||||
import { toolPanelSpacingClassName } from './disclosure';
|
||||
import { useExpandCollapse, useLocalize } from '~/hooks';
|
||||
|
|
@ -61,12 +61,12 @@ export default function MemoryArtifacts({ attachments }: { attachments?: TAttach
|
|||
return (
|
||||
<>
|
||||
<div className="relative my-1 flex h-5 shrink-0 items-center gap-2.5">
|
||||
<button
|
||||
<Button
|
||||
variant="ghost"
|
||||
className={cn(
|
||||
'group/disclosure inline-flex w-full items-center gap-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-heavy',
|
||||
'group/disclosure h-auto w-full justify-start gap-2 rounded-none p-0 font-normal hover:bg-transparent',
|
||||
hasErrors ? 'text-status-error' : 'text-text-secondary',
|
||||
)}
|
||||
type="button"
|
||||
onClick={() => setShowInfo((prev) => !prev)}
|
||||
aria-expanded={showInfo}
|
||||
aria-controls={contentId}
|
||||
|
|
@ -104,7 +104,7 @@ export default function MemoryArtifacts({ attachments }: { attachments?: TAttach
|
|||
)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
id={contentId}
|
||||
|
|
|
|||
|
|
@ -282,13 +282,15 @@ export default function WebSearch({
|
|||
{completedText}
|
||||
</span>
|
||||
<div className="relative flex h-5 items-center gap-1.5">
|
||||
<button
|
||||
type="button"
|
||||
<Button
|
||||
variant="ghost"
|
||||
className={cn(
|
||||
'tool-status-text group/disclosure flex h-5 min-w-0 items-center gap-2 rounded-full',
|
||||
hasSourceData
|
||||
? 'text-text-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-heavy'
|
||||
: 'pointer-events-none text-text-secondary',
|
||||
'tool-status-text group/disclosure h-5 min-w-0 justify-start gap-2 rounded-full p-0 font-normal text-text-secondary hover:bg-transparent',
|
||||
/** This row is a status line, not a padded control: the shared
|
||||
* recipe's color transition would turn its hover into a fade,
|
||||
* and the chevron reveal beside it is deliberately instant. */
|
||||
'transition-none',
|
||||
!hasSourceData && 'pointer-events-none disabled:opacity-100',
|
||||
)}
|
||||
disabled={!hasSourceData}
|
||||
onClick={hasSourceData ? handleToggleSources : undefined}
|
||||
|
|
@ -311,7 +313,7 @@ export default function WebSearch({
|
|||
aria-hidden="true"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</Button>
|
||||
{hasDetails && (
|
||||
<HoverCard openDelay={50} open={showDetails} onOpenChange={setShowDetails}>
|
||||
{/* Composed through `asChild` so the shared Button owns the
|
||||
|
|
|
|||
|
|
@ -212,6 +212,14 @@ export default function useAskAnswerMode(conversationId?: string | null) {
|
|||
* drafts are disabled, perform that handoff directly. */
|
||||
if (!batchMode && !saveDrafts) {
|
||||
formContext?.setValue('text', answerText);
|
||||
} else if (!batchMode && answerText) {
|
||||
/** Drafts were re-enabled after this answer was captured with saving
|
||||
* off, so no ask draft exists for autosave to restore: the composer
|
||||
* would open empty and the next collapse would read that empty
|
||||
* value back over the in-memory answer. Seed it so the handoff has
|
||||
* something to read. The in-memory value is authoritative because
|
||||
* `setAnswerText` writes both while saving is on. */
|
||||
setDraft({ id: getAskAnswerDraftId(liveAsk.actionId), value: answerText });
|
||||
}
|
||||
setCollapsedIds((prev) => prev.filter((id) => id !== liveAsk.actionId));
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue